SkPDF: SkPDFGraphicState Lookup hashtabled

In Release, running `dm --src skp --config pdf`, I get a
speedup of about 1.2%.

SkPDFGraphicState class:
-   Holds the subset of SkPaint that maps to a PDF Graphics
    State
-   These fields are easily comparable, making hashtable
    comparisons easy.

SkPDFCanon:
-   findGraphicState() takes a SkPDFGraphicState, not a SkPaint
-   fGraphicStateRecords is a SkHashSet, not a SkTDArray

SkPDFGraphicState:
-   mode_for_pdf() replaces logic inside equivalent(), but is
    only called once per lookup.
-   emitObject() no longer modifies the SkPDFGraphicState to
    cache the SkPDFDict stucture.  (Since it is de-duped,
    this get no speedup).
-   Static Functions that don't use the canon return a plain
    SkPDFDict now.  No need for fPopulated.

SkTHash.h
-   SkHashSet::forall added

SkPDFDevice; SkPDFShader
-   Updated for new SkPDFGraphicState interface.

BUG=skia:3585

Review URL: https://codereview.chromium.org/1046293002
diff --git a/src/pdf/SkPDFCanon.h b/src/pdf/SkPDFCanon.h
index d0bef27..5198e7b 100644
--- a/src/pdf/SkPDFCanon.h
+++ b/src/pdf/SkPDFCanon.h
@@ -7,12 +7,13 @@
 #ifndef SkPDFCanon_DEFINED
 #define SkPDFCanon_DEFINED
 
+#include "SkPDFGraphicState.h"
 #include "SkPDFShader.h"
 #include "SkTDArray.h"
+#include "SkTHash.h"
 
 class SkBitmap;
 class SkPDFFont;
-class SkPDFGraphicState;
 class SkPDFBitmap;
 class SkPaint;
 
@@ -56,8 +57,8 @@
     SkPDFImageShader* findImageShader(const SkPDFShader::State&) const;
     void addImageShader(SkPDFImageShader*);
 
-    SkPDFGraphicState* findGraphicState(const SkPaint&) const;
-    void addGraphicState(SkPDFGraphicState*);
+    const SkPDFGraphicState* findGraphicState(const SkPDFGraphicState&) const;
+    void addGraphicState(const SkPDFGraphicState*);
 
     SkPDFBitmap* findBitmap(const SkBitmap&) const;
     void addBitmap(SkPDFBitmap*);
@@ -76,7 +77,20 @@
 
     SkTDArray<SkPDFImageShader*> fImageShaderRecords;
 
-    SkTDArray<SkPDFGraphicState*> fGraphicStateRecords;
+    struct WrapGS {
+        explicit WrapGS(const SkPDFGraphicState* ptr = NULL) : fPtr(ptr) {}
+        const SkPDFGraphicState* fPtr;
+        bool operator==(const WrapGS& rhs) const {
+            SkASSERT(fPtr);
+            SkASSERT(rhs.fPtr);
+            return *fPtr == *rhs.fPtr;
+        }
+        static uint32_t Hash(const WrapGS& w) {
+            SkASSERT(w.fPtr);
+            return w.fPtr->hash();
+        }
+    };
+    SkTHashSet<WrapGS, WrapGS::Hash> fGraphicStateRecords;
 
     SkTDArray<SkPDFBitmap*> fBitmapRecords;
 };