add optional manual global initialization

M    include/effects/SkAvoidXfermode.h
M    include/effects/SkDiscretePathEffect.h
M    include/effects/Sk1DPathEffect.h
M    include/effects/Sk2DPathEffect.h
M    include/effects/SkBlurDrawLooper.h
M    include/effects/SkPixelXorXfermode.h
M    include/effects/SkDashPathEffect.h
M    include/effects/SkColorMatrixFilter.h
M    include/effects/SkEmbossMaskFilter.h
M    include/effects/SkLayerDrawLooper.h
M    include/effects/SkGroupShape.h
M    include/effects/SkBlurImageFilter.h
M    include/effects/SkRectShape.h
A    include/effects/SkEffects.h
M    include/effects/SkCornerPathEffect.h
M    include/effects/SkGradientShader.h
M    include/effects/SkBlurMaskFilter.h
M    include/effects/SkLayerRasterizer.h
M    include/core/SkMallocPixelRef.h
M    include/core/SkFlattenable.h
M    include/core/SkShape.h
M    include/core/SkPixelRef.h
M    include/core/SkGraphics.h
M    include/core/SkPathEffect.h
M    include/core/SkPostConfig.h
M    include/core/SkXfermode.h
M    include/core/SkColorFilter.h
M    include/images/SkFlipPixelRef.h
M    include/images/SkImageRef_GlobalPool.h
M    src/effects/SkDashPathEffect.cpp
M    src/effects/SkColorMatrixFilter.cpp
M    src/effects/SkBlurImageFilter.cpp
M    src/effects/SkGroupShape.cpp
M    src/effects/SkCornerPathEffect.cpp
M    src/effects/SkGradientShader.cpp
M    src/effects/SkBlurMaskFilter.cpp
M    src/effects/SkAvoidXfermode.cpp
M    src/effects/Sk2DPathEffect.cpp
M    src/effects/SkBlurDrawLooper.cpp
M    src/effects/SkPixelXorXfermode.cpp
M    src/effects/SkColorFilters.cpp
M    src/effects/SkLayerDrawLooper.cpp
M    src/effects/SkRectShape.cpp
A    src/effects/SkEffects.cpp
M    src/effects/SkLayerRasterizer.cpp
M    src/effects/SkDiscretePathEffect.cpp
M    src/effects/Sk1DPathEffect.cpp
A    src/effects/SkEffects_none.cpp
M    src/core/SkPixelRef.cpp
M    src/core/SkGraphics.cpp
M    src/core/SkFlattenable.cpp
M    src/core/SkBitmapProcShader.h
M    src/core/SkPathEffect.cpp
M    src/core/SkShape.cpp
M    src/core/SkXfermode.cpp
M    src/core/SkMallocPixelRef.cpp
M    src/core/SkBitmapProcShader.cpp
M    src/images/SkFlipPixelRef.cpp
M    src/images/SkImageRef_GlobalPool.cpp
A    src/ports/SkGlobalInitialization_chromium.cpp
M    src/ports/SkImageRef_ashmem.h
M    src/ports/SkImageRef_ashmem.cpp
A    src/ports/SkGlobalInitialization_default.cpp
M    gyp/effects.gyp
M    gyp/tools.gyp
M    gyp/ports.gyp



git-svn-id: http://skia.googlecode.com/svn/trunk@2876 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gyp/effects.gyp b/gyp/effects.gyp
index 270edc3..4549439 100644
--- a/gyp/effects.gyp
+++ b/gyp/effects.gyp
@@ -25,6 +25,7 @@
         '../include/effects/SkDashPathEffect.h',
         '../include/effects/SkDiscretePathEffect.h',
         '../include/effects/SkDrawExtraPathEffect.h',
+        '../include/effects/SkEffects.h',
         '../include/effects/SkEmbossMaskFilter.h',
         '../include/effects/SkGradientShader.h',
         '../include/effects/SkGroupShape.h',
@@ -53,6 +54,7 @@
         '../src/effects/SkCornerPathEffect.cpp',
         '../src/effects/SkDashPathEffect.cpp',
         '../src/effects/SkDiscretePathEffect.cpp',
+        '../src/effects/SkEffects.cpp',
         '../src/effects/SkEmbossMask.cpp',
         '../src/effects/SkEmbossMask.h',
         '../src/effects/SkEmbossMask_Table.h',
diff --git a/gyp/ports.gyp b/gyp/ports.gyp
index dd9c981..d53542b 100644
--- a/gyp/ports.gyp
+++ b/gyp/ports.gyp
@@ -10,6 +10,8 @@
       'include_dirs': [
         '../include/config',
         '../include/core',
+        '../include/images',
+        '../include/effects',
         '../include/ports',
         '../include/xml',
         '../src/core',
@@ -19,6 +21,7 @@
         '../src/ports/SkDebug_win.cpp',
         '../src/ports/SkFontHost_sandbox_none.cpp',
         '../src/ports/SkFontHost_win.cpp',
+        '../src/ports/SkGlobalInitialization_default.cpp',
         '../src/ports/SkThread_win.cpp',
 
         '../src/ports/SkFontHost_tables.cpp',
diff --git a/gyp/tools.gyp b/gyp/tools.gyp
index 3bc2814..1e419cd 100644
--- a/gyp/tools.gyp
+++ b/gyp/tools.gyp
@@ -25,6 +25,7 @@
       'target_name': 'skdiff',
       'type': 'executable',
       'sources': [
+        '../src/effects/SkEffects_none.cpp',
         '../tools/skdiff_main.cpp',
       ],
       'dependencies': [
@@ -38,6 +39,7 @@
       'target_name': 'skhello',
       'type': 'executable',
       'sources': [
+        '../src/effects/SkEffects_none.cpp',
         '../tools/skhello.cpp',
       ],
       'dependencies': [
@@ -51,6 +53,7 @@
       'target_name': 'skimage',
       'type': 'executable',
       'sources': [
+        '../src/effects/SkEffects_none.cpp',
         '../tools/skimage_main.cpp',
       ],
       'dependencies': [
diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h
index 3b9bb4d..e346996 100644
--- a/include/core/SkColorFilter.h
+++ b/include/core/SkColorFilter.h
@@ -92,7 +92,8 @@
         are ignored.
     */
     static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
-
+    
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 protected:
     SkColorFilter() {}
     SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h
index af6a636..99127af 100644
--- a/include/core/SkFlattenable.h
+++ b/include/core/SkFlattenable.h
@@ -20,6 +20,40 @@
 class SkFlattenableWriteBuffer;
 class SkString;
 
+#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
+#define SK_DECLARE_FLATTENABLE_REGISTRAR() 
+
+#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \
+    static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
+                                                      flattenable::CreateProc);
+                                                      
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable)
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
+    static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
+                                                      flattenable::CreateProc);
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
+
+#else
+
+#define SK_DECLARE_FLATTENABLE_REGISTRAR() static void Init();
+
+#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \
+    void flattenable::Init() { \
+        SkFlattenable::Registrar(#flattenable, CreateProc); \
+    }
+
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
+    void flattenable::Init() {
+    
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
+        SkFlattenable::Registrar(#flattenable, flattenable::CreateProc);
+    
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
+    }
+
+#endif
+
 /** \class SkFlattenable
  
  SkFlattenable is the base class for objects that need to be flattened
@@ -61,6 +95,11 @@
     
 protected:
     SkFlattenable(SkFlattenableReadBuffer&) {}
+
+private:
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+    static void InitializeFlattenables();
+#endif
 };
 
 // helpers for matrix and region
diff --git a/include/core/SkGraphics.h b/include/core/SkGraphics.h
index b41da32..90c92e3 100644
--- a/include/core/SkGraphics.h
+++ b/include/core/SkGraphics.h
@@ -14,7 +14,13 @@
 
 class SkGraphics {
 public:
+    /**
+     *  Call this at process initialization time if your environment does not
+     *  permit static global initializers that execute code. Note that 
+     *  Init() is not thread-safe.
+     */
     static void Init();
+
     static void Term();
 
     /**
@@ -55,7 +61,7 @@
      *  This format is subject to change.
      */
     static void SetFlags(const char* flags);
-
+    
 private:
     /** This is automatically called by SkGraphics::Init(), and must be
         implemented by the host OS. This allows the host OS to register a callback
diff --git a/include/core/SkMallocPixelRef.h b/include/core/SkMallocPixelRef.h
index a0abe20..903bad3 100644
--- a/include/core/SkMallocPixelRef.h
+++ b/include/core/SkMallocPixelRef.h
@@ -37,6 +37,7 @@
         return SkNEW_ARGS(SkMallocPixelRef, (buffer));
     }
 
+    SK_DECLARE_PIXEL_REF_REGISTRAR()
 protected:
     // overrides from SkPixelRef
     virtual void* onLockPixels(SkColorTable**);
diff --git a/include/core/SkPathEffect.h b/include/core/SkPathEffect.h
index 880219f..1b4cd5f 100644
--- a/include/core/SkPathEffect.h
+++ b/include/core/SkPathEffect.h
@@ -34,6 +34,7 @@
     */
     virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width) = 0;
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 private:
     // illegal
     SkPathEffect(const SkPathEffect&);
diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h
index 374868e..3a64393 100644
--- a/include/core/SkPixelRef.h
+++ b/include/core/SkPixelRef.h
@@ -23,6 +23,25 @@
 // this is an opaque class, not interpreted by skia
 class SkGpuTexture;
 
+#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
+#define SK_DECLARE_PIXEL_REF_REGISTRAR() 
+
+#define SK_DEFINE_PIXEL_REF_REGISTRAR(pixelRef) \
+    static SkPixelRef::Registrar g##pixelRef##Reg(#pixelRef, \
+                                                  pixelRef::Create);
+                                                      
+#else
+
+#define SK_DECLARE_PIXEL_REF_REGISTRAR() static void Init();
+
+#define SK_DEFINE_PIXEL_REF_REGISTRAR(pixelRef) \
+    void pixelRef::Init() { \
+        SkPixelRef::Registrar(#pixelRef, Create); \
+    }
+
+#endif
+
 /** \class SkPixelRef
 
     This class is the smart container for pixel memory, and is used with
@@ -187,6 +206,10 @@
     SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
 
 private:
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+    static void InitializeFlattenables();
+#endif
+
     SkMutex*        fMutex; // must remain in scope for the life of this object
     void*           fPixels;
     SkColorTable*   fColorTable;    // we do not track ownership, subclass does
diff --git a/include/core/SkPostConfig.h b/include/core/SkPostConfig.h
index 4433dfc..edce334 100644
--- a/include/core/SkPostConfig.h
+++ b/include/core/SkPostConfig.h
@@ -291,3 +291,8 @@
 #endif
 #endif
 
+//////////////////////////////////////////////////////////////////////
+
+#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
+#endif
diff --git a/include/core/SkShape.h b/include/core/SkShape.h
index b40d886..c7cf9ec 100644
--- a/include/core/SkShape.h
+++ b/include/core/SkShape.h
@@ -38,6 +38,8 @@
     // public for Registrar
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     virtual void onDraw(SkCanvas*);
 
diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h
index 8295f17..0d1c207 100644
--- a/include/core/SkXfermode.h
+++ b/include/core/SkXfermode.h
@@ -172,6 +172,7 @@
         return AsMode(xfer, mode);
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 protected:
     SkXfermode(SkFlattenableReadBuffer& rb) : SkFlattenable(rb) {}
 
diff --git a/include/effects/Sk1DPathEffect.h b/include/effects/Sk1DPathEffect.h
index 51a5a78..814e547 100644
--- a/include/effects/Sk1DPathEffect.h
+++ b/include/effects/Sk1DPathEffect.h
@@ -63,6 +63,8 @@
         return SkNEW_ARGS(SkPath1DPathEffect, (buffer));
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkPath1DPathEffect(SkFlattenableReadBuffer& buffer);
 
diff --git a/include/effects/Sk2DPathEffect.h b/include/effects/Sk2DPathEffect.h
index f0d60ca..b5d7fbb 100644
--- a/include/effects/Sk2DPathEffect.h
+++ b/include/effects/Sk2DPathEffect.h
@@ -47,6 +47,8 @@
     // protected so that subclasses can call this during unflattening
     Sk2DPathEffect(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 private:
     SkMatrix    fMatrix, fInverse;
     // illegal
@@ -69,6 +71,8 @@
     
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkPath2DPathEffect(SkFlattenableReadBuffer& buffer);
 
diff --git a/include/effects/SkAvoidXfermode.h b/include/effects/SkAvoidXfermode.h
index 8497265..398eaea 100644
--- a/include/effects/SkAvoidXfermode.h
+++ b/include/effects/SkAvoidXfermode.h
@@ -59,6 +59,8 @@
         return SkNEW_ARGS(SkAvoidXfermode, (buffer));
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkAvoidXfermode(SkFlattenableReadBuffer&);
 
diff --git a/include/effects/SkBlurDrawLooper.h b/include/effects/SkBlurDrawLooper.h
index 1cfb68c..be1a78e 100644
--- a/include/effects/SkBlurDrawLooper.h
+++ b/include/effects/SkBlurDrawLooper.h
@@ -48,6 +48,7 @@
         return SkNEW_ARGS(SkBlurDrawLooper, (buffer));
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 
 protected:
     SkBlurDrawLooper(SkFlattenableReadBuffer&);
diff --git a/include/effects/SkBlurImageFilter.h b/include/effects/SkBlurImageFilter.h
index c9ef882..55cef65 100644
--- a/include/effects/SkBlurImageFilter.h
+++ b/include/effects/SkBlurImageFilter.h
@@ -18,6 +18,9 @@
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(SkBlurImageFilter, (buffer));
     }
+
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     explicit SkBlurImageFilter(SkFlattenableReadBuffer& buffer);
     virtual void flatten(SkFlattenableWriteBuffer& buffer);
diff --git a/include/effects/SkBlurMaskFilter.h b/include/effects/SkBlurMaskFilter.h
index 8128ad9..9e85d87 100644
--- a/include/effects/SkBlurMaskFilter.h
+++ b/include/effects/SkBlurMaskFilter.h
@@ -55,6 +55,8 @@
                                         SkScalar ambient, SkScalar specular,
                                         SkScalar blurRadius);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 private:
     SkBlurMaskFilter(); // can't be instantiated
 };
diff --git a/include/effects/SkColorMatrixFilter.h b/include/effects/SkColorMatrixFilter.h
index 87d1a8b..32ae7df 100644
--- a/include/effects/SkColorMatrixFilter.h
+++ b/include/effects/SkColorMatrixFilter.h
@@ -38,6 +38,8 @@
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     // overrides for SkFlattenable
     virtual Factory getFactory();
diff --git a/include/effects/SkCornerPathEffect.h b/include/effects/SkCornerPathEffect.h
index b4d7f86..990bad0 100644
--- a/include/effects/SkCornerPathEffect.h
+++ b/include/effects/SkCornerPathEffect.h
@@ -37,6 +37,8 @@
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkCornerPathEffect(SkFlattenableReadBuffer&);
 
diff --git a/include/effects/SkDashPathEffect.h b/include/effects/SkDashPathEffect.h
index 29a6d1b..6d34910 100644
--- a/include/effects/SkDashPathEffect.h
+++ b/include/effects/SkDashPathEffect.h
@@ -39,6 +39,8 @@
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkDashPathEffect(SkFlattenableReadBuffer&);
     
diff --git a/include/effects/SkDiscretePathEffect.h b/include/effects/SkDiscretePathEffect.h
index 02ef391..5369ddb 100644
--- a/include/effects/SkDiscretePathEffect.h
+++ b/include/effects/SkDiscretePathEffect.h
@@ -36,6 +36,8 @@
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkDiscretePathEffect(SkFlattenableReadBuffer&);
 
diff --git a/include/effects/SkEffects.h b/include/effects/SkEffects.h
new file mode 100644
index 0000000..04091de
--- /dev/null
+++ b/include/effects/SkEffects.h
@@ -0,0 +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 SkEffects_DEFINED
+#define SkEffects_DEFINED
+
+class SkEffects {
+public:
+    static void Init();
+};
+
+#endif
diff --git a/include/effects/SkEmbossMaskFilter.h b/include/effects/SkEmbossMaskFilter.h
index c0e6b7e..257e19a 100644
--- a/include/effects/SkEmbossMaskFilter.h
+++ b/include/effects/SkEmbossMaskFilter.h
@@ -41,6 +41,8 @@
     //  This method is not exported to java.
     virtual void flatten(SkFlattenableWriteBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkEmbossMaskFilter(SkFlattenableReadBuffer&);
 
diff --git a/include/effects/SkGradientShader.h b/include/effects/SkGradientShader.h
index bb0fb23..3232703 100644
--- a/include/effects/SkGradientShader.h
+++ b/include/effects/SkGradientShader.h
@@ -112,6 +112,8 @@
     static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
                                  const SkColor colors[], const SkScalar pos[],
                                  int count, SkUnitMapper* mapper = NULL);
+
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 };
 
 #endif
diff --git a/include/effects/SkGroupShape.h b/include/effects/SkGroupShape.h
index 76dd13d..7764003 100644
--- a/include/effects/SkGroupShape.h
+++ b/include/effects/SkGroupShape.h
@@ -138,6 +138,8 @@
     // public for Registrar
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     // overrides
     virtual void onDraw(SkCanvas*);
diff --git a/include/effects/SkLayerDrawLooper.h b/include/effects/SkLayerDrawLooper.h
index b9b0802..697d7b2 100644
--- a/include/effects/SkLayerDrawLooper.h
+++ b/include/effects/SkLayerDrawLooper.h
@@ -106,6 +106,8 @@
         return SkNEW_ARGS(SkLayerDrawLooper, (buffer));
     }
     
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkLayerDrawLooper(SkFlattenableReadBuffer&);
 
diff --git a/include/effects/SkLayerRasterizer.h b/include/effects/SkLayerRasterizer.h
index 50758b1..91deb61 100644
--- a/include/effects/SkLayerRasterizer.h
+++ b/include/effects/SkLayerRasterizer.h
@@ -38,6 +38,8 @@
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkLayerRasterizer(SkFlattenableReadBuffer&);
 
diff --git a/include/effects/SkPixelXorXfermode.h b/include/effects/SkPixelXorXfermode.h
index b9975cf..a7197ab 100644
--- a/include/effects/SkPixelXorXfermode.h
+++ b/include/effects/SkPixelXorXfermode.h
@@ -29,6 +29,8 @@
         return SkNEW_ARGS(SkPixelXorXfermode, (buffer));
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     // override from SkXfermode
     virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst);
diff --git a/include/effects/SkRectShape.h b/include/effects/SkRectShape.h
index b521846..519398c 100644
--- a/include/effects/SkRectShape.h
+++ b/include/effects/SkRectShape.h
@@ -47,6 +47,8 @@
     // public for Registrar
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkRectShape(SkFlattenableReadBuffer&);
 
diff --git a/include/images/SkFlipPixelRef.h b/include/images/SkFlipPixelRef.h
index e82c713..455a3da 100644
--- a/include/images/SkFlipPixelRef.h
+++ b/include/images/SkFlipPixelRef.h
@@ -56,7 +56,9 @@
     virtual Factory getFactory() const { return Create; }
     virtual void flatten(SkFlattenableWriteBuffer&) const;
     static SkPixelRef* Create(SkFlattenableReadBuffer& buffer);
-    
+
+    SK_DECLARE_PIXEL_REF_REGISTRAR()
+
 protected:
     virtual void* onLockPixels(SkColorTable**);
     virtual void onUnlockPixels();
diff --git a/include/images/SkImageRef_GlobalPool.h b/include/images/SkImageRef_GlobalPool.h
index ce57319..909ee71 100644
--- a/include/images/SkImageRef_GlobalPool.h
+++ b/include/images/SkImageRef_GlobalPool.h
@@ -23,6 +23,8 @@
         return Create;
     }
     static SkPixelRef* Create(SkFlattenableReadBuffer&);
+    
+    SK_DECLARE_PIXEL_REF_REGISTRAR()
 
     // API to control the global pool
 
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 65387e4..32b6f9e 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -289,8 +289,7 @@
     return shader;
 }
 
-static SkFlattenable::Registrar gBitmapProcShaderReg("SkBitmapProcShader",
-                                               SkBitmapProcShader::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkBitmapProcShader)
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index cd70279..4f8d0c5 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -37,6 +37,7 @@
     // override from flattenable
     virtual bool toDumpString(SkString* str) const;
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 protected:
     SkBitmapProcShader(SkFlattenableReadBuffer& );
     virtual void flatten(SkFlattenableWriteBuffer& );
diff --git a/src/core/SkFlattenable.cpp b/src/core/SkFlattenable.cpp
index b4fb568..7f22e6e 100644
--- a/src/core/SkFlattenable.cpp
+++ b/src/core/SkFlattenable.cpp
@@ -348,7 +348,20 @@
     gCount += 1;
 }
 
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
+static void report_no_entries(const char* functionName) {
+    if (!gCount) {
+        SkDebugf("%s has no registered name/factory pairs."
+            " Call SkGraphics::InitializeGlobals() at process initialization"
+            " time.", functionName);   
+    }
+}
+#endif
+
 SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
+    report_no_entries(__FUNCTION__);
+#endif
     const Pair* pairs = gPairs;
     for (int i = gCount - 1; i >= 0; --i) {
         if (strcmp(pairs[i].fName, name) == 0) {
@@ -359,6 +372,9 @@
 }
 
 const char* SkFlattenable::FactoryToName(Factory fact) {
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
+    report_no_entries(__FUNCTION__);
+#endif
     const Pair* pairs = gPairs;
     for (int i = gCount - 1; i >= 0; --i) {
         if (pairs[i].fFactory == fact) {
@@ -371,4 +387,3 @@
 bool SkFlattenable::toDumpString(SkString* str) const {
     return false;
 }
-
diff --git a/src/core/SkGraphics.cpp b/src/core/SkGraphics.cpp
index 8ae4944..8cfb432 100644
--- a/src/core/SkGraphics.cpp
+++ b/src/core/SkGraphics.cpp
@@ -51,6 +51,10 @@
 #endif
 
 void SkGraphics::Init() {
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+    SkFlattenable::InitializeFlattenables();
+    SkPixelRef::InitializeFlattenables();
+#endif
 #ifdef BUILD_EMBOSS_TABLE
     SkEmbossMask_BuildTable();
 #endif
diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp
index 97da5c1..3e22075 100644
--- a/src/core/SkMallocPixelRef.cpp
+++ b/src/core/SkMallocPixelRef.cpp
@@ -59,6 +59,4 @@
     }
 }
 
-static SkPixelRef::Registrar reg("SkMallocPixelRef",
-                                 SkMallocPixelRef::Create);
-
+SK_DEFINE_PIXEL_REF_REGISTRAR(SkMallocPixelRef)
diff --git a/src/core/SkPathEffect.cpp b/src/core/SkPathEffect.cpp
index 41a6ebb..3e017e2 100644
--- a/src/core/SkPathEffect.cpp
+++ b/src/core/SkPathEffect.cpp
@@ -134,12 +134,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkFlattenable::Registrar gComposePathEffectReg("SkComposePathEffect",
-                                     SkComposePathEffect::CreateProc);
-
-static SkFlattenable::Registrar gSumPathEffectReg("SkSumPathEffect",
-                                     SkSumPathEffect::CreateProc);
-
-static SkFlattenable::Registrar gStrokePathEffectReg("SkStrokePathEffect",
-                                     SkStrokePathEffect::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkPathEffect)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkStrokePathEffect)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
 
diff --git a/src/core/SkPixelRef.cpp b/src/core/SkPixelRef.cpp
index 31eccc5..e828ba0 100644
--- a/src/core/SkPixelRef.cpp
+++ b/src/core/SkPixelRef.cpp
@@ -137,7 +137,20 @@
     gCount += 1;
 }
 
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
+static void report_no_entries(const char* functionName) {
+    if (!gCount) {
+        SkDebugf("%s has no registered name/factory pairs."
+            " Call SkGraphics::InitializeGlobals() at process initialization"
+            " time.", functionName);   
+    }
+}
+#endif
+
 SkPixelRef::Factory SkPixelRef::NameToFactory(const char name[]) {
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
+    report_no_entries(__FUNCTION__);
+#endif
     const Pair* pairs = gPairs;
     for (int i = gCount - 1; i >= 0; --i) {
         if (strcmp(pairs[i].fName, name) == 0) {
@@ -148,6 +161,9 @@
 }
 
 const char* SkPixelRef::FactoryToName(Factory fact) {
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_DEBUG)
+    report_no_entries(__FUNCTION__);
+#endif
     const Pair* pairs = gPairs;
     for (int i = gCount - 1; i >= 0; --i) {
         if (pairs[i].fFactory == fact) {
diff --git a/src/core/SkShape.cpp b/src/core/SkShape.cpp
index fb6e0fb..339601a 100644
--- a/src/core/SkShape.cpp
+++ b/src/core/SkShape.cpp
@@ -74,4 +74,4 @@
 
 void SkShape::onDraw(SkCanvas*) {}
 
-static SkFlattenable::Registrar gReg("SkShape", SkShape::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkShape)
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index bfd3816..fdf1798 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -1220,18 +1220,10 @@
     return proc16;
 }
 
-static SkFlattenable::Registrar
-    gSkProcCoeffXfermodeReg("SkProcCoeffXfermode",
-                            SkProcCoeffXfermode::CreateProc);
-
-static SkFlattenable::Registrar
-    gSkClearXfermodeReg("SkClearXfermode", SkClearXfermode::CreateProc);
-
-static SkFlattenable::Registrar
-    gSkSrcXfermodeReg("SkSrcXfermode", SkSrcXfermode::CreateProc);
-
-static SkFlattenable::Registrar
-    gSkDstInXfermodeReg("SkDstInXfermode", SkDstInXfermode::CreateProc);
-
-static SkFlattenable::Registrar
-    gSkDstOutXfermodeReg("SkDstOutXfermode", SkDstOutXfermode::CreateProc);
+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)
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
diff --git a/src/effects/Sk1DPathEffect.cpp b/src/effects/Sk1DPathEffect.cpp
index 054f1d5..1e641cd 100644
--- a/src/effects/Sk1DPathEffect.cpp
+++ b/src/effects/Sk1DPathEffect.cpp
@@ -183,6 +183,5 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkFlattenable::Registrar gReg("SkPath1DPathEffect",
-                                     SkPath1DPathEffect::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkPath1DPathEffect)
 
diff --git a/src/effects/Sk2DPathEffect.cpp b/src/effects/Sk2DPathEffect.cpp
index ee081f1..3729610 100644
--- a/src/effects/Sk2DPathEffect.cpp
+++ b/src/effects/Sk2DPathEffect.cpp
@@ -117,6 +117,5 @@
     dst->addPath(fPath, loc.fX, loc.fY);
 }
 
-static SkFlattenable::Registrar gReg("SkPath2DPathEffect",
-                                     SkPath2DPathEffect::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect)
 
diff --git a/src/effects/SkAvoidXfermode.cpp b/src/effects/SkAvoidXfermode.cpp
index ee28c31..d2cd49b 100644
--- a/src/effects/SkAvoidXfermode.cpp
+++ b/src/effects/SkAvoidXfermode.cpp
@@ -250,5 +250,4 @@
     // override in subclass
 }
 
-static SkFlattenable::Registrar
-    gSkAvoidXfermodeReg("SkAvoidXfermode", SkAvoidXfermode::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkAvoidXfermode)
diff --git a/src/effects/SkBlurDrawLooper.cpp b/src/effects/SkBlurDrawLooper.cpp
index 5021428..a44f081 100644
--- a/src/effects/SkBlurDrawLooper.cpp
+++ b/src/effects/SkBlurDrawLooper.cpp
@@ -116,6 +116,5 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkFlattenable::Registrar gReg("SkBlurDrawLooper",
-                                     SkBlurDrawLooper::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkBlurDrawLooper)
 
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
index 8971c61..effc734 100644
--- a/src/effects/SkBlurImageFilter.cpp
+++ b/src/effects/SkBlurImageFilter.cpp
@@ -29,5 +29,4 @@
     buffer.writeScalar(fSigma.fHeight);
 }
 
-static SkFlattenable::Registrar
-    gSrcColorFilterReg("SkBlurImageFilter", SkBlurImageFilter::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkBlurImageFilter)
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index c97acf2..415f1ec 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -137,8 +137,6 @@
     return gBlurStyle2BlurType[fBlurStyle];
 }
 
-///////////////////////////////////////////////////////////////////////////////
-
-static SkFlattenable::Registrar gReg("SkBlurMaskFilter",
-                                     SkBlurMaskFilterImpl::CreateProc);
-
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl)
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp
index 3560c6c..e6262c1 100644
--- a/src/effects/SkColorFilters.cpp
+++ b/src/effects/SkColorFilters.cpp
@@ -323,6 +323,10 @@
         }
     }
 
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkLightingColorFilter, (buffer));
+    }
+
 protected:
     virtual void flatten(SkFlattenableWriteBuffer& buffer) {
         this->INHERITED::flatten(buffer);
@@ -342,10 +346,6 @@
     SkColor fMul, fAdd;
 
 private:
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkLightingColorFilter, (buffer));
-    }
-
     typedef SkColorFilter INHERITED;
 };
 
@@ -374,6 +374,10 @@
         }
     }
 
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)  {
+        return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (buffer));
+    }
+
 protected:
     virtual Factory getFactory() { return CreateProc; }
 
@@ -381,10 +385,6 @@
         : INHERITED(buffer) {}
 
 private:
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)  {
-        return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (buffer));
-    }
-
     typedef SkLightingColorFilter INHERITED;
 };
 
@@ -412,6 +412,10 @@
         }
     }
 
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkLightingColorFilter_JustMul, (buffer));
+    }
+
 protected:
     virtual Factory getFactory() { return CreateProc; }
 
@@ -419,10 +423,6 @@
         : INHERITED(buffer) {}
 
 private:
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkLightingColorFilter_JustMul, (buffer));
-    }
-
     typedef SkLightingColorFilter INHERITED;
 };
 
@@ -453,6 +453,10 @@
         }
     }
 
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (buffer));
+    }
+
 protected:
     virtual Factory getFactory() { return CreateProc; }
 
@@ -460,10 +464,6 @@
         : INHERITED(buffer) {}
 
 private:
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (buffer));
-    }
-
     typedef SkLightingColorFilter INHERITED;
 };
 
@@ -496,6 +496,10 @@
         }
     }
 
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkLightingColorFilter_NoPin, (buffer));
+    }
+
 protected:
     virtual Factory getFactory() { return CreateProc; }
 
@@ -503,16 +507,17 @@
         : INHERITED(buffer) {}
 
 private:
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkLightingColorFilter_NoPin, (buffer));
-    }
-
     typedef SkLightingColorFilter INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
 class SkSimpleColorFilter : public SkColorFilter {
+public:
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW(SkSimpleColorFilter);
+    }
+
 protected:
     void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) {
         if (result != src) {
@@ -526,9 +531,6 @@
         return CreateProc;
     }
 
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW(SkSimpleColorFilter);
-    }
 };
 
 SkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) {
@@ -561,14 +563,15 @@
     return SkNEW_ARGS(SkLightingColorFilter, (mul, add));
 }
 
-static SkFlattenable::Registrar
-    gSrcColorFilterReg("Src_SkModeColorFilterReg",
-                       Src_SkModeColorFilter::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Proc_SkModeColorFilter)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter)
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
 
-static SkFlattenable::Registrar
-    gSrcOverColorFilterReg("SrcOver_SkModeColorFilterReg",
-                       SrcOver_SkModeColorFilter::CreateProc);
-
-static SkFlattenable::Registrar
-    gProcColorFilterReg("Proc_SkModeColorFilterReg",
-                       Proc_SkModeColorFilter::CreateProc);
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index b984041..a58e06d 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -337,6 +337,4 @@
     return SkNEW_ARGS(SkColorMatrixFilter, (buf));
 }
 
-static SkFlattenable::Registrar
-  gSkColorMatrixFilterReg("SkColorMatrixFilter",
-                          SkColorMatrixFilter::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkColorMatrixFilter)
diff --git a/src/effects/SkCornerPathEffect.cpp b/src/effects/SkCornerPathEffect.cpp
index a4d6747..4da31ab 100644
--- a/src/effects/SkCornerPathEffect.cpp
+++ b/src/effects/SkCornerPathEffect.cpp
@@ -145,8 +145,5 @@
     fRadius = buffer.readScalar();
 }
 
-///////////////////////////////////////////////////////////////////////////////
-
-static SkFlattenable::Registrar gReg("SkCornerPathEffect",
-                                     SkCornerPathEffect::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkCornerPathEffect)
 
diff --git a/src/effects/SkDashPathEffect.cpp b/src/effects/SkDashPathEffect.cpp
index ed66d3d..7950d64 100644
--- a/src/effects/SkDashPathEffect.cpp
+++ b/src/effects/SkDashPathEffect.cpp
@@ -168,6 +168,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkFlattenable::Registrar gReg("SkDashPathEffect",
-                                     SkDashPathEffect::CreateProc);
-
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkDashPathEffect)
diff --git a/src/effects/SkDiscretePathEffect.cpp b/src/effects/SkDiscretePathEffect.cpp
index 8a413ed..a438859 100644
--- a/src/effects/SkDiscretePathEffect.cpp
+++ b/src/effects/SkDiscretePathEffect.cpp
@@ -87,6 +87,5 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkFlattenable::Registrar gReg("SkDiscretePathEffect",
-                                     SkDiscretePathEffect::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkDiscretePathEffect)
 
diff --git a/src/effects/SkEffects.cpp b/src/effects/SkEffects.cpp
new file mode 100644
index 0000000..d4ccac0
--- /dev/null
+++ b/src/effects/SkEffects.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 "SkTypes.h"
+
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
+#include "Sk1DPathEffect.h"
+#include "Sk2DPathEffect.h"
+#include "SkAvoidXfermode.h"
+#include "SkBlurDrawLooper.h"
+#include "SkBlurImageFilter.h"
+#include "SkBlurMaskFilter.h"
+#include "SkColorFilter.h"
+#include "SkColorMatrixFilter.h"
+#include "SkCornerPathEffect.h"
+#include "SkDashPathEffect.h"
+#include "SkDiscretePathEffect.h"
+#include "SkEffects.h"
+#include "SkFlattenable.h"
+#include "SkGradientShader.h"
+#include "SkGroupShape.h"
+#include "SkLayerDrawLooper.h"
+#include "SkLayerRasterizer.h"
+#include "SkPathEffect.h"
+#include "SkPixelXorXfermode.h"
+#include "SkRectShape.h"
+
+void SkEffects::Init() {
+    SkAvoidXfermode::Init();
+    SkBlurDrawLooper::Init();
+    SkBlurImageFilter::Init();
+    SkBlurMaskFilter::Init();
+    SkColorFilter::Init();
+    SkColorMatrixFilter::Init();
+    SkCornerPathEffect::Init();
+    SkDashPathEffect::Init();
+    SkDiscretePathEffect::Init();
+    SkGradientShader::Init();
+    SkGroupShape::Init();
+    SkLayerDrawLooper::Init();
+    SkLayerRasterizer::Init();
+    SkPath1DPathEffect::Init();
+    SkPath2DPathEffect::Init();
+    SkPixelXorXfermode::Init();
+    SkRectShape::Init();
+}
+
+#endif
diff --git a/src/effects/SkEffects_none.cpp b/src/effects/SkEffects_none.cpp
new file mode 100644
index 0000000..519fcf7
--- /dev/null
+++ b/src/effects/SkEffects_none.cpp
@@ -0,0 +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.
+ */
+
+#include "SkTypes.h"
+
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
+#include "../../include/effects/SkEffects.h"
+
+void SkEffects::Init() {
+}
+
+#endif
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp
index af357a6..2d99d3d 100644
--- a/src/effects/SkGradientShader.cpp
+++ b/src/effects/SkGradientShader.cpp
@@ -796,6 +796,8 @@
         buffer.writeScalar(fEnd.fY);
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     Linear_Gradient(SkFlattenableReadBuffer& buffer)
         : Gradient_Shader(buffer),
@@ -2241,15 +2243,11 @@
     return SkNEW_ARGS(Sweep_Gradient, (cx, cy, colors, pos, count, mapper));
 }
 
-static SkFlattenable::Registrar gLinearGradientReg("Linear_Gradient",
-                                                   Linear_Gradient::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Linear_Gradient)
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Radial_Gradient)
 
-static SkFlattenable::Registrar gRadialGradientReg("Radial_Gradient",
-                                                   Radial_Gradient::CreateProc);
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Sweep_Gradient)
 
-static SkFlattenable::Registrar gSweepGradientReg("Sweep_Gradient",
-                                                   Sweep_Gradient::CreateProc);
-
-static SkFlattenable::Registrar
-    gTwoPointRadialGradientReg("Two_Point_Radial_Gradient",
-                               Two_Point_Radial_Gradient::CreateProc);
+    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Two_Point_Radial_Gradient)
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
diff --git a/src/effects/SkGroupShape.cpp b/src/effects/SkGroupShape.cpp
index 3dc084a..fd741ee 100644
--- a/src/effects/SkGroupShape.cpp
+++ b/src/effects/SkGroupShape.cpp
@@ -131,5 +131,5 @@
     return SkNEW_ARGS(SkGroupShape, (buffer));
 }
 
-static SkFlattenable::Registrar gReg("SkGroupShape", SkGroupShape::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkGroupShape)
 
diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp
index 3244a57..acb3e88 100644
--- a/src/effects/SkLayerDrawLooper.cpp
+++ b/src/effects/SkLayerDrawLooper.cpp
@@ -245,5 +245,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkFlattenable::Registrar gReg("SkLayerDrawLooper",
-                                     SkLayerDrawLooper::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkLayerDrawLooper)
diff --git a/src/effects/SkLayerRasterizer.cpp b/src/effects/SkLayerRasterizer.cpp
index fd73ffd..9b29550 100644
--- a/src/effects/SkLayerRasterizer.cpp
+++ b/src/effects/SkLayerRasterizer.cpp
@@ -224,6 +224,5 @@
     return CreateProc;
 }
 
-static SkFlattenable::Registrar gReg("SkLayerRasterizer",
-                                     SkLayerRasterizer::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkLayerRasterizer)
 
diff --git a/src/effects/SkPixelXorXfermode.cpp b/src/effects/SkPixelXorXfermode.cpp
index 47e4cd8..935a475 100644
--- a/src/effects/SkPixelXorXfermode.cpp
+++ b/src/effects/SkPixelXorXfermode.cpp
@@ -36,6 +36,4 @@
     return SkNEW_ARGS(SkPixelXorXfermode, (rb));
 }
 
-static SkFlattenable::Registrar
-    gSkPixelXorXfermodeReg("SkPixelXorXfermode",
-                           SkPixelXorXfermode::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkPixelXorXfermode)
diff --git a/src/effects/SkRectShape.cpp b/src/effects/SkRectShape.cpp
index 6fdc1e1..3e37072 100644
--- a/src/effects/SkRectShape.cpp
+++ b/src/effects/SkRectShape.cpp
@@ -92,5 +92,5 @@
     fPaint.unflatten(buffer);
 }
 
-static SkFlattenable::Registrar gReg("SkRectShape", SkRectShape::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkRectShape)
 
diff --git a/src/images/SkFlipPixelRef.cpp b/src/images/SkFlipPixelRef.cpp
index c81e8b6..e81c83c 100644
--- a/src/images/SkFlipPixelRef.cpp
+++ b/src/images/SkFlipPixelRef.cpp
@@ -81,8 +81,7 @@
     return SkNEW_ARGS(SkFlipPixelRef, (buffer));
 }
 
-static SkPixelRef::Registrar reg("SkFlipPixelRef",
-                                 SkFlipPixelRef::Create);
+SK_DEFINE_PIXEL_REF_REGISTRAR(SkFlipPixelRef)
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/images/SkImageRef_GlobalPool.cpp b/src/images/SkImageRef_GlobalPool.cpp
index 43c72b1..6ea42c1 100644
--- a/src/images/SkImageRef_GlobalPool.cpp
+++ b/src/images/SkImageRef_GlobalPool.cpp
@@ -57,8 +57,7 @@
     return SkNEW_ARGS(SkImageRef_GlobalPool, (buffer));
 }
 
-static SkPixelRef::Registrar reg("SkImageRef_GlobalPool",
-                                 SkImageRef_GlobalPool::Create);
+SK_DEFINE_PIXEL_REF_REGISTRAR(SkImageRef_GlobalPool)
 
 ///////////////////////////////////////////////////////////////////////////////
 // global imagerefpool wrappers
diff --git a/src/ports/SkGlobalInitialization_chromium.cpp b/src/ports/SkGlobalInitialization_chromium.cpp
new file mode 100644
index 0000000..6a7b213
--- /dev/null
+++ b/src/ports/SkGlobalInitialization_chromium.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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 "SkBitmapProcShader.h"
+#include "SkBlurImageFilter.h"
+#include "SkBlurMaskFilter.h"
+#include "SkColorFilter.h"
+#include "SkCornerPathEffect.h"
+#include "SkDashPathEffect.h"
+#include "SkGradientShader.h"
+#include "SkLayerDrawLooper.h"
+#include "SkMallocPixelRef.h"
+#include "SkXfermode.h"
+
+void SkFlattenable::InitializeFlattenables() {
+    SkBitmapProcShader::Init();
+    SkBlurImageFilter::Init();
+    SkBlurMaskFilter::Init();
+    SkColorFilter::Init();
+    SkCornerPathEffect::Init();
+    SkDashPathEffect::Init();
+    SkGradientShader::Init();
+    SkLayerDrawLooper::Init();
+    SkXfermode::Init();
+}
+
+void SkPixelRef::InitializeFlattenables() {
+    SkMallocPixelRef::Init();
+}
diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp
new file mode 100644
index 0000000..6be776a
--- /dev/null
+++ b/src/ports/SkGlobalInitialization_default.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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 "SkTypes.h"
+
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
+#include "SkBitmapProcShader.h"
+#include "SkEffects.h"
+#include "SkFlipPixelRef.h"
+#include "SkImageRef_ashmem.h"
+#include "SkImageRef_GlobalPool.h"
+#include "SkMallocPixelRef.h"
+#include "SkPathEffect.h"
+#include "SkPixelRef.h"
+#include "SkShape.h"
+#include "SkXfermode.h"
+
+void SkFlattenable::InitializeFlattenables() {
+    SkBitmapProcShader::Init();
+    SkEffects::Init();
+    SkPathEffect::Init();
+    SkShape::Init();
+    SkXfermode::Init();
+}
+
+void SkPixelRef::InitializeFlattenables() {
+    SkFlipPixelRef::Init();
+    SkImageRef_GlobalPool::Init();
+    SkMallocPixelRef::Init();
+}
+
+#endif
diff --git a/src/ports/SkImageRef_ashmem.cpp b/src/ports/SkImageRef_ashmem.cpp
index 0c9c94b..8c69b38 100644
--- a/src/ports/SkImageRef_ashmem.cpp
+++ b/src/ports/SkImageRef_ashmem.cpp
@@ -240,5 +240,4 @@
     return SkNEW_ARGS(SkImageRef_ashmem, (buffer));
 }
 
-static SkPixelRef::Registrar reg("SkImageRef_ashmem",
-                                 SkImageRef_ashmem::Create);
+SK_DEFINE_PIXEL_REF_REGISTRAR(SkImageRef_ashmem)
diff --git a/src/ports/SkImageRef_ashmem.h b/src/ports/SkImageRef_ashmem.h
index fb58f4c..f50ea80 100644
--- a/src/ports/SkImageRef_ashmem.h
+++ b/src/ports/SkImageRef_ashmem.h
@@ -29,6 +29,7 @@
     }
     static SkPixelRef* Create(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_PIXEL_REF_REGISTRAR()
 protected:
     virtual bool onDecode(SkImageDecoder* codec, SkStream* stream,
                           SkBitmap* bitmap, SkBitmap::Config config,