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/SkPDFGraphicState.h b/src/pdf/SkPDFGraphicState.h
index 85a324b..dddf439 100644
--- a/src/pdf/SkPDFGraphicState.h
+++ b/src/pdf/SkPDFGraphicState.h
@@ -13,19 +13,17 @@
#include "SkPaint.h"
#include "SkPDFTypes.h"
#include "SkTemplates.h"
+#include "SkChecksum.h"
+class SkPDFCanon;
class SkPDFFormXObject;
/** \class SkPDFGraphicState
SkPaint objects roughly correspond to graphic state dictionaries that can
be installed. So that a given dictionary is only output to the pdf file
- once, we want to canonicalize them. Static methods in this class manage
- a weakly referenced set of SkPDFGraphicState objects: when the last
- reference to a SkPDFGraphicState is removed, it removes itself from the
- static set of objects.
-
+ once, we want to canonicalize them.
*/
-class SkPDFGraphicState : public SkPDFDict {
+class SkPDFGraphicState : public SkPDFObject {
SK_DECLARE_INST_COUNT(SkPDFGraphicState)
public:
enum SkPDFSMaskMode {
@@ -33,8 +31,6 @@
kLuminosity_SMaskMode
};
- virtual ~SkPDFGraphicState();
-
// Override emitObject so that we can populate the dictionary on
// demand.
virtual void emitObject(SkWStream* stream,
@@ -57,32 +53,37 @@
* @param sMask The form xobject to use as a soft mask.
* @param invert Indicates if the alpha of the sMask should be inverted.
* @param sMaskMode Whether to use alpha or luminosity for the sMask.
+ *
+ * These are not de-duped.
*/
- static SkPDFGraphicState* GetSMaskGraphicState(SkPDFFormXObject* sMask,
- bool invert,
- SkPDFSMaskMode sMaskMode);
+ static SkPDFDict* GetSMaskGraphicState(SkPDFFormXObject* sMask,
+ bool invert,
+ SkPDFSMaskMode sMaskMode);
/** Get a graphic state that only unsets the soft mask. The reference
* count of the object is incremented and it is the caller's responsibility
* to unreference it when done. This is needed to accommodate the weak
* reference pattern used when the returned object is new and has no
* other references.
+ *
+ * The returned object is a singleton.
*/
- static SkPDFGraphicState* GetNoSMaskGraphicState();
+ static SkPDFDict* GetNoSMaskGraphicState();
- bool equals(const SkPaint&) const;
-
- // Only public for SK_DECLARE_STATIC_LAZY_PTR
- static SkPDFGraphicState* CreateNoSMaskGraphicState();
+ bool operator==(const SkPDFGraphicState& rhs) const {
+ return 0 == memcmp(&fStrokeWidth, &rhs.fStrokeWidth, 12);
+ }
+ uint32_t hash() const { return SkChecksum::Murmur3(&fStrokeWidth, 12); }
private:
- const SkPaint fPaint;
- bool fPopulated;
+ const SkScalar fStrokeWidth;
+ const SkScalar fStrokeMiter;
+ const uint8_t fAlpha;
+ const uint8_t fStrokeCap; // SkPaint::Cap
+ const uint8_t fStrokeJoin; // SkPaint::Join
+ const uint8_t fMode; // SkXfermode::Mode
- SkPDFGraphicState();
- SkPDFGraphicState(const SkPaint& paint);
-
- void populateDict();
+ SkPDFGraphicState(const SkPaint&);
typedef SkPDFDict INHERITED;
};