Bug 716415 - Update Skia to svn revision 2980. r=jrmuizel
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 19 Jan 2012 17:48:34 +1300
changeset 84863 7e9a396c0a562c84cef99b8dd2d09b2deec00615
parent 84862 be4ed2c8f4461406f58939a1b7c08423f09d2fa8
child 84864 be5d69db8531cc80a74d8b907ed640feb0265e24
push id21881
push usermbrubeck@mozilla.com
push dateThu, 19 Jan 2012 18:41:36 +0000
treeherdermozilla-central@e5e66f40c35b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs716415
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 716415 - Update Skia to svn revision 2980. r=jrmuizel
gfx/skia/README_MOZILLA
gfx/skia/include/config/SkUserConfig.h
gfx/skia/include/core/SkBitmap.h
gfx/skia/include/core/SkBlitter.h
gfx/skia/include/core/SkCanvas.h
gfx/skia/include/core/SkColorFilter.h
gfx/skia/include/core/SkColorShader.h
gfx/skia/include/core/SkDevice.h
gfx/skia/include/core/SkDraw.h
gfx/skia/include/core/SkEmptyShader.h
gfx/skia/include/core/SkEndian.h
gfx/skia/include/core/SkFlattenable.h
gfx/skia/include/core/SkFloatingPoint.h
gfx/skia/include/core/SkFontHost.h
gfx/skia/include/core/SkGraphics.h
gfx/skia/include/core/SkImageFilter.h
gfx/skia/include/core/SkMMapStream.h
gfx/skia/include/core/SkMallocPixelRef.h
gfx/skia/include/core/SkOSFile.h
gfx/skia/include/core/SkPaint.h
gfx/skia/include/core/SkPath.h
gfx/skia/include/core/SkPathEffect.h
gfx/skia/include/core/SkPixelRef.h
gfx/skia/include/core/SkPoint.h
gfx/skia/include/core/SkPostConfig.h
gfx/skia/include/core/SkPreConfig.h
gfx/skia/include/core/SkRect.h
gfx/skia/include/core/SkRegion.h
gfx/skia/include/core/SkScalar.h
gfx/skia/include/core/SkScalerContext.h
gfx/skia/include/core/SkShader.h
gfx/skia/include/core/SkShape.h
gfx/skia/include/core/SkTArray.h
gfx/skia/include/core/SkTDArray.h
gfx/skia/include/core/SkTRegistry.h
gfx/skia/include/core/SkThread_platform.h
gfx/skia/include/core/SkTypes.h
gfx/skia/include/core/SkUtils.h
gfx/skia/include/core/SkXfermode.h
gfx/skia/include/effects/Sk1DPathEffect.h
gfx/skia/include/effects/Sk2DPathEffect.h
gfx/skia/include/effects/SkArithmeticMode.h
gfx/skia/include/effects/SkAvoidXfermode.h
gfx/skia/include/effects/SkBlurDrawLooper.h
gfx/skia/include/effects/SkBlurImageFilter.h
gfx/skia/include/effects/SkBlurMaskFilter.h
gfx/skia/include/effects/SkColorMatrixFilter.h
gfx/skia/include/effects/SkCornerPathEffect.h
gfx/skia/include/effects/SkDashPathEffect.h
gfx/skia/include/effects/SkDiscretePathEffect.h
gfx/skia/include/effects/SkEffects.h
gfx/skia/include/effects/SkEmbossMaskFilter.h
gfx/skia/include/effects/SkGradientShader.h
gfx/skia/include/effects/SkGroupShape.h
gfx/skia/include/effects/SkLayerDrawLooper.h
gfx/skia/include/effects/SkLayerRasterizer.h
gfx/skia/include/effects/SkPixelXorXfermode.h
gfx/skia/include/effects/SkPorterDuff.h
gfx/skia/include/effects/SkRectShape.h
gfx/skia/include/effects/SkTableColorFilter.h
gfx/skia/include/effects/SkTestImageFilters.h
gfx/skia/include/effects/SkTransparentShader.h
gfx/skia/include/gpu/GrColor.h
gfx/skia/include/gpu/GrConfig.h
gfx/skia/include/gpu/GrContext.h
gfx/skia/include/gpu/GrGLConfig.h
gfx/skia/include/gpu/GrGLConfig_chrome.h
gfx/skia/include/gpu/GrGLDefines.h
gfx/skia/include/gpu/GrGLInterface.h
gfx/skia/include/gpu/GrPaint.h
gfx/skia/include/gpu/GrRenderTarget.h
gfx/skia/include/gpu/GrResource.h
gfx/skia/include/gpu/GrSamplerState.h
gfx/skia/include/gpu/GrTexture.h
gfx/skia/include/gpu/GrTypes.h
gfx/skia/include/gpu/GrUserConfig.h
gfx/skia/include/gpu/SkGpuDevice.h
gfx/skia/include/gpu/SkGr.h
gfx/skia/include/gpu/SkGrTexturePixelRef.h
gfx/skia/include/gpu/SkNativeGLContext.h
gfx/skia/include/images/SkFlipPixelRef.h
gfx/skia/include/images/SkImageRef_GlobalPool.h
gfx/skia/include/pdf/SkPDFDevice.h
gfx/skia/include/utils/SkCamera.h
gfx/skia/include/utils/SkDumpCanvas.h
gfx/skia/include/utils/SkJSON.h
gfx/skia/include/utils/SkMatrix44.h
gfx/skia/include/utils/SkNWayCanvas.h
gfx/skia/include/utils/SkWGL.h
gfx/skia/include/views/SkOSWindow_Mac.h
gfx/skia/include/views/SkView.h
gfx/skia/include/views/SkWindow.h
gfx/skia/src/animator/SkDisplayEvent.cpp
gfx/skia/src/core/SkAAClip.cpp
gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp
gfx/skia/src/core/SkAntiRun.h
gfx/skia/src/core/SkBitmap.cpp
gfx/skia/src/core/SkBitmapProcShader.cpp
gfx/skia/src/core/SkBitmapProcShader.h
gfx/skia/src/core/SkBitmapProcState_filter.h
gfx/skia/src/core/SkBitmapSampler.cpp
gfx/skia/src/core/SkBlitMask.h
gfx/skia/src/core/SkBlitMask_D32.cpp
gfx/skia/src/core/SkBlitter.cpp
gfx/skia/src/core/SkBlitter_ARGB32.cpp
gfx/skia/src/core/SkBlitter_Sprite.cpp
gfx/skia/src/core/SkCanvas.cpp
gfx/skia/src/core/SkColorFilter.cpp
gfx/skia/src/core/SkComposeShader.cpp
gfx/skia/src/core/SkConfig8888.h
gfx/skia/src/core/SkCoreBlitters.h
gfx/skia/src/core/SkDevice.cpp
gfx/skia/src/core/SkDraw.cpp
gfx/skia/src/core/SkEdgeBuilder.cpp
gfx/skia/src/core/SkEdgeClipper.cpp
gfx/skia/src/core/SkFlattenable.cpp
gfx/skia/src/core/SkFloat.cpp
gfx/skia/src/core/SkGlyphCache.cpp
gfx/skia/src/core/SkGlyphCache.h
gfx/skia/src/core/SkGraphics.cpp
gfx/skia/src/core/SkMMapStream.cpp
gfx/skia/src/core/SkMallocPixelRef.cpp
gfx/skia/src/core/SkMemory_stdlib.cpp
gfx/skia/src/core/SkPaint.cpp
gfx/skia/src/core/SkPath.cpp
gfx/skia/src/core/SkPathEffect.cpp
gfx/skia/src/core/SkPathMeasure.cpp
gfx/skia/src/core/SkPictureFlat.h
gfx/skia/src/core/SkPicturePlayback.cpp
gfx/skia/src/core/SkPicturePlayback.h
gfx/skia/src/core/SkPictureRecord.cpp
gfx/skia/src/core/SkPixelRef.cpp
gfx/skia/src/core/SkRect.cpp
gfx/skia/src/core/SkRegion.cpp
gfx/skia/src/core/SkRegion_path.cpp
gfx/skia/src/core/SkScalerContext.cpp
gfx/skia/src/core/SkScan_AntiPath.cpp
gfx/skia/src/core/SkScan_Path.cpp
gfx/skia/src/core/SkShader.cpp
gfx/skia/src/core/SkShape.cpp
gfx/skia/src/core/SkStroke.cpp
gfx/skia/src/core/SkTypeface.cpp
gfx/skia/src/core/SkTypefaceCache.cpp
gfx/skia/src/core/SkUtils.cpp
gfx/skia/src/core/SkXfermode.cpp
gfx/skia/src/effects/Sk1DPathEffect.cpp
gfx/skia/src/effects/Sk2DPathEffect.cpp
gfx/skia/src/effects/SkArithmeticMode.cpp
gfx/skia/src/effects/SkAvoidXfermode.cpp
gfx/skia/src/effects/SkBlurDrawLooper.cpp
gfx/skia/src/effects/SkBlurImageFilter.cpp
gfx/skia/src/effects/SkBlurMask.cpp
gfx/skia/src/effects/SkBlurMaskFilter.cpp
gfx/skia/src/effects/SkColorFilters.cpp
gfx/skia/src/effects/SkColorMatrixFilter.cpp
gfx/skia/src/effects/SkCornerPathEffect.cpp
gfx/skia/src/effects/SkDashPathEffect.cpp
gfx/skia/src/effects/SkDiscretePathEffect.cpp
gfx/skia/src/effects/SkEffects.cpp
gfx/skia/src/effects/SkEffects_none.cpp
gfx/skia/src/effects/SkGradientShader.cpp
gfx/skia/src/effects/SkGroupShape.cpp
gfx/skia/src/effects/SkLayerDrawLooper.cpp
gfx/skia/src/effects/SkLayerRasterizer.cpp
gfx/skia/src/effects/SkPixelXorXfermode.cpp
gfx/skia/src/effects/SkPorterDuff.cpp
gfx/skia/src/effects/SkRectShape.cpp
gfx/skia/src/effects/SkTableColorFilter.cpp
gfx/skia/src/effects/SkTestImageFilters.cpp
gfx/skia/src/effects/SkTransparentShader.cpp
gfx/skia/src/gpu/GrAAHairLinePathRenderer.cpp
gfx/skia/src/gpu/GrAAHairLinePathRenderer.h
gfx/skia/src/gpu/GrAtlas.cpp
gfx/skia/src/gpu/GrBinHashKey.h
gfx/skia/src/gpu/GrBufferAllocPool.cpp
gfx/skia/src/gpu/GrContext.cpp
gfx/skia/src/gpu/GrDefaultPathRenderer.cpp
gfx/skia/src/gpu/GrDefaultPathRenderer.h
gfx/skia/src/gpu/GrDrawState.h
gfx/skia/src/gpu/GrDrawTarget.cpp
gfx/skia/src/gpu/GrDrawTarget.h
gfx/skia/src/gpu/GrGLCreateNullInterface.cpp
gfx/skia/src/gpu/GrGLInterface.cpp
gfx/skia/src/gpu/GrGLProgram.cpp
gfx/skia/src/gpu/GrGLProgram.h
gfx/skia/src/gpu/GrGLRenderTarget.cpp
gfx/skia/src/gpu/GrGLRenderTarget.h
gfx/skia/src/gpu/GrGLSL.cpp
gfx/skia/src/gpu/GrGLSL.h
gfx/skia/src/gpu/GrGLShaderVar.h
gfx/skia/src/gpu/GrGLTexture.cpp
gfx/skia/src/gpu/GrGLTexture.h
gfx/skia/src/gpu/GrGLUtil.cpp
gfx/skia/src/gpu/GrGpu.cpp
gfx/skia/src/gpu/GrGpu.h
gfx/skia/src/gpu/GrGpuFactory.cpp
gfx/skia/src/gpu/GrGpuGL.cpp
gfx/skia/src/gpu/GrGpuGL.h
gfx/skia/src/gpu/GrGpuGLShaders.cpp
gfx/skia/src/gpu/GrGpuGLShaders.h
gfx/skia/src/gpu/GrInOrderDrawBuffer.cpp
gfx/skia/src/gpu/GrInOrderDrawBuffer.h
gfx/skia/src/gpu/GrPathRenderer.h
gfx/skia/src/gpu/GrRenderTarget.cpp
gfx/skia/src/gpu/GrResource.cpp
gfx/skia/src/gpu/GrResourceCache.cpp
gfx/skia/src/gpu/GrResourceCache.h
gfx/skia/src/gpu/GrStencil.cpp
gfx/skia/src/gpu/GrStencil.h
gfx/skia/src/gpu/GrTesselatedPathRenderer.cpp
gfx/skia/src/gpu/GrTesselatedPathRenderer.h
gfx/skia/src/gpu/GrTextContext.cpp
gfx/skia/src/gpu/GrTexture.cpp
gfx/skia/src/gpu/SkGLContext.cpp
gfx/skia/src/gpu/SkGpuDevice.cpp
gfx/skia/src/gpu/SkGr.cpp
gfx/skia/src/gpu/SkGrTexturePixelRef.cpp
gfx/skia/src/gpu/app-android.cpp
gfx/skia/src/images/SkFlipPixelRef.cpp
gfx/skia/src/images/SkImageDecoder.cpp
gfx/skia/src/images/SkImageRef_GlobalPool.cpp
gfx/skia/src/images/SkMovie_gif.cpp
gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
gfx/skia/src/opts/SkBlitRow_opts_none.cpp
gfx/skia/src/opts/opts_check_SSE2.cpp
gfx/skia/src/pdf/SkPDFDevice.cpp
gfx/skia/src/pdf/SkPDFFont.cpp
gfx/skia/src/pdf/SkPDFGraphicState.cpp
gfx/skia/src/pdf/SkPDFShader.cpp
gfx/skia/src/pipe/SkGPipeRead.cpp
gfx/skia/src/pipe/SkGPipeWrite.cpp
gfx/skia/src/ports/FontHostConfiguration_android.cpp
gfx/skia/src/ports/FontHostConfiguration_android.h
gfx/skia/src/ports/SkDebug_android.cpp
gfx/skia/src/ports/SkFontHost_FONTPATH.cpp
gfx/skia/src/ports/SkFontHost_FreeType.cpp
gfx/skia/src/ports/SkFontHost_android.cpp
gfx/skia/src/ports/SkFontHost_fontconfig.cpp
gfx/skia/src/ports/SkFontHost_freetype_mac.cpp
gfx/skia/src/ports/SkFontHost_gamma.cpp
gfx/skia/src/ports/SkFontHost_gamma_none.cpp
gfx/skia/src/ports/SkFontHost_linux.cpp
gfx/skia/src/ports/SkFontHost_mac_atsui.cpp
gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
gfx/skia/src/ports/SkFontHost_none.cpp
gfx/skia/src/ports/SkFontHost_sandbox_none.cpp
gfx/skia/src/ports/SkFontHost_simple.cpp
gfx/skia/src/ports/SkFontHost_win.cpp
gfx/skia/src/ports/SkGlobalInitialization_chromium.cpp
gfx/skia/src/ports/SkGlobalInitialization_default.cpp
gfx/skia/src/ports/SkImageRef_ashmem.cpp
gfx/skia/src/ports/SkImageRef_ashmem.h
gfx/skia/src/ports/SkMemory_brew.cpp
gfx/skia/src/ports/SkMemory_malloc.cpp
gfx/skia/src/ports/SkThread_pthread.cpp
gfx/skia/src/utils/SkCamera.cpp
gfx/skia/src/utils/SkJSON.cpp
gfx/skia/src/utils/SkMatrix44.cpp
gfx/skia/src/utils/SkOSFile.cpp
gfx/skia/src/utils/mac/SkNSView.h
gfx/skia/src/utils/mac/SkNSView.mm
gfx/skia/src/utils/mac/SkOSWindow_Mac.mm
gfx/skia/src/utils/mac/SkOptionsTableView.mm
gfx/skia/src/utils/mac/SkSampleNSView.h
gfx/skia/src/utils/win/SkOSWindow_Win.cpp
gfx/skia/src/utils/win/SkWGL_win.cpp
gfx/skia/src/views/SkEvent.cpp
gfx/skia/src/views/SkEventSink.cpp
gfx/skia/src/views/SkView.cpp
gfx/skia/src/views/SkWidgetViews.cpp
gfx/skia/src/xml/SkBML_XMLParser.cpp
gfx/skia/update.sh
--- a/gfx/skia/README_MOZILLA
+++ b/gfx/skia/README_MOZILLA
@@ -1,5 +1,5 @@
 The source from this directory was copied from the skia subversion trunk
 using the update.sh script. The changes made were those applied by update.sh,
 the addition/update of Makefile.in files for the Mozilla build system.
 
-The subversion revision used was r2232.
+The subversion revision used was r2980.
--- a/gfx/skia/include/config/SkUserConfig.h
+++ b/gfx/skia/include/config/SkUserConfig.h
@@ -88,28 +88,28 @@
 
 
 /*  Some compilers don't support long long for 64bit integers. If yours does
     not, define this to the appropriate type.
  */
 //#define SkLONGLONG int64_t
 
 
-/*  Some envorinments do not suport writable globals (eek!). If yours does not,
-    define this flag.
- */
-//#define SK_USE_RUNTIME_GLOBALS
-
-
 /*  To write debug messages to a console, skia will call SkDebugf(...) following
     printf conventions (e.g. const char* format, ...). If you want to redirect
     this to something other than printf, define yours here
  */
 //#define SkDebugf(...)  MyFunction(__VA_ARGS__)
 
+/*
+ *  To specify a different default font cache limit, define this. If this is
+ *  undefined, skia will use a built-in value.
+ */
+//#define SK_DEFAULT_FONT_CACHE_LIMIT   (1024 * 1024)
+
 /* If defined, use CoreText instead of ATSUI on OS X.
 */
 //#define SK_USE_MAC_CORE_TEXT
 
 
 /*  If zlib is available and you want to support the flate compression
     algorithm (used in PDF generation), define SK_ZLIB_INCLUDE to be the
     include path.
@@ -140,18 +140,16 @@
 /*  If SK_DEBUG is defined, then you can optionally define SK_SUPPORT_UNITTEST
     which will run additional self-tests at startup. These can take a long time,
     so this flag is optional.
  */
 #ifdef SK_DEBUG
 //#define SK_SUPPORT_UNITTEST
 #endif
 
-#define SK_DISABLE_DITHER_32BIT_GRADIENT
-
 /* If your system embeds skia and has complex event logging, define this
    symbol to name a file that maps the following macros to your system's
    equivalents:
        SK_TRACE_EVENT0(event)
        SK_TRACE_EVENT1(event, name1, value1)
        SK_TRACE_EVENT2(event, name1, value1, name2, value2)
    src/utils/SkDebugTrace.h has a trivial implementation that writes to
    the debug output stream. If SK_USER_TRACE_INCLUDE_FILE is not defined,
@@ -163,13 +161,9 @@
  */
 #ifdef SK_SAMPLES_FOR_X
         #define SK_R32_SHIFT    16
         #define SK_G32_SHIFT    8
         #define SK_B32_SHIFT    0
         #define SK_A32_SHIFT    24
 #endif
 
-#ifdef SK_BUILD_FOR_WIN32 
-        #define SK_IGNORE_STDINT_DOT_H 
- #endif 
-
 #endif
--- a/gfx/skia/include/core/SkBitmap.h
+++ b/gfx/skia/include/core/SkBitmap.h
@@ -153,16 +153,29 @@ public:
         size.setMul(fHeight, fRowBytes);
         return size;
     }
 
     /** Same as getSafeSize(), but does not truncate the answer to 32bits.
     */
     Sk64 getSafeSize64() const ;
 
+    /** Returns true if this bitmap is marked as immutable, meaning that the
+        contents of its pixels will not change for the lifetime of the bitmap.
+    */
+    bool isImmutable() const;
+
+    /** Marks this bitmap as immutable, meaning that the contents of its
+        pixels will not change for the lifetime of the bitmap and of the
+        underlying pixelref. This state can be set, but it cannot be 
+        cleared once it is set. This state propagates to all other bitmaps
+        that share the same pixelref.
+    */
+    void setImmutable();
+
     /** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
     */
     bool isOpaque() const;
 
     /** Specify if this bitmap's pixels are all opaque or not. Is only meaningful for configs
         that support per-pixel alpha (RGB32, A1, A8).
     */
     void setIsOpaque(bool);
@@ -220,51 +233,35 @@ public:
         @param pixels   Address for the pixels, managed by the caller.
         @param ctable   ColorTable (or null) that matches the specified pixels
     */
     void setPixels(void* p, SkColorTable* ctable = NULL);
 
     /** Copies the bitmap's pixels to the location pointed at by dst and returns
         true if possible, returns false otherwise.
 
-        In the event that the bitmap's stride is equal to dstRowBytes, and if
-        it is greater than strictly required by the bitmap's current config
-        (this may happen if the bitmap is an extracted subset of another), then
-        this function will copy bytes past the eand of each row, excluding the
-        last row. No copies are made outside of the declared size of dst,
-        however.
+        In the case when the dstRowBytes matches the bitmap's rowBytes, the copy
+        may be made faster by copying over the dst's per-row padding (for all
+        rows but the last). By setting preserveDstPad to true the caller can
+        disable this optimization and ensure that pixels in the padding are not
+        overwritten.
 
         Always returns false for RLE formats.
 
         @param dst      Location of destination buffer.
         @param dstSize  Size of destination buffer. Must be large enough to hold
                         pixels using indicated stride.
         @param dstRowBytes  Width of each line in the buffer. If -1, uses
                             bitmap's internal stride.
+        @param preserveDstPad Must we preserve padding in the dst
     */
-    bool copyPixelsTo(void* const dst, size_t dstSize, int dstRowBytes = -1)
+    bool copyPixelsTo(void* const dst, size_t dstSize, int dstRowBytes = -1,
+                      bool preserveDstPad = false)
          const;
 
-    /** Copies the pixels at location src to the bitmap's pixel buffer.
-        Returns true if copy if possible (bitmap buffer is large enough),
-        false otherwise.
-
-        Like copyPixelsTo, this function may write values beyond the end of
-        each row, although never outside the defined buffer.
-
-        Always returns false for RLE formats.
-
-        @param src      Location of the source buffer.
-        @param srcSize  Height of source buffer in pixels.
-        @param srcRowBytes  Width of each line in the buffer. If -1, uses i
-                            bitmap's internal stride.
-    */
-    bool copyPixelsFrom(const void* const src, size_t srcSize,
-                        int srcRowBytes = -1);
-
     /** Use the standard HeapAllocator to create the pixelref that manages the
         pixel memory. It will be sized based on the current width/height/config.
         If this is called multiple times, a new pixelref object will be created
         each time.
 
         If the bitmap retains a reference to the colortable (assuming it is
         not null) it will take care of incrementing the reference count.
 
@@ -473,29 +470,39 @@ public:
         returned and dst will be untouched.
         @param dst  The bitmap that will be set to a subset of this bitmap
         @param subset The rectangle of pixels in this bitmap that dst will
                       reference.
         @return true if the subset copy was successfully made.
     */
     bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
 
-    /** Makes a deep copy of this bitmap, respecting the requested config.
-        Returns false if either there is an error (i.e. the src does not have
-        pixels) or the request cannot be satisfied (e.g. the src has per-pixel
-        alpha, and the requested config does not support alpha).
-        @param dst The bitmap to be sized and allocated
-        @param c The desired config for dst
-        @param allocator Allocator used to allocate the pixelref for the dst
-                         bitmap. If this is null, the standard HeapAllocator
-                         will be used.
-        @return true if the copy could be made.
-    */
+    /** Makes a deep copy of this bitmap, respecting the requested config,
+     *  and allocating the dst pixels on the cpu.
+     *  Returns false if either there is an error (i.e. the src does not have
+     *  pixels) or the request cannot be satisfied (e.g. the src has per-pixel
+     *  alpha, and the requested config does not support alpha).
+     *  @param dst The bitmap to be sized and allocated
+     *  @param c The desired config for dst
+     *  @param allocator Allocator used to allocate the pixelref for the dst
+     *                   bitmap. If this is null, the standard HeapAllocator
+     *                   will be used.
+     *  @return true if the copy could be made.
+     */
     bool copyTo(SkBitmap* dst, Config c, Allocator* allocator = NULL) const;
 
+    /** Makes a deep copy of this bitmap, respecting the requested config, and
+     *  with custom allocation logic that will keep the copied pixels
+     *  in the same domain as the source: If the src pixels are allocated for
+     *  the cpu, then so will the dst. If the src pixels are allocated on the
+     *  gpu (typically as a texture), the it will do the same for the dst.
+     *  If the request cannot be fulfilled, returns false and dst is unmodified.
+     */
+    bool deepCopyTo(SkBitmap* dst, Config c) const;
+
     /** Returns true if this bitmap can be deep copied into the requested config
         by calling copyTo().
      */
     bool canCopyTo(Config newConfig) const;
 
     bool hasMipMap() const;
     void buildMipMap(bool forceRebuild = false);
     void freeMipMap();
@@ -590,18 +597,19 @@ private:
     mutable void*       fPixels;
     mutable SkColorTable* fColorTable;    // only meaningful for kIndex8
     // When there is no pixel ref (setPixels was called) we still need a
     // gen id for SkDevice implementations that may cache a copy of the
     // pixels (e.g. as a gpu texture)
     mutable int         fRawPixelGenerationID;
 
     enum Flags {
-        kImageIsOpaque_Flag = 0x01,
-        kImageIsVolatile_Flag     = 0x02
+        kImageIsOpaque_Flag     = 0x01,
+        kImageIsVolatile_Flag   = 0x02,
+        kImageIsImmutable_Flag  = 0x04
     };
 
     uint32_t    fRowBytes;
     uint32_t    fWidth;
     uint32_t    fHeight;
     uint8_t     fConfig;
     uint8_t     fFlags;
     uint8_t     fBytesPerPixel; // based on config
--- a/gfx/skia/include/core/SkBlitter.h
+++ b/gfx/skia/include/core/SkBlitter.h
@@ -12,55 +12,76 @@
 
 #include "SkBitmap.h"
 #include "SkMatrix.h"
 #include "SkPaint.h"
 #include "SkRefCnt.h"
 #include "SkRegion.h"
 #include "SkMask.h"
 
+/** SkBlitter and its subclasses are responsible for actually writing pixels
+    into memory. Besides efficiency, they handle clipping and antialiasing.
+*/
 class SkBlitter {
 public:
     virtual ~SkBlitter();
 
+    /// Blit a horizontal run of one or more pixels.
     virtual void blitH(int x, int y, int width);
-    virtual void blitAntiH(int x, int y, const SkAlpha* antialias,
-                           const int16_t* runs);
+    /// 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[]);
+    /// 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.
     virtual void blitRect(int x, int y, int width, int height);
+    /** 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);
+    /// Blit a pattern of pixels defined by a rectangle-clipped mask;
+    /// typically used for text.
     virtual void blitMask(const SkMask&, const SkIRect& clip);
 
-    /*  If the blitter just sets a single value for each pixel, return the
+    /** 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);
 
-    // not virtual, just helpers
+    ///@name non-virtual helpers
     void blitMaskRegion(const SkMask& mask, const SkRegion& clip);
     void blitRectRegion(const SkIRect& rect, const SkRegion& clip);
     void blitRegion(const SkRegion& clip);
+    ///@}
 
-    // factories
+    /** @name Factories
+        Return the correct blitter to use given the specified context.
+     */
     static SkBlitter* Choose(const SkBitmap& device,
                              const SkMatrix& matrix,
                              const SkPaint& paint) {
         return Choose(device, matrix, paint, NULL, 0);
     }
 
     static SkBlitter* Choose(const SkBitmap& device,
                              const SkMatrix& matrix,
                              const SkPaint& paint,
                              void* storage, size_t storageSize);
 
     static SkBlitter* ChooseSprite(const SkBitmap& device,
                                    const SkPaint&,
                                    const SkBitmap& src,
                                    int left, int top,
                                    void* storage, size_t storageSize);
+    ///@}
 
 private:
 };
 
 /** This blitter silently never draws anything.
 */
 class SkNullBlitter : public SkBlitter {
 public:
@@ -80,56 +101,62 @@ public:
 class SkRectClipBlitter : public SkBlitter {
 public:
     void init(SkBlitter* blitter, const SkIRect& clipRect) {
         SkASSERT(!clipRect.isEmpty());
         fBlitter = blitter;
         fClipRect = clipRect;
     }
 
-    // overrides
     virtual void blitH(int x, int y, int width) SK_OVERRIDE;
     virtual void blitAntiH(int x, int y, const SkAlpha[],
                            const int16_t runs[]) SK_OVERRIDE;
     virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
     virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
+    virtual void blitAntiRect(int x, int y, int width, int height,
+                     SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE;
     virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
     virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
 
 private:
     SkBlitter*  fBlitter;
     SkIRect     fClipRect;
 };
 
 /** Wraps another (real) blitter, and ensures that the real blitter is only
-called with coordinates that have been clipped by the specified clipRgn.
-This means the caller need not perform the clipping ahead of time.
+    called with coordinates that have been clipped by the specified clipRgn.
+    This means the caller need not perform the clipping ahead of time.
 */
 class SkRgnClipBlitter : public SkBlitter {
 public:
     void init(SkBlitter* blitter, const SkRegion* clipRgn) {
         SkASSERT(clipRgn && !clipRgn->isEmpty());
         fBlitter = blitter;
         fRgn = clipRgn;
     }
 
-    // overrides
     virtual void blitH(int x, int y, int width) SK_OVERRIDE;
     virtual void blitAntiH(int x, int y, const SkAlpha[],
                            const int16_t runs[]) SK_OVERRIDE;
     virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
     virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
+    virtual void blitAntiRect(int x, int y, int width, int height,
+                     SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE;
     virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
     virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
 
 private:
     SkBlitter*      fBlitter;
     const SkRegion* fRgn;
 };
 
+/** Factory to set up the appropriate most-efficient wrapper blitter
+    to apply a clip. Returns a pointer to a member, so lifetime must
+    be managed carefully.
+*/
 class SkBlitterClipper {
 public:
     SkBlitter*  apply(SkBlitter* blitter, const SkRegion* clip,
                       const SkIRect* bounds = NULL);
 
 private:
     SkNullBlitter       fNullBlitter;
     SkRectClipBlitter   fRectBlitter;
--- a/gfx/skia/include/core/SkCanvas.h
+++ b/gfx/skia/include/core/SkCanvas.h
@@ -56,16 +56,23 @@ public:
         @param bitmap   Specifies a bitmap for the canvas to draw into. Its
                         structure are copied to the canvas.
     */
     explicit SkCanvas(const SkBitmap& bitmap);
     virtual ~SkCanvas();
 
     ///////////////////////////////////////////////////////////////////////////
 
+    /**
+     *  Return the width/height of the underlying device. The current drawable
+     *  area may be small (due to clipping or saveLayer). For a canvas with
+     *  no device, 0,0 will be returned.
+     */
+    SkISize getDeviceSize() const;
+
     /** Return the canvas' device object, which may be null. The device holds
         the bitmap of the pixels that the canvas draws into. The reference count
         of the returned device is not changed by this call.
     */
     SkDevice* getDevice() const;
 
     /** Specify a device for this canvas to draw into. If it is not null, its
         reference count is incremented. If the canvas was already holding a
@@ -94,33 +101,116 @@ public:
      */
     SkDevice* createCompatibleDevice(SkBitmap::Config config, 
                                     int width, int height,
                                     bool isOpaque);
 
     ///////////////////////////////////////////////////////////////////////////
 
     /**
-     *  Copy the pixels from the device into bitmap. Returns true on success.
-     *  If false is returned, then the bitmap parameter is left unchanged.
-     *  The bitmap parameter is treated as output-only, and will be completely
-     *  overwritten (if the method returns true).
+     * This enum can be used with read/writePixels to perform a pixel ops to or
+     * from an 8888 config other than Skia's native config (SkPMColor). There
+     * are three byte orders supported: native, BGRA, and RGBA. Each has a
+     * premultiplied and unpremultiplied variant.
+     *
+     * Components of a 8888 pixel can be packed/unpacked from a 32bit word using
+     * either byte offsets or shift values. Byte offsets are endian-invariant
+     * while shifts are not. BGRA and RGBA configs are defined by byte
+     * orderings. The native config is defined by shift values (SK_A32_SHIFT,
+     * ..., SK_B32_SHIFT).
+     */
+    enum Config8888 {
+        /**
+         * Skia's native order specified by:
+         *      SK_A32_SHIFT, SK_R32_SHIFT, SK_G32_SHIFT, and SK_B32_SHIFT
+         *
+         * kNative_Premul_Config8888 is equivalent to SkPMColor
+         * kNative_Unpremul_Config8888 has the same component order as SkPMColor
+         * but is not premultiplied.
+         */
+        kNative_Premul_Config8888,
+        kNative_Unpremul_Config8888,
+        /**
+         * low byte to high byte: B, G, R, A.
+         */
+        kBGRA_Premul_Config8888,
+        kBGRA_Unpremul_Config8888,
+        /**
+         * low byte to high byte: R, G, B, A.
+         */
+        kRGBA_Premul_Config8888,
+        kRGBA_Unpremul_Config8888,
+    };
+
+    /**
+     *  On success (returns true), copy the canvas pixels into the bitmap.
+     *  On failure, the bitmap parameter is left unchanged and false is
+     *  returned.
+     *
+     *  The canvas' pixels are converted to the bitmap's config. The only
+     *  supported config is kARGB_8888_Config, though this is likely to be
+     *  relaxed in  the future. The meaning of config kARGB_8888_Config is
+     *  modified by the enum param config8888. The default value interprets
+     *  kARGB_8888_Config as SkPMColor
+     *
+     *  If the bitmap has pixels already allocated, the canvas pixels will be
+     *  written there. If not, bitmap->allocPixels() will be called 
+     *  automatically. If the bitmap is backed by a texture readPixels will
+     *  fail.
+     *
+     *  The actual pixels written is the intersection of the canvas' bounds, and
+     *  the rectangle formed by the bitmap's width,height and the specified x,y.
+     *  If bitmap pixels extend outside of that intersection, they will not be
+     *  modified.
+     *
+     *  Other failure conditions:
+     *    * If the canvas is backed by a non-raster device (e.g. PDF) then
+     *       readPixels will fail.
+     *    * If bitmap is texture-backed then readPixels will fail. (This may be
+     *       relaxed in the future.)
+     *
+     *  Example that reads the entire canvas into a bitmap using the native
+     *  SkPMColor:
+     *    SkISize size = canvas->getDeviceSize();
+     *    bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth,
+     *                                                   size.fHeight);
+     *    if (canvas->readPixels(bitmap, 0, 0)) {
+     *       // use the pixels
+     *    }
+     */
+    bool readPixels(SkBitmap* bitmap,
+                    int x, int y,
+                    Config8888 config8888 = kNative_Premul_Config8888);
+
+    /**
+     * DEPRECATED: This will be removed as soon as webkit is no longer relying
+     * on it. The bitmap is resized to the intersection of srcRect and the
+     * canvas bounds. New pixels are always allocated on success. Bitmap is
+     * unmodified on failure.
      */
     bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
-    bool readPixels(SkBitmap* bitmap);
 
     /**
      *  Similar to draw sprite, this method will copy the pixels in bitmap onto
-     *  the device, with the top/left corner specified by (x, y). The pixel
-     *  values in the device are completely replaced: there is no blending.
+     *  the canvas, with the top/left corner specified by (x, y). The canvas'
+     *  pixel values are completely replaced: there is no blending.
+     *
+     *  Currently if bitmap is backed by a texture this is a no-op. This may be
+     *  relaxed in the future.
+     *
+     *  If the bitmap has config kARGB_8888_Config then the config8888 param
+     *  will determines how the pixel valuess are intepreted. If the bitmap is
+     *  not kARGB_8888_Config then this parameter is ignored.
      *
      *  Note: If you are recording drawing commands on this canvas to
      *  SkPicture, writePixels() is ignored!
      */
-    void writePixels(const SkBitmap& bitmap, int x, int y);
+    void writePixels(const SkBitmap& bitmap,
+                     int x, int y,
+                     Config8888 config8888 = kNative_Premul_Config8888);
 
     ///////////////////////////////////////////////////////////////////////////
 
     enum SaveFlags {
         /** save the matrix state, restoring it on restore() */
         kMatrix_SaveFlag            = 0x01,
         /** save the clip state, restoring it on restore() */
         kClip_SaveFlag              = 0x02,
@@ -192,16 +282,21 @@ public:
 
     /** Efficient way to pop any calls to save() that happened after the save
         count reached saveCount. It is an error for saveCount to be less than
         getSaveCount()
         @param saveCount    The number of save() levels to restore from
     */
     void restoreToCount(int saveCount);
 
+    /** Returns true if drawing is currently going to a layer (from saveLayer)
+     *  rather than to the root device.
+     */
+    bool isDrawingToLayer() const;
+
     /** Preconcat the current matrix with the specified translation
         @param dx   The distance to translate in X
         @param dy   The distance to translate in Y
         returns true if the operation succeeded (e.g. did not overflow)
     */
     virtual bool translate(SkScalar dx, SkScalar dy);
 
     /** Preconcat the current matrix with the specified scale.
@@ -641,17 +736,17 @@ public:
         @param matrix       (may be null) Applied to the text before it is
                             mapped onto the path
         @param paint        The paint used for the text
         */
     virtual void drawTextOnPath(const void* text, size_t byteLength,
                                 const SkPath& path, const SkMatrix* matrix,
                                 const SkPaint& paint);
 
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
     /** Draw the text on path, with each character/glyph origin specified by the pos[]
         array. The origin is interpreted by the Align setting in the paint.
         @param text The text to be drawn
         @param byteLength   The number of bytes to read from the text parameter
         @param pos      Array of positions, used to position each character
         @param paint    The paint used for the text (e.g. color, size, style)
         @param path The path to draw on
         @param matrix The canvas matrix
@@ -837,16 +932,17 @@ private:
     SkDeque     fMCStack;
     // points to top of stack
     MCRec*      fMCRec;
     // the first N recs that can fit here mean we won't call malloc
     uint32_t    fMCRecStorage[32];
 
     SkBounder*  fBounder;
     SkDevice*   fLastDeviceToGainFocus;
+    int         fLayerCount;    // number of successful saveLayer calls
 
     void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&,
                               const SkClipStack& clipStack);
 
     bool fDeviceCMDirty;            // cleared by updateDeviceCMCache()
     void updateDeviceCMCache();
 
     friend class SkDrawIter;    // needs setupDrawForLayerDevice()
--- a/gfx/skia/include/core/SkColorFilter.h
+++ b/gfx/skia/include/core/SkColorFilter.h
@@ -18,16 +18,41 @@ class SK_API SkColorFilter : public SkFl
 public:
     /**
      *  If the filter can be represented by a source color plus Mode, this
      *  returns true, and sets (if not NULL) the color and mode appropriately.
      *  If not, this returns false and ignores the parameters.
      */
     virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode);
 
+    /**
+     *  If the filter can be represented by a 5x4 matrix, this
+     *  returns true, and sets the matrix appropriately.
+     *  If not, this returns false and ignores the parameter.
+     */
+    virtual bool asColorMatrix(SkScalar matrix[20]);
+
+    /**
+     *  If the filter can be represented by per-component table, return true,
+     *  and if table is not null, copy the bitmap containing the table into it.
+     *
+     *  The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding
+     *  to each component in ARGB order. e.g. row[0] == alpha, row[1] == red,
+     *  etc. To transform a color, you (logically) perform the following:
+     *
+     *      a' = *table.getAddr8(a, 0);
+     *      r' = *table.getAddr8(r, 1);
+     *      g' = *table.getAddr8(g, 2);
+     *      b' = *table.getAddr8(b, 3);
+     *
+     *  The original component value is the horizontal index for a given row,
+     *  and the stored value at that index is the new value for that component.
+     */
+    virtual bool asComponentTable(SkBitmap* table);
+
     /** Called with a scanline of colors, as if there was a shader installed.
         The implementation writes out its filtered version into result[].
         Note: shader and result may be the same buffer.
         @param src      array of colors, possibly generated by a shader
         @param count    the number of entries in the src[] and result[] arrays
         @param result   written by the filter
     */
     virtual void filterSpan(const SkPMColor src[], int count,
@@ -87,17 +112,18 @@ public:
                                            SkXfermodeProc16 proc16 = NULL);
 
     /** Create a colorfilter that multiplies the RGB channels by one color, and
         then adds a second color, pinning the result for each component to
         [0..255]. The alpha components of the mul and add arguments
         are ignored.
     */
     static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
-
+    
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 protected:
     SkColorFilter() {}
     SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
 
 private:
     typedef SkFlattenable INHERITED;
 };
 
--- a/gfx/skia/include/core/SkColorShader.h
+++ b/gfx/skia/include/core/SkColorShader.h
@@ -27,40 +27,42 @@ public:
     /** Create a ColorShader that ignores the color in the paint, and uses the
         specified color. Note: like all shaders, at draw time the paint's alpha
         will be respected, and is applied to the specified color.
     */
     SkColorShader(SkColor c);
 
     virtual ~SkColorShader();
 
-    virtual uint32_t getFlags() { return fFlags; }
-    virtual uint8_t getSpan16Alpha() const;
+    virtual uint32_t getFlags() SK_OVERRIDE;
+    virtual uint8_t getSpan16Alpha() const SK_OVERRIDE;
+    virtual bool isOpaque() const SK_OVERRIDE;
     virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
-                            const SkMatrix& matrix);
-    virtual void shadeSpan(int x, int y, SkPMColor span[], int count);
-    virtual void shadeSpan16(int x, int y, uint16_t span[], int count);
-    virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
+                            const SkMatrix& matrix) SK_OVERRIDE;
+    virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE;
+    virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE;
+    virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE;
 
     // we return false for this, use asAGradient
     virtual BitmapType asABitmap(SkBitmap* outTexture,
                                  SkMatrix* outMatrix,
                                  TileMode xy[2],
-                                 SkScalar* twoPointRadialParams) const;
+                                 SkScalar* twoPointRadialParams) const SK_OVERRIDE;
 
-    virtual GradientType asAGradient(GradientInfo* info) const;
+    virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
 
 protected:
-    SkColorShader(SkFlattenableReadBuffer& );
-    virtual void flatten(SkFlattenableWriteBuffer& );
-    virtual Factory getFactory() { return CreateProc; }
+    SkColorShader(SkFlattenableReadBuffer&);
+
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    virtual Factory getFactory() SK_OVERRIDE;
+
 private:
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkColorShader, (buffer));
-    }
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
     SkColor     fColor;         // ignored if fInheritColor is true
     SkPMColor   fPMColor;       // cached after setContext()
     uint32_t    fFlags;         // cached after setContext()
     uint16_t    fColor16;       // cached after setContext()
     SkBool8     fInheritColor;
 
     typedef SkShader INHERITED;
 };
--- a/gfx/skia/include/core/SkDevice.h
+++ b/gfx/skia/include/core/SkDevice.h
@@ -102,47 +102,51 @@ public:
         to access the bitmap, as it notifies the subclass to perform any flushing
         etc. before you examine the pixels.
         @param changePixels set to true if the caller plans to change the pixels
         @return the device's bitmap
     */
     const SkBitmap& accessBitmap(bool changePixels);
 
     /**
-     *  Copy the pixels from the device into bitmap. Returns true on success.
-     *  If false is returned, then the bitmap parameter is left unchanged.
-     *  The bitmap parameter is treated as output-only, and will be completely
-     *  overwritten (if the method returns true).
-     */
-    virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
-
-    /**
+     *  DEPRECATED: This will be made protected once WebKit stops using it.
+     *              Instead use Canvas' writePixels method.
+     *
      *  Similar to draw sprite, this method will copy the pixels in bitmap onto
      *  the device, with the top/left corner specified by (x, y). The pixel
      *  values in the device are completely replaced: there is no blending.
+     *
+     *  Currently if bitmap is backed by a texture this is a no-op. This may be
+     *  relaxed in the future.
+     *
+     *  If the bitmap has config kARGB_8888_Config then the config8888 param
+     *  will determines how the pixel valuess are intepreted. If the bitmap is
+     *  not kARGB_8888_Config then this parameter is ignored.
      */
-    virtual void writePixels(const SkBitmap& bitmap, int x, int y);
+    virtual void writePixels(const SkBitmap& bitmap, int x, int y,
+                             SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888);
 
     /**
      * Return the device's associated gpu render target, or NULL.
      */
     virtual SkGpuRenderTarget* accessRenderTarget() { return NULL; }
 
-protected:
-    enum Usage {
-       kGeneral_Usage,
-       kSaveLayer_Usage, // <! internal use only
-    };
 
     /**
      *  Return the device's origin: its offset in device coordinates from
      *  the default origin in its canvas' matrix/clip
      */
     const SkIPoint& getOrigin() const { return fOrigin; }
 
+protected:
+    enum Usage {
+       kGeneral_Usage,
+       kSaveLayer_Usage, // <! internal use only
+    };
+
     struct TextFlags {
         uint32_t            fFlags;     // SkPaint::getFlags()
         SkPaint::Hinting    fHinting;
     };
 
     /**
      *  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
@@ -221,59 +225,115 @@ protected:
     virtual void drawText(const SkDraw&, const void* text, size_t len,
                           SkScalar x, SkScalar y, const SkPaint& paint);
     virtual void drawPosText(const SkDraw&, const void* text, size_t len,
                              const SkScalar pos[], SkScalar constY,
                              int scalarsPerPos, const SkPaint& paint);
     virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
                                 const SkPath& path, const SkMatrix* matrix,
                                 const SkPaint& paint);
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
     virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
                                    const SkPoint pos[], const SkPaint& paint,
                                    const SkPath& path, const SkMatrix* matrix);
 #endif
     virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
                               const SkPoint verts[], const SkPoint texs[],
                               const SkColor colors[], SkXfermode* xmode,
                               const uint16_t indices[], int indexCount,
                               const SkPaint& paint);
     /** The SkDevice passed will be an SkDevice which was returned by a call to
         onCreateCompatibleDevice on this device with kSaveLayer_Usage.
      */
     virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
                             const SkPaint&);
 
+    /**
+     *  On success (returns true), copy the device pixels into the bitmap.
+     *  On failure, the bitmap parameter is left unchanged and false is
+     *  returned.
+     *
+     *  The device's pixels are converted to the bitmap's config. The only
+     *  supported config is kARGB_8888_Config, though this is likely to be
+     *  relaxed in  the future. The meaning of config kARGB_8888_Config is
+     *  modified by the enum param config8888. The default value interprets
+     *  kARGB_8888_Config as SkPMColor
+     *
+     *  If the bitmap has pixels already allocated, the device pixels will be
+     *  written there. If not, bitmap->allocPixels() will be called 
+     *  automatically. If the bitmap is backed by a texture readPixels will
+     *  fail.
+     *
+     *  The actual pixels written is the intersection of the device's bounds,
+     *  and the rectangle formed by the bitmap's width,height and the specified
+     *  x,y. If bitmap pixels extend outside of that intersection, they will not
+     *  be modified.
+     *
+     *  Other failure conditions:
+     *    * If the device is not a raster device (e.g. PDF) then readPixels will
+     *      fail.
+     *    * If bitmap is texture-backed then readPixels will fail. (This may be
+     *      relaxed in the future.)
+     */
+    bool readPixels(SkBitmap* bitmap,
+                    int x, int y,
+                    SkCanvas::Config8888 config8888);
+
     ///////////////////////////////////////////////////////////////////////////
 
     /** Update as needed the pixel value in the bitmap, so that the caller can access
         the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
         must remain unchanged.
     */
     virtual void onAccessBitmap(SkBitmap*);
 
     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
     // just for subclasses, to assign a custom pixelref
     SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
         fBitmap.setPixelRef(pr, offset);
         return pr;
     }
+    
+    /**
+     * Implements readPixels API. The caller will ensure that:
+     *  1. bitmap has pixel config kARGB_8888_Config.
+     *  2. bitmap has pixels.
+     *  3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is
+     *     contained in the device bounds.
+     */
+    virtual bool onReadPixels(const SkBitmap& bitmap,
+                              int x, int y,
+                              SkCanvas::Config8888 config8888);
 
     /** Called when this device is installed into a Canvas. Balanaced by a call
         to unlockPixels() when the device is removed from a Canvas.
     */
     virtual void lockPixels();
     virtual void unlockPixels();
 
+    /**
+     *  Override and return true for filters that the device handles
+     *  intrinsically. Returning false means call the filter.
+     *  Default impl returns false.
+     */
+    virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
+                             const SkMatrix& ctm,
+                             SkBitmap* result, SkIPoint* offset);
+
+    // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if 
+    // either is identical to kNative_Premul_Config8888. Otherwise, -1.
+    static const SkCanvas::Config8888 kPMColorAlias;
+
 private:
     friend class SkCanvas;
     friend struct DeviceCM; //for setMatrixClip
     friend class SkDraw;
     friend class SkDrawIter;
     friend class SkDeviceFilteredPaint;
+    friend class DeviceImageFilterProxy;
 
     // 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
     SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config, 
                                                  int width, int height,
                                                  bool isOpaque);
 
--- a/gfx/skia/include/core/SkDraw.h
+++ b/gfx/skia/include/core/SkDraw.h
@@ -50,17 +50,17 @@ public:
     void    drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const;
     void    drawText(const char text[], size_t byteLength, SkScalar x,
                      SkScalar y, const SkPaint& paint) const;
     void    drawPosText(const char text[], size_t byteLength,
                         const SkScalar pos[], SkScalar constY,
                         int scalarsPerPosition, const SkPaint& paint) const;
     void    drawTextOnPath(const char text[], size_t byteLength,
                         const SkPath&, const SkMatrix*, const SkPaint&) const;
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
     void    drawPosTextOnPath(const char text[], size_t byteLength,
                               const SkPoint pos[], const SkPaint& paint,
                               const SkPath& path, const SkMatrix* matrix) const;
 #endif
     void    drawVertices(SkCanvas::VertexMode mode, int count,
                          const SkPoint vertices[], const SkPoint textures[],
                          const SkColor colors[], SkXfermode* xmode,
                          const uint16_t indices[], int ptCount,
@@ -144,13 +144,14 @@ private:
     SkFixed         fPrevAdvance;
     const char*     fText;
     const char*     fStop;
     SkMeasureCacheProc fGlyphCacheProc;
 
     const SkPath*   fPath;      // returned in next
     SkScalar        fXPos;      // accumulated xpos, returned in next
     SkAutoKern      fAutoKern;
+    int             fXYIndex;   // cache for horizontal -vs- vertical text
 };
 
 #endif
 
 
--- a/gfx/skia/include/core/SkEmptyShader.h
+++ b/gfx/skia/include/core/SkEmptyShader.h
@@ -10,32 +10,34 @@
 
 #ifndef SkEmptyShader_DEFINED
 #define SkEmptyShader_DEFINED
 
 #include "SkShader.h"
 
 /**
  *  \class SkEmptyShader
- *  A Shader that always draws nothing.
+ *  A Shader that always draws nothing. Its setContext always returns false,
+ *  so it never expects that its shadeSpan() methods will get called.
  */
 class SK_API SkEmptyShader : public SkShader {
 public:
-    SkEmptyShader();
+    SkEmptyShader() {}
 
-    virtual uint32_t getFlags();
-    virtual uint8_t getSpan16Alpha() const;
-    virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
-                            const SkMatrix& matrix);
-    virtual void shadeSpan(int x, int y, SkPMColor span[], int count);
-    virtual void shadeSpan16(int x, int y, uint16_t span[], int count);
-    virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
+    virtual uint32_t getFlags() SK_OVERRIDE;
+    virtual uint8_t getSpan16Alpha() const SK_OVERRIDE;
+    virtual bool setContext(const SkBitmap&, const SkPaint&,
+                            const SkMatrix&) SK_OVERRIDE;
+    virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE;
+    virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE;
+    virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE;
 
 protected:
     SkEmptyShader(SkFlattenableReadBuffer&);
-    virtual Factory getFactory();
-    virtual void flatten(SkFlattenableWriteBuffer&);
+
+    virtual Factory getFactory() SK_OVERRIDE;
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
 
 private:
     typedef SkShader INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/core/SkEndian.h
+++ b/gfx/skia/include/core/SkEndian.h
@@ -75,11 +75,24 @@ static inline void SkEndianSwap32s(uint3
     #define SkEndian_SwapLE32(n)    (n)
 #else   // SK_CPU_BENDIAN
     #define SkEndian_SwapBE16(n)    (n)
     #define SkEndian_SwapBE32(n)    (n)
     #define SkEndian_SwapLE16(n)    SkEndianSwap16(n)
     #define SkEndian_SwapLE32(n)    SkEndianSwap32(n)
 #endif
 
+// When a bytestream is embedded in a 32-bit word, how far we need to
+// shift the word to extract each byte from the low 8 bits by anding with 0xff.
+#ifdef SK_CPU_LENDIAN
+    #define SkEndian_Byte0Shift 0
+    #define SkEndian_Byte1Shift 8
+    #define SkEndian_Byte2Shift 16
+    #define SkEndian_Byte3Shift 24
+#else   // SK_CPU_BENDIAN
+    #define SkEndian_Byte0Shift 24
+    #define SkEndian_Byte1Shift 16
+    #define SkEndian_Byte2Shift 8
+    #define SkEndian_Byte3Shift 0
+#endif
 
 #endif
 
--- a/gfx/skia/include/core/SkFlattenable.h
+++ b/gfx/skia/include/core/SkFlattenable.h
@@ -15,16 +15,50 @@
 #include "SkReader32.h"
 #include "SkTDArray.h"
 #include "SkWriter32.h"
 
 class SkFlattenableReadBuffer;
 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
  into a data stream for either transport or as part of the key to the
  font cache.
  */
 class SK_API SkFlattenable : public SkRefCnt {
 public:
@@ -56,16 +90,23 @@ public:
     public:
         Registrar(const char name[], Factory factory) {
             SkFlattenable::Register(name, factory);
         }
     };
     
 protected:
     SkFlattenable(SkFlattenableReadBuffer&) {}
+
+private:
+#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+    static void InitializeFlattenables();
+#endif
+
+    friend class SkGraphics;
 };
 
 // helpers for matrix and region
 
 class SkMatrix;
 extern void SkReadMatrix(SkReader32*, SkMatrix*);
 extern void SkWriteMatrix(SkWriter32*, const SkMatrix&);
 
--- a/gfx/skia/include/core/SkFloatingPoint.h
+++ b/gfx/skia/include/core/SkFloatingPoint.h
@@ -53,22 +53,34 @@ static inline float sk_float_copysign(fl
     #define sk_float_ceil(x)        ceilf(x)
 #ifdef SK_BUILD_FOR_MAC
     #define sk_float_acos(x)        static_cast<float>(acos(x))
     #define sk_float_asin(x)        static_cast<float>(asin(x))
 #else
     #define sk_float_acos(x)        acosf(x)
     #define sk_float_asin(x)        asinf(x)
 #endif
-    #define sk_float_atan2(y,x) atan2f(y,x)
+    #define sk_float_atan2(y,x)     atan2f(y,x)
     #define sk_float_abs(x)         fabsf(x)
     #define sk_float_mod(x,y)       fmodf(x,y)
     #define sk_float_exp(x)         expf(x)
     #define sk_float_log(x)         logf(x)
-    #define sk_float_isNaN(x)       _isnan(x)
+#endif
+
+#ifdef SK_BUILD_FOR_WIN
+    #define sk_float_isfinite(x)    _finite(x)
+    #define sk_float_isnan(x)       _isnan(x)
+    static inline int sk_float_isinf(float x) {
+        int32_t bits = SkFloat2Bits(x);
+        return (bits << 1) == (0xFF << 24);
+    }
+#else
+    #define sk_float_isfinite(x)    isfinite(x)
+    #define sk_float_isnan(x)       isnan(x)
+    #define sk_float_isinf(x)       isinf(x)
 #endif
 
 #ifdef SK_USE_FLOATBITS
     #define sk_float_floor2int(x)   SkFloatToIntFloor(x)
     #define sk_float_round2int(x)   SkFloatToIntRound(x)
     #define sk_float_ceil2int(x)    SkFloatToIntCeil(x)
 #else
     #define sk_float_floor2int(x)   (int)sk_float_floor(x)
--- a/gfx/skia/include/core/SkFontHost.h
+++ b/gfx/skia/include/core/SkFontHost.h
@@ -227,30 +227,19 @@ public:
                 offset > the table's size, or tag is not a valid table,
                 then 0 is returned.
      */
     static size_t GetTableData(SkFontID fontID, SkFontTableTag tag,
                                size_t offset, size_t length, void* data);
 
     ///////////////////////////////////////////////////////////////////////////
 
-    /** Return the number of bytes (approx) that should be purged from the font
-        cache. The input parameter is the cache's estimate of how much as been
-        allocated by the cache so far.
-        To purge (basically) everything, return the input parameter.
-        To purge nothing, return 0
-    */
-    static size_t ShouldPurgeFontCache(size_t sizeAllocatedSoFar);
+    /** DEPRECATED -- only called by SkFontHost_FreeType internally
 
-    /** Return SkScalerContext gamma flag, or 0, based on the paint that will be
-        used to draw something with antialiasing.
-    */
-    static int ComputeGammaFlag(const SkPaint& paint);
-
-    /** Return NULL or a pointer to 256 bytes for the black (table[0]) and
+        Return NULL or a pointer to 256 bytes for the black (table[0]) and
         white (table[1]) gamma tables.
     */
     static void GetGammaTables(const uint8_t* tables[2]);
 
     ///////////////////////////////////////////////////////////////////////////
 
     /** LCDs either have their color elements arranged horizontally or
         vertically. When rendering subpixel glyphs we need to know which way
@@ -281,22 +270,30 @@ public:
         kRGB_LCDOrder = 0,    //!< this is the default
         kBGR_LCDOrder = 1,
         kNONE_LCDOrder = 2,
     };
 
     static void SetSubpixelOrder(LCDOrder order);
     static LCDOrder GetSubpixelOrder();
 
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
     ///////////////////////////////////////////////////////////////////////////
 
     /**
      * Return the number of font units per em.
      *
      * @param fontID the font to query.
      * @return the number of font units per em or 0 on error.
      */
     static uint32_t GetUnitsPerEm(SkFontID fontID);
 #endif
+
+    /** If Skia is running in a constrained environment and the typeface
+        implementation is handle based, the typeface data may become
+        unavailable asynchronously. If a font host or scaler context method is
+        unable to access font data, it may call this function as a request to
+        make the handle contained in the typeface useable.
+    */
+    static void EnsureTypefaceAccessible(const SkTypeface& typeface);
 };
 
 #endif
--- a/gfx/skia/include/core/SkGraphics.h
+++ b/gfx/skia/include/core/SkGraphics.h
@@ -9,34 +9,67 @@
 
 #ifndef SkGraphics_DEFINED
 #define SkGraphics_DEFINED
 
 #include "SkTypes.h"
 
 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();
+
+    /**
+     *  Call this to release any memory held privately, such as the font cache.
+     */
     static void Term();
 
-    /** Return the (approximate) number of bytes used by the font cache.
-    */
-    static size_t GetFontCacheUsed();
-    
-    /** Attempt to purge the font cache until <= the specified amount remains
-        in the cache. Specifying 0 will attempt to purge the entire cache.
-        Returns true if some amount was purged from the font cache.
-    */
-    static bool SetFontCacheUsed(size_t usageInBytes);
-
-    /** Return the version numbers for the library. If the parameter is not
-        null, it is set to the version number.
+    /**
+     *  Return the version numbers for the library. If the parameter is not
+     *  null, it is set to the version number.
      */
     static void GetVersion(int32_t* major, int32_t* minor, int32_t* patch);
 
+    /**
+     *  Return the max number of bytes that should be used by the font cache.
+     *  If the cache needs to allocate more, it will purge previous entries.
+     *  This max can be changed by calling SetFontCacheLimit().
+     */
+    static size_t GetFontCacheLimit();
+    
+    /**
+     *  Specify the max number of bytes that should be used by the font cache.
+     *  If the cache needs to allocate more, it will purge previous entries.
+     *
+     *  This function returns the previous setting, as if GetFontCacheLimit()
+     *  had be called before the new limit was set.
+     */
+    static size_t SetFontCacheLimit(size_t bytes);
+
+    /**
+     *  For debugging purposes, this will attempt to purge the font cache. It
+     *  does not change the limit, but will cause subsequent font measures and
+     *  draws to be recreated, since they will no longer be in the cache.
+     */
+    static void PurgeFontCache();
+    
+    /**
+     *  Applications with command line options may pass optional state, such
+     *  as cache sizes, here, for instance:
+     *  font-cache-limit=12345678
+     *
+     *  The flags format is name=value[;name=value...] with no spaces.
+     *  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
         with the C++ runtime to call SkGraphics::FreeCaches()
     */
     static void InstallNewHandler();
 };
 
--- a/gfx/skia/include/core/SkImageFilter.h
+++ b/gfx/skia/include/core/SkImageFilter.h
@@ -5,36 +5,92 @@
  * found in the LICENSE file.
  */
 
 #ifndef SkImageFilter_DEFINED
 #define SkImageFilter_DEFINED
 
 #include "SkFlattenable.h"
 
-class SkImageFilter : public SkFlattenable {
+class SkBitmap;
+class SkDevice;
+class SkMatrix;
+struct SkPoint;
+
+/**
+ *  Experimental.
+ *
+ *  Base class for image filters. If one is installed in the paint, then
+ *  all drawing occurs as usual, but it is as if the drawing happened into an
+ *  offscreen (before the xfermode is applied). This offscreen bitmap will
+ *  then be handed to the imagefilter, who in turn creates a new bitmap which
+ *  is what will finally be drawn to the device (using the original xfermode).
+ *
+ *  THIS SIGNATURE IS TEMPORARY
+ *
+ *  There are several weaknesses in this function signature:
+ *  1. Does not expose the destination/target device, so filters that can draw
+ *     directly to it are unable to take advantage of that optimization.
+ *  2. Does not expose a way to create a "compabitible" image (i.e. gpu -> gpu)
+ *  3. As with #1, the filter is unable to "read" the dest (which would be slow)
+ *
+ *  Therefore, we should not create any real dependencies on this API yet -- it
+ *  is being checked in as a check-point so we can explore these and other
+ *  considerations.
+ */
+class SK_API SkImageFilter : public SkFlattenable {
 public:
+    class Proxy {
+    public:
+        virtual SkDevice* createDevice(int width, int height) = 0;
+        
+        // returns true if the proxy handled the filter itself. if this returns
+        // false then the filter's code will be called.
+        virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
+                                 const SkMatrix& ctm,
+                                 SkBitmap* result, SkIPoint* offset) = 0;
+    };
 
     /**
      *  Request a new (result) image to be created from the src image.
      *  If the src has no pixels (isNull()) then the request just wants to
      *  receive the config and width/height of the result.
      *
      *  The matrix is the current matrix on the canvas.
      *
      *  Offset is the amount to translate the resulting image relative to the
      *  src when it is drawn. 
      *
      *  If the result image cannot be created, return false, in which case both
      *  the result and offset parameters will be ignored by the caller.
      */
-    bool filterImage(const SkBitmap& src, const SkMatrix&,
-                     SkBitmap* result, SkPoint* offset);
+    bool filterImage(Proxy*, const SkBitmap& src, const SkMatrix& ctm,
+                     SkBitmap* result, SkIPoint* offset);
+
+    /**
+     *  Given the src bounds of an image, this returns the bounds of the result
+     *  image after the filter has been applied.
+     */
+    bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst);
+
+    /**
+     *  Experimental.
+     *
+     *  If the filter can be expressed as a gaussian-blur, return true and
+     *  set the sigma to the values for horizontal and vertical.
+     */
+    virtual bool asABlur(SkSize* sigma) const;
 
 protected:
-    virtual bool onFilterImage(const SkBitmap& src, const SkMatrix&
-                               SkBitmap* result, SkPoint* offset) = 0;
+    SkImageFilter() {}
+    explicit SkImageFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
+
+    // Default impl returns false
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+                               SkBitmap* result, SkIPoint* offset);
+    // Default impl copies src into dst and returns true
+    virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*);
 
 private:
     typedef SkFlattenable INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/core/SkMMapStream.h
+++ b/gfx/skia/include/core/SkMMapStream.h
@@ -14,17 +14,16 @@
 
 class SkMMAPStream : public SkMemoryStream {
 public:
     SkMMAPStream(const char filename[]);
     virtual ~SkMMAPStream();
 
     virtual void setMemory(const void* data, size_t length, bool);
 private:
-    int     fFildes;
     void*   fAddr;
     size_t  fSize;
     
     void closeMMap();
     
     typedef SkMemoryStream INHERITED;
 };
 
--- a/gfx/skia/include/core/SkMallocPixelRef.h
+++ b/gfx/skia/include/core/SkMallocPixelRef.h
@@ -32,16 +32,17 @@ public:
     virtual void flatten(SkFlattenableWriteBuffer&) const;
     virtual Factory getFactory() const {
         return Create;
     }
     static SkPixelRef* Create(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(SkMallocPixelRef, (buffer));
     }
 
+    SK_DECLARE_PIXEL_REF_REGISTRAR()
 protected:
     // overrides from SkPixelRef
     virtual void* onLockPixels(SkColorTable**);
     virtual void onUnlockPixels();
 
     SkMallocPixelRef(SkFlattenableReadBuffer& buffer);
 
 private:
--- a/gfx/skia/include/core/SkOSFile.h
+++ b/gfx/skia/include/core/SkOSFile.h
@@ -8,17 +8,17 @@
 
 
 // 
 #ifndef SkOSFile_DEFINED
 #define SkOSFile_DEFINED
 
 #include "SkString.h"
 
-#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
+#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
     #include <dirent.h>
 #endif
 
 struct SkFILE;
 
 enum SkFILE_Flags {
     kRead_SkFILE_Flag   = 0x01,
     kWrite_SkFILE_Flag  = 0x02
@@ -53,17 +53,17 @@ public:
             interleaved on a single iterator.
         */
         bool next(SkString* name, bool getDir = false);
 
     private:
 #ifdef SK_BUILD_FOR_WIN
         HANDLE      fHandle;
         uint16_t*   fPath16;
-#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
+#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
         DIR*        fDIR;
         SkString    fPath, fSuffix;
 #endif
     };
 };
 
 class SkUTF16_Str {
 public:
--- a/gfx/skia/include/core/SkPaint.h
+++ b/gfx/skia/include/core/SkPaint.h
@@ -16,16 +16,17 @@
 class SkAutoGlyphCache;
 class SkColorFilter;
 class SkDescriptor;
 class SkFlattenableReadBuffer;
 class SkFlattenableWriteBuffer;
 struct SkGlyph;
 struct SkRect;
 class SkGlyphCache;
+class SkImageFilter;
 class SkMaskFilter;
 class SkMatrix;
 class SkPath;
 class SkPathEffect;
 class SkRasterizer;
 class SkShader;
 class SkDrawLooper;
 class SkTypeface;
@@ -93,19 +94,17 @@ public:
         kStrikeThruText_Flag  = 0x10,   //!< mask to enable strike-thru text
         kFakeBoldText_Flag    = 0x20,   //!< mask to enable fake-bold text
         kLinearText_Flag      = 0x40,   //!< mask to enable linear-text
         kSubpixelText_Flag    = 0x80,   //!< mask to enable subpixel text positioning
         kDevKernText_Flag     = 0x100,  //!< mask to enable device kerning text
         kLCDRenderText_Flag   = 0x200,  //!< mask to enable subpixel glyph renderering
         kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
         kAutoHinting_Flag     = 0x800,  //!< mask to force Freetype's autohinter
-
-        // experimental/private
-        kForceAAText_Flag     = 0x1000,
+        kVerticalText_Flag    = 0x1000,
 
         // when adding extra flags, note that the fFlags member is specified
         // with a bit-width and you'll have to expand it.
 
         kAllFlags = 0x1FFF
     };
 
     /** Return the paint's flags. Use the Flag enum to test flag values.
@@ -197,16 +196,30 @@ public:
 
     /** Helper for setFlags(), setting or clearing the kAutoHinting_Flag bit
         @param useAutohinter true to set the kEmbeddedBitmapText bit in the
                                   paint's flags,
                              false to clear it.
     */
     void setAutohinted(bool useAutohinter);
 
+    bool isVerticalText() const {
+        return SkToBool(this->getFlags() & kVerticalText_Flag);
+    }
+    
+    /**
+     *  Helper for setting or clearing the kVerticalText_Flag bit in
+     *  setFlags(...).
+     *
+     *  If this bit is set, then advances are treated as Y values rather than
+     *  X values, and drawText will places its glyphs vertically rather than
+     *  horizontally.
+     */
+    void setVerticalText(bool);
+
     /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
         @return true if the underlineText bit is set in the paint's flags.
     */
     bool isUnderlineText() const {
         return SkToBool(this->getFlags() & kUnderlineText_Flag);
     }
 
     /** Helper for setFlags(), setting or clearing the kUnderlineText_Flag bit
@@ -590,16 +603,19 @@ public:
         decremented. If rasterizer is not NULL, its reference count is
         incremented.
         @param rasterizer May be NULL. The new rasterizer to be installed in
                           the paint.
         @return           rasterizer
     */
     SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
 
+    SkImageFilter* getImageFilter() const { return fImageFilter; }
+    SkImageFilter* setImageFilter(SkImageFilter*);
+
     /**
      *  Return the paint's SkDrawLooper (if any). Does not affect the looper's
      *  reference count.
      */
     SkDrawLooper* getLooper() const { return fLooper; }
 
     /**
      *  Set or clear the looper object.
@@ -738,33 +754,39 @@ public:
         This looks at the current TextEncoding field of the paint. If you also
         want to have the text converted into glyph IDs, call textToGlyphs
         instead.
     */
     int countText(const void* text, size_t byteLength) const {
         return this->textToGlyphs(text, byteLength, NULL);
     }
 
-    /** Return the width of the text.
-        @param text         The text to be measured
-        @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
-    */
+    /** Return the width of the text. This will return the vertical measure
+     *  if isVerticalText() is true, in which case the returned value should
+     *  be treated has a height instead of a width.
+     *
+     *  @param text         The text to be measured
+     *  @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;
 
-    /** Return the width of the text.
-        @param text         Address of the text
-        @param length       Number of bytes of text to measure
-        @return The width of the text
-    */
+    /** Return the width of the text. This will return the vertical measure
+     *  if isVerticalText() is true, in which case the returned value should
+     *  be treated has a height instead of a width.
+     *
+     *  @param text     Address of the text
+     *  @param length   Number of bytes of text to measure
+     *  @return         The width of the text
+     */
     SkScalar measureText(const void* text, size_t length) const {
         return this->measureText(text, length, NULL, 0);
     }
 
     /** Specify the direction the text buffer should be processed in breakText()
     */
     enum TextBufferDirection {
         /** When measuring text for breakText(), begin at the start of the text
@@ -772,57 +794,59 @@ public:
         */
         kForward_TextBufferDirection,
         /** When measuring text for breakText(), begin at the end of the text
             buffer and proceed backwards through the data.
         */
         kBackward_TextBufferDirection
     };
 
-    /** Return the width of the text.
-        @param text     The text to be measured
-        @param length   Number of bytes of text to measure
-        @param maxWidth Maximum width. Only the subset of text whose accumulated
-                        widths are <= maxWidth are measured.
-        @param measuredWidth Optional. If non-null, this returns the actual
-                        width of the measured text.
-        @param tbd      Optional. The direction the text buffer should be
-                        traversed during measuring.
-        @return         The number of bytes of text that were measured. Will be
-                        <= length.
-    */
+    /** Return the number of bytes of text that were measured. If
+     *  isVerticalText() is true, then the vertical advances are used for
+     *  the measurement.
+     *  
+     *  @param text     The text to be measured
+     *  @param length   Number of bytes of text to measure
+     *  @param maxWidth Maximum width. Only the subset of text whose accumulated
+     *                  widths are <= maxWidth are measured.
+     *  @param measuredWidth Optional. If non-null, this returns the actual
+     *                  width of the measured text.
+     *  @param tbd      Optional. The direction the text buffer should be
+     *                  traversed during measuring.
+     *  @return         The number of bytes of text that were measured. Will be
+     *                  <= length.
+     */
     size_t  breakText(const void* text, size_t length, SkScalar maxWidth,
                       SkScalar* measuredWidth = NULL,
                       TextBufferDirection tbd = kForward_TextBufferDirection)
                       const;
 
-    /** Return the advance widths for the characters in the string.
-        @param text         the text
-        @param byteLength   number of bytes to of text
-        @param widths       If not null, returns the array of advance widths of
-                            the glyphs. If not NULL, must be at least a large
-                            as the number of unichars in the specified text.
-        @param bounds       If not null, returns the bounds for each of
-                            character, relative to (0, 0)
-        @return the number of unichars in the specified text.
-    */
+    /** Return the advances for the text. These will be vertical advances if
+     *  isVerticalText() returns true.
+     *
+     *  @param text         the text
+     *  @param byteLength   number of bytes to of text
+     *  @param widths       If not null, returns the array of advances for
+     *                      the glyphs. If not NULL, must be at least a large
+     *                      as the number of unichars in the specified text.
+     *  @param bounds       If not null, returns the bounds for each of
+     *                      character, relative to (0, 0)
+     *  @return the number of unichars in the specified text.
+     */
     int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
                       SkRect bounds[] = NULL) const;
 
     /** Return the path (outline) for the specified text.
         Note: just like SkCanvas::drawText, this will respect the Align setting
               in the paint.
     */
     void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
                      SkPath* path) const;
 
-    void getPosTextPath(const void* text, size_t length, 
-                        const SkPoint pos[], SkPath* path) const;
-
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
     const SkGlyph& getUnicharMetrics(SkUnichar);
     const void* findImage(const SkGlyph&);
 
     uint32_t getGenerationID() const;
 #endif
 
     // returns true if the paint's settings (e.g. xfermode + alpha) resolve to
     // mean that we need not draw at all (e.g. SrcOver + 0-alpha)
@@ -836,30 +860,28 @@ private:
 
     SkPathEffect*   fPathEffect;
     SkShader*       fShader;
     SkXfermode*     fXfermode;
     SkMaskFilter*   fMaskFilter;
     SkColorFilter*  fColorFilter;
     SkRasterizer*   fRasterizer;
     SkDrawLooper*   fLooper;
+    SkImageFilter*  fImageFilter;
 
     SkColor         fColor;
     SkScalar        fWidth;
     SkScalar        fMiterLimit;
-    unsigned        fFlags : 13;
+    unsigned        fFlags : 14;
     unsigned        fTextAlign : 2;
     unsigned        fCapType : 2;
     unsigned        fJoinType : 2;
     unsigned        fStyle : 2;
     unsigned        fTextEncoding : 2;  // 3 values
     unsigned        fHinting : 2;
-#ifdef ANDROID
-    uint32_t        fGenerationID;
-#endif
 
     SkDrawCacheProc    getDrawCacheProc() const;
     SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
                                            bool needFullMetrics) const;
 
     SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
                           int* count, SkRect* bounds) const;
 
@@ -875,16 +897,22 @@ private:
     enum {
         kCanonicalTextSizeForPaths = 64
     };
     friend class SkAutoGlyphCache;
     friend class SkCanvas;
     friend class SkDraw;
     friend class SkPDFDevice;
     friend class SkTextToPathIter;
+
+#ifdef SK_BUILD_FOR_ANDROID
+    // 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;
+#endif
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "SkPathEffect.h"
 
 /** \class SkStrokePathEffect
 
--- a/gfx/skia/include/core/SkPath.h
+++ b/gfx/skia/include/core/SkPath.h
@@ -8,17 +8,17 @@
 
 
 #ifndef SkPath_DEFINED
 #define SkPath_DEFINED
 
 #include "SkMatrix.h"
 #include "SkTDArray.h"
 
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
 #define GEN_ID_INC              fGenerationID++
 #define GEN_ID_PTR_INC(ptr)     ptr->fGenerationID++
 #else
 #define GEN_ID_INC
 #define GEN_ID_PTR_INC(ptr)
 #endif
 
 class SkReader32;
@@ -33,17 +33,17 @@ class SkString;
 */
 class SK_API SkPath {
 public:
     SkPath();
     SkPath(const SkPath&);
     ~SkPath();
 
     SkPath& operator=(const SkPath&);
-    
+
     friend bool operator==(const SkPath&, const SkPath&);
     friend bool operator!=(const SkPath& a, const SkPath& b) {
         return !(a == b);
     }
 
     enum FillType {
         /** Specifies that "inside" is computed by a non-zero sum of signed
             edge crossings
@@ -65,17 +65,17 @@ public:
         computed. The default value is kWinding_FillType.
 
         @return the path's fill type
     */
     FillType getFillType() const { return (FillType)fFillType; }
 
     /** Set the path's fill type. This is used to define how "inside" is
         computed. The default value is kWinding_FillType.
-     
+
         @param ft The new fill type for this path
     */
     void setFillType(FillType ft) {
         fFillType = SkToU8(ft);
         GEN_ID_INC;
     }
 
     /** Returns true if the filltype is one of the Inverse variants */
@@ -175,16 +175,45 @@ public:
     void rewind();
 
     /** Returns true if the path is empty (contains no lines or curves)
 
         @return true if the path is empty (contains no lines or curves)
     */
     bool isEmpty() const;
 
+    /** Test a line for zero length
+
+        @return true if the line is of zero length; otherwise false.
+    */
+    static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2) {
+        return p1.equalsWithinTolerance(p2, SK_ScalarNearlyZero);
+    }
+
+    /** Test a quad for zero length
+
+        @return true if the quad is of zero length; otherwise false.
+    */
+    static bool IsQuadDegenerate(const SkPoint& p1, const SkPoint& p2,
+                                 const SkPoint& p3) {
+        return p1.equalsWithinTolerance(p2, SK_ScalarNearlyZero) &&
+               p2.equalsWithinTolerance(p3, SK_ScalarNearlyZero);
+    }
+
+    /** Test a cubic curve for zero length
+
+        @return true if the cubic is of zero length; otherwise false.
+    */
+    static bool IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2,
+                                  const SkPoint& p3, const SkPoint& p4) {
+        return p1.equalsWithinTolerance(p2, SK_ScalarNearlyZero) &&
+               p2.equalsWithinTolerance(p3, SK_ScalarNearlyZero) &&
+               p3.equalsWithinTolerance(p4, SK_ScalarNearlyZero);
+    }
+
     /** Returns true if the path specifies a rectangle. If so, and if rect is
         not null, set rect to the bounds of the path. If the path does not
         specify a rectangle, return false and ignore rect.
      
         @param rect If not null, returns the bounds of the path if it specifies
                     a rectangle
         @return true if the path specifies a rectangle
     */
@@ -589,83 +618,115 @@ public:
         kQuad_Verb,     //!< iter.next returns 3 points
         kCubic_Verb,    //!< iter.next returns 4 points
         kClose_Verb,    //!< iter.next returns 1 point (contour's moveTo pt)
         kDone_Verb      //!< iter.next returns 0 points
     };
 
     /** Iterate through all of the segments (lines, quadratics, cubics) of
         each contours in a path.
+
+        The iterator cleans up the segments along the way, removing degenerate
+        segments and adding close verbs where necessary. When the forceClose
+        argument is provided, each contour (as defined by a new starting
+        move command) will be completed with a close verb regardless of the
+        contour's contents.
     */
     class SK_API Iter {
     public:
-                Iter();
-                Iter(const SkPath&, bool forceClose);
+        Iter();
+        Iter(const SkPath&, bool forceClose);
 
         void setPath(const SkPath&, bool forceClose);
 
         /** Return the next verb in this iteration of the path. When all
             segments have been visited, return kDone_Verb.
-         
+
             @param  pts The points representing the current verb and/or segment
             @return The verb for the current segment
         */
         Verb next(SkPoint pts[4]);
 
         /** If next() returns kLine_Verb, then this query returns true if the
             line was the result of a close() command (i.e. the end point is the
             initial moveto for this contour). If next() returned a different
             verb, this returns an undefined value.
-         
+
             @return If the last call to next() returned kLine_Verb, return true
                     if it was the result of an explicit close command.
         */
         bool isCloseLine() const { return SkToBool(fCloseLine); }
-        
+
         /** Returns true if the current contour is closed (has a kClose_Verb)
             @return true if the current contour is closed (has a kClose_Verb)
         */
         bool isClosedContour() const;
 
     private:
         const SkPoint*  fPts;
         const uint8_t*  fVerbs;
         const uint8_t*  fVerbStop;
         SkPoint         fMoveTo;
         SkPoint         fLastPt;
         SkBool8         fForceClose;
         SkBool8         fNeedClose;
-        SkBool8         fNeedMoveTo;
         SkBool8         fCloseLine;
+        SkBool8         fSegmentState;
 
         bool cons_moveTo(SkPoint pts[1]);
         Verb autoClose(SkPoint pts[2]);
+        void consumeDegenerateSegments();
+    };
+
+    /** Iterate through the verbs in the path, providing the associated points.
+    */
+    class SK_API RawIter {
+    public:
+        RawIter();
+        RawIter(const SkPath&);
+
+        void setPath(const SkPath&);
+
+        /** Return the next verb in this iteration of the path. When all
+            segments have been visited, return kDone_Verb.
+         
+            @param  pts The points representing the current verb and/or segment
+            @return The verb for the current segment
+        */
+        Verb next(SkPoint pts[4]);
+
+    private:
+        const SkPoint*  fPts;
+        const uint8_t*  fVerbs;
+        const uint8_t*  fVerbStop;
+        SkPoint         fMoveTo;
+        SkPoint         fLastPt;
     };
 
     void dump(bool forceClose, const char title[] = NULL) const;
     void dump() const;
 
     void flatten(SkWriter32&) const;
     void unflatten(SkReader32&);
 
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
     uint32_t getGenerationID() const;
 #endif
 
     SkDEBUGCODE(void validate() const;)
 
 private:
     SkTDArray<SkPoint>  fPts;
     SkTDArray<uint8_t>  fVerbs;
     mutable SkRect      fBounds;
     uint8_t             fFillType;
     uint8_t             fSegmentMask;
     mutable uint8_t     fBoundsIsDirty;
     mutable uint8_t     fConvexity;
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
     uint32_t            fGenerationID;
 #endif
 
     // called, if dirty, by getBounds()
     void computeBounds() const;
 
     friend class Iter;
     void cons_moveto();
@@ -683,9 +744,8 @@ private:
     */
     void reversePathTo(const SkPath&);
 
     friend const SkPoint* sk_get_path_points(const SkPath&, int index);
     friend class SkAutoPathBoundsUpdate;
 };
 
 #endif
-
--- a/gfx/skia/include/core/SkPathEffect.h
+++ b/gfx/skia/include/core/SkPathEffect.h
@@ -29,16 +29,17 @@ public:
     /** Given a src path and a width value, return true if the patheffect
         has produced a new path (dst) and a new width value. If false is returned,
         ignore dst and width.
         On input, width >= 0 means the src should be stroked
         On output, width >= 0 means the dst should be stroked
     */
     virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width) = 0;
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 private:
     // illegal
     SkPathEffect(const SkPathEffect&);
     SkPathEffect& operator=(const SkPathEffect&);
 };
 
 /** \class SkPairPathEffect
 
--- a/gfx/skia/include/core/SkPixelRef.h
+++ b/gfx/skia/include/core/SkPixelRef.h
@@ -5,29 +5,48 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
 
 #ifndef SkPixelRef_DEFINED
 #define SkPixelRef_DEFINED
 
+#include "SkBitmap.h"
 #include "SkRefCnt.h"
 #include "SkString.h"
 
-class SkBitmap;
 class SkColorTable;
 struct SkIRect;
 class SkMutex;
 class SkFlattenableReadBuffer;
 class SkFlattenableWriteBuffer;
 
 // 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
     SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
     access the actual pixel memory by calling lockPixels/unlockPixels.
 
     This class can be shared/accessed between multiple threads.
 */
@@ -112,24 +131,30 @@ public:
     void setURI(const SkString& uri) { fURI = uri; }
 
     /** Are we really wrapping a texture instead of a bitmap?
      */
     virtual SkGpuTexture* getTexture() { return NULL; }
 
     bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
 
+    /** Makes a deep copy of this PixelRef, respecting the requested config.
+        Returns NULL if either there is an error (e.g. the destination could
+        not be created with the given config), or this PixelRef does not 
+        support deep copies.  */
+    virtual SkPixelRef* deepCopy(SkBitmap::Config config) { return NULL; }
+
     // serialization
 
     typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
 
     virtual Factory getFactory() const { return NULL; }
     virtual void flatten(SkFlattenableWriteBuffer&) const;
 
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
     /**
      *  Acquire a "global" ref on this object.
      *  The default implementation just calls ref(), but subclasses can override
      *  this method to implement additional behavior.
      */
     virtual void globalRef(void* data=NULL);
 
     /**
@@ -176,22 +201,28 @@ protected:
     /** Return the mutex associated with this pixelref. This value is assigned
         in the constructor, and cannot change during the lifetime of the object.
     */
     SkMutex* mutex() const { return fMutex; }
 
     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
     int             fLockCount;
 
     mutable uint32_t fGenerationID;
 
     SkString    fURI;
 
     // can go from false to true, but never from true to false
     bool    fIsImmutable;
+
+    friend class SkGraphics;
 };
 
 #endif
--- a/gfx/skia/include/core/SkPoint.h
+++ b/gfx/skia/include/core/SkPoint.h
@@ -310,16 +310,23 @@ struct SK_API SkPoint {
     friend bool operator==(const SkPoint& a, const SkPoint& b) {
         return a.fX == b.fX && a.fY == b.fY;
     }
 
     friend bool operator!=(const SkPoint& a, const SkPoint& b) {
         return a.fX != b.fX || a.fY != b.fY;
     }
 
+    /** Return true if this and the given point are componentwise within tol.
+    */
+    bool equalsWithinTolerance(const SkPoint& v, SkScalar tol) const {
+        return SkScalarNearlyZero(fX - v.fX, tol)
+               && SkScalarNearlyZero(fY - v.fY, tol);
+    }
+
     /** Returns a new point whose coordinates are the difference between
         a's and b's (a - b)
     */
     friend SkPoint operator-(const SkPoint& a, const SkPoint& b) {
         SkPoint v;
         v.set(a.fX - b.fX, a.fY - b.fY);
         return v;
     }
--- a/gfx/skia/include/core/SkPostConfig.h
+++ b/gfx/skia/include/core/SkPostConfig.h
@@ -51,31 +51,57 @@
         #error "all or none of the 32bit SHIFT amounts must be defined"
     #endif
 #else
     #if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT)
         #error "all or none of the 32bit SHIFT amounts must be defined"
     #endif
 #endif
 
+#if !defined(SK_HAS_COMPILER_FEATURE)
+    #if defined(__has_feature)
+        #define SK_HAS_COMPILER_FEATURE(x) __has_feature(x)
+    #else
+        #define SK_HAS_COMPILER_FEATURE(x) 0
+    #endif
+#endif
+
+/**
+ * The clang static analyzer likes to know that when the program is not
+ * expected to continue (crash, assertion failure, etc). It will notice that
+ * some combination of parameters lead to a function call that does not return.
+ * It can then make appropriate assumptions about the parameters in code
+ * executed only if the non-returning function was *not* called.
+ */
+#if !defined(SkNO_RETURN_HINT)
+    #if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
+        namespace {
+            inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
+            void SkNO_RETURN_HINT() {}
+        }
+    #else
+        #define SkNO_RETURN_HINT() do {} while (false)
+    #endif
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////
 
 #ifndef SkNEW
     #define SkNEW(type_name)                new type_name
     #define SkNEW_ARGS(type_name, args)     new type_name args
     #define SkNEW_ARRAY(type_name, count)   new type_name[count]
     #define SkDELETE(obj)                   delete obj
     #define SkDELETE_ARRAY(array)           delete[] array
 #endif
 
 #ifndef SK_CRASH
 #if 1   // set to 0 for infinite loop, which can help connecting gdb
-    #define SK_CRASH() *(int *)(uintptr_t)0xbbadbeef = 0
+    #define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
 #else
-    #define SK_CRASH()  do {} while (true)
+    #define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true)
 #endif
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #if defined(SK_SOFTWARE_FLOAT) && defined(SK_SCALAR_IS_FLOAT)
     // if this is defined, we convert floats to 2scompliment ints for compares
     #ifndef SK_SCALAR_SLOW_COMPARES
@@ -95,17 +121,17 @@
 
     #include <windows.h>
 
     #ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
         #undef WIN32_LEAN_AND_MEAN
     #endif
 
     #ifndef SK_DEBUGBREAK
-        #define SK_DEBUGBREAK(cond)     do { if (!(cond)) __debugbreak(); } while (false)
+        #define SK_DEBUGBREAK(cond)     do { if (!(cond)) { SkNO_RETURN_HINT(); __debugbreak(); }} while (false)
     #endif
 
     #ifndef SK_A32_SHIFT
         #define SK_A32_SHIFT 24
         #define SK_R32_SHIFT 16
         #define SK_G32_SHIFT 8
         #define SK_B32_SHIFT 0
     #endif
@@ -260,8 +286,13 @@
 // but it doesn't work.
 #define SK_OVERRIDE override
 #else
 // Linux GCC ignores "__attribute__((override))" and rejects "override".
 #define SK_OVERRIDE
 #endif
 #endif
 
+//////////////////////////////////////////////////////////////////////
+
+#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
+#endif
--- a/gfx/skia/include/core/SkPreConfig.h
+++ b/gfx/skia/include/core/SkPreConfig.h
@@ -11,44 +11,54 @@
 #define SkPreConfig_DEFINED
 
 #ifdef WEBKIT_VERSION_MIN_REQUIRED
     #include "config.h"
 #endif
 
 //////////////////////////////////////////////////////////////////////
 
-#if !defined(SK_BUILD_FOR_ANDROID_NDK) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_SYMBIAN) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW)
+#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_SYMBIAN) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW)
 
     #ifdef __APPLE__
         #include "TargetConditionals.h"
     #endif
 
     #if defined(PALMOS_SDK_VERSION)
         #define SK_BUILD_FOR_PALM
     #elif defined(UNDER_CE)
         #define SK_BUILD_FOR_WINCE
     #elif defined(WIN32)
         #define SK_BUILD_FOR_WIN32
     #elif defined(__SYMBIAN32__)
         #define SK_BUILD_FOR_WIN32
-    #elif defined(linux) || defined(__OpenBSD_)
+    #elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
+          defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__)
         #define SK_BUILD_FOR_UNIX
     #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
         #define SK_BUILD_FOR_IOS
     #elif defined(ANDROID_NDK)
         #define SK_BUILD_FOR_ANDROID_NDK
-    #elif defined(ANROID)
+    #elif defined(ANDROID)
         #define SK_BUILD_FOR_ANDROID
     #else
         #define SK_BUILD_FOR_MAC
     #endif
 
 #endif
 
+/* Even if the user only defined the NDK variant we still need to build
+ * the default Android code. Therefore, when attempting to include/exclude
+ * something from the NDK variant check first that we are building for 
+ * Android then check the status of the NDK define.
+ */
+#if defined(SK_BUILD_FOR_ANDROID_NDK) && !defined(SK_BUILD_FOR_ANDROID)
+    #define SK_BUILD_FOR_ANDROID
+#endif
+
 //////////////////////////////////////////////////////////////////////
 
 #if !defined(SK_DEBUG) && !defined(SK_RELEASE)
     #ifdef NDEBUG
         #define SK_RELEASE
     #else
         #define SK_DEBUG
     #endif
--- a/gfx/skia/include/core/SkRect.h
+++ b/gfx/skia/include/core/SkRect.h
@@ -330,20 +330,44 @@ struct SK_API SkRect {
     }
 
     static SkRect MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h) {
         SkRect r;
         r.set(x, y, x + w, y + h);
         return r;
     }
 
-    /** Return true if the rectangle's width or height are <= 0
-    */
-    bool        isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
-    bool        hasValidCoordinates() const;
+    /**
+     *  Return true if the rectangle's width or height are <= 0
+     */
+    bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+    
+    /**
+     *  Returns true iff all values in the rect are finite. If any are
+     *  infinite or NaN (or SK_FixedNaN when SkScalar is fixed) then this
+     *  returns false.
+     */
+    bool isFinite() const {
+#ifdef SK_SCALAR_IS_FLOAT
+        // x * 0 will be NaN iff x is infinity or NaN.
+        // a + b will be NaN iff either a or b is NaN.
+        float value = fLeft * 0 + fTop * 0 + fRight * 0 + fBottom * 0;
+        
+        // value is either NaN or it is finite (zero).
+        // value==value will be true iff value is not NaN
+        return value == value;
+#else
+        // use bit-or for speed, since we don't care about short-circuting the
+        // tests, and we expect the common case will be that we need to check all.
+        int isNaN = (SK_FixedNaN == fLeft)  | (SK_FixedNaN == fTop) |
+                    (SK_FixedNaN == fRight) | (SK_FixedNaN == fBottom);
+        return !isNaN;
+#endif
+    }
+
     SkScalar    left() const { return fLeft; }
     SkScalar    top() const { return fTop; }
     SkScalar    right() const { return fRight; }
     SkScalar    bottom() const { return fBottom; }
     SkScalar    width() const { return fRight - fLeft; }
     SkScalar    height() const { return fBottom - fTop; }
     SkScalar    centerX() const { return SkScalarHalf(fLeft + fRight); }
     SkScalar    centerY() const { return SkScalarHalf(fTop + fBottom); }
--- a/gfx/skia/include/core/SkRegion.h
+++ b/gfx/skia/include/core/SkRegion.h
@@ -81,19 +81,19 @@ public:
 
     /**
      *  Return the bounds of this region. If the region is empty, returns an
      *  empty rectangle.
      */
     const SkIRect& getBounds() const { return fBounds; }
 
     /**
-     *  Returns true if the region is non-empty, and if so, sets the specified
-     *  path to the boundary(s) of the region. If the region is empty, then
-     *  this returns false, and path is left unmodified.
+     *  Returns true if the region is non-empty, and if so, appends the
+     *  boundary(s) of the region to the specified path.
+     *  If the region is empty, returns false, and path is left unmodified.
      */
     bool getBoundaryPath(SkPath* path) const;
 
     /**
      *  Set the region to be empty, and return false, since the resulting
      *  region is empty
      */
     bool setEmpty();
@@ -278,17 +278,17 @@ public:
 
     /**
      *  Set this region to the result of applying the Op to the specified
      *  regions: this = (rgna op rgnb).
      *  Return true if the resulting region is non-empty.
      */
     bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
 
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
     /** Returns a new char* containing the list of rectangles in this region
      */
     char* toString();
 #endif
 
     /**
      *  Returns the sequence of rectangles, sorted in Y and X, that make up
      *  this region.
--- a/gfx/skia/include/core/SkScalar.h
+++ b/gfx/skia/include/core/SkScalar.h
@@ -87,17 +87,17 @@
     static inline float SkIntToScalar(float param) {
         /* If the parameter passed into SkIntToScalar is a float,
          * one of two things has happened:
          * 1. the parameter was an SkScalar (which is typedef'd to float)
          * 2. the parameter was a float instead of an int
          *
          * Either way, it's not good.
          */
-        SkASSERT(!"looks like you passed an SkScalar into SkIntToScalar");
+        SkDEBUGFAIL("looks like you passed an SkScalar into SkIntToScalar");
         return (float)0;
     }
 #else  // not SK_DEBUG
     /** SkIntToScalar(n) returns its integer argument as an SkScalar
     */
     #define SkIntToScalar(n)        ((float)(n))
 #endif // not SK_DEBUG
     /** SkFixedToScalar(n) returns its SkFixed argument as an SkScalar
@@ -114,17 +114,17 @@
     #define SkDoubleToScalar(n)      (float)(n)
 
     /** SkScalarFraction(x) returns the signed fractional part of the argument
     */
     #define SkScalarFraction(x)     sk_float_mod(x, 1.0f)
 
     #define SkScalarFloorToScalar(x)    sk_float_floor(x)
     #define SkScalarCeilToScalar(x)     sk_float_ceil(x)
-    #define SkScalarRoundToScalar(x)    sk_float_round(x)
+    #define SkScalarRoundToScalar(x)    sk_float_floor((x) + 0.5f)
 
     #define SkScalarFloorToInt(x)       sk_float_floor2int(x)
     #define SkScalarCeilToInt(x)        sk_float_ceil2int(x)
     #define SkScalarRoundToInt(x)       sk_float_round2int(x)
 
     /** Returns the absolute value of the specified SkScalar
     */
     #define SkScalarAbs(x)          sk_float_abs(x)
--- a/gfx/skia/include/core/SkScalerContext.h
+++ b/gfx/skia/include/core/SkScalerContext.h
@@ -152,43 +152,46 @@ struct SkGlyph {
     }
 
     void toMask(SkMask* mask) const;
 };
 
 class SkScalerContext {
 public:
     enum Flags {
-        kFrameAndFill_Flag  = 0x01,
-        kDevKernText_Flag   = 0x02,
-        kGammaForBlack_Flag = 0x04, // illegal to set both Gamma flags
-        kGammaForWhite_Flag = 0x08, // illegal to set both Gamma flags
+        kFrameAndFill_Flag        = 0x0001,
+        kDevKernText_Flag         = 0x0002,
+        kEmbeddedBitmapText_Flag  = 0x0004,
+        kEmbolden_Flag            = 0x0008,
+        kSubpixelPositioning_Flag = 0x0010,
+        kAutohinting_Flag         = 0x0020,
+        kVertical_Flag            = 0x0040,
 
         // together, these two flags resulting in a two bit value which matches
         // up with the SkPaint::Hinting enum.
-        kHintingBit1_Flag   = 0x10,
-        kHintingBit2_Flag   = 0x20,
-
-        kEmbeddedBitmapText_Flag = 0x40,
-        kEmbolden_Flag      = 0x80,
-        kSubpixelPositioning_Flag = 0x100,
-        kAutohinting_Flag   = 0x200,
+        kHinting_Shift            = 7, // to shift into the other flags above
+        kHintingBit1_Flag         = 0x0080,
+        kHintingBit2_Flag         = 0x0100,
 
         // these should only ever be set if fMaskFormat is LCD16 or LCD32
-        kLCD_Vertical_Flag  = 0x400,    // else Horizontal
-        kLCD_BGROrder_Flag  = 0x800,    // else RGB order
+        kLCD_Vertical_Flag        = 0x0200,    // else Horizontal
+        kLCD_BGROrder_Flag        = 0x0400,    // else RGB order
 
-        // experimental
-        kForceAA_Flag       = 0x1000
+        // luminance : 0 for black text, kLuminance_Max for white text
+        kLuminance_Shift          = 11, // to shift into the other flags above
+        kLuminance_Bits           = 3,  // ensure Flags doesn't exceed 16bits
     };
-private:
+    
+    // computed values
     enum {
-        kHintingMask = kHintingBit1_Flag | kHintingBit2_Flag
+        kHinting_Mask   = kHintingBit1_Flag | kHintingBit2_Flag,
+        kLuminance_Max  = (1 << kLuminance_Bits) - 1,
+        kLuminance_Mask = kLuminance_Max << kLuminance_Shift,
     };
-public:
+
     struct Rec {
         uint32_t    fOrigFontID;
         uint32_t    fFontID;
         SkScalar    fTextSize, fPreScaleX, fPreSkewX;
         SkScalar    fPost2x2[2][2];
         SkScalar    fFrameWidth, fMiterLimit;
         uint8_t     fMaskFormat;
         uint8_t     fStrokeJoin;
@@ -198,46 +201,68 @@ public:
         // multiples of four and this structure is put in an SkDescriptor in
         // SkPaint::MakeRec.
 
         void    getMatrixFrom2x2(SkMatrix*) const;
         void    getLocalMatrix(SkMatrix*) const;
         void    getSingleMatrix(SkMatrix*) const;
 
         SkPaint::Hinting getHinting() const {
-            return static_cast<SkPaint::Hinting>((fFlags & kHintingMask) >> 4);
+            unsigned hint = (fFlags & kHinting_Mask) >> kHinting_Shift;
+            return static_cast<SkPaint::Hinting>(hint);
         }
 
         void setHinting(SkPaint::Hinting hinting) {
-            fFlags = (fFlags & ~kHintingMask) | (hinting << 4);
+            fFlags = (fFlags & ~kHinting_Mask) | (hinting << kHinting_Shift);
+        }
+
+        unsigned getLuminanceBits() const {
+            return (fFlags & kLuminance_Mask) >> kLuminance_Shift;
+        }
+        
+        void setLuminanceBits(unsigned lum) {
+            SkASSERT(lum <= kLuminance_Max);
+            fFlags = (fFlags & ~kLuminance_Mask) | (lum << kLuminance_Shift);
+        }
+
+        U8CPU getLuminanceByte() const {
+            SkASSERT(3 == kLuminance_Bits);
+            unsigned lum = this->getLuminanceBits();
+            lum |= (lum << kLuminance_Bits);
+            lum |= (lum << kLuminance_Bits*2);
+            return lum >> (4*kLuminance_Bits - 8);
         }
 
         SkMask::Format getFormat() const {
             return static_cast<SkMask::Format>(fMaskFormat);
         }
     };
 
     SkScalerContext(const SkDescriptor* desc);
     virtual ~SkScalerContext();
 
     SkMask::Format getMaskFormat() const {
         return (SkMask::Format)fRec.fMaskFormat;
     }
 
+    bool isSubpixel() const {
+        return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag);
+    }
+    
     // remember our glyph offset/base
     void setBaseGlyphCount(unsigned baseGlyphCount) {
         fBaseGlyphCount = baseGlyphCount;
     }
 
     /** Return the corresponding glyph for the specified unichar. Since contexts
         may be chained (under the hood), the glyphID that is returned may in
         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);
 
     /** Map the glyphID to its glyph index, and then to its char code. Unmapped
         glyphs return zero.
     */
     SkUnichar glyphIDToChar(uint16_t glyphID);
 
     unsigned    getGlyphCount() { return this->generateGlyphCount(); }
     void        getAdvance(SkGlyph*);
--- a/gfx/skia/include/core/SkShader.h
+++ b/gfx/skia/include/core/SkShader.h
@@ -92,16 +92,25 @@ public:
      *  alpha your shader will return. The default implementation returns 0.
      *  Your subclass should override if it can (even sometimes) report a
      *  non-zero value, since that will enable various blitters to perform
      *  faster.
      */
     virtual uint32_t getFlags() { return 0; }
 
     /**
+     *  Returns true if the shader is guaranteed to produce only opaque
+     *  colors, subject to the SkPaint using the shader to apply an opaque
+     *  alpha value. Subclasses should override this to allow some
+     *  optimizations.  isOpaque() can be called at any time, unlike getFlags,
+     *  which only works properly when the context is set.
+     */
+    virtual bool isOpaque() const { return false; }
+
+    /**
      *  Return the alpha associated with the data returned by shadeSpan16(). If
      *  kHasSpan16_Flag is not set, this value is meaningless.
      */
     virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
 
     /**
      *  Called once before drawing, with the current paint and device matrix.
      *  Return true if your shader supports these parameters, or false if not.
--- a/gfx/skia/include/core/SkShape.h
+++ b/gfx/skia/include/core/SkShape.h
@@ -33,16 +33,18 @@ public:
 
     // overrides
     virtual Factory getFactory();
     virtual void flatten(SkFlattenableWriteBuffer&);
 
     // public for Registrar
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     virtual void onDraw(SkCanvas*);
 
     SkShape(SkFlattenableReadBuffer&);
 
 private:
 
     typedef SkFlattenable INHERITED;
--- a/gfx/skia/include/core/SkTArray.h
+++ b/gfx/skia/include/core/SkTArray.h
@@ -294,30 +294,30 @@ protected:
      */
     template <int N>
     SkTArray(const T* array, int count, SkAlignedSTStorage<N,T>* storage) {
         this->init(array, count, storage->get(), N);
     }
 
     void init(const T* array, int count,
                void* preAllocStorage, int preAllocOrReserveCount) {
-        GrAssert(count >= 0);
-        GrAssert(preAllocOrReserveCount >= 0);
+        SkASSERT(count >= 0);
+        SkASSERT(preAllocOrReserveCount >= 0);
         fCount              = count;
         fReserveCount       = (preAllocOrReserveCount > 0) ?
                                     preAllocOrReserveCount :
                                     gMIN_ALLOC_COUNT;
         fPreAllocMemArray   = preAllocStorage;
         if (fReserveCount >= fCount &&
             NULL != preAllocStorage) {
             fAllocCount = fReserveCount;
             fMemArray = preAllocStorage;
         } else {
-            fAllocCount = GrMax(fCount, fReserveCount);
-            fMemArray = GrMalloc(fAllocCount * sizeof(T));
+            fAllocCount = SkMax32(fCount, fReserveCount);
+            fMemArray = sk_malloc_throw(fAllocCount * sizeof(T));
         }
 
         SkTArrayExt::copy(this, array);
     }
 
 private:
 
     static const int gMIN_ALLOC_COUNT = 8;
--- a/gfx/skia/include/core/SkTDArray.h
+++ b/gfx/skia/include/core/SkTDArray.h
@@ -86,17 +86,27 @@ public:
         T* array = fArray;
         fArray = NULL;
         fReserve = fCount = 0;
         SkDEBUGCODE(fData = NULL;)
         return array;
     }
 
     bool isEmpty() const { return fCount == 0; }
+
+    /**
+     *  Return the number of elements in the array
+     */
     int count() const { return fCount; }
+
+    /**
+     *  return the number of bytes in the array: count * sizeof(T)
+     */
+    size_t bytes() const { return fCount * sizeof(T); }
+
     T*  begin() const { return fArray; }
     T*  end() const { return fArray ? fArray + fCount : NULL; }
     T&  operator[](int index) const {
         SkASSERT((unsigned)index < fCount);
         return fArray[index];
     }
 
     void reset() {
--- a/gfx/skia/include/core/SkTRegistry.h
+++ b/gfx/skia/include/core/SkTRegistry.h
@@ -16,17 +16,17 @@
     and provides a function-pointer. This can be used to auto-register a set of
     services, e.g. a set of image codecs.
  */
 template <typename T, typename P> class SkTRegistry : SkNoncopyable {
 public:
     typedef T (*Factory)(P);
 
     SkTRegistry(Factory fact) {
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
         // work-around for double-initialization bug
         {
             SkTRegistry* reg = gHead;
             while (reg) {
                 if (reg == this) {
                     return;
                 }
                 reg = reg->fChain;
--- a/gfx/skia/include/core/SkThread_platform.h
+++ b/gfx/skia/include/core/SkThread_platform.h
@@ -5,17 +5,17 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
 
 #ifndef SkThread_platform_DEFINED
 #define SkThread_platform_DEFINED
 
-#if defined(ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK)
+#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK)
 
 #include <utils/threads.h>
 #include <utils/Atomic.h>
 
 #define sk_atomic_inc(addr)     android_atomic_inc(addr)
 #define sk_atomic_dec(addr)     android_atomic_dec(addr)
 
 class SkMutex : android::Mutex {
--- a/gfx/skia/include/core/SkTypes.h
+++ b/gfx/skia/include/core/SkTypes.h
@@ -88,24 +88,26 @@ inline void operator delete(void* p) {
 #define SK_INIT_TO_AVOID_WARNING    = 0
 
 #ifndef SkDebugf
     void SkDebugf(const char format[], ...);
 #endif
 
 #ifdef SK_DEBUG
     #define SkASSERT(cond)              SK_DEBUGBREAK(cond)
+    #define SkDEBUGFAIL(message)        SkASSERT(false && message)
     #define SkDEBUGCODE(code)           code
     #define SkDECLAREPARAM(type, var)   , type var
     #define SkPARAM(var)                , var
 //  #define SkDEBUGF(args       )       SkDebugf##args
     #define SkDEBUGF(args       )       SkDebugf args
     #define SkAssertResult(cond)        SkASSERT(cond)
 #else
     #define SkASSERT(cond)
+    #define SkDEBUGFAIL(message)
     #define SkDEBUGCODE(code)
     #define SkDEBUGF(args)
     #define SkDECLAREPARAM(type, var)
     #define SkPARAM(var)
 
     // unlike SkASSERT, this guy executes its condition in the non-debug build
     #define SkAssertResult(cond)        cond
 #endif
@@ -211,16 +213,18 @@ static inline bool SkIsU16(long x) {
 
 /** Returns x rounded up to a multiple of 2
 */
 #define SkAlign2(x)     (((x) + 1) >> 1 << 1)
 /** Returns x rounded up to a multiple of 4
 */
 #define SkAlign4(x)     (((x) + 3) >> 2 << 2)
 
+#define SkIsAlign4(x) (((x) & 3) == 0)
+
 typedef uint32_t SkFourByteTag;
 #define SkSetFourByteTag(a, b, c, d)    (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
 
 /** 32 bit integer to hold a unicode value
 */
 typedef int32_t SkUnichar;
 /** 32 bit value to hold a millisecond count
 */
--- a/gfx/skia/include/core/SkUtils.h
+++ b/gfx/skia/include/core/SkUtils.h
@@ -27,17 +27,17 @@ SkMemset16Proc SkMemset16GetPlatformProc
     @param buffer   The memory to have value copied into it
     @param value    The 32bit value to be copied into buffer
     @param count    The number of times value should be copied into the buffer.
 */
 void sk_memset32_portable(uint32_t dst[], uint32_t value, int count);
 typedef void (*SkMemset32Proc)(uint32_t dst[], uint32_t value, int count);
 SkMemset32Proc SkMemset32GetPlatformProc();
 
-#if defined(ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK)
+#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK)
     #include "cutils/memory.h"
     
     #define sk_memset16(dst, value, count)    android_memset16(dst, value, (count) << 1)
     #define sk_memset32(dst, value, count)    android_memset32(dst, value, (count) << 2)
 #endif
 
 #ifndef sk_memset16
 extern SkMemset16Proc sk_memset16;
@@ -86,16 +86,31 @@ int SkUTF16_CountUnichars(const uint16_t
 SkUnichar SkUTF16_NextUnichar(const uint16_t**);
 // this guy backs up to the previus unichar value, and returns it (*--p)
 SkUnichar SkUTF16_PrevUnichar(const uint16_t**);
 size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t utf16[] = NULL);
 
 size_t SkUTF16_ToUTF8(const uint16_t utf16[], int numberOf16BitValues,
                            char utf8[] = NULL);
 
+inline bool SkUnichar_IsVariationSelector(SkUnichar uni) {
+/*  The 'true' ranges are:
+ *      0x180B  <= uni <=  0x180D
+ *      0xFE00  <= uni <=  0xFE0F
+ *      0xE0100 <= uni <= 0xE01EF
+ */
+    if (uni < 0x180B || uni > 0xE01EF) {
+        return false;
+    }
+    if ((uni > 0x180D && uni < 0xFE00) || (uni > 0xFE0F && uni < 0xE0100)) {
+        return false;
+    }
+    return true;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 class SkAutoTrace {
 public:
     /** NOTE: label contents are not copied, just the ptr is
         retained, so DON'T DELETE IT.
     */
     SkAutoTrace(const char label[]) : fLabel(label) {
--- a/gfx/skia/include/core/SkXfermode.h
+++ b/gfx/skia/include/core/SkXfermode.h
@@ -126,16 +126,28 @@ public:
     virtual bool asMode(Mode* mode);
 
     /**
      *  The same as calling xfermode->asMode(mode), except that this also checks
      *  if the xfermode is NULL, and if so, treats its as kSrcOver_Mode.
      */
     static bool AsMode(SkXfermode*, Mode* mode);
 
+    /**
+     *  Returns true if the xfermode claims to be the specified Mode. This works
+     *  correctly even if the xfermode is NULL (which equates to kSrcOver.) Thus
+     *  you can say this without checking for a null...
+     *
+     *  If (SkXfermode::IsMode(paint.getXfermode(),
+     *                         SkXfermode::kDstOver_Mode)) {
+     *      ...
+     *  }
+     */
+    static bool IsMode(SkXfermode* xfer, Mode mode);
+
     /** Return an SkXfermode object for the specified mode.
      */
     static SkXfermode* Create(Mode mode);
 
     /** Return a function pointer to a routine that applies the specified
         porter-duff transfer mode.
      */
     static SkXfermodeProc GetProc(Mode mode);
@@ -155,16 +167,17 @@ public:
      */
     static bool ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst);
 
     // DEPRECATED: call AsMode(...)
     static bool IsMode(SkXfermode* xfer, Mode* mode) {
         return AsMode(xfer, mode);
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 protected:
     SkXfermode(SkFlattenableReadBuffer& rb) : SkFlattenable(rb) {}
 
     /** The default implementation of xfer32/xfer16/xferA8 in turn call this
         method, 1 color at a time (upscaled to a SkPMColor). The default
         implmentation of this method just returns dst. If performance is
         important, your subclass should override xfer32/xfer16/xferA8 directly.
 
--- a/gfx/skia/include/effects/Sk1DPathEffect.h
+++ b/gfx/skia/include/effects/Sk1DPathEffect.h
@@ -52,31 +52,33 @@ public:
         @param advance The space between instances of path
         @param phase distance (mod advance) along path for its initial position
         @param style how to transform path at each point (based on the current
                      position and tangent)
     */
     SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
 
     // override from SkPathEffect
-    virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+    virtual bool filterPath(SkPath*, const SkPath&, SkScalar* width) SK_OVERRIDE;
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(SkPath1DPathEffect, (buffer));
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkPath1DPathEffect(SkFlattenableReadBuffer& buffer);
 
     // overrides from Sk1DPathEffect
-    virtual SkScalar begin(SkScalar contourLength);
-    virtual SkScalar next(SkPath* dst, SkScalar distance, SkPathMeasure&);
+    virtual SkScalar begin(SkScalar contourLength) SK_OVERRIDE;
+    virtual SkScalar next(SkPath*, SkScalar distance, SkPathMeasure&) SK_OVERRIDE;
     // overrides from SkFlattenable
-    virtual void flatten(SkFlattenableWriteBuffer& );
-    virtual Factory getFactory() { return CreateProc; }
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
     
 private:
     SkPath      fPath;          // copied from constructor
     SkScalar    fAdvance;       // copied from constructor
     SkScalar    fInitialOffset; // computed from phase
     Style       fStyle;         // copied from constructor
 
     typedef Sk1DPathEffect INHERITED;
--- a/gfx/skia/include/effects/Sk2DPathEffect.h
+++ b/gfx/skia/include/effects/Sk2DPathEffect.h
@@ -14,21 +14,21 @@
 #include "SkPathEffect.h"
 #include "SkMatrix.h"
 
 class Sk2DPathEffect : public SkPathEffect {
 public:
     Sk2DPathEffect(const SkMatrix& mat);
 
     // overrides
-    virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+    virtual bool filterPath(SkPath*, const SkPath&, SkScalar* width) SK_OVERRIDE;
 
     // overrides from SkFlattenable
-    virtual void flatten(SkFlattenableWriteBuffer&);
-    virtual Factory getFactory();
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    virtual Factory getFactory() SK_OVERRIDE;
 
 protected:
     /** New virtual, to be overridden by subclasses.
         This is called once from filterPath, and provides the
         uv parameter bounds for the path. Subsequent calls to
         next() will receive u and v values within these bounds,
         and then a call to end() will signal the end of processing.
     */
@@ -42,16 +42,18 @@ protected:
     */
     virtual void nextSpan(int u, int v, int ucount, SkPath* dst);
 
     const SkMatrix& getMatrix() const { return fMatrix; }
 
     // protected so that subclasses can call this during unflattening
     Sk2DPathEffect(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 private:
     SkMatrix    fMatrix, fInverse;
     // illegal
     Sk2DPathEffect(const Sk2DPathEffect&);
     Sk2DPathEffect& operator=(const Sk2DPathEffect&);
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
@@ -64,22 +66,24 @@ public:
     /**
      *  Stamp the specified path to fill the shape, using the matrix to define
      *  the latice.
      */
     SkPath2DPathEffect(const SkMatrix&, const SkPath&);
     
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkPath2DPathEffect(SkFlattenableReadBuffer& buffer);
 
-    virtual void flatten(SkFlattenableWriteBuffer&);
-    virtual Factory getFactory();
-    virtual void next(const SkPoint& loc, int u, int v, SkPath* dst);
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    virtual Factory getFactory() SK_OVERRIDE;
+    virtual void next(const SkPoint&, int u, int v, SkPath* dst) SK_OVERRIDE;
 
 private:
     SkPath  fPath;
 
     typedef Sk2DPathEffect INHERITED;
 };
 
 
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/effects/SkArithmeticMode.h
@@ -0,0 +1,30 @@
+/*
+ * 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 SkArithmeticMode_DEFINED
+#define SkArithmeticMode_DEFINED
+
+#include "SkXfermode.h"
+
+class SkArithmeticMode : public SkXfermode {
+public:
+    /**
+     *  result = clamp[k1 * src * dst + k2 * src + k3 * dst + k4]
+     *
+     *  src and dst are treated as being [0.0 .. 1.0]. The polynomial is
+     *  evaluated on their unpremultiplied components.
+     *
+     *  k1=k2=k3=0, k4=1.0 results in returning opaque white
+     *  k1=k3=k4=0, k2=1.0 results in returning the src
+     *  k1=k2=k4=0, k3=1.0 results in returning the dst
+     */
+    static SkXfermode* Create(SkScalar k1, SkScalar k2,
+                              SkScalar k3, SkScalar k4);
+};
+
+#endif
+
--- a/gfx/skia/include/effects/SkAvoidXfermode.h
+++ b/gfx/skia/include/effects/SkAvoidXfermode.h
@@ -38,32 +38,34 @@ public:
                 are similar to the op-color
                 Tolerance near 0: draw only on colors that are nearly identical to the op-color
                 Tolerance near 255: draw on any colors even remotely similar to the op-color
      */
     SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode);
 
     // overrides from SkXfermode
     virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
-                        const SkAlpha aa[]);
+                        const SkAlpha aa[]) SK_OVERRIDE;
     virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
-                        const SkAlpha aa[]);
+                        const SkAlpha aa[]) SK_OVERRIDE;
     virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count,
-                          const SkAlpha aa[]);
+                          const SkAlpha aa[]) SK_OVERRIDE;
     virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
-                        const SkAlpha aa[]);
+                        const SkAlpha aa[]) SK_OVERRIDE;
 
     // overrides from SkFlattenable
-    virtual Factory getFactory();
-    virtual void flatten(SkFlattenableWriteBuffer&);
+    virtual Factory getFactory() SK_OVERRIDE;
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(SkAvoidXfermode, (buffer));
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkAvoidXfermode(SkFlattenableReadBuffer&);
 
 private:
     SkColor     fOpColor;
     uint32_t    fDistMul;   // x.14
     Mode        fMode;
 
--- a/gfx/skia/include/effects/SkBlurDrawLooper.h
+++ b/gfx/skia/include/effects/SkBlurDrawLooper.h
@@ -43,16 +43,17 @@ public:
     // overrides from SkDrawLooper
     virtual void init(SkCanvas*);
     virtual bool next(SkCanvas*, SkPaint* paint);
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(SkBlurDrawLooper, (buffer));
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 
 protected:
     SkBlurDrawLooper(SkFlattenableReadBuffer&);
     // overrides from SkFlattenable
     virtual void flatten(SkFlattenableWriteBuffer& );
     virtual Factory getFactory() { return CreateProc; }
 
 private:
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/effects/SkBlurImageFilter.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 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 SkBlurImageFilter_DEFINED
+#define SkBlurImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+
+class SK_API SkBlurImageFilter : public SkImageFilter {
+public:
+    SkBlurImageFilter(SkScalar sigmaX, SkScalar sigmaY);
+
+    virtual bool asABlur(SkSize* sigma) const SK_OVERRIDE;
+
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkBlurImageFilter, (buffer));
+    }
+
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
+protected:
+    explicit SkBlurImageFilter(SkFlattenableReadBuffer& buffer);
+
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+                               SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
+    virtual void flatten(SkFlattenableWriteBuffer& buffer) SK_OVERRIDE;
+    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
+
+private:
+    SkSize   fSigma;
+    typedef SkImageFilter INHERITED;
+};
+
+#endif
+
--- a/gfx/skia/include/effects/SkBlurMaskFilter.h
+++ b/gfx/skia/include/effects/SkBlurMaskFilter.h
@@ -50,14 +50,16 @@ public:
         @param specular     coefficient for specular highlights (e.g. 8)
         @param blurRadius   amount to blur before applying lighting (e.g. 3)
         @return the emboss maskfilter
     */
     static SkMaskFilter* CreateEmboss(  const SkScalar direction[3],
                                         SkScalar ambient, SkScalar specular,
                                         SkScalar blurRadius);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 private:
     SkBlurMaskFilter(); // can't be instantiated
 };
 
 #endif
 
--- a/gfx/skia/include/effects/SkColorMatrixFilter.h
+++ b/gfx/skia/include/effects/SkColorMatrixFilter.h
@@ -18,31 +18,34 @@ public:
     SkColorMatrixFilter();
     explicit SkColorMatrixFilter(const SkColorMatrix&);
     SkColorMatrixFilter(const SkScalar array[20]);
 
     void setMatrix(const SkColorMatrix&);
     void setArray(const SkScalar array[20]);
 
     // overrides from SkColorFilter
-    virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]);
-    virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]);
-    virtual uint32_t getFlags();
+    virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]) SK_OVERRIDE;
+    virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]) SK_OVERRIDE;
+    virtual uint32_t getFlags() SK_OVERRIDE;
+    virtual bool asColorMatrix(SkScalar matrix[20]) SK_OVERRIDE;
 
     // overrides for SkFlattenable
-    virtual void flatten(SkFlattenableWriteBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer& buffer) SK_OVERRIDE;
 
     struct State {
         int32_t fArray[20];
         int     fShift;
         int32_t fResult[4];
     };
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     // overrides for SkFlattenable
     virtual Factory getFactory();
 
     SkColorMatrixFilter(SkFlattenableReadBuffer& buffer);
 
 private:
 
--- a/gfx/skia/include/effects/SkCornerPathEffect.h
+++ b/gfx/skia/include/effects/SkCornerPathEffect.h
@@ -32,16 +32,18 @@ public:
     // overrides for SkFlattenable
     //  This method is not exported to java.
     virtual Factory getFactory();
     //  This method is not exported to java.
     virtual void flatten(SkFlattenableWriteBuffer&);
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkCornerPathEffect(SkFlattenableReadBuffer&);
 
 private:
     SkScalar    fRadius;
     
     typedef SkPathEffect INHERITED;
 };
--- a/gfx/skia/include/effects/SkDashPathEffect.h
+++ b/gfx/skia/include/effects/SkDashPathEffect.h
@@ -34,16 +34,18 @@ public:
     // overrides for SkFlattenable
     //  This method is not exported to java.
     virtual Factory getFactory();
     //  This method is not exported to java.
     virtual void flatten(SkFlattenableWriteBuffer&);
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkDashPathEffect(SkFlattenableReadBuffer&);
     
 private:
     SkScalar*   fIntervals;
     int32_t     fCount;
     // computed from phase
     SkScalar    fInitialDashLength;
--- a/gfx/skia/include/effects/SkDiscretePathEffect.h
+++ b/gfx/skia/include/effects/SkDiscretePathEffect.h
@@ -31,16 +31,18 @@ public:
     // overrides for SkFlattenable
     //  This method is not exported to java.
     virtual Factory getFactory();
     //  This method is not exported to java.
     virtual void flatten(SkFlattenableWriteBuffer&);
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkDiscretePathEffect(SkFlattenableReadBuffer&);
 
 private:
     SkScalar fSegLength, fPerterb;
     
     typedef SkPathEffect INHERITED;
 };
new file mode 100644
--- /dev/null
+++ b/gfx/skia/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
--- a/gfx/skia/include/effects/SkEmbossMaskFilter.h
+++ b/gfx/skia/include/effects/SkEmbossMaskFilter.h
@@ -36,16 +36,18 @@ public:
 
     // overrides from SkFlattenable
 
     //  This method is not exported to java.
     virtual Factory getFactory();
     //  This method is not exported to java.
     virtual void flatten(SkFlattenableWriteBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkEmbossMaskFilter(SkFlattenableReadBuffer&);
 
 private:
     Light       fLight;
     SkScalar    fBlurRadius;
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
--- a/gfx/skia/include/effects/SkGradientShader.h
+++ b/gfx/skia/include/effects/SkGradientShader.h
@@ -107,12 +107,14 @@ public:
                         If this is not null, the values must begin with 0, end with 1.0, and
                         intermediate values must be strictly increasing.
         @param  count   Must be >= 2. The number of colors (and pos if not NULL) entries
         @param  mapper  May be NULL. Callback to modify the spread of the colors.
     */
     static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
                                  const SkColor colors[], const SkScalar pos[],
                                  int count, SkUnitMapper* mapper = NULL);
+
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
 };
 
 #endif
 
--- a/gfx/skia/include/effects/SkGroupShape.h
+++ b/gfx/skia/include/effects/SkGroupShape.h
@@ -133,16 +133,18 @@ public:
 
     // overrides
     virtual Factory getFactory();
     virtual void flatten(SkFlattenableWriteBuffer&);
 
     // public for Registrar
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     // overrides
     virtual void onDraw(SkCanvas*);
 
     SkGroupShape(SkFlattenableReadBuffer&);
 
 private:
     struct Rec {
--- a/gfx/skia/include/effects/SkLayerDrawLooper.h
+++ b/gfx/skia/include/effects/SkLayerDrawLooper.h
@@ -17,28 +17,37 @@ class SK_API SkLayerDrawLooper : public 
 public:
             SkLayerDrawLooper();
     virtual ~SkLayerDrawLooper();
 
     /**
      *  Bits specifies which aspects of the layer's paint should replace the
      *  corresponding aspects on the draw's paint.
      *  kEntirePaint_Bits means use the layer's paint completely.
-     *  0 means ignore the layer's paint.
+     *  0 means ignore the layer's paint... except that LayerInfo's fFlagsMask
+     *  and fColorMode are always applied.
      */
     enum Bits {
         kStyle_Bit      = 1 << 0,   //!< use this layer's Style/stroke settings
         kTextSkewX_Bit  = 1 << 1,   //!< use this layer's textskewx
         kPathEffect_Bit = 1 << 2,   //!< use this layer's patheffect
         kMaskFilter_Bit = 1 << 3,   //!< use this layer's maskfilter
         kShader_Bit     = 1 << 4,   //!< use this layer's shader
         kColorFilter_Bit = 1 << 5,  //!< use this layer's colorfilter
         kXfermode_Bit   = 1 << 6,   //!< use this layer's xfermode
         
-        kEntirePaint_Bits = -1,      //!< use this layer's paint entirely
+        /**
+         *  Use the layer's paint entirely, with these exceptions:
+         *  - We never override the draw's paint's text_encoding, since that is
+         *    used to interpret the text/len parameters in draw[Pos]Text.
+         *  - Flags and Color are always computed using the LayerInfo's
+         *    fFlagsMask and fColorMode.
+         */
+        kEntirePaint_Bits = -1,
+        
     };
     typedef int32_t BitFlags;
 
     /**
      *  Info for how to apply the layer's paint and offset.
      *
      *  fFlagsMask selects which flags in the layer's paint should be applied.
      *      result = (draw-flags & ~fFlagsMask) | (layer-flags & fFlagsMask)
@@ -92,16 +101,18 @@ public:
     virtual void init(SkCanvas*);
     virtual bool next(SkCanvas*, SkPaint* paint);
 
     // must be public for Registrar :(
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(SkLayerDrawLooper, (buffer));
     }
     
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkLayerDrawLooper(SkFlattenableReadBuffer&);
 
     // overrides from SkFlattenable
     virtual void flatten(SkFlattenableWriteBuffer& );
     virtual Factory getFactory() { return CreateProc; }
     
 private:
--- a/gfx/skia/include/effects/SkLayerRasterizer.h
+++ b/gfx/skia/include/effects/SkLayerRasterizer.h
@@ -33,16 +33,18 @@ public:
     void addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy);
 
     // overrides from SkFlattenable
     virtual Factory getFactory();
     virtual void    flatten(SkFlattenableWriteBuffer&);
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkLayerRasterizer(SkFlattenableReadBuffer&);
 
     // override from SkRasterizer
     virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
                              const SkIRect* clipBounds,
                              SkMask* mask, SkMask::CreateMode mode);
 
--- a/gfx/skia/include/effects/SkPixelXorXfermode.h
+++ b/gfx/skia/include/effects/SkPixelXorXfermode.h
@@ -24,16 +24,18 @@ public:
     // override from SkFlattenable
     virtual Factory getFactory();
     virtual void flatten(SkFlattenableWriteBuffer&);
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(SkPixelXorXfermode, (buffer));
     }
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     // override from SkXfermode
     virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst);
 
 private:
     SkColor fOpColor;
 
     SkPixelXorXfermode(SkFlattenableReadBuffer& rb);
--- a/gfx/skia/include/effects/SkPorterDuff.h
+++ b/gfx/skia/include/effects/SkPorterDuff.h
@@ -40,17 +40,17 @@ public:
         kSrcATop_Mode,  //!< [Da, Sc * Da + (1 - Sa) * Dc]
         kDstATop_Mode,  //!< [Sa, Sa * Dc + Sc * (1 - Da)]
         kXor_Mode,      //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
         kDarken_Mode,   //!< [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]
         kLighten_Mode,  //!< [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]
         kMultiply_Mode, //!< [Sa * Da, Sc * Dc]
         kScreen_Mode,   //!< [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
         kAdd_Mode,      //!< Saturate(S + D)
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
         kOverlay_Mode,
 #endif
 
         kModeCount
     };
 
     /** Return an SkXfermode object for the specified mode.
     */
--- a/gfx/skia/include/effects/SkRectShape.h
+++ b/gfx/skia/include/effects/SkRectShape.h
@@ -42,16 +42,18 @@ public:
 
     // overrides
     virtual Factory getFactory();
     virtual void flatten(SkFlattenableWriteBuffer&);
 
     // public for Registrar
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
 
+    SK_DECLARE_FLATTENABLE_REGISTRAR()
+
 protected:
     SkRectShape(SkFlattenableReadBuffer&);
 
     // overrides
     virtual void onDraw(SkCanvas*);
 
 private:
     SkRect  fBounds;
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/effects/SkTableColorFilter.h
@@ -0,0 +1,34 @@
+
+#ifndef SkTableColorFilter_DEFINED
+#define SkTableColorFilter_DEFINED
+
+#include "SkColorFilter.h"
+
+class SkTableColorFilter {
+public:
+    /**
+     *  Create a table colorfilter, copying the table into the filter, and
+     *  applying it to all 4 components.
+     *      a' = table[a];
+     *      r' = table[r];
+     *      g' = table[g];
+     *      b' = table[b];
+     *  Compoents are operated on in unpremultiplied space. If the incomming
+     *  colors are premultiplied, they are temporarily unpremultiplied, then
+     *  the table is applied, and then the result is remultiplied.
+     */
+    static SkColorFilter* Create(const uint8_t table[256]);
+    
+    /**
+     *  Create a table colorfilter, with a different table for each
+     *  component [A, R, G, B]. If a given table is NULL, then it is
+     *  treated as identity, with the component left unchanged. If a table
+     *  is not null, then its contents are copied into the filter.
+     */
+    static SkColorFilter* CreateARGB(const uint8_t tableA[256],
+                                     const uint8_t tableR[256],
+                                     const uint8_t tableG[256],
+                                     const uint8_t tableB[256]);
+};
+
+#endif
new file mode 100755
--- /dev/null
+++ b/gfx/skia/include/effects/SkTestImageFilters.h
@@ -0,0 +1,157 @@
+
+#ifndef _SkTestImageFilters_h
+#define _SkTestImageFilters_h
+
+#include "SkImageFilter.h"
+
+class SkOffsetImageFilter : public SkImageFilter {
+public:
+    SkOffsetImageFilter(SkScalar dx, SkScalar dy) {
+        fOffset.set(dx, dy);
+    }
+
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkOffsetImageFilter, (buffer));
+    }
+
+protected:
+    SkOffsetImageFilter(SkFlattenableReadBuffer& buffer);
+
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+                               SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
+    virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) SK_OVERRIDE;
+    // overrides from SkFlattenable
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    virtual Factory getFactory() SK_OVERRIDE;
+
+private:
+    SkVector fOffset;
+
+    typedef SkImageFilter INHERITED;
+};
+
+class SkComposeImageFilter : public SkImageFilter {
+public:
+    SkComposeImageFilter(SkImageFilter* outer, SkImageFilter* inner) {
+        fOuter = outer;
+        fInner = inner;
+        SkSafeRef(outer);
+        SkSafeRef(inner);
+    }
+    virtual ~SkComposeImageFilter();
+
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkComposeImageFilter, (buffer));
+    }
+    
+protected:
+    SkComposeImageFilter(SkFlattenableReadBuffer& buffer);
+    
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+                               SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
+    virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) SK_OVERRIDE;
+    // overrides from SkFlattenable
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    virtual Factory getFactory() SK_OVERRIDE;
+    
+private:
+    SkImageFilter*  fOuter;
+    SkImageFilter*  fInner;
+    
+    typedef SkImageFilter INHERITED;
+};
+
+#include "SkXfermode.h"
+
+class SkMergeImageFilter : public SkImageFilter {
+public:
+    SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second,
+                       SkXfermode::Mode = SkXfermode::kSrcOver_Mode);
+    SkMergeImageFilter(SkImageFilter* const filters[], int count,
+                       const SkXfermode::Mode modes[] = NULL);
+    virtual ~SkMergeImageFilter();
+    
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkMergeImageFilter, (buffer));
+    }
+    
+protected:
+    SkMergeImageFilter(SkFlattenableReadBuffer& buffer);
+    
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+                               SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
+    virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) SK_OVERRIDE;
+    // overrides from SkFlattenable
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    virtual Factory getFactory() SK_OVERRIDE;
+    
+private:
+    SkImageFilter**     fFilters;
+    uint8_t*            fModes; // SkXfermode::Mode
+    int                 fCount;
+
+    // private storage, to avoid dynamically allocating storage for our copy
+    // of the filters and modes (unless fCount is so large we can't fit).
+    intptr_t    fStorage[16];
+
+    void initAlloc(int count, bool hasModes);
+    void init(SkImageFilter* const [], int count, const SkXfermode::Mode []);
+    
+    typedef SkImageFilter INHERITED;
+};
+
+class SkColorFilter;
+
+class SkColorFilterImageFilter : public SkImageFilter {
+public:
+    SkColorFilterImageFilter(SkColorFilter* cf) : fColorFilter(cf) {
+        SkSafeRef(cf);
+    }
+    virtual ~SkColorFilterImageFilter();
+
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkColorFilterImageFilter, (buffer));
+    }
+    
+protected:
+    SkColorFilterImageFilter(SkFlattenableReadBuffer& buffer);
+    
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+                               SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
+    // overrides from SkFlattenable
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    virtual Factory getFactory() SK_OVERRIDE;
+    
+private:
+    SkColorFilter*  fColorFilter;
+    
+    typedef SkImageFilter INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+// Fun mode that scales down (only) and then scales back up to look pixelated
+class SkDownSampleImageFilter : public SkImageFilter {
+public:
+    SkDownSampleImageFilter(SkScalar scale) : fScale(scale) {}
+    
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkDownSampleImageFilter, (buffer));
+    }
+    
+protected:
+    SkDownSampleImageFilter(SkFlattenableReadBuffer& buffer);
+    
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+                               SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
+    // overrides from SkFlattenable
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    virtual Factory getFactory()  SK_OVERRIDE;
+    
+private:
+    SkScalar fScale;
+    
+    typedef SkImageFilter INHERITED;
+};
+
+#endif
--- a/gfx/skia/include/effects/SkTransparentShader.h
+++ b/gfx/skia/include/effects/SkTransparentShader.h
@@ -10,29 +10,28 @@
 #ifndef SkTransparentShader_DEFINED
 #define SkTransparentShader_DEFINED
 
 #include "SkShader.h"
 
 class SkTransparentShader : public SkShader {
 public:
     SkTransparentShader() {}
-    virtual uint32_t getFlags();
+
+    virtual uint32_t getFlags() SK_OVERRIDE;
     virtual bool    setContext( const SkBitmap& device,
                                 const SkPaint& paint,
-                                const SkMatrix& matrix);
-    virtual void    shadeSpan(int x, int y, SkPMColor[], int count);
-    virtual void    shadeSpan16(int x, int y, uint16_t span[], int count);
+                                const SkMatrix& matrix) SK_OVERRIDE;
+    virtual void    shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
+    virtual void    shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE;
 
     // overrides for SkFlattenable
-    virtual Factory getFactory() { return Create; }
-    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
-        this->INHERITED::flatten(buffer);
-    }
-        
+    virtual Factory getFactory() SK_OVERRIDE;
+    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+
 private:
     // these are a cache from the call to setContext()
     const SkBitmap* fDevice;
     uint8_t         fAlpha;
 
     SkTransparentShader(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
     
     static SkFlattenable* Create(SkFlattenableReadBuffer& buffer) {
--- a/gfx/skia/include/gpu/GrColor.h
+++ b/gfx/skia/include/gpu/GrColor.h
@@ -14,25 +14,22 @@
 #include "GrTypes.h"
 
 /**
  *  GrColor is 4 bytes for R, G, B, A, in a compile-time specific order. The
  *  components are stored premultiplied.
  */
 typedef uint32_t GrColor;
 
-// indices for address a GrColor as an array of bytes
 
-#define GrColor_INDEX_R     0
-#define GrColor_INDEX_G     1
-#define GrColor_INDEX_B     2
-#define GrColor_INDEX_A     3
-
-// shfit amount to assign a component to a GrColor int
-
+// shift amount to assign a component to a GrColor int
+// These shift values are chosen for compatibility with GL attrib arrays
+// ES doesn't allow BGRA vertex attrib order so if they were not in this order
+// we'd have to swizzle in shaders. Note the assumption that the cpu is little
+// endian.
 #define GrColor_SHIFT_R     0
 #define GrColor_SHIFT_G     8
 #define GrColor_SHIFT_B     16
 #define GrColor_SHIFT_A     24
 
 /**
  *  Pack 4 components (RGBA) into a GrColor int
  */
--- a/gfx/skia/include/gpu/GrConfig.h
+++ b/gfx/skia/include/gpu/GrConfig.h
@@ -56,17 +56,17 @@
     #if defined(_WIN32)
         #undef GR_WIN32_BUILD
         #define GR_WIN32_BUILD      1
 //      #error "WIN"
     #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
         #undef GR_IOS_BUILD
         #define GR_IOS_BUILD        1
 //      #error "IOS"
-    #elif (defined(ANDROID_NDK) && ANDROID_NDK) || defined(ANDROID)
+    #elif defined(SK_BUILD_FOR_ANDROID)
         #undef GR_ANDROID_BUILD
         #define GR_ANDROID_BUILD    1
 //      #error "ANDROID"
     #elif TARGET_OS_MAC
         #undef GR_MAC_BUILD
         #define GR_MAC_BUILD        1
 //      #error "MAC"
     #elif TARGET_OS_QNX || defined(__QNXNTO__)
@@ -215,22 +215,22 @@ extern GR_API void GrPrintf(const char f
     #define GR_WARN(MSG) ("WARNING: " MSG)
 #endif
 
 /**
  *  GR_ALWAYSBREAK is an unconditional break in all builds.
  */
 #if !defined(GR_ALWAYSBREAK)
     #if     GR_WIN32_BUILD
-        #define GR_ALWAYSBREAK __debugbreak()
+        #define GR_ALWAYSBREAK SkNO_RETURN_HINT(); __debugbreak()
     #else
         // TODO: do other platforms really not have continuable breakpoints?
         // sign extend for 64bit architectures to be sure this is
         // in the high address range
-        #define GR_ALWAYSBREAK *((int*)(int64_t)(int32_t)0xbeefcafe) = 0;
+        #define GR_ALWAYSBREAK SkNO_RETURN_HINT(); *((int*)(int64_t)(int32_t)0xbeefcafe) = 0;
     #endif
 #endif
 
 /**
  *  GR_DEBUGBREAK is an unconditional break in debug builds.
  */
 #if !defined(GR_DEBUGBREAK)
     #if GR_DEBUG
@@ -346,17 +346,17 @@ inline void GrCrash(const char* msg) { G
 
 /**
  *  GR_AGGRESSIVE_SHADER_OPTS controls how aggressively shaders are optimized
  *  for special cases. On systems where program changes are expensive this
  *  may not be advantageous. Consecutive draws may no longer use the same
  *  program.
  */
 #if !defined(GR_AGGRESSIVE_SHADER_OPTS)
-    #define GR_AGGRESSIVE_SHADER_OPTS 0
+    #define GR_AGGRESSIVE_SHADER_OPTS 1
 #endif
 
 /**
  * GR_GEOM_BUFFER_LOCK_THRESHOLD gives a threshold (in bytes) for when Gr should
  * lock a GrGeometryBuffer to update its contents. It will use lock() if the
  * size of the updated region is greater than the threshold. Otherwise it will
  * use updateData().
  */
@@ -375,16 +375,17 @@ inline void GrCrash(const char* msg) { G
  * GR_MAX_OFFSCREEN_AA_SIZE controls the size at which offscreen AA will tile.
  * Tiling saves GPU memory by limiting the size of the offscreen buffer. The
  * max offscreen may be as large as (4*GR_MAX_OFFSCREEN_AA_SIZE)^2 pixels.
  */
 #if !defined(GR_MAX_OFFSCREEN_AA_SIZE)
     #define GR_MAX_OFFSCREEN_AA_SIZE    256
 #endif
 
+
 ///////////////////////////////////////////////////////////////////////////////
 // tail section:
 //
 // Now we just assert if we are missing some required define, or if we detect
 // and inconsistent combination of defines
 //
 
 
--- a/gfx/skia/include/gpu/GrContext.h
+++ b/gfx/skia/include/gpu/GrContext.h
@@ -34,21 +34,16 @@ class GrVertexBufferAllocPool;
 class GR_API GrContext : public GrRefCnt {
 public:
     /**
      * Creates a GrContext from within a 3D context.
      */
     static GrContext* Create(GrEngine engine,
                              GrPlatform3DContext context3D);
 
-    /**
-     *  Helper to create a opengl-shader based context
-     */
-    static GrContext* CreateGLShaderContext();
-
     virtual ~GrContext();
 
     /**
      * The GrContext normally assumes that no outsider is setting state
      * within the underlying 3D API's context/device/whatever. This call informs
      * the context that the state was modified and it should resend. Shouldn't
      * be called frequently for good performance.
      */
@@ -108,33 +103,71 @@ public:
     /**
      * Key generated by client. Should be a unique key on the texture data.
      * Does not need to consider that width and height of the texture. Two
      * textures with the same TextureKey but different bounds will not collide.
      */
     typedef uint64_t TextureKey;
 
     /**
+     *  Create a new entry, based on the specified key and texture, and return
+     *  its "locked" entry. Must call be balanced with an unlockTexture() call.
+     *
+     *  @param key      A client-generated key that identifies the contents
+     *                  of the texture. Respecified to findAndLockTexture
+     *                  for subsequent uses of the texture.
+     *  @param sampler  The sampler state used to draw a texture may be used
+     *                  to determine how to store the pixel data in the texture
+     *                  cache. (e.g. different versions may exist for different
+     *                  wrap modes on GPUs with limited or no NPOT texture
+     *                  support). Only the wrap and filter fields are used. NULL
+     *                  implies clamp wrap modes and nearest filtering.
+     * @param desc      Description of the texture properties.
+     * @param srcData   Pointer to the pixel values.
+     * @param rowBytes  The number of bytes between rows of the texture. Zero
+     *                  implies tightly packed rows.
+     */
+    TextureCacheEntry createAndLockTexture(TextureKey key,
+                                           const GrSamplerState* sampler,
+                                           const GrTextureDesc& desc,
+                                           void* srcData, size_t rowBytes);
+
+    /**
      *  Search for an entry based on key and dimensions. If found, "lock" it and
      *  return it. The entry's texture() function will return NULL if not found.
-     *  Must call be balanced with an unlockTexture() call.
+     *  Must be balanced with an unlockTexture() call.
+     *
+     *  @param key      A client-generated key that identifies the contents
+     *                  of the texture.
+     *  @param width    The width of the texture in pixels as specifed in
+     *                  the GrTextureDesc originally passed to
+     *                  createAndLockTexture
+     *  @param width    The height of the texture in pixels as specifed in
+     *                  the GrTextureDesc originally passed to
+     *                  createAndLockTexture
+     *  @param sampler  The sampler state used to draw a texture may be used
+     *                  to determine the cache entry used. (e.g. different
+     *                  versions may exist for different wrap modes on GPUs with
+     *                  limited or no NPOT texture support). Only the wrap and 
+     *                  filter fields are used. NULL implies clamp wrap modes
+     *                  and nearest filtering.
      */
     TextureCacheEntry findAndLockTexture(TextureKey key,
                                          int width,
                                          int height,
-                                         const GrSamplerState&);
-
+                                         const GrSamplerState* sampler);
     /**
-     *  Create a new entry, based on the specified key and texture, and return
-     *  its "locked" entry. Must call be balanced with an unlockTexture() call.
+     * Determines whether a texture is in the cache. If the texture is found it
+     * will not be locked or returned. This call does not affect the priority of
+     * the texture for deletion.
      */
-    TextureCacheEntry createAndLockTexture(TextureKey key,
-                                           const GrSamplerState&,
-                                           const GrTextureDesc&,
-                                           void* srcData, size_t rowBytes);
+    bool isTextureInCache(TextureKey key,
+                          int width,
+                          int height,
+                          const GrSamplerState*) const;
 
     /**
      * Enum that determines how closely a returned scratch texture must match
      * a provided GrTextureDesc.
      */
     enum ScratchTexMatch {
         /**
          * Finds a texture that exactly matches the descriptor.
@@ -177,17 +210,17 @@ public:
      */
     GrTexture* createUncachedTexture(const GrTextureDesc&,
                                      void* srcData,
                                      size_t rowBytes);
 
     /**
      *  Returns true if the specified use of an indexed texture is supported.
      */
-    bool supportsIndex8PixelConfig(const GrSamplerState&,
+    bool supportsIndex8PixelConfig(const GrSamplerState*,
                                    int width,
                                    int height) const;
 
     /**
      *  Return the current texture cache limits.
      *
      *  @param maxTextures If non-null, returns maximum number of textures that
      *                     can be held in the cache.
@@ -233,16 +266,45 @@ public:
      */
     const GrRenderTarget* getRenderTarget() const;
     GrRenderTarget* getRenderTarget();
 
     ///////////////////////////////////////////////////////////////////////////
     // Platform Surfaces
 
     /**
+     * Wraps an existing texture with a GrTexture object.
+     *
+     * OpenGL: if the object is a texture Gr may change its GL texture params
+     *         when it is drawn.
+     *
+     * @param  desc     description of the object to create.
+     *
+     * @return GrTexture object or NULL on failure.
+     */
+    GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
+
+    /**
+     * Wraps an existing render target with a GrRenderTarget object. It is
+     * similar to createPlatformTexture but can be used to draw into surfaces
+     * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
+     * the client will resolve to a texture).
+     *
+     * @param  desc     description of the object to create.
+     *
+     * @return GrTexture object or NULL on failure.
+     */
+     GrRenderTarget* createPlatformRenderTarget(
+                                    const GrPlatformRenderTargetDesc& desc);
+
+    /**
+     * This interface is depracted and will be removed in a future revision.
+     * Callers should use createPlatformTexture or createPlatformRenderTarget
+     * instead.
+     *
      * Wraps an existing 3D API surface in a GrObject. desc.fFlags determines
      * the type of object returned. If kIsTexture is set the returned object
      * will be a GrTexture*. Otherwise, it will be a GrRenderTarget*. If both 
      * are set the render target object is accessible by
      * GrTexture::asRenderTarget().
      *
      * GL: if the object is a texture Gr may change its GL texture parameters
      *     when it is drawn.
@@ -416,60 +478,115 @@ public:
 
     /**
      * Call to ensure all drawing to the context has been issued to the
      * underlying 3D API.
      * @param flagsBitfield     flags that control the flushing behavior. See
      *                          FlushBits.
      */
     void flush(int flagsBitfield = 0);
-    
+
     /**
      * Reads a rectangle of pixels from a render target.
-     * @param renderTarget  the render target to read from. NULL means the
+     * @param target        the render target to read from. NULL means the
      *                      current render target.
      * @param left          left edge of the rectangle to read (inclusive)
      * @param top           top edge of the rectangle to read (inclusive)
      * @param width         width of rectangle to read in pixels.
      * @param height        height of rectangle to read in pixels.
      * @param config        the pixel config of the destination buffer
      * @param buffer        memory to read the rectangle into.
+     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
+     *                      means rows are tightly packed.
      *
      * @return true if the read succeeded, false if not. The read can fail
-     *              because of a unsupported pixel config or because no render
+     *              because of an unsupported pixel config or because no render
      *              target is currently set.
      */
     bool readRenderTargetPixels(GrRenderTarget* target,
                                 int left, int top, int width, int height,
-                                GrPixelConfig config, void* buffer);
+                                GrPixelConfig config, void* buffer, 
+                                size_t rowBytes) {
+        return this->internalReadRenderTargetPixels(target, left, top,
+                                                    width, height,
+                                                    config, buffer,
+                                                    rowBytes, 0);
+    }
+
+    /**
+     * Copy the src pixels [buffer, rowbytes, pixelconfig] into a render target
+     * at the specified rectangle.
+     * @param target        the render target to write into. NULL means the
+     *                      current render target.
+     * @param left          left edge of the rectangle to write (inclusive)
+     * @param top           top edge of the rectangle to write (inclusive)
+     * @param width         width of rectangle to write in pixels.
+     * @param height        height of rectangle to write in pixels.
+     * @param config        the pixel config of the source buffer
+     * @param buffer        memory to read the rectangle from.
+     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
+     *                      means rows are tightly packed.
+     */
+    void writeRenderTargetPixels(GrRenderTarget* target,
+                                 int left, int top, int width, int height,
+                                 GrPixelConfig config, const void* buffer,
+                                 size_t rowBytes) {
+        this->internalWriteRenderTargetPixels(target, left, top, width, height,
+                                              config, buffer, rowBytes, 0);
+    }
 
     /**
      * Reads a rectangle of pixels from a texture.
-     * @param texture       the render target to read from.
+     * @param texture       the texture to read from.
      * @param left          left edge of the rectangle to read (inclusive)
      * @param top           top edge of the rectangle to read (inclusive)
      * @param width         width of rectangle to read in pixels.
      * @param height        height of rectangle to read in pixels.
      * @param config        the pixel config of the destination buffer
      * @param buffer        memory to read the rectangle into.
+     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
+     *                      means rows are tightly packed.
      *
      * @return true if the read succeeded, false if not. The read can fail
-     *              because of a unsupported pixel config.
+     *              because of an unsupported pixel config.
      */
-    bool readTexturePixels(GrTexture* target,
+    bool readTexturePixels(GrTexture* texture,
                            int left, int top, int width, int height,
-                           GrPixelConfig config, void* buffer);
+                           GrPixelConfig config, void* buffer,
+                           size_t rowBytes) {
+        return this->internalReadTexturePixels(texture, left, top,
+                                               width, height,
+                                               config, buffer, rowBytes, 0);
+    }
 
     /**
-     *  Copy the src pixels [buffer, stride, pixelconfig] into the current
-     *  render-target at the specified rectangle.
+     * Writes a rectangle of pixels to a texture.
+     * @param texture       the render target to read from.
+     * @param left          left edge of the rectangle to write (inclusive)
+     * @param top           top edge of the rectangle to write (inclusive)
+     * @param width         width of rectangle to write in pixels.
+     * @param height        height of rectangle to write in pixels.
+     * @param config        the pixel config of the source buffer
+     * @param buffer        memory to read pixels from
+     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
+     *                      means rows are tightly packed.
      */
-    void writePixels(int left, int top, int width, int height,
-                     GrPixelConfig, const void* buffer, size_t stride);
-
+    void writeTexturePixels(GrTexture* texture,
+                            int left, int top, int width, int height,
+                            GrPixelConfig config, const void* buffer,
+                            size_t rowBytes) {
+        this->internalWriteTexturePixels(texture, left, top, width, height, 
+                                         config, buffer, rowBytes, 0);
+    }
+    /**
+     * Copies all texels from one texture to another.
+     * @param src           the texture to copy from.
+     * @param dst           the render target to copy to.
+     */
+    void copyTexture(GrTexture* src, GrRenderTarget* dst);
     /**
      * Applies a 1D convolution kernel in the X direction to a rectangle of
      * pixels from a given texture.
      * @param texture         the texture to read from
      * @param rect            the destination rectangle
      * @param kernel          the convolution kernel (kernelWidth elements)
      * @param kernelWidth     the width of the convolution kernel
      */
@@ -576,17 +693,17 @@ private:
 
     inline int aaStrokeRectIndexCount() const;
     GrIndexBuffer* aaStrokeRectIndexBuffer();
 
     void setupDrawBuffer();
 
     void flushDrawBuffer();
 
-    static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
+    void setPaint(const GrPaint& paint, GrDrawTarget* target);
 
     GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
 
     GrPathRenderer* getPathRenderer(const GrPath& path,
                                     GrPathFill fill,
                                     bool antiAlias);
 
     struct OffscreenRecord;
@@ -622,17 +739,53 @@ private:
                             GrPathRenderer* pr,
                             OffscreenRecord* record);
 
     void convolve(GrTexture* texture,
                   const SkRect& rect,
                   float imageIncrement[2],
                   const float* kernel,
                   int kernelWidth);
-    
+
+    /**
+     * Flags to the internal read/write pixels funcs
+     */
+    enum PixelOpsFlags {
+        kDontFlush_PixelOpsFlag = 0x1,
+    };
+
+    bool internalReadRenderTargetPixels(GrRenderTarget* target,
+                                        int left, int top,
+                                        int width, int height,
+                                        GrPixelConfig config, void* buffer, 
+                                        size_t rowBytes, uint32_t flags);
+
+    void internalWriteRenderTargetPixels(GrRenderTarget* target,
+                                        int left, int top,
+                                        int width, int height,
+                                        GrPixelConfig, const void* buffer,
+                                        size_t rowBytes, uint32_t flags);
+
+    bool internalReadTexturePixels(GrTexture* texture,
+                                   int left, int top,
+                                   int width, int height,
+                                   GrPixelConfig config, void* buffer,
+                                   size_t rowBytes, uint32_t flags);
+
+    void internalWriteTexturePixels(GrTexture* texture,
+                                    int left, int top,
+                                    int width, int height,
+                                    GrPixelConfig config, const void* buffer,
+                                    size_t rowBytes, uint32_t flags);
+    // needed for access to internalWriteTexturePixels. TODO: make GrContext
+    // be a facade for an internal class. Then functions that are public on the 
+    // internal class would have only be callable in src/gpu. The facade would
+    // only have to functions necessary for clients.
+    friend class GrAtlas;
+
     // computes vertex layout bits based on the paint. If paint expresses
     // a texture for a stage, the stage coords will be bound to postitions
     // unless hasTexCoords[s]==true in which case stage s's input coords
     // are bound to tex coord index s. hasTexCoords == NULL is a shortcut
     // for an array where all the values are false.
     static int PaintStageVertexLayoutBits(
                                     const GrPaint& paint,
                                     const bool hasTexCoords[GrPaint::kTotalStages]);
--- a/gfx/skia/include/gpu/GrGLConfig.h
+++ b/gfx/skia/include/gpu/GrGLConfig.h
@@ -72,16 +72,25 @@
  * GR_GL_PER_GL_FUNC_CALLBACK: When set to 1 the GrGLInterface object provides
  * a function pointer that is called just before every gl function. The ptr must
  * be valid (i.e. there is no NULL check). However, by default the callback will
  * be set to a function that does nothing. The signature of the function is:
  *    void function(const GrGLInterface*)
  * It is not extern "C".
  * The GrGLInterface field fCallback specifies the function ptr and there is an
  * additional field fCallbackData of type intptr_t for client data.
+ *
+ * GR_GL_RGBA_8888_PIXEL_OPS_SLOW: Set this to 1 if it is known that performing
+ * glReadPixels / glTex(Sub)Image with format=GL_RGBA, type=GL_UNISIGNED_BYTE is
+ * significantly slower than format=GL_BGRA, type=GL_UNISIGNED_BYTE.
+ *
+ * GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL: Set this to 1 if calling
+ * glReadPixels to read the entire framebuffer is faster than calling it with
+ * the same sized rectangle but with a framebuffer bound that is larger than
+ * the rectangle read.
  */
 
 #if !defined(GR_GL_LOG_CALLS)
     #define GR_GL_LOG_CALLS                     GR_DEBUG
 #endif
 
 #if !defined(GR_GL_LOG_CALLS_START)
     #define GR_GL_LOG_CALLS_START               0
@@ -106,34 +115,30 @@
 #if !defined(GR_GL_USE_BUFFER_DATA_NULL_HINT)
     #define GR_GL_USE_BUFFER_DATA_NULL_HINT     1
 #endif
 
 #if !defined(GR_GL_PER_GL_FUNC_CALLBACK)
     #define GR_GL_PER_GL_FUNC_CALLBACK          0
 #endif
 
+#if !defined(GR_GL_RGBA_8888_PIXEL_OPS_SLOW)
+    #define GR_GL_RGBA_8888_PIXEL_OPS_SLOW      0
+#endif
+
+#if !defined(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL)
+    #define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL 0
+#endif
+
 #if(GR_GL_NO_CONSTANT_ATTRIBUTES) && (GR_GL_ATTRIBUTE_MATRICES)
     #error "Cannot combine GR_GL_NO_CONSTANT_ATTRIBUTES and GR_GL_ATTRIBUTE_MATRICES"
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
 
-/**
- * The following macros are used to staticlly configure the default
- * GrGLInterface, but should not be used outside of the GrGLInterface
- * scaffolding.  Undefine here to prevent accidental use.
- */
-#undef GR_SUPPORT_GLDESKTOP
-#undef GR_SUPPORT_GLES1
-#undef GR_SUPPORT_GLES2
-#undef GR_SUPPORT_GLES
-
-////////////////////////////////////////////////////////////////////////////////
-
 #if GR_SCALAR_IS_FIXED
     #define GrGLType   GL_FIXED
 #elif GR_SCALAR_IS_FLOAT
     #define GrGLType   GR_GL_FLOAT
 #else
     #error "unknown GR_SCALAR type"
 #endif
 
@@ -145,26 +150,16 @@
     #define GR_GL_TEXT_TEXTURE_NORMALIZED   0
 #elif GR_TEXT_SCALAR_IS_FIXED
     #define GrGLTextType                    GR_GL_FIXED
     #define GR_GL_TEXT_TEXTURE_NORMALIZED   0
 #else
     #error "unknown GR_TEXT_SCALAR type"
 #endif
 
-// Pick a pixel config for 32bit bitmaps. Our default is GL_RGBA (except on
-// Windows where we match GDI's order).
-#ifndef GR_GL_32BPP_COLOR_FORMAT
-    #if GR_WIN32_BUILD || GR_LINUX_BUILD
-        #define GR_GL_32BPP_COLOR_FORMAT    GR_GL_BGRA
-    #else
-        #define GR_GL_32BPP_COLOR_FORMAT    GR_GL_RGBA
-    #endif
-#endif
-
 ////////////////////////////////////////////////////////////////////////////////
 
 struct GrGLInterface;
 
 extern void GrGLCheckErr(const GrGLInterface* gl,
                          const char* location,
                          const char* call);
 
@@ -220,24 +215,16 @@ extern void GrGLClearErr(const GrGLInter
         GR_GL_LOG_CALLS_IMPL(X);                                \
     } while (false)
 
 #define GR_GL_GET_ERROR(IFACE) (IFACE)->fGetError()
 
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
- *  GrGLResetRowLength() will reset GL_UNPACK_ROW_LENGTH to 0. We write
- *  this wrapper, since GL_UNPACK_ROW_LENGTH is not available on all GL versions
- */
-extern void GrGLResetRowLength(const GrGLInterface*);
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
  *  Some drivers want the var-int arg to be zero-initialized on input.
  */
 #define GR_GL_INIT_ZERO     0
 #define GR_GL_GetIntegerv(gl, e, p)     \
     do {                            \
         *(p) = GR_GL_INIT_ZERO;     \
         GR_GL_CALL(gl, GetIntegerv(e, p));   \
     } while (0)
--- a/gfx/skia/include/gpu/GrGLConfig_chrome.h
+++ b/gfx/skia/include/gpu/GrGLConfig_chrome.h
@@ -3,25 +3,28 @@
  * 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 GrGLConfig_chrome_DEFINED
 #define GrGLConfig_chrome_DEFINED
 
-// chrome always assumes BGRA
-#define GR_GL_32BPP_COLOR_FORMAT        GR_GL_BGRA
-
 // glGetError() forces a sync with gpu process on chrome
 #define GR_GL_CHECK_ERROR_START         0
 
 // ANGLE creates a temp VB for vertex attributes not specified per-vertex.
 #define GR_GL_NO_CONSTANT_ATTRIBUTES    GR_WIN32_BUILD
 
+// For RGBA teximage/readpixels ANGLE will sw-convert to/from BGRA.
+#define GR_GL_RGBA_8888_PIXEL_OPS_SLOW  GR_WIN32_BUILD
+
+// ANGLE can go faster if the entire fbo is read rather than a subrect
+#define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL GR_WIN32_BUILD
+
 // cmd buffer allocates memory and memsets it to zero when it sees glBufferData
 // with NULL.
 #define GR_GL_USE_BUFFER_DATA_NULL_HINT 0
 
 // chrome uses this to set the context on each GL call.
 #define GR_GL_PER_GL_FUNC_CALLBACK      1
 
 #endif
--- a/gfx/skia/include/gpu/GrGLDefines.h
+++ b/gfx/skia/include/gpu/GrGLDefines.h
@@ -169,17 +169,19 @@
 #define GR_GL_STENCIL_BACK_VALUE_MASK        0x8CA4
 #define GR_GL_STENCIL_BACK_WRITEMASK         0x8CA5
 #define GR_GL_VIEWPORT                       0x0BA2
 #define GR_GL_SCISSOR_BOX                    0x0C10
 /*      GL_SCISSOR_TEST */
 #define GR_GL_COLOR_CLEAR_VALUE              0x0C22
 #define GR_GL_COLOR_WRITEMASK                0x0C23
 #define GR_GL_UNPACK_ALIGNMENT               0x0CF5
+#define GR_GL_UNPACK_FLIP_Y                  0x9240
 #define GR_GL_PACK_ALIGNMENT                 0x0D05
+#define GR_GL_PACK_REVERSE_ROW_ORDER         0x93A4
 #define GR_GL_MAX_TEXTURE_SIZE               0x0D33
 #define GR_GL_MAX_VIEWPORT_DIMS              0x0D3A
 #define GR_GL_SUBPIXEL_BITS                  0x0D50
 #define GR_GL_RED_BITS                       0x0D52
 #define GR_GL_GREEN_BITS                     0x0D53
 #define GR_GL_BLUE_BITS                      0x0D54
 #define GR_GL_ALPHA_BITS                     0x0D55
 #define GR_GL_DEPTH_BITS                     0x0D56
@@ -277,23 +279,27 @@
 #define GR_GL_LINE_STIPPLE_PATTERN           0x0B25
 #define GR_GL_LINE_STIPPLE_REPEAT            0x0B26
 #define GR_GL_LINE_WIDTH                     0x0B21
 #define GR_GL_LINE_WIDTH_GRANULARITY         0x0B23
 #define GR_GL_LINE_WIDTH_RANGE               0x0B22
 
 /* PixelFormat */
 #define GR_GL_DEPTH_COMPONENT                0x1902
+#define GR_GL_RED                            0x1903
+#define GR_GL_GREEN                          0x1904
+#define GR_GL_BLUE                           0x1905
 #define GR_GL_ALPHA                          0x1906
 #define GR_GL_RGB                            0x1907
 #define GR_GL_RGBA                           0x1908
 #define GR_GL_BGRA                           0x80E1
 #define GR_GL_LUMINANCE                      0x1909
 #define GR_GL_LUMINANCE_ALPHA                0x190A
 #define GR_GL_PALETTE8_RGBA8                 0x8B96
+#define GR_GL_ALPHA8                         0x803C
 
 /* PixelType */
 /*      GL_UNSIGNED_BYTE */
 #define GR_GL_UNSIGNED_SHORT_4_4_4_4         0x8033
 #define GR_GL_UNSIGNED_SHORT_5_5_5_1         0x8034
 #define GR_GL_UNSIGNED_SHORT_5_6_5           0x8363
 
 /* Shaders */
@@ -343,35 +349,41 @@
 
 /* StringName */
 #define GR_GL_VENDOR                         0x1F00
 #define GR_GL_RENDERER                       0x1F01
 #define GR_GL_VERSION                        0x1F02
 #define GR_GL_EXTENSIONS                     0x1F03
 
 /* Pixel Mode / Transfer */
-#define GR_GL_UNPACK_ROW_LENGTH            0x0CF2
+#define GR_GL_UNPACK_ROW_LENGTH              0x0CF2
+#define GR_GL_PACK_ROW_LENGTH                0x0D02
+
 
 /* TextureMagFilter */
 #define GR_GL_NEAREST                        0x2600
 #define GR_GL_LINEAR                         0x2601
 
 /* TextureMinFilter */
 /*      GL_NEAREST */
 /*      GL_LINEAR */
 #define GR_GL_NEAREST_MIPMAP_NEAREST         0x2700
 #define GR_GL_LINEAR_MIPMAP_NEAREST          0x2701
 #define GR_GL_NEAREST_MIPMAP_LINEAR          0x2702
 #define GR_GL_LINEAR_MIPMAP_LINEAR           0x2703
 
+/* TextureUsage */
+#define GR_GL_FRAMEBUFFER_ATTACHMENT         0x93A3
+
 /* TextureParameterName */
 #define GR_GL_TEXTURE_MAG_FILTER             0x2800
 #define GR_GL_TEXTURE_MIN_FILTER             0x2801
 #define GR_GL_TEXTURE_WRAP_S                 0x2802
 #define GR_GL_TEXTURE_WRAP_T                 0x2803
+#define GR_GL_TEXTURE_USAGE                  0x93A2
 
 /* TextureTarget */
 /*      GL_TEXTURE_2D */
 #define GR_GL_TEXTURE                        0x1702
 #define GR_GL_TEXTURE_CUBE_MAP               0x8513
 #define GR_GL_TEXTURE_BINDING_CUBE_MAP       0x8514
 #define GR_GL_TEXTURE_CUBE_MAP_POSITIVE_X    0x8515
 #define GR_GL_TEXTURE_CUBE_MAP_NEGATIVE_X    0x8516
@@ -417,20 +429,27 @@
 #define GR_GL_ACTIVE_TEXTURE                 0x84E0
 #define GR_GL_MAX_TEXTURE_UNITS              0x84E2
 
 /* TextureWrapMode */
 #define GR_GL_REPEAT                         0x2901
 #define GR_GL_CLAMP_TO_EDGE                  0x812F
 #define GR_GL_MIRRORED_REPEAT                0x8370
 
+/* Texture Swizzle */
+#define GR_GL_TEXTURE_SWIZZLE_R              0x8E42
+#define GR_GL_TEXTURE_SWIZZLE_G              0x8E43
+#define GR_GL_TEXTURE_SWIZZLE_B              0x8E44
+#define GR_GL_TEXTURE_SWIZZLE_A              0x8E45
+#define GR_GL_TEXTURE_SWIZZLE_RGBA           0x8E46
+
 /* Texture mapping */
-#define GR_GL_TEXTURE_ENV                   0x2300
-#define GR_GL_TEXTURE_ENV_MODE              0x2200
-#define GR_GL_TEXTURE_1D                    0x0DE0
+#define GR_GL_TEXTURE_ENV                    0x2300
+#define GR_GL_TEXTURE_ENV_MODE               0x2200
+#define GR_GL_TEXTURE_1D                     0x0DE0
 /* GL_TEXTURE_2D */
 /* GL_TEXTURE_WRAP_S */
 /* GL_TEXTURE_WRAP_T */
 /* GL_TEXTURE_MAG_FILTER */
 /* GL_TEXTURE_MIN_FILTER */
 #define GR_GL_TEXTURE_ENV_COLOR             0x2201
 #define GR_GL_TEXTURE_GEN_S                 0x0C60
 #define GR_GL_TEXTURE_GEN_T                 0x0C61
@@ -609,16 +628,17 @@
 
 #define GR_GL_RENDERBUFFER                   0x8D41
 
 #define GR_GL_RGBA4                          0x8056
 #define GR_GL_RGB5_A1                        0x8057
 #define GR_GL_RGB565                         0x8D62
 #define GR_GL_RGBA8                          0x8058
 #define GR_GL_RGB8                           0x8051
+#define GR_GL_BGRA8                          0x93A1
 #define GR_GL_SRGB                           0x8C40
 #define GR_GL_SRGB8                          0x8C41
 #define GR_GL_SRGB_ALPHA                     0x8C42
 #define GR_GL_SRGB8_ALPHA8                   0x8C43
 #define GR_GL_DEPTH_COMPONENT16              0x81A5
 #define GR_GL_STENCIL_INDEX                  0x1901
 #define GR_GL_STENCIL_INDEX4                 0x8D47
 #define GR_GL_STENCIL_INDEX8                 0x8D48
--- a/gfx/skia/include/gpu/GrGLInterface.h
+++ b/gfx/skia/include/gpu/GrGLInterface.h
@@ -106,18 +106,17 @@ typedef float GrGLclampf;
 typedef double GrGLdouble;
 typedef double GrGLclampd;
 typedef void GrGLvoid;
 typedef long GrGLintptr;
 typedef long GrGLsizeiptr;
 
 enum GrGLBinding {
     kDesktop_GrGLBinding = 0x01,
-    kES1_GrGLBinding = 0x02,
-    kES2_GrGLBinding = 0x04
+    kES2_GrGLBinding = 0x02
 };
 
 extern "C" {
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLActiveTextureProc)(GrGLenum texture);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLAttachShaderProc)(GrGLuint program, GrGLuint shader);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBeginQueryProc)(GrGLenum target, GrGLuint id);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBindAttribLocationProc)(GrGLuint program, GrGLuint index, const char* name);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBindBufferProc)(GrGLenum target, GrGLuint buffer);
@@ -125,40 +124,36 @@ extern "C" {
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBlendColorProc)(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBindFragDataLocationProc)(GrGLuint program, GrGLuint colorNumber, const GrGLchar* name);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBlendFuncProc)(GrGLenum sfactor, GrGLenum dfactor);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBufferDataProc)(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data, GrGLenum usage);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBufferSubDataProc)(GrGLenum target, GrGLintptr offset, GrGLsizeiptr size, const GrGLvoid* data);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLClearProc)(GrGLbitfield mask);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLClearColorProc)(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLClearStencilProc)(GrGLint s);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLClientActiveTextureProc)(GrGLenum texture);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLColor4ubProc)(GrGLubyte red, GrGLubyte green, GrGLubyte blue, GrGLubyte alpha);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLColorMaskProc)(GrGLboolean red, GrGLboolean green, GrGLboolean blue, GrGLboolean alpha);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLColorPointerProc)(GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* pointer);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLCompileShaderProc)(GrGLuint shader);
     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 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);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteBuffersProc)(GrGLsizei n, const GrGLuint* buffers);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteProgramProc)(GrGLuint program);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteQueriesProc)(GrGLsizei n, const GrGLuint *ids);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteShaderProc)(GrGLuint shader);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteTexturesProc)(GrGLsizei n, const GrGLuint* textures);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDepthMaskProc)(GrGLboolean flag);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDisableProc)(GrGLenum cap);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDisableClientStateProc)(GrGLenum array);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDisableVertexAttribArrayProc)(GrGLuint index);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDrawArraysProc)(GrGLenum mode, GrGLint first, GrGLsizei count);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDrawBufferProc)(GrGLenum mode);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDrawBuffersProc)(GrGLsizei n, const GrGLenum* bufs);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDrawElementsProc)(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableProc)(GrGLenum cap);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableClientStateProc)(GrGLenum cap);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableVertexAttribArrayProc)(GrGLuint index);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEndQueryProc)(GrGLenum target);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLFinishProc)();
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLFlushProc)();
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLFrontFaceProc)(GrGLenum mode);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGenBuffersProc)(GrGLsizei n, GrGLuint* buffers);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGenQueriesProc)(GrGLsizei n, GrGLuint *ids);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGenTexturesProc)(GrGLsizei n, GrGLuint* textures);
@@ -174,36 +169,31 @@ extern "C" {
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetQueryObjectuivProc)(GrGLuint id, GrGLenum pname, GrGLuint *params);    
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetShaderInfoLogProc)(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length, char* infolog);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetShaderivProc)(GrGLuint shader, GrGLenum pname, GrGLint* params);
     typedef const GrGLubyte* (GR_GL_FUNCTION_TYPE *GrGLGetStringProc)(GrGLenum name);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLGetTexLevelParameterivProc)(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params);
     typedef GrGLint (GR_GL_FUNCTION_TYPE *GrGLGetUniformLocationProc)(GrGLuint program, const char* name);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLLineWidthProc)(GrGLfloat width);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLLinkProgramProc)(GrGLuint program);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLLoadMatrixfProc)(const GrGLfloat* m);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLMatrixModeProc)(GrGLenum mode);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLPixelStoreiProc)(GrGLenum pname, GrGLint param);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLPointSizeProc)(GrGLfloat size);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLQueryCounterProc)(GrGLuint id, GrGLenum target);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLReadBufferProc)(GrGLenum src);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLReadPixelsProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLScissorProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLShadeModelProc)(GrGLenum mode);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLShaderSourceProc)(GrGLuint shader, GrGLsizei count, const char** str, const GrGLint* length);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilFuncProc)(GrGLenum func, GrGLint ref, GrGLuint mask);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilFuncSeparateProc)(GrGLenum face, GrGLenum func, GrGLint ref, GrGLuint mask);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilMaskProc)(GrGLuint mask);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilMaskSeparateProc)(GrGLenum face, GrGLuint mask);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilOpProc)(GrGLenum fail, GrGLenum zfail, GrGLenum zpass);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilOpSeparateProc)(GrGLenum face, GrGLenum fail, GrGLenum zfail, GrGLenum zpass);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexCoordPointerProc)(GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* pointer);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexEnviProc)(GrGLenum target, GrGLenum pname, GrGLint param);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexImage2DProc)(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexParameteriProc)(GrGLenum target, GrGLenum pname, GrGLint param);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexStorage2DProc)(GrGLenum target, GrGLsizei levels, GrGLenum internalformat, GrGLsizei width, GrGLsizei height);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexSubImage2DProc)(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1fProc)(GrGLint location, GrGLfloat v0);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1iProc)(GrGLint location, GrGLint v0);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1ivProc)(GrGLint location, GrGLsizei count, const GrGLint* v);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform2fProc)(GrGLint location, GrGLfloat v0, GrGLfloat v1);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform2iProc)(GrGLint location, GrGLint v0, GrGLint v1);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform2fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
@@ -217,17 +207,16 @@ extern "C" {
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform4fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform4ivProc)(GrGLint location, GrGLsizei count, const GrGLint* v);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniformMatrix2fvProc)(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniformMatrix3fvProc)(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniformMatrix4fvProc)(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUseProgramProc)(GrGLuint program);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexAttrib4fvProc)(GrGLuint indx, const GrGLfloat* values);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexAttribPointerProc)(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexPointerProc)(GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* pointer);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLViewportProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
 
     // FBO Extension Functions
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBindFramebufferProc)(GrGLenum target, GrGLuint framebuffer);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBindRenderbufferProc)(GrGLenum target, GrGLuint renderbuffer);
     typedef GrGLenum (GR_GL_FUNCTION_TYPE *GrGLCheckFramebufferStatusProc)(GrGLenum target);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteFramebuffersProc)(GrGLsizei n, const GrGLuint *framebuffers);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteRenderbuffersProc)(GrGLsizei n, const GrGLuint *renderbuffers);
@@ -273,83 +262,62 @@ enum GrGLCapability {
  * IMPORTANT NOTE: The OpenGL entry points exposed here include both core GL
  * functions, and extensions.  The system assumes that the address of the
  * extension pointer will be valid across contexts.
  */
 struct GR_API GrGLInterface : public GrRefCnt {
 
     GrGLInterface();
 
-    bool validate(GrEngine engine) const;
+    bool validate() const;
     bool supportsDesktop() const {
         return 0 != (kDesktop_GrGLBinding & fBindingsExported);
     }
-    bool supportsES1() const {
-        return 0 != (kES1_GrGLBinding & fBindingsExported);
-    }
     bool supportsES2() const {
         return 0 !=  (kES2_GrGLBinding & fBindingsExported);
     }
-    bool supportsES() const {
-        return 0 != ((kES1_GrGLBinding | kES2_GrGLBinding) &
-                        fBindingsExported);
-    }
 
     // Indicator variable specifying the type of GL implementation
     // exported:  GLES{1|2} or Desktop.
     GrGLBinding fBindingsExported;
 
-    /// Does this GL support NPOT textures on FBOs?
-    /// boolean value, or kProbe_GrGLCapability to probe (slowly) at context creation.
-    int fNPOTRenderTargetSupport;
-
-    /// Some GL implementations (PowerVR SGX devices like the iPhone 4)
-    /// have restrictions on the size of small render targets.
-    /// kProbe_GrGLCapability to probe (slowly) at context creation.
-    int fMinRenderTargetHeight;
-    int fMinRenderTargetWidth;
-
     GrGLActiveTextureProc fActiveTexture;
     GrGLAttachShaderProc fAttachShader;
     GrGLBeginQueryProc fBeginQuery;
     GrGLBindAttribLocationProc fBindAttribLocation;
     GrGLBindBufferProc fBindBuffer;
     GrGLBindFragDataLocationProc fBindFragDataLocation;
     GrGLBindTextureProc fBindTexture;
     GrGLBlendColorProc fBlendColor;
     GrGLBlendFuncProc fBlendFunc;
     GrGLBufferDataProc fBufferData;
     GrGLBufferSubDataProc fBufferSubData;
     GrGLClearProc fClear;
     GrGLClearColorProc fClearColor;
     GrGLClearStencilProc fClearStencil;
-    GrGLClientActiveTextureProc fClientActiveTexture;
-    GrGLColor4ubProc fColor4ub;
     GrGLColorMaskProc fColorMask;
     GrGLColorPointerProc fColorPointer;
     GrGLCompileShaderProc fCompileShader;
     GrGLCompressedTexImage2DProc fCompressedTexImage2D;
     GrGLCreateProgramProc fCreateProgram;
     GrGLCreateShaderProc fCreateShader;
     GrGLCullFaceProc fCullFace;
     GrGLDeleteBuffersProc fDeleteBuffers;
     GrGLDeleteProgramProc fDeleteProgram;
     GrGLDeleteQueriesProc fDeleteQueries;
     GrGLDeleteShaderProc fDeleteShader;
     GrGLDeleteTexturesProc fDeleteTextures;
     GrGLDepthMaskProc fDepthMask;
     GrGLDisableProc fDisable;
-    GrGLDisableClientStateProc fDisableClientState;
     GrGLDisableVertexAttribArrayProc fDisableVertexAttribArray;
     GrGLDrawArraysProc fDrawArrays;
     GrGLDrawBufferProc fDrawBuffer;
     GrGLDrawBuffersProc fDrawBuffers;
     GrGLDrawElementsProc fDrawElements;
     GrGLEnableProc fEnable;
-    GrGLEnableClientStateProc fEnableClientState;
     GrGLEnableVertexAttribArrayProc fEnableVertexAttribArray;
     GrGLEndQueryProc fEndQuery;
     GrGLFinishProc fFinish;
     GrGLFlushProc fFlush;
     GrGLFrontFaceProc fFrontFace;
     GrGLGenBuffersProc fGenBuffers;
     GrGLGenQueriesProc fGenQueries;
     GrGLGenTexturesProc fGenTextures;
@@ -365,37 +333,32 @@ struct GR_API GrGLInterface : public GrR
     GrGLGetProgramivProc fGetProgramiv;
     GrGLGetShaderInfoLogProc fGetShaderInfoLog;
     GrGLGetShaderivProc fGetShaderiv;
     GrGLGetStringProc fGetString;
     GrGLGetTexLevelParameterivProc fGetTexLevelParameteriv;
     GrGLGetUniformLocationProc fGetUniformLocation;
     GrGLLineWidthProc fLineWidth;
     GrGLLinkProgramProc fLinkProgram;
-    GrGLLoadMatrixfProc fLoadMatrixf;
-    GrGLMatrixModeProc fMatrixMode;
     GrGLPixelStoreiProc fPixelStorei;
-    GrGLPointSizeProc fPointSize;
     GrGLQueryCounterProc fQueryCounter;
     GrGLReadBufferProc fReadBuffer;
     GrGLReadPixelsProc fReadPixels;
     GrGLScissorProc fScissor;
-    GrGLShadeModelProc fShadeModel;
     GrGLShaderSourceProc fShaderSource;
     GrGLStencilFuncProc fStencilFunc;
     GrGLStencilFuncSeparateProc fStencilFuncSeparate;
     GrGLStencilMaskProc fStencilMask;
     GrGLStencilMaskSeparateProc fStencilMaskSeparate;
     GrGLStencilOpProc fStencilOp;
     GrGLStencilOpSeparateProc fStencilOpSeparate;
-    GrGLTexCoordPointerProc fTexCoordPointer;
-    GrGLTexEnviProc fTexEnvi;
     GrGLTexImage2DProc fTexImage2D;
     GrGLTexParameteriProc fTexParameteri;
     GrGLTexSubImage2DProc fTexSubImage2D;
+    GrGLTexStorage2DProc fTexStorage2D;
     GrGLUniform1fProc fUniform1f;
     GrGLUniform1iProc fUniform1i;
     GrGLUniform1fvProc fUniform1fv;
     GrGLUniform1ivProc fUniform1iv;
     GrGLUniform2fProc fUniform2f;
     GrGLUniform2iProc fUniform2i;
     GrGLUniform2fvProc  fUniform2fv;
     GrGLUniform2ivProc fUniform2iv;
@@ -408,17 +371,16 @@ struct GR_API GrGLInterface : public GrR
     GrGLUniform4fvProc fUniform4fv;
     GrGLUniform4ivProc fUniform4iv;
     GrGLUniformMatrix2fvProc fUniformMatrix2fv;
     GrGLUniformMatrix3fvProc fUniformMatrix3fv;
     GrGLUniformMatrix4fvProc fUniformMatrix4fv;
     GrGLUseProgramProc fUseProgram;
     GrGLVertexAttrib4fvProc fVertexAttrib4fv;
     GrGLVertexAttribPointerProc fVertexAttribPointer;
-    GrGLVertexPointerProc fVertexPointer;
     GrGLViewportProc fViewport;
 
     // FBO Extension Functions
     GrGLBindFramebufferProc fBindFramebuffer;
     GrGLBindRenderbufferProc fBindRenderbuffer;
     GrGLCheckFramebufferStatusProc fCheckFramebufferStatus;
     GrGLDeleteFramebuffersProc fDeleteFramebuffers;
     GrGLDeleteRenderbuffersProc fDeleteRenderbuffers;
@@ -446,14 +408,11 @@ struct GR_API GrGLInterface : public GrR
     GrGLBindFragDataLocationIndexedProc fBindFragDataLocationIndexed;
 
     // Per-GL func callback
 #if GR_GL_PER_GL_FUNC_CALLBACK
     GrGLInterfaceCallbackProc fCallback;
     GrGLInterfaceCallbackData fCallbackData;
 #endif
 
-private:
-    bool validateShaderFunctions() const;
-    bool validateFixedFunctions() const;
 };
 
 #endif
--- a/gfx/skia/include/gpu/GrPaint.h
+++ b/gfx/skia/include/gpu/GrPaint.h
@@ -28,42 +28,44 @@ public:
         kMaxMasks    = 1,
     };
 
     // All the paint fields are public except textures/samplers
     GrBlendCoeff                fSrcBlendCoeff;
     GrBlendCoeff                fDstBlendCoeff;
     bool                        fAntiAlias;
     bool                        fDither;
+    bool                        fColorMatrixEnabled;
 
     GrColor                     fColor;
 
     GrColor                     fColorFilterColor;
     SkXfermode::Mode            fColorFilterXfermode;
+    float                       fColorMatrix[20];
 
     void setTexture(int i, GrTexture* texture) {
         GrAssert((unsigned)i < kMaxTextures);
         GrSafeRef(texture);
         GrSafeUnref(fTextures[i]);
         fTextures[i] = texture;
     }
 
     GrTexture* getTexture(int i) const { 
         GrAssert((unsigned)i < kMaxTextures);
         return fTextures[i]; 
     }
 
-    GrSamplerState* getTextureSampler(int i) {
+    GrSamplerState* textureSampler(int i) {
         GrAssert((unsigned)i < kMaxTextures);
         return fTextureSamplers + i;
     }
 
-    const GrSamplerState* getTextureSampler(int i) const {
+    const GrSamplerState& getTextureSampler(int i) const {
         GrAssert((unsigned)i < kMaxTextures);
-        return fTextureSamplers + i;
+        return fTextureSamplers[i];
     }
 
     // The mask can be alpha-only or per channel. It is applied
     // after the colorfilter
     void setMask(int i, GrTexture* mask) {
         GrAssert((unsigned)i < kMaxMasks);
         GrSafeRef(mask);
         GrSafeUnref(fMaskTextures[i]);
@@ -72,24 +74,24 @@ public:
 
     GrTexture* getMask(int i) const { 
         GrAssert((unsigned)i < kMaxMasks);
         return fMaskTextures[i]; 
     }
 
     // mask's sampler matrix is always applied to the positions
     // (i.e. no explicit texture coordinates)
-    GrSamplerState* getMaskSampler(int i) {
+    GrSamplerState* maskSampler(int i) {
         GrAssert((unsigned)i < kMaxMasks);
         return fMaskSamplers + i;
     }
 
-    const GrSamplerState* getMaskSampler(int i) const {
+    const GrSamplerState& getMaskSampler(int i) const {
         GrAssert((unsigned)i < kMaxMasks);
-        return fMaskSamplers + i;
+        return fMaskSamplers[i];
     }
 
     // pre-concats sampler matrices for non-NULL textures and masks
     void preConcatActiveSamplerMatrices(const GrMatrix& matrix) {
         for (int i = 0; i < kMaxTextures; ++i) {
             fTextureSamplers[i].preConcatMatrix(matrix);
         }
         for (int i = 0; i < kMaxMasks; ++i) {
@@ -122,16 +124,18 @@ public:
         fDstBlendCoeff = paint.fDstBlendCoeff;
         fAntiAlias = paint.fAntiAlias;
         fDither = paint.fDither;
 
         fColor = paint.fColor;
 
         fColorFilterColor = paint.fColorFilterColor;
         fColorFilterXfermode = paint.fColorFilterXfermode;
+        memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
+        fColorMatrixEnabled = paint.fColorMatrixEnabled;
 
         for (int i = 0; i < kMaxTextures; ++i) {
             GrSafeUnref(fTextures[i]);
             fTextureSamplers[i] = paint.fTextureSamplers[i];
             fTextures[i] = paint.fTextures[i];
             GrSafeRef(fTextures[i]);
         }
         for (int i = 0; i < kMaxMasks; ++i) {
@@ -160,16 +164,18 @@ public:
         this->resetTextures();
         this->resetColorFilter();
         this->resetMasks();
     }
 
     void resetColorFilter() {
         fColorFilterXfermode = SkXfermode::kDst_Mode;
         fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
+        memset(fColorMatrix, 0, sizeof(fColorMatrix));
+        fColorMatrixEnabled = false;
     }
 
     bool hasTexture() const {
         return 0 != this->getActiveTextureStageMask();
     }
 
     bool hasMask() const {
         return 0 != this->getActiveMaskStageMask();
@@ -234,21 +240,21 @@ private:
 
     void resetColor() {
         fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
     }
 
     void resetTextures() {
         for (int i = 0; i < kMaxTextures; ++i) {
             this->setTexture(i, NULL);
-            fTextureSamplers[i].setClampNoFilter();
+            fTextureSamplers[i].reset();
         }
     }
 
     void resetMasks() {
         for (int i = 0; i < kMaxMasks; ++i) {
             this->setMask(i, NULL);
-            fMaskSamplers[i].setClampNoFilter();
+            fMaskSamplers[i].reset();
         }
     }
 };
 
 #endif
--- a/gfx/skia/include/gpu/GrRenderTarget.h
+++ b/gfx/skia/include/gpu/GrRenderTarget.h
@@ -39,30 +39,16 @@ public:
      */
     int width() const { return fWidth; }
     /**
      * @return the height of the rendertarget
      */
     int height() const { return fHeight; }
 
     /**
-     * Retrieves the allocated width. It may differ from width for
-     * NPOT or min-RT size reasons.
-     * @return allocated width in pixels
-     */
-    int allocatedWidth() const { return fAllocatedWidth; }
-
-    /**
-     * Retrieves the allocated height. It may differ from height for
-     * NPOT or min-RT size reasons.
-     * @return allocated height in pixels
-     */
-    int allocatedHeight() const { return fAllocatedHeight; }
-
-    /**
      * @return the pixel config. Can be kUnknown_GrPixelConfig
      * if client asked us to render to a target that has a pixel
      * config that isn't equivalent with one of our configs.
      */
     GrPixelConfig config() const { return fConfig; }
 
     /**
      * @return the texture associated with the rendertarget, may be NULL.
@@ -132,22 +118,39 @@ public:
     /**
      * Reads a rectangle of pixels from the render target.
      * @param left          left edge of the rectangle to read (inclusive)
      * @param top           top edge of the rectangle to read (inclusive)
      * @param width         width of rectangle to read in pixels.
      * @param height        height of rectangle to read in pixels.
      * @param config        the pixel config of the destination buffer
      * @param buffer        memory to read the rectangle into.
+     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
+     *                      means rows are tightly packed.
      *
      * @return true if the read succeeded, false if not. The read can fail
-     *              because of a unsupported pixel config.
+     *              because of an unsupported pixel config.
      */
     bool readPixels(int left, int top, int width, int height,
-                    GrPixelConfig config, void* buffer);
+                    GrPixelConfig config, void* buffer, size_t rowBytes);
+
+    /**
+     * Copy the src pixels [buffer, rowbytes, pixelconfig] into the render
+     * target at the specified rectangle.
+     * @param left          left edge of the rectangle to write (inclusive)
+     * @param top           top edge of the rectangle to write (inclusive)
+     * @param width         width of rectangle to write in pixels.
+     * @param height        height of rectangle to write in pixels.
+     * @param config        the pixel config of the source buffer
+     * @param buffer        memory to read the rectangle from.
+     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
+     *                      means rows are tightly packed.
+     */
+    void writePixels(int left, int top, int width, int height,
+                     GrPixelConfig config, const void* buffer, size_t rowBytes);
 
     // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
     // 0 in GL), or be unresolvable because the client didn't give us the 
     // resolve destination.
     enum ResolveType {
         kCanResolve_ResolveType,
         kAutoResolves_ResolveType,
         kCantResolve_ResolveType,
@@ -160,27 +163,23 @@ public:
     GrStencilBuffer* getStencilBuffer() const { return fStencilBuffer; }
     void setStencilBuffer(GrStencilBuffer* stencilBuffer);
 
 protected:
     GrRenderTarget(GrGpu* gpu,
                    GrTexture* texture,
                    int width,
                    int height,
-                   int allocatedWidth,
-                   int allocatedHeight,
                    GrPixelConfig config,
                    int sampleCnt)
         : INHERITED(gpu)
         , fStencilBuffer(NULL)
         , fTexture(texture)
         , fWidth(width)
         , fHeight(height)
-        , fAllocatedWidth(allocatedWidth)
-        , fAllocatedHeight(allocatedHeight)
         , fConfig(config)
         , fSampleCnt(sampleCnt) {
         fResolveRect.setLargestInverted();
     }
 
     friend class GrTexture;
     // When a texture unrefs an owned rendertarget this func
     // removes the back pointer. This could be done called from 
@@ -192,18 +191,16 @@ protected:
         fTexture = NULL;
     }
 
 private:
     GrStencilBuffer*  fStencilBuffer;
     GrTexture*        fTexture; // not ref'ed
     int               fWidth;
     int               fHeight;
-    int               fAllocatedWidth;
-    int               fAllocatedHeight;
     GrPixelConfig     fConfig;
     int               fSampleCnt;
     GrIRect           fResolveRect;
 
     typedef GrResource INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/gpu/GrResource.h
+++ b/gfx/skia/include/gpu/GrResource.h
@@ -8,16 +8,17 @@
 
 
 #ifndef GrResource_DEFINED
 #define GrResource_DEFINED
 
 #include "GrRefCnt.h"
 
 class GrGpu;
+class GrContext;
 
 class GrResource : public GrRefCnt {
 public:
     explicit GrResource(GrGpu* gpu);
 
     virtual ~GrResource() {
         // subclass should have released this.
         GrAssert(!isValid());
@@ -50,16 +51,25 @@ public:
     /**
      * Retrieves the size of the object in GPU memory. This is approximate since
      * we aren't aware of additional padding or copies made by the driver.
      *
      * @return the size of the buffer in bytes
      */
      virtual size_t sizeInBytes() const = 0;
 
+     /**
+      * Retrieves the context that owns the resource. Note that it is possible
+      * for this to return NULL. When resources have been release()ed or
+      * abandon()ed they no longer have an unknowning context. Destroying a
+      * GrContext automatically releases all its resources.
+      */
+     const GrContext* getContext() const;
+     GrContext* getContext();
+
 protected:
 
     virtual void onRelease() = 0;
     virtual void onAbandon() = 0;
 
     GrGpu* getGpu() const { return fGpu; }
 
 private:
--- a/gfx/skia/include/gpu/GrSamplerState.h
+++ b/gfx/skia/include/gpu/GrSamplerState.h
@@ -33,17 +33,19 @@ public:
          * pass. (rasterizing such that texture samples fall exactly halfway
          * between texels in x and y spaced 4 texels apart.) Only supported
          * on shader backends.
          */
         k4x4Downsample_Filter,
         /**
          * Apply a separable convolution kernel.
          */
-        kConvolution_Filter
+        kConvolution_Filter,
+
+        kDefault_Filter = kNearest_Filter
     };
 
     /**
      * The intepretation of the texture matrix depends on the sample mode. The
      * texture matrix is applied both when the texture coordinates are explicit
      * and  when vertex positions are used as texture  coordinates. In the latter
      * case the texture matrix is applied to the pre-view-matrix position 
      * values.
@@ -63,125 +65,85 @@ public:
      *  The angle from the origin of texture coordinates in post-matrix space
      *  determines the gradient value.
      */
     enum SampleMode {
         kNormal_SampleMode,     //!< sample color directly
         kRadial_SampleMode,     //!< treat as radial gradient
         kRadial2_SampleMode,    //!< treat as 2-point radial gradient
         kSweep_SampleMode,      //!< treat as sweep gradient
+
+        kDefault_SampleMode = kNormal_SampleMode
     };
 
     /**
      * Describes how a texture is sampled when coordinates are outside the
      * texture border
      */
     enum WrapMode {
         kClamp_WrapMode,
         kRepeat_WrapMode,
-        kMirror_WrapMode
+        kMirror_WrapMode,
+
+        kDefault_WrapMode = kClamp_WrapMode
     };
 
     /**
      * Default sampler state is set to clamp, use normal sampling mode, be
      * unfiltered, and use identity matrix.
      */
     GrSamplerState()
     : fRadial2CenterX1()
     , fRadial2Radius0()
     , fRadial2PosRoot() {
-        this->setClampNoFilter();
-    }
-
-    explicit GrSamplerState(Filter filter)
-    : fRadial2CenterX1()
-    , fRadial2Radius0()
-    , fRadial2PosRoot() {
-        fWrapX = kClamp_WrapMode;
-        fWrapY = kClamp_WrapMode;
-        fSampleMode = kNormal_SampleMode;
-        fFilter = filter;
-        fMatrix.setIdentity();
-        fTextureDomain.setEmpty();
-    }
-
-    GrSamplerState(WrapMode wx, WrapMode wy, Filter filter)
-    : fRadial2CenterX1()
-    , fRadial2Radius0()
-    , fRadial2PosRoot() {
-        fWrapX = wx;
-        fWrapY = wy;
-        fSampleMode = kNormal_SampleMode;
-        fFilter = filter;
-        fMatrix.setIdentity();
-        fTextureDomain.setEmpty();
-    }
-
-    GrSamplerState(WrapMode wx, WrapMode wy, 
-                   const GrMatrix& matrix, Filter filter)
-    : fRadial2CenterX1()
-    , fRadial2Radius0()
-    , fRadial2PosRoot() {
-        fWrapX = wx;
-        fWrapY = wy;
-        fSampleMode = kNormal_SampleMode;
-        fFilter = filter;
-        fMatrix = matrix;
-        fTextureDomain.setEmpty();
-    }
-
-    GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, 
-                   const GrMatrix& matrix, Filter filter)
-    : fRadial2CenterX1()
-    , fRadial2Radius0()
-    , fRadial2PosRoot() {
-        fWrapX = wx;
-        fWrapY = wy;
-        fSampleMode = sample;
-        fMatrix = matrix;
-        fFilter = filter;
-        fTextureDomain.setEmpty();
+        this->reset();
     }
 
     WrapMode getWrapX() const { return fWrapX; }
     WrapMode getWrapY() const { return fWrapY; }
     SampleMode getSampleMode() const { return fSampleMode; }
     const GrMatrix& getMatrix() const { return fMatrix; }
     const GrRect& getTextureDomain() const { return fTextureDomain; }
     bool hasTextureDomain() const {return SkIntToScalar(0) != fTextureDomain.right();}
     Filter getFilter() const { return fFilter; }
     int getKernelWidth() const { return fKernelWidth; }
     const float* getKernel() const { return fKernel; }
     const float* getImageIncrement() const { return fImageIncrement; }
+    bool swapsRAndB() const { return fSwapRAndB; }
 
     bool isGradient() const {
         return  kRadial_SampleMode == fSampleMode ||
                 kRadial2_SampleMode == fSampleMode ||
                 kSweep_SampleMode == fSampleMode;
     }
 
     void setWrapX(WrapMode mode) { fWrapX = mode; }
     void setWrapY(WrapMode mode) { fWrapY = mode; }
     void setSampleMode(SampleMode mode) { fSampleMode = mode; }
     
     /**
-     * Sets the sampler's matrix. See SampleMode for explanation of
+     * Access the sampler's matrix. See SampleMode for explanation of
      * relationship between the matrix and sample mode.
-     * @param matrix the matrix to set
      */
-    void setMatrix(const GrMatrix& matrix) { fMatrix = matrix; }
-    
+    GrMatrix* matrix() { return &fMatrix; }
+
     /**
      * Sets the sampler's texture coordinate domain to a 
      * custom rectangle, rather than the default (0,1).
      * This option is currently only supported with kClamp_WrapMode
      */
     void setTextureDomain(const GrRect& textureDomain) { fTextureDomain = textureDomain; }
 
     /**
+     * Swaps the R and B components when reading from the texture. Has no effect
+     * if the texture is alpha only.
+     */
+    void setRAndBSwap(bool swap) { fSwapRAndB = swap; }
+
+    /**
      *  Multiplies the current sampler matrix  a matrix
      *
      *  After this call M' = M*m where M is the old matrix, m is the parameter
      *  to this function, and M' is the new matrix. (We consider points to
      *  be column vectors so tex cood vector t is transformed by matrix X as 
      *  t' = X*t.)
      *
      *  @param matrix   the matrix used to modify the matrix.
@@ -189,28 +151,41 @@ public:
     void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); }
 
     /**
      * Sets filtering type.
      * @param filter    type of filtering to apply
      */
     void setFilter(Filter filter) { fFilter = filter; }
 
-    void setClampNoFilter() {
-        fWrapX = kClamp_WrapMode;
-        fWrapY = kClamp_WrapMode;
-        fSampleMode = kNormal_SampleMode;
-        fFilter = kNearest_Filter;
-        fMatrix.setIdentity();
+    void reset(WrapMode wrapXAndY,
+               Filter filter,
+               const GrMatrix& matrix) {
+        fWrapX = wrapXAndY;
+        fWrapY = wrapXAndY;
+        fSampleMode = kDefault_SampleMode;
+        fFilter = filter;
+        fMatrix = matrix;
         fTextureDomain.setEmpty();
+        fSwapRAndB = false;
+    }
+    void reset(WrapMode wrapXAndY,
+               Filter filter) {
+        this->reset(wrapXAndY, filter, GrMatrix::I());
+    }
+    void reset(const GrMatrix& matrix) {
+        this->reset(kDefault_WrapMode, kDefault_Filter, matrix);
+    }
+    void reset() {
+        this->reset(kDefault_WrapMode, kDefault_Filter, GrMatrix::I());
     }
 
     GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
     GrScalar getRadial2Radius0() const { return fRadial2Radius0; }
-    bool     isRadial2PosRoot() const { return fRadial2PosRoot; }
+    bool     isRadial2PosRoot() const { return SkToBool(fRadial2PosRoot); }
     // do the radial gradient params lead to a linear (rather than quadratic)
     // equation.
     bool radial2IsDegenerate() const { return GR_Scalar1 == fRadial2CenterX1; }
 
     /**
      * Sets the parameters for kRadial2_SampleMode. The texture
      * matrix must be set so that the first point is at (0,0) and the second
      * point lies on the x-axis. The second radius minus the first is 1 unit.
@@ -231,35 +206,30 @@ public:
         }
         if (NULL != imageIncrement) {
             memcpy(fImageIncrement, imageIncrement, sizeof(fImageIncrement));
         } else {
             memset(fImageIncrement, 0, sizeof(fImageIncrement));
         }
     }
 
-    static const GrSamplerState& ClampNoFilter() {
-        return gClampNoFilter;
-    }
-
 private:
-    WrapMode    fWrapX;
-    WrapMode    fWrapY;
-    SampleMode  fSampleMode;
-    Filter      fFilter;
+    WrapMode    fWrapX : 8;
+    WrapMode    fWrapY : 8;
+    SampleMode  fSampleMode : 8;
+    Filter      fFilter : 8;
     GrMatrix    fMatrix;
+    bool        fSwapRAndB;
     GrRect      fTextureDomain;
 
     // these are undefined unless fSampleMode == kRadial2_SampleMode
     GrScalar    fRadial2CenterX1;
     GrScalar    fRadial2Radius0;
-    bool        fRadial2PosRoot;
+    SkBool8     fRadial2PosRoot;
 
     // These are undefined unless fFilter == kConvolution_Filter
-    int         fKernelWidth;
-    float       fKernel[MAX_KERNEL_WIDTH];
+    uint8_t     fKernelWidth;
     float       fImageIncrement[2];
-
-    static const GrSamplerState gClampNoFilter;
+    float       fKernel[MAX_KERNEL_WIDTH];
 };
 
 #endif
 
--- a/gfx/skia/include/gpu/GrTexture.h
+++ b/gfx/skia/include/gpu/GrTexture.h
@@ -28,30 +28,16 @@ public:
     /**
      * Retrieves the height of the texture.
      *
      * @return the height in texels
      */
     int height() const { return fHeight; }
 
     /**
-     * Retrieves the allocated width. It may differ from width for
-     * NPOT or min-RT size reasons.
-     * @return allocated width in texels
-     */
-    int allocatedWidth() const { return fAllocatedWidth; }
-
-    /**
-     * Retrieves the allocated height. It may differ from height for
-     * NPOT or min-RT size reasons.
-     * @return allocated height in texels
-     */
-    int allocatedHeight() const { return fAllocatedHeight; }
-
-    /**
      * Convert from texels to normalized texture coords for POT textures
      * only.
      */
     GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth));
                                                return x >> fShiftFixedX; }
     GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight));
                                                return y >> fShiftFixedY; }
 
@@ -59,54 +45,51 @@ public:
      * Retrieves the pixel config specified when the texture was created.
      */
     GrPixelConfig config() const { return fConfig; }
 
     /**
      *  Approximate number of bytes used by the texture
      */
     virtual size_t sizeInBytes() const {
-        return (size_t) fAllocatedWidth *
-                        fAllocatedHeight *
-                        GrBytesPerPixel(fConfig);
+        return (size_t) fWidth * fHeight * GrBytesPerPixel(fConfig);
     }
 
     /**
-     * Updates a subrectangle of texels in the texture.
-     *
-     * @param x         left edge of rectangle to update
-     * @param y         top edge of rectangle to update
-     * @param width     width of rectangle to update
-     * @param height    height of rectangle to update
-     * @param srcData   width*height texels of data in same format that was
-     *                  used at texture creation.
-     * @param rowBytes  number of bytes per row in srcData, 0 means rows are 
-     *                  packed
-     */
-    virtual void uploadTextureData(int x,
-                                   int y,
-                                   int width,
-                                   int height,
-                                   const void* srcData,
-                                   size_t rowBytes) = 0;
-
-    /**
-     * Reads a rectangle of pixels from the texture.
+     * Read a rectangle of pixels from the texture.
      * @param left          left edge of the rectangle to read (inclusive)
      * @param top           top edge of the rectangle to read (inclusive)
      * @param width         width of rectangle to read in pixels.
      * @param height        height of rectangle to read in pixels.
      * @param config        the pixel config of the destination buffer
      * @param buffer        memory to read the rectangle into.
+     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
+     *                      means rows are tightly packed.
      *
      * @return true if the read succeeded, false if not. The read can fail
      *              because of a unsupported pixel config.
      */
     bool readPixels(int left, int top, int width, int height,
-                    GrPixelConfig config, void* buffer);
+                    GrPixelConfig config, void* buffer,
+                    size_t rowBytes);
+
+    /**
+     * Writes a rectangle of pixels to the texture.
+     * @param left          left edge of the rectangle to write (inclusive)
+     * @param top           top edge of the rectangle to write (inclusive)
+     * @param width         width of rectangle to write in pixels.
+     * @param height        height of rectangle to write in pixels.
+     * @param config        the pixel config of the source buffer
+     * @param buffer        memory to read pixels from
+     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
+     *                      means rows are tightly packed.
+     */
+    void writePixels(int left, int top, int width, int height,
+                     GrPixelConfig config, const void* buffer,
+                     size_t rowBytes);
 
     /**
      * Retrieves the render target underlying this texture that can be passed to
      * GrGpu::setRenderTarget().
      *
      * @return    handle to render target or NULL if the texture is not a
      *            render target
      */
@@ -136,43 +119,37 @@ public:
 protected:
     GrRenderTarget* fRenderTarget; // texture refs its rt representation
                                    // base class cons sets to NULL
                                    // subclass cons can create and set
 
     GrTexture(GrGpu* gpu,
               int width,
               int height,
-              int allocatedWidth,
-              int allocatedHeight,
               GrPixelConfig config)
     : INHERITED(gpu)
     , fRenderTarget(NULL)
     , fWidth(width)
     , fHeight(height)
-    , fAllocatedWidth(allocatedWidth)
-    , fAllocatedHeight(allocatedHeight)
     , fConfig(config) {
         // only make sense if alloc size is pow2
         fShiftFixedX = 31 - Gr_clz(fWidth);
         fShiftFixedY = 31 - Gr_clz(fHeight);
     }
 
     // GrResource overrides
     virtual void onRelease() {
         this->releaseRenderTarget();
     }
 
     virtual void onAbandon();
 
 private:
     int fWidth;
     int fHeight;
-    int fAllocatedWidth;
-    int fAllocatedHeight;
 
     // these two shift a fixed-point value into normalized coordinates
     // for this texture if the texture is power of two sized.
     int      fShiftFixedX;
     int      fShiftFixedY;
 
     GrPixelConfig fConfig;
 
--- a/gfx/skia/include/gpu/GrTypes.h
+++ b/gfx/skia/include/gpu/GrTypes.h
@@ -50,17 +50,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
 /**
  *  Macro to round n up to the next multiple of 4, or return it unchanged if
  *  n is already a multiple of 4
  */
 #define GrALIGN4(n)     SkAlign4(n)
-#define GrIsALIGN4(n)   (((n) & 3) == 0)
+#define GrIsALIGN4(n)   SkIsAlign4(n)
 
 template <typename T> const T& GrMin(const T& a, const T& b) {
 	return (a < b) ? a : b;
 }
 
 template <typename T> const T& GrMax(const T& a, const T& b) {
 	return (b < a) ? a : b;
 }
@@ -263,47 +263,161 @@ static inline int GrMaskFormatBytesPerPi
     // kA8   (0) -> 1
     // kA565 (1) -> 2
     // kA888 (2) -> 4
     return 1 << (int)format;
 }
 
 /**
  * Pixel configurations.
+ *
+ * Unpremultiplied configs are intended for converting pixel data in and out
+ * from skia. Surfaces with these configs have limited support. As an input
+ * (GrPaint texture) the corresponding GrSamplerState must have its filter set
+ * to kNearest_Filter. Otherwise, the draw will fail. When the render target
+ * has an unpremultiplied config draws must use blend coeffs 1,0 (AKA src-mode).
+ * Other coeffs will cause the draw to fail.
  */
 enum GrPixelConfig {
     kUnknown_GrPixelConfig,
     kAlpha_8_GrPixelConfig,
     kIndex_8_GrPixelConfig,
     kRGB_565_GrPixelConfig,
-    kRGBA_4444_GrPixelConfig, //!< premultiplied
-    kRGBA_8888_GrPixelConfig, //!< premultiplied
-    kRGBX_8888_GrPixelConfig, //!< treat the alpha channel as opaque
+    /**
+     * Premultiplied
+     */
+    kRGBA_4444_GrPixelConfig,
+    /**
+     * Premultiplied. Byte order is r,g,b,a
+     */
+    kRGBA_8888_PM_GrPixelConfig,
+    /**
+     * Unpremultiplied. Byte order is r,g,b,a
+     */
+    kRGBA_8888_UPM_GrPixelConfig,
+    /**
+     * Premultiplied. Byte order is b,g,r,a
+     */
+    kBGRA_8888_PM_GrPixelConfig,
+    /**
+     * Unpremultiplied. Byte order is b,g,r,a
+     */
+    kBGRA_8888_UPM_GrPixelConfig,
 };
 
+// Aliases for pixel configs that match skia's byte order
+#ifndef SK_CPU_LENDIAN
+    #error "Skia gpu currently assumes little endian"
+#endif
+#if 24 == SK_A32_SHIFT && 16 == SK_R32_SHIFT && \
+     8 == SK_G32_SHIFT &&  0 == SK_B32_SHIFT
+    static const GrPixelConfig kSkia8888_PM_GrPixelConfig = kBGRA_8888_PM_GrPixelConfig;
+    static const GrPixelConfig kSkia8888_UPM_GrPixelConfig = kBGRA_8888_UPM_GrPixelConfig;
+#elif 24 == SK_A32_SHIFT && 16 == SK_B32_SHIFT && \
+       8 == SK_G32_SHIFT &&  0 == SK_R32_SHIFT
+    static const GrPixelConfig kSkia8888_PM_GrPixelConfig = kRGBA_8888_PM_GrPixelConfig;
+    static const GrPixelConfig kSkia8888_UPM_GrPixelConfig = kRGBA_8888_UPM_GrPixelConfig;
+#else
+    #error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format."
+#endif
+
+// WebKit is relying on this old name for the native skia PM config. This will
+// be deleted ASAP because it is so similar to kRGBA_PM_8888_GrPixelConfig but
+// has a different interpretation when skia is compiled BGRA.
+static const GrPixelConfig kRGBA_8888_GrPixelConfig = kSkia8888_PM_GrPixelConfig;
+
+// Returns true if the pixel config has 8bit r,g,b,a components in that byte
+// order
+static inline bool GrPixelConfigIsRGBA8888(GrPixelConfig config) {
+    switch (config) {
+        case kRGBA_8888_PM_GrPixelConfig:
+        case kRGBA_8888_UPM_GrPixelConfig:
+            return true;
+        default:
+            return false;
+    }
+}
+
+// Returns true if the pixel config has 8bit b,g,r,a components in that byte
+// order
+static inline bool GrPixelConfigIsBGRA8888(GrPixelConfig config) {
+    switch (config) {
+        case kBGRA_8888_PM_GrPixelConfig:
+        case kBGRA_8888_UPM_GrPixelConfig:
+            return true;
+        default:
+            return false;
+    }
+}
+
+// Returns true if the pixel config is 32 bits per pixel
+static inline bool GrPixelConfigIs32Bit(GrPixelConfig config) {
+    switch (config) {
+        case kRGBA_8888_PM_GrPixelConfig:
+        case kRGBA_8888_UPM_GrPixelConfig:
+        case kBGRA_8888_PM_GrPixelConfig:
+        case kBGRA_8888_UPM_GrPixelConfig:
+            return true;
+        default:
+            return false;
+    }
+}
+
+// Takes a config and returns the equivalent config with the R and B order
+// swapped if such a config exists. Otherwise, kUnknown_GrPixelConfig
+static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
+    switch (config) {
+        case kBGRA_8888_PM_GrPixelConfig:
+            return kRGBA_8888_PM_GrPixelConfig;
+        case kBGRA_8888_UPM_GrPixelConfig:
+            return kRGBA_8888_UPM_GrPixelConfig;
+        case kRGBA_8888_PM_GrPixelConfig:
+            return kBGRA_8888_PM_GrPixelConfig;
+        case kRGBA_8888_UPM_GrPixelConfig:
+            return kBGRA_8888_UPM_GrPixelConfig;
+        default:
+            return kUnknown_GrPixelConfig;
+    }
+}
+
 static inline size_t GrBytesPerPixel(GrPixelConfig config) {
     switch (config) {
         case kAlpha_8_GrPixelConfig:
         case kIndex_8_GrPixelConfig:
             return 1;
         case kRGB_565_GrPixelConfig:
         case kRGBA_4444_GrPixelConfig:
             return 2;
-        case kRGBA_8888_GrPixelConfig:
-        case kRGBX_8888_GrPixelConfig:
+        case kRGBA_8888_PM_GrPixelConfig:
+        case kRGBA_8888_UPM_GrPixelConfig:
+        case kBGRA_8888_PM_GrPixelConfig:
+        case kBGRA_8888_UPM_GrPixelConfig:
             return 4;
         default:
             return 0;
     }
 }
 
 static inline bool GrPixelConfigIsOpaque(GrPixelConfig config) {
     switch (config) {
         case kRGB_565_GrPixelConfig:
-        case kRGBX_8888_GrPixelConfig:
+            return true;
+        default:
+            return false;
+    }
+}
+
+/**
+ * Premultiplied alpha is the usual for skia. Therefore, configs that are
+ * ambiguous (alpha-only or color-only) are considered premultiplied.
+ */
+static inline bool GrPixelConfigIsUnpremultiplied(GrPixelConfig config) {
+    switch (config) {
+        case kRGBA_8888_UPM_GrPixelConfig:
+        case kBGRA_8888_UPM_GrPixelConfig:
             return true;
         default:
             return false;
     }
 }
 
 static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) {
     switch (config) {
@@ -371,17 +485,17 @@ struct GrTextureDesc {
      */
     GrAALevels             fAALevel;
     int                    fWidth;  //!< Width of the texture
     int                    fHeight; //!< Height of the texture
     /**
      * Format of source data of the texture. Not guaraunteed to be the same as
      * internal format used by 3D API.
      */
-    GrPixelConfig          fFormat; 
+    GrPixelConfig          fConfig;
 };
 
 /**
  * Set Operations used to construct clips.
  */
 enum GrSetOp {
     kReplace_SetOp,
     kIntersect_SetOp,
@@ -494,16 +608,109 @@ enum GrConvexHint {
                                               //   either all wind cw or all
                                               //   wind ccw.
     kConcave_ConvexHint                       //<! Path is known to be
                                               //   concave
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
+// opaque type for 3D API object handles
+typedef intptr_t GrPlatform3DObject;
+
+/**
+ * Gr can wrap an existing texture created by the client with a GrTexture
+ * object. The client is responsible for ensuring that the texture lives at
+ * least as long as the GrTexture object wrapping it. We require the client to 
+ * explicitly provide information about the texture, such as width, height, 
+ * and pixel config, rather than querying the 3D APIfor these values. We expect
+ * these to be immutable even if the 3D API doesn't require this (OpenGL).
+ *
+ * Textures that are also render targets are supported as well. Gr will manage
+ * any ancillary 3D API (stencil buffer, FBO id, etc) objects necessary for
+ * Gr to draw into the render target. To access the render target object
+ * call GrTexture::asRenderTarget().
+ *
+ * If in addition to the render target flag, the caller also specifies a sample
+ * count Gr will create an MSAA buffer that resolves into the texture. Gr auto-
+ * resolves when it reads from the texture. The client can explictly resolve
+ * using the GrRenderTarget interface.
+ */
+
+enum GrPlatformTextureFlags {
+    /**
+     * No flags enabled
+     */
+    kNone_GrPlatformTextureFlag              = 0x0,
+    /**
+     * Indicates that the texture is also a render target, and thus should have
+     * a GrRenderTarget object.
+     *
+     * D3D (future): client must have created the texture with flags that allow
+     * it to be used as a render target.
+     */
+    kRenderTarget_GrPlatformTextureFlag      = 0x1,
+};
+GR_MAKE_BITFIELD_OPS(GrPlatformTextureFlags)
+
+struct GrPlatformTextureDesc {
+    GrPlatformTextureDesc() { memset(this, 0, sizeof(*this)); }
+    GrPlatformTextureFlags          fFlags;
+    int                             fWidth;         //<! width in pixels
+    int                             fHeight;        //<! height in pixels
+    GrPixelConfig                   fConfig;        //<! color format
+    /**
+     * If the render target flag is set and sample count is greater than 0
+     * then Gr will create an MSAA buffer that resolves to the texture.
+     */
+    int                             fSampleCnt;
+    /**
+     * Handle to the 3D API object.
+     * OpenGL: Texture ID.
+     */
+    GrPlatform3DObject              fTextureHandle;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Gr can wrap an existing render target created by the client in the 3D API
+ * with a GrRenderTarget object. The client is responsible for ensuring that the
+ * underlying 3D API object lives at least as long as the GrRenderTarget object
+ * wrapping it. We require the client to explicitly provide information about 
+ * the target, such as width, height, and pixel config rather than querying the
+ * 3D API for these values. We expect these properties to be immutable even if
+ * the 3D API doesn't require this (OpenGL).
+ */
+
+struct GrPlatformRenderTargetDesc {
+    GrPlatformRenderTargetDesc() { memset(this, 0, sizeof(*this)); }
+    int                             fWidth;         //<! width in pixels
+    int                             fHeight;        //<! height in pixels
+    GrPixelConfig                   fConfig;        //<! color format
+    /**
+     * The number of samples per pixel. Gr uses this to influence decisions
+     * about applying other forms of antialiasing.
+     */
+    int                             fSampleCnt;
+    /**
+     * Number of bits of stencil per-pixel.
+     */
+    int                             fStencilBits;
+    /**
+     * Handle to the 3D API object.
+     * OpenGL: FBO ID
+     */
+    GrPlatform3DObject              fRenderTargetHandle;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// DEPRECATED. createPlatformSurface is replaced by createPlatformTexture
+// and createPlatformRenderTarget. These enums and structs will be removed.
+
 enum GrPlatformSurfaceType {
     /**
      * Specifies that the object being created is a render target.
      */
     kRenderTarget_GrPlatformSurfaceType,
     /**
      * Specifies that the object being created is a texture.
      */
@@ -527,22 +734,16 @@ enum GrPlatformRenderTargetFlags {
      * and insert appropriate flushes and resolves betweeen data hazards.
      * GrRenderTarget has a flagForResolve()
      */
     kGrCanResolve_GrPlatformRenderTargetFlagBit     = 0x2,
 };
 
 GR_MAKE_BITFIELD_OPS(GrPlatformRenderTargetFlags)
 
-// opaque type for 3D API object handles
-typedef intptr_t GrPlatform3DObject;
-
-/**
- * Description of platform surface to create. See below for GL example.
- */
 struct GrPlatformSurfaceDesc {
     GrPlatformSurfaceType           fSurfaceType;   // type of surface to create
     /**
      * Flags for kRenderTarget and kTextureRenderTarget surface types
      */
     GrPlatformRenderTargetFlags     fRenderTargetFlags;
 
     int                             fWidth;         // width in pixels
@@ -613,17 +814,17 @@ struct GrPlatformSurfaceDesc {
  * glBindFramebuffer(GL_FRAMEBUFFER, readFBOID);
  * glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureID, 0);
  *
  * GrPlatformSurfaceDesc renderTargetTextureDesc;
  * renderTargetTextureDesc.fSurfaceType       = kTextureRenderTarget_GrPlatformSurfaceType;
  * renderTargetTextureDesc.fRenderTargetFlags = kGrCanResolve_GrPlatformRenderTargetFlagBit;
  * renderTargetTextureDesc.fWidth = W;
  * renderTargetTextureDesc.fHeight = H;
- * renderTargetTextureDesc.fConfig = kRGBA_8888_GrPixelConfig
+ * renderTargetTextureDesc.fConfig = kSkia8888_PM_GrPixelConfig
  * renderTargetTextureDesc.fStencilBits = 8;
  * renderTargetTextureDesc.fSampleCnt = S;
  * renderTargetTextureDesc.fPlatformTexture = textureID;
  * renderTargetTextureDesc.fPlatformRenderTarget = drawFBOID;
  * renderTargetTextureDesc.fPlatformResolveDestination = readFBOID;
  *
  * GrTexture* texture = static_cast<GrTexture*>(grContext->createPlatrformSurface(renderTargetTextureDesc));
  */
--- a/gfx/skia/include/gpu/GrUserConfig.h
+++ b/gfx/skia/include/gpu/GrUserConfig.h
@@ -17,37 +17,22 @@
 #if 0
     #undef GR_RELEASE
     #undef GR_DEBUG
     #define GR_RELEASE  0
     #define GR_DEBUG    1
 #endif
 
 /*
- *  The default 32bit pixel config for texture upload is GL_RGBA on all
- *  platforms except on Windows where it is GL_BGRA. If your bitmaps map to a
- *  different GL enum, specify that with this define. For portability use
- *  GR_BGRA rather than GL_BGRA for platforms where this format is an
- *  extension.
- */
-//#define GR_GL_32BPP_COLOR_FORMAT  GL_RGBA
-
-/*
  *  To diagnose texture cache performance, define this to 1 if you want to see
  *  a log statement everytime we upload an image to create a texture.
  */
 //#define GR_DUMP_TEXTURE_UPLOAD    1
 
 /*
- * To log all GL calls define this. Can be turned on and off at runtime by
- * gPrintGL global variable.
- */
-//#define GR_GL_LOG_CALLS 1
-
-/*
  * When drawing rects this causes Ganesh to use a vertex buffer containing
  * a unit square that is positioned by a matrix. Enable on systems where
  * emitting per-rect-draw verts is more expensive than constant/matrix
  * updates. Defaults to 0.
  */
 //#define GR_STATIC_RECT_VB 1
 
 /*
@@ -59,21 +44,16 @@
 /*
  * This gives a threshold in bytes of when to lock a GrGeometryBuffer vs using
  * updateData. (Note the depending on the underlying 3D API the update functions
  * may always be implemented using a lock)
  */
 //#define GR_GEOM_BUFFER_LOCK_THRESHOLD (1<<15)
 
 ///////////////////////////////////////////////////////////////////////////////
-/*
- *  temporary flags (may go away soon)
- */
-
-///////////////////////////////////////////////////////////////////////////////
 // Decide Ganesh types
 
 #define GR_SCALAR_IS_FIXED          0
 #define GR_SCALAR_IS_FLOAT          1
 
 #define GR_TEXT_SCALAR_IS_USHORT    0
 #define GR_TEXT_SCALAR_IS_FIXED     0
 #define GR_TEXT_SCALAR_IS_FLOAT     1
--- a/gfx/skia/include/gpu/SkGpuDevice.h
+++ b/gfx/skia/include/gpu/SkGpuDevice.h
@@ -54,97 +54,107 @@ public:
 
     GrContext* context() const { return fContext; }
 
     /**
      *  Override from SkGpuDevice, so we can set our FBO to be the render target
      *  The canvas parameter must be a SkGpuCanvas
      */
     virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
-                           const SkClipStack& clipStack);
+                           const SkClipStack& clipStack) SK_OVERRIDE;
 
-    virtual SkGpuRenderTarget* accessRenderTarget() { 
-        return (SkGpuRenderTarget*)fRenderTarget; 
-    }
+    virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE;
 
     // overrides from SkDevice
 
-    virtual void clear(SkColor color);
-    virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
-    virtual void writePixels(const SkBitmap& bitmap, int x, int y);
+    virtual void clear(SkColor color) SK_OVERRIDE;
+    virtual void writePixels(const SkBitmap& bitmap, int x, int y,
+                             SkCanvas::Config8888 config8888) SK_OVERRIDE;
 
     virtual void setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
-                               const SkClipStack&);
+                               const SkClipStack&) SK_OVERRIDE;
 
-    virtual void drawPaint(const SkDraw&, const SkPaint& paint);
+    virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
     virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
-                            const SkPoint[], const SkPaint& paint);
+                            const SkPoint[], const SkPaint& paint) SK_OVERRIDE;
     virtual void drawRect(const SkDraw&, const SkRect& r,
-                          const SkPaint& paint);
+                          const SkPaint& paint) SK_OVERRIDE;
     virtual void drawPath(const SkDraw&, const SkPath& path,
                           const SkPaint& paint, const SkMatrix* prePathMatrix,
-                          bool pathIsMutable);
+                          bool pathIsMutable) SK_OVERRIDE;
     virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
                             const SkIRect* srcRectOrNull,
-                            const SkMatrix& matrix, const SkPaint& paint);
+                            const SkMatrix&, const SkPaint&) SK_OVERRIDE;
     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
                             int x, int y, const SkPaint& paint);
     virtual void drawText(const SkDraw&, const void* text, size_t len,
-                          SkScalar x, SkScalar y, const SkPaint& paint);
+                          SkScalar x, SkScalar y, const SkPaint&) SK_OVERRIDE;
     virtual void drawPosText(const SkDraw&, const void* text, size_t len,
                              const SkScalar pos[], SkScalar constY,
-                             int scalarsPerPos, const SkPaint& paint);
+                             int scalarsPerPos, const SkPaint&) SK_OVERRIDE;
     virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
                                 const SkPath& path, const SkMatrix* matrix,
-                                const SkPaint& paint);
+                                const SkPaint&) SK_OVERRIDE;
     virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
                               const SkPoint verts[], const SkPoint texs[],
                               const SkColor colors[], SkXfermode* xmode,
                               const uint16_t indices[], int indexCount,
-                              const SkPaint& paint);
+                              const SkPaint&) SK_OVERRIDE;
     virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
-                            const SkPaint&);
-    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
+                            const SkPaint&) SK_OVERRIDE;
+    virtual bool filterTextFlags(const SkPaint&, TextFlags*) SK_OVERRIDE;
 
-    virtual void flush() { fContext->flush(false); }
+    virtual void flush(); 
 
     /**
      * Make's this device's rendertarget current in the underlying 3D API.
      * Also implicitly flushes.
      */
     virtual void makeRenderTargetCurrent();
 
+    virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
+                             const SkMatrix& ctm,
+                             SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
+    
 protected:
     typedef GrContext::TextureCacheEntry TexCache;
     enum TexType {
         kBitmap_TexType,
         kDeviceRenderTarget_TexType,
         kSaveLayerDeviceRenderTarget_TexType
     };
     TexCache lockCachedTexture(const SkBitmap& bitmap,
-                               const GrSamplerState& sampler,
+                               const GrSamplerState* sampler,
                                TexType type = kBitmap_TexType);
+    bool isBitmapInTextureCache(const SkBitmap& bitmap,
+                                const GrSamplerState& sampler) const;
     void unlockCachedTexture(TexCache);
 
     class SkAutoCachedTexture {
     public:
         SkAutoCachedTexture();
         SkAutoCachedTexture(SkGpuDevice* device,
                             const SkBitmap& bitmap,
-                            const GrSamplerState& sampler,
+                            const GrSamplerState* sampler,
                             GrTexture** texture);
         ~SkAutoCachedTexture();
 
-        GrTexture* set(SkGpuDevice*, const SkBitmap&, const GrSamplerState&);
+        GrTexture* set(SkGpuDevice*, const SkBitmap&, const GrSamplerState*);
 
     private:
         SkGpuDevice*    fDevice;
         TexCache        fTex;
     };
     friend class SkAutoTexCache;
+    
+    // overrides from SkDevice
+    virtual bool onReadPixels(const SkBitmap& bitmap,
+                              int x, int y,
+                              SkCanvas::Config8888 config8888) SK_OVERRIDE;
+
 
 private:
     GrContext*      fContext;
 
     GrSkDrawProcs*  fDrawProcs;
 
     // state for our offscreen render-target
     TexCache            fCache;
@@ -185,16 +195,20 @@ private:
                                                int width, int height, 
                                                bool isOpaque,
                                                Usage usage);
 
     SkDrawProcs* initDrawForText(GrTextContext*);
     bool bindDeviceAsTexture(GrPaint* paint);
 
     void prepareRenderTarget(const SkDraw&);
+    bool shouldTileBitmap(const SkBitmap& bitmap,
+                          const GrSamplerState& sampler,
+                          const SkIRect* srcRectPtr,
+                          int* tileSize) const;
     void internalDrawBitmap(const SkDraw&, const SkBitmap&,
                             const SkIRect&, const SkMatrix&, GrPaint* grPaint);
 
     typedef SkDevice INHERITED;
 };
 
 #endif
 
--- a/gfx/skia/include/gpu/SkGr.h
+++ b/gfx/skia/include/gpu/SkGr.h
@@ -9,17 +9,17 @@
 
 
 #ifndef SkGr_DEFINED
 #define SkGr_DEFINED
 
 #include <stddef.h>
 
 // Gr headers
-#include "GrConfig.h"
+#include "GrTypes.h"
 #include "GrContext.h"
 #include "GrFontScaler.h"
 #include "GrClipIterator.h"
 #include "GrPath.h"
 
 // skia headers
 #include "SkBitmap.h"
 #include "SkPath.h"
@@ -194,13 +194,13 @@ private:
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // Helper functions
 
 static const GrContext::TextureKey gUNCACHED_KEY = ~0;
 GrContext::TextureCacheEntry sk_gr_create_bitmap_texture(GrContext* ctx,
                                                 GrContext::TextureKey key,
-                                                const GrSamplerState& sampler,
+                                                const GrSamplerState* sampler,
                                                 const SkBitmap& bitmap);
 
 
 #endif
--- a/gfx/skia/include/gpu/SkGrTexturePixelRef.h
+++ b/gfx/skia/include/gpu/SkGrTexturePixelRef.h
@@ -47,16 +47,19 @@ public:
 
     // override from SkPixelRef
     virtual SkGpuTexture* getTexture();
 
 protected:
     // override from SkPixelRef
     virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subset);
 
+    // override from SkPixelRef
+    virtual SkPixelRef* deepCopy(SkBitmap::Config dstConfig) SK_OVERRIDE;
+
 private:
     GrTexture*  fTexture;
     typedef SkROLockPixelsPixelRef INHERITED;
 };
 
 /**
  *  PixelRef that wraps a GrRenderTarget
  */
@@ -67,15 +70,18 @@ public:
 
     // override from SkPixelRef
     virtual SkGpuTexture* getTexture();
 
 protected:
     // override from SkPixelRef
     virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subset);
 
+    // override from SkPixelRef
+    virtual SkPixelRef* deepCopy(SkBitmap::Config dstConfig) SK_OVERRIDE;
+
 private:
     GrRenderTarget*  fRenderTarget;
     typedef SkROLockPixelsPixelRef INHERITED;
 };
 
 #endif
 
--- a/gfx/skia/include/gpu/SkNativeGLContext.h
+++ b/gfx/skia/include/gpu/SkNativeGLContext.h
@@ -7,16 +7,20 @@
  */
 #ifndef SkNativeGLContext_DEFINED
 #define SkNativeGLContext_DEFINED
 
 #include "SkGLContext.h"
 
 #if defined(SK_BUILD_FOR_MAC)
     #include <AGL/agl.h>
+
+#elif defined(SK_BUILD_FOR_ANDROID)
+    #include <GLES2/gl2.h>
+    #include <EGL/egl.h>
 #elif defined(SK_BUILD_FOR_UNIX)
     #include <X11/Xlib.h>
     #include <GL/glx.h>
 #elif defined(SK_BUILD_FOR_WIN32)
     #include <Windows.h>
     #include <GL/GL.h>
 #endif
 
@@ -38,16 +42,20 @@ public:
         AGLContext fOldAGLContext;
     #elif defined(SK_BUILD_FOR_UNIX)
         GLXContext fOldGLXContext;
         Display* fOldDisplay;
         GLXDrawable fOldDrawable;
     #elif defined(SK_BUILD_FOR_WIN32)
         HDC fOldHDC;
         HGLRC fOldHGLRC;
+    #elif defined(SK_BUILD_FOR_ANDROID)
+        EGLContext fOldEGLContext;
+        EGLDisplay fOldDisplay;
+        EGLSurface fOldSurface;
     #endif
     };
 
 protected:
     virtual const GrGLInterface* createGLContext() SK_OVERRIDE;
     virtual void destroyGLContext() SK_OVERRIDE;
 
 private:
@@ -58,12 +66,16 @@ private:
     Display* fDisplay;
     Pixmap fPixmap;
     GLXPixmap fGlxPixmap;
 #elif defined(SK_BUILD_FOR_WIN32)
     HWND fWindow;
     HDC fDeviceContext;
     HGLRC fGlRenderContext;
     static ATOM gWC;
+#elif defined(SK_BUILD_FOR_ANDROID)
+    EGLContext fContext;
+    EGLDisplay fDisplay;
+    EGLSurface fSurface;
 #endif
 };
 
 #endif
--- a/gfx/skia/include/images/SkFlipPixelRef.h
+++ b/gfx/skia/include/images/SkFlipPixelRef.h
@@ -51,17 +51,19 @@ private:
                                  const void* srcAddr);
 
     // serialization
 
 public:
     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();
 
     SkFlipPixelRef(SkFlattenableReadBuffer&);
 
 private:
     SkMutex         fMutex;
--- a/gfx/skia/include/images/SkImageRef_GlobalPool.h
+++ b/gfx/skia/include/images/SkImageRef_GlobalPool.h
@@ -18,16 +18,18 @@ public:
     SkImageRef_GlobalPool(SkStream*, SkBitmap::Config, int sampleSize = 1);
     virtual ~SkImageRef_GlobalPool();
     
     // overrides
     virtual Factory getFactory() const {
         return Create;
     }
     static SkPixelRef* Create(SkFlattenableReadBuffer&);
+    
+    SK_DECLARE_PIXEL_REF_REGISTRAR()
 
     // API to control the global pool
 
     /** Return the amount specified as the budget for the cache (in bytes).
      */
     static size_t GetRAMBudget();
     
     /** Set a new budget value for the cache.
--- a/gfx/skia/include/pdf/SkPDFDevice.h
+++ b/gfx/skia/include/pdf/SkPDFDevice.h
@@ -57,57 +57,53 @@ public:
      *         inverse scale+translate to accommodate the one that SkPDFDevice
      *         always does.
      */
     // TODO(vandebo): The sizes should be SkSize and not SkISize.
     SK_API SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
                        const SkMatrix& initialTransform);
     SK_API virtual ~SkPDFDevice();
 
-    virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
-
-    virtual void clear(SkColor color);
+    virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
 
-    virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
-        return false;
-    }
+    virtual void clear(SkColor color) SK_OVERRIDE;
 
     /** These are called inside the per-device-layer loop for each draw call.
      When these are called, we have already applied any saveLayer operations,
      and are handling any looping from the paint, and any effects from the
      DrawFilter.
      */
-    virtual void drawPaint(const SkDraw&, const SkPaint& paint);
+    virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
     virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
                             size_t count, const SkPoint[],
-                            const SkPaint& paint);
+                            const SkPaint& paint) SK_OVERRIDE;
     virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
     virtual void drawPath(const SkDraw&, const SkPath& origpath,
                           const SkPaint& paint, const SkMatrix* prePathMatrix,
-                          bool pathIsMutable);
+                          bool pathIsMutable) SK_OVERRIDE;
     virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
                             const SkIRect* srcRectOrNull,
-                            const SkMatrix& matrix, const SkPaint& paint);
+                            const SkMatrix& matrix, const SkPaint&) SK_OVERRIDE;
     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
-                            const SkPaint& paint);
+                            const SkPaint& paint) SK_OVERRIDE;
     virtual void drawText(const SkDraw&, const void* text, size_t len,
-                          SkScalar x, SkScalar y, const SkPaint& paint);
+                          SkScalar x, SkScalar y, const SkPaint&) SK_OVERRIDE;
     virtual void drawPosText(const SkDraw&, const void* text, size_t len,
                              const SkScalar pos[], SkScalar constY,
-                             int scalarsPerPos, const SkPaint& paint);
+                             int scalarsPerPos, const SkPaint&) SK_OVERRIDE;
     virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
                                 const SkPath& path, const SkMatrix* matrix,
-                                const SkPaint& paint);
+                                const SkPaint& paint) SK_OVERRIDE;
     virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
                               int vertexCount, const SkPoint verts[],
                               const SkPoint texs[], const SkColor colors[],
                               SkXfermode* xmode, const uint16_t indices[],
-                              int indexCount, const SkPaint& paint);
+                              int indexCount, const SkPaint& paint) SK_OVERRIDE;
     virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
-                            const SkPaint&);
+                            const SkPaint&) SK_OVERRIDE;
 
     enum DrawingArea {
         kContent_DrawingArea,  // Drawing area for the page content.
         kMargin_DrawingArea,   // Drawing area for the margin content.
     };
 
     /** Sets the drawing area for the device. Subsequent draw calls are directed
      *  to the specific drawing area (margin or content). The default drawing
@@ -155,16 +151,20 @@ public:
     }
 
     /** Returns a SkPDFGlyphSetMap which represents glyph usage of every font
      *  that shows on this device.
      */
     const SkPDFGlyphSetMap& getFontGlyphUsage() const {
         return *(fFontGlyphUsage.get());
     }
+    
+protected:
+    virtual bool onReadPixels(const SkBitmap& bitmap, int x, int y,
+                              SkCanvas::Config8888) SK_OVERRIDE;
 
 private:
     // TODO(vandebo): push most of SkPDFDevice's state into a core object in
     // order to get the right access levels without using friend.
     friend class ScopedContentEntry;
 
     SkISize fPageSize;
     SkISize fContentSize;
@@ -194,17 +194,17 @@ private:
 
     SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
                 const SkRegion& existingClipRegion);
 
     // override from SkDevice
     virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
                                                int width, int height,
                                                bool isOpaque,
-                                               Usage usage);
+                                               Usage usage) SK_OVERRIDE;
 
     void init();
     void cleanUp(bool clearFontUsage);
     void createFormXObjectFromDevice(SkRefPtr<SkPDFFormXObject>* xobject);
 
     // Clear the passed clip from all existing content entries.
     void clearClipFromContent(const SkClipStack* clipStack,
                               const SkRegion& clipRegion);
--- a/gfx/skia/include/utils/SkCamera.h
+++ b/gfx/skia/include/utils/SkCamera.h
@@ -145,17 +145,17 @@ public:
     void save();
     void restore();
 
     void translate(SkScalar x, SkScalar y, SkScalar z);
     void rotateX(SkScalar deg);
     void rotateY(SkScalar deg);
     void rotateZ(SkScalar deg);
 
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
     void setCameraLocation(SkScalar x, SkScalar y, SkScalar z);
 #endif
 
     void getMatrix(SkMatrix*) const;
     void applyToCanvas(SkCanvas*) const;
 
     SkScalar dotWithNormal(SkScalar dx, SkScalar dy, SkScalar dz) const;
     
--- a/gfx/skia/include/utils/SkDumpCanvas.h
+++ b/gfx/skia/include/utils/SkDumpCanvas.h
@@ -53,46 +53,46 @@ public:
                           const SkPaint*) = 0;
     };
         
     Dumper* getDumper() const { return fDumper; }
     void    setDumper(Dumper*);
     
     int getNestLevel() const { return fNestLevel; }
     
-    virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) SK_OVERRIDE;
+    virtual int save(SaveFlags) SK_OVERRIDE;
     virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
-                          SaveFlags flags = kARGB_ClipLayer_SaveFlag) SK_OVERRIDE;
+                          SaveFlags) SK_OVERRIDE;
     virtual void restore() SK_OVERRIDE;
 
     virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
     virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
     virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
     virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
     virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
     virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
     
     virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE;
     virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE;
     virtual bool clipRegion(const SkRegion& deviceRgn,
-                            SkRegion::Op op = SkRegion::kIntersect_Op) SK_OVERRIDE;
+                            SkRegion::Op) SK_OVERRIDE;
 
     virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
     virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
                             const SkPaint& paint) SK_OVERRIDE;
     virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE;
     virtual void drawPath(const SkPath& path, const SkPaint& paint) SK_OVERRIDE;
     virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
-                            const SkPaint* paint = NULL) SK_OVERRIDE;
+                            const SkPaint* paint) SK_OVERRIDE;
     virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
-                                const SkRect& dst, const SkPaint* paint = NULL) SK_OVERRIDE;
+                                const SkRect& dst, const SkPaint* paint) SK_OVERRIDE;
     virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
-                                  const SkPaint* paint = NULL) SK_OVERRIDE;
+                                  const SkPaint* paint) SK_OVERRIDE;
     virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
-                            const SkPaint* paint = NULL) SK_OVERRIDE;
+                            const SkPaint* paint) SK_OVERRIDE;
     virtual void drawText(const void* text, size_t byteLength, SkScalar x,
                           SkScalar y, const SkPaint& paint) SK_OVERRIDE;
     virtual void drawPosText(const void* text, size_t byteLength,
                              const SkPoint pos[], const SkPaint& paint) SK_OVERRIDE;
     virtual void drawPosTextH(const void* text, size_t byteLength,
                               const SkScalar xpos[], SkScalar constY,
                               const SkPaint& paint) SK_OVERRIDE;
     virtual void drawTextOnPath(const void* text, size_t byteLength,
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/utils/SkJSON.h
@@ -0,0 +1,285 @@
+/*
+ * 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
--- a/gfx/skia/include/utils/SkMatrix44.h
+++ b/gfx/skia/include/utils/SkMatrix44.h
@@ -41,16 +41,30 @@
         return static_cast<float>(x);
     }
     static inline double SkMScalarToDouble(float x) {
         return static_cast<double>(x);
     }
     static const SkMScalar SK_MScalarPI = 3.14159265f;
 #endif
 
+#ifdef SK_SCALAR_IS_FLOAT
+    #define SkMScalarToScalar SkMScalarToFloat
+    #define SkScalarToMScalar SkFloatToMScalar
+#else
+    #if SK_MSCALAR_IS_DOUBLE
+        // we don't have fixed <-> double macros, use double<->scalar macros
+        #define SkMScalarToScalar SkDoubleToScalar
+        #define SkScalarToMScalar SkScalarToDouble
+    #else
+        #define SkMScalarToScalar SkFloatToFixed
+        #define SkScalarToMScalar SkFixedToFloat
+    #endif
+#endif
+
 static const SkMScalar SK_MScalar1 = 1;
 
 ///////////////////////////////////////////////////////////////////////////////
 
 struct SkVector4 {
     SkScalar fData[4];
 
     SkVector4() {
--- a/gfx/skia/include/utils/SkNWayCanvas.h
+++ b/gfx/skia/include/utils/SkNWayCanvas.h
@@ -18,63 +18,63 @@ public:
     
     void addCanvas(SkCanvas*);
     void removeCanvas(SkCanvas*);
     void removeAll();
 
     ///////////////////////////////////////////////////////////////////////////
     // These are forwarded to the N canvases we're referencing
 
-    virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
-    virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
-                          SaveFlags flags = kARGB_ClipLayer_SaveFlag);
-    virtual void restore();
-    virtual bool translate(SkScalar dx, SkScalar dy);
-    virtual bool scale(SkScalar sx, SkScalar sy);
-    virtual bool rotate(SkScalar degrees);
-    virtual bool skew(SkScalar sx, SkScalar sy);
-    virtual bool concat(const SkMatrix& matrix);
-    virtual void setMatrix(const SkMatrix& matrix);
+    virtual int save(SaveFlags) SK_OVERRIDE;
+    virtual int saveLayer(const SkRect* bounds, const SkPaint*,
+                          SaveFlags) SK_OVERRIDE;
+    virtual void restore() SK_OVERRIDE;
+    virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
+    virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
+    virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
+    virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
+    virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
+    virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
     virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE;
     virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE;
     virtual bool clipRegion(const SkRegion& deviceRgn,
-                            SkRegion::Op op = SkRegion::kIntersect_Op);
+                            SkRegion::Op) SK_OVERRIDE;
 
-    virtual void drawPaint(const SkPaint& paint);
+    virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
     virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
-                            const SkPaint& paint);
-    virtual void drawRect(const SkRect& rect, const SkPaint& paint);
-    virtual void drawPath(const SkPath& path, const SkPaint& paint);
+                            const SkPaint&) SK_OVERRIDE;
+    virtual void drawRect(const SkRect& rect, const SkPaint&) SK_OVERRIDE;
+    virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
     virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
-                            const SkPaint* paint = NULL);
+                            const SkPaint*) SK_OVERRIDE;
     virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
-                                const SkRect& dst, const SkPaint* paint = NULL);
+                                const SkRect& dst, const SkPaint*) SK_OVERRIDE;
     virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
-                                  const SkPaint* paint = NULL);
+                                  const SkPaint*) SK_OVERRIDE;
     virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
-                            const SkPaint* paint = NULL);
+                            const SkPaint*) SK_OVERRIDE;
     virtual void drawText(const void* text, size_t byteLength, SkScalar x,
-                          SkScalar y, const SkPaint& paint);
+                          SkScalar y, const SkPaint&) SK_OVERRIDE;
     virtual void drawPosText(const void* text, size_t byteLength,
-                             const SkPoint pos[], const SkPaint& paint);
+                             const SkPoint pos[], const SkPaint&) SK_OVERRIDE;
     virtual void drawPosTextH(const void* text, size_t byteLength,
                               const SkScalar xpos[], SkScalar constY,
-                              const SkPaint& paint);
+                              const SkPaint&) SK_OVERRIDE;
     virtual void drawTextOnPath(const void* text, size_t byteLength,
                                 const SkPath& path, const SkMatrix* matrix,
-                                const SkPaint& paint);
-    virtual void drawPicture(SkPicture&);
+                                const SkPaint&) SK_OVERRIDE;
+    virtual void drawPicture(SkPicture&) SK_OVERRIDE;
     virtual void drawVertices(VertexMode vmode, int vertexCount,
                               const SkPoint vertices[], const SkPoint texs[],
                               const SkColor colors[], SkXfermode* xmode,
                               const uint16_t indices[], int indexCount,
-                              const SkPaint& paint);
+                              const SkPaint&) SK_OVERRIDE;
 
-    virtual SkBounder* setBounder(SkBounder* bounder);
-    virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
+    virtual SkBounder* setBounder(SkBounder*) SK_OVERRIDE;
+    virtual SkDrawFilter* setDrawFilter(SkDrawFilter*) SK_OVERRIDE;
     
 private:
     SkTDArray<SkCanvas*> fList;
     
     class Iter;
 
     typedef SkCanvas INHERITED;
 };
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/utils/SkWGL.h
@@ -0,0 +1,90 @@
+
+/*
+ * 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 "SkRefCnt.h"
+
+#ifndef SkWGL_DEFINED
+#define SkWGL_DEFINED
+
+/**
+ * Working with WGL extensions can be a pain. Among the reasons is that You must
+ * have a GL context to get the proc addresses, but you want to use the procs to
+ * create a context in the first place. So you have to create a dummy GL ctx to
+ * get the proc addresses.
+ *
+ * This file helps by providing SkCreateWGLInterface(). It returns a struct of
+ * function pointers that it initializes. It also has a helper function to query
+ * for WGL extensions. It handles the fact that wglGetExtensionsString is itself
+ * an extension.
+ */
+
+#if !defined(WIN32_LEAN_AND_MEAN)
+    #define WIN32_LEAN_AND_MEAN
+    #define SK_LOCAL_LEAN_AND_MEAN
+#endif
+#include <Windows.h>
+#if defined(SK_LOCAL_LEAN_AND_MEAN)
+    #undef WIN32_LEAN_AND_MEAN
+    #undef SK_LOCAL_LEAN_AND_MEAN
+#endif
+
+#define SK_WGL_DRAW_TO_WINDOW                                       0x2001
+#define SK_WGL_ACCELERATION                                         0x2003
+#define SK_WGL_SUPPORT_OPENGL                                       0x2010
+#define SK_WGL_DOUBLE_BUFFER                                        0x2011
+#define SK_WGL_COLOR_BITS                                           0x2014
+#define SK_WGL_ALPHA_BITS                                           0x201B
+#define SK_WGL_STENCIL_BITS                                         0x2023
+#define SK_WGL_FULL_ACCELERATION                                    0x2027
+#define SK_WGL_SAMPLE_BUFFERS                                       0x2041
+#define SK_WGL_SAMPLES                                              0x2042
+#define SK_WGL_CONTEXT_MAJOR_VERSION                                0x2091
+#define SK_WGL_CONTEXT_MINOR_VERSION                                0x2092
+#define SK_WGL_CONTEXT_LAYER_PLANE                                  0x2093
+#define SK_WGL_CONTEXT_FLAGS                                        0x2094
+#define SK_WGL_CONTEXT_PROFILE_MASK                                 0x9126
+#define SK_WGL_CONTEXT_DEBUG_BIT                                    0x0001
+#define SK_WGL_CONTEXT_FORWARD_COMPATIBLE_BIT                       0x0002
+#define SK_WGL_CONTEXT_CORE_PROFILE_BIT                             0x00000001
+#define SK_WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT                    0x00000002
+#define SK_WGL_CONTEXT_ES2_PROFILE_BIT                              0x00000004
+#define SK_ERROR_INVALID_VERSION                                    0x2095
+#define SK_ERROR_INVALID_PROFILE                                    0x2096
+
+class SkWGLExtensions {
+public:
+    SkWGLExtensions();
+    /**
+     * Determines if an extensions is available for a given DC.
+     * WGL_extensions_string is considered a prerequisite for all other
+     * extensions. It is necessary to check this before calling other class
+     * functions.
+     */
+    bool hasExtension(HDC dc, const char* ext) const;
+
+    const char* getExtensionsString(HDC hdc) const;
+    BOOL choosePixelFormat(HDC hdc, const int*, const FLOAT*, UINT, int*, UINT*) const;
+    BOOL getPixelFormatAttribiv(HDC, int, int, UINT, const int*, int*) const;
+    BOOL getPixelFormatAttribfv(HDC hdc, int, int, UINT, const int*, FLOAT*) const;
+    HGLRC createContextAttribs(HDC, HGLRC, const int *) const;
+
+private:
+    typedef const char* (WINAPI *GetExtensionsStringProc)(HDC hdc);
+    typedef BOOL (WINAPI *ChoosePixelFormatProc)(HDC 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 *);
+
+    GetExtensionsStringProc fGetExtensionsString;
+    ChoosePixelFormatProc fChoosePixelFormat;
+    GetPixelFormatAttribfvProc fGetPixelFormatAttribfv;
+    GetPixelFormatAttribivProc fGetPixelFormatAttribiv;
+    CreateContextAttribsProc fCreateContextAttribs;
+};
+
+#endif
--- a/gfx/skia/include/views/SkOSWindow_Mac.h
+++ b/gfx/skia/include/views/SkOSWindow_Mac.h
@@ -36,9 +36,9 @@ protected:
 private:
     void*   fHWND;
     bool    fInvalEventIsPending;
     void*   fNotifier;
     void*   fGLContext;
     typedef SkWindow INHERITED;
 };
 
-#endif
\ No newline at end of file
+#endif
--- a/gfx/skia/include/views/SkView.h
+++ b/gfx/skia/include/views/SkView.h
@@ -9,16 +9,17 @@
 
 #ifndef SkView_DEFINED
 #define SkView_DEFINED
 
 #include "SkEventSink.h"
 #include "SkRect.h"
 #include "SkDOM.h"
 #include "SkTDict.h"
+#include "SkMatrix.h"
 
 class SkCanvas;
 class SkLayerView;
 
 /** \class SkView
 
     SkView is the base class for screen management. All widgets and controls inherit
     from SkView.
@@ -75,25 +76,43 @@ public:
     /** Set the view's width and height. These must both be >= 0. This does not affect the view's loc */
     void        setSize(SkScalar width, SkScalar height);
     void        setSize(const SkPoint& size) { this->setSize(size.fX, size.fY); }
     void        setWidth(SkScalar width) { this->setSize(width, fHeight); }
     void        setHeight(SkScalar height) { this->setSize(fWidth, height); }
     /** Return a rectangle set to [0, 0, width, height] */
     void        getLocalBounds(SkRect* bounds) const;
 
+    /** Loc - the view's offset with respect to its parent in its view hiearchy.
+        NOTE: For more complex transforms, use Local Matrix. The tranformations 
+        are applied in the following order:
+             canvas->translate(fLoc.fX, fLoc.fY);		
+             canvas->concat(fMatrix);
+    */
     /** Return the view's left edge */
     SkScalar    locX() const { return fLoc.fX; }
     /** Return the view's top edge */
     SkScalar    locY() const { return fLoc.fY; }
     /** Set the view's left and top edge. This does not affect the view's size */
     void        setLoc(SkScalar x, SkScalar y);
     void        setLoc(const SkPoint& loc) { this->setLoc(loc.fX, loc.fY); }
     void        setLocX(SkScalar x) { this->setLoc(x, fLoc.fY); }
     void        setLocY(SkScalar y) { this->setLoc(fLoc.fX, y); }
+    
+    /** Local Matrix - matrix used to tranform the view with respect to its 
+        parent in its view hiearchy. Use setLocalMatrix to apply matrix 
+        transformations to the current view and in turn affect its children.
+        NOTE: For simple offsets, use Loc. The transformations are applied in
+        the following order:
+             canvas->translate(fLoc.fX, fLoc.fY);		
+             canvas->concat(fMatrix);
+    */
+    const SkMatrix& getLocalMatrix() const { return fMatrix; }
+    void            setLocalMatrix(const SkMatrix& matrix);
+
     /** Offset (move) the view by the specified dx and dy. This does not affect the view's size */
     void        offset(SkScalar dx, SkScalar dy);
 
     /** Call this to have the view draw into the specified canvas. */
     virtual void draw(SkCanvas* canvas);
 
     /** Call this to invalidate part of all of a view, requesting that the view's
         draw method be called. The rectangle parameter specifies the part of the view
@@ -333,28 +352,31 @@ public:
 protected:
 
     // override these if you're acting as a layer/host
     virtual bool    onGetFocusView(SkView**) const { return false; }
     virtual bool    onSetFocusView(SkView*) { return false; }
 
 private:
     SkScalar    fWidth, fHeight;
+    SkMatrix    fMatrix;
     SkPoint     fLoc;
     SkView*     fParent;
     SkView*     fFirstChild;
     SkView*     fNextSibling;
     SkView*     fPrevSibling;
     uint8_t     fFlags;
     uint8_t     fContainsFocus;
 
     friend class B2FIter;
     friend class F2BIter;
     
     friend class SkLayerView;
 
     bool    setFocusView(SkView* fvOrNull);
     SkView* acceptFocus(FocusDirection);
     void    detachFromParent_NoLayout();
+    /** Compute the matrix to transform view-local coordinates into global ones */
+    void    localToGlobal(SkMatrix* matrix) const;
 };
 
 #endif
 
--- a/gfx/skia/include/views/SkWindow.h
+++ b/gfx/skia/include/views/SkWindow.h
@@ -103,17 +103,17 @@ private:
 ///////////////////////////////////////////////////////////
 
 #ifdef SK_USE_WXWIDGETS
     #include "SkOSWindow_wxwidgets.h"
 #elif defined(SK_BUILD_FOR_MAC)
     #include "SkOSWindow_Mac.h"
 #elif defined(SK_BUILD_FOR_WIN)
     #include "SkOSWindow_Win.h"
-#elif defined(ANDROID)
+#elif defined(SK_BUILD_FOR_ANDROID)
     #include "SkOSWindow_Android.h"
 #elif defined(SK_BUILD_FOR_UNIX)
   #include "SkOSWindow_Unix.h"
 #elif defined(SK_BUILD_FOR_SDL)
     #include "SkOSWindow_SDL.h"
 #elif defined(SK_BUILD_FOR_IOS)
     #include "SkOSWindow_iOS.h"
 #endif
--- a/gfx/skia/src/animator/SkDisplayEvent.cpp
+++ b/gfx/skia/src/animator/SkDisplayEvent.cpp
@@ -250,17 +250,17 @@ bool SkDisplayEvent::setProperty(int ind
         SkASSERT(*chars == '-');
         chars++;
         fMax = (SkKey) SkUTF8_NextUnichar(&chars);
         SkASSERT(fMax >= code);
     }
     return true;
 }
 
-#ifdef ANDROID
+#ifdef SK_BUILD_FOR_ANDROID
 
 #include "SkMetaData.h"
 #include "SkParse.h"
 #include "SkTextBox.h"
 #include "SkXMLWriter.h"
 
 void SkMetaData::setPtr(char const*, void* ) {}
 void SkMetaData::setS32(char const*, int ) {}
--- a/gfx/skia/src/core/SkAAClip.cpp
+++ b/gfx/skia/src/core/SkAAClip.cpp
@@ -204,17 +204,17 @@ void SkAAClip::validate() const {
     while (yoff < ystop) {
         SkASSERT(prevY < yoff->fY);
         SkASSERT(yoff->fY <= lastY);
         prevY = yoff->fY;
         SkASSERT(prevOffset < (int32_t)yoff->fOffset);
         prevOffset = yoff->fOffset;
         const uint8_t* row = head->data() + yoff->fOffset;
         size_t rowLength = compute_row_length(row, fBounds.width());
-        SkASSERT(yoff->fOffset + rowLength <= head->fDataSize);
+        SkASSERT(yoff->fOffset + rowLength <= (size_t) head->fDataSize);
         yoff += 1;
     }
     // check the last entry;
     --yoff;
     SkASSERT(yoff->fY == lastY);
 }
 #endif
 
@@ -455,16 +455,18 @@ static bool row_is_all_zeros(const uint8
     return true;
 }
 
 bool SkAAClip::trimTopBottom() {
     if (this->isEmpty()) {
         return false;
     }
 
+    this->validate();
+
     const int width = fBounds.width();
     RunHead* head = fRunHead;
     YOffset* yoff = head->yoffsets();
     YOffset* stop = yoff + head->fRowCount;
     const uint8_t* base = head->data();
 
     //  Look to trim away empty rows from the top.
     //
@@ -493,16 +495,20 @@ bool SkAAClip::trimTopBottom() {
         YOffset* dst = head->yoffsets();
         size_t size = head->fRowCount * sizeof(YOffset) + head->fDataSize;
         memmove(dst, dst + skip, size - skip * sizeof(YOffset));
 
         fBounds.fTop += dy;
         SkASSERT(!fBounds.isEmpty());
         head->fRowCount -= skip;
         SkASSERT(head->fRowCount > 0);
+        
+        this->validate();
+        // need to reset this after the memmove
+        base = head->data();
     }
 
     //  Look to trim away empty rows from the bottom.
     //  We know that we have at least one non-zero row, so we can just walk
     //  backwards without checking for running past the start.
     //
     stop = yoff = head->yoffsets() + head->fRowCount;
     do {
@@ -515,16 +521,17 @@ bool SkAAClip::trimTopBottom() {
         // have to adjust any of the Y values, we just have to trim the array
         memmove(stop - skip, stop, head->fDataSize);
 
         fBounds.fBottom = fBounds.fTop + yoff->fY + 1;
         SkASSERT(!fBounds.isEmpty());
         head->fRowCount -= skip;
         SkASSERT(head->fRowCount > 0);
     }
+    this->validate();
 
     return true;
 }
 
 // can't validate before we're done, since trimming is part of the process of
 // making us valid after the Builder. Since we build from top to bottom, its
 // possible our fBounds.fBottom is bigger than our last scanline of data, so
 // we trim fBounds.fBottom back up.
@@ -670,31 +677,111 @@ bool SkAAClip::setRect(const SkRect& r, 
 
     // TODO: special case this
 
     SkPath path;
     path.addRect(r);
     return this->setPath(path, NULL, doAA);
 }
 
+static void append_run(SkTDArray<uint8_t>& array, uint8_t value, int count) {
+    SkASSERT(count >= 0);
+    while (count > 0) {
+        int n = count;
+        if (n > 255) {
+            n = 255;
+        }
+        uint8_t* data = array.append(2);
+        data[0] = n;
+        data[1] = value;
+        count -= n;
+    }
+}
+
 bool SkAAClip::setRegion(const SkRegion& rgn) {
     if (rgn.isEmpty()) {
         return this->setEmpty();
     }
     if (rgn.isRect()) {
         return this->setRect(rgn.getBounds());
     }
-    
+
+#if 0
     SkAAClip clip;
     SkRegion::Iterator iter(rgn);
     for (; !iter.done(); iter.next()) {
         clip.op(iter.rect(), SkRegion::kUnion_Op);
     }
     this->swap(clip);
     return !this->isEmpty();
+#else    
+    const SkIRect& bounds = rgn.getBounds();
+    const int offsetX = bounds.fLeft;
+    const int offsetY = bounds.fTop;
+
+    SkTDArray<YOffset> yArray;
+    SkTDArray<uint8_t> xArray;
+
+    yArray.setReserve(SkMin32(bounds.height(), 1024));
+    xArray.setReserve(SkMin32(bounds.width() * 128, 64 * 1024));
+
+    SkRegion::Iterator iter(rgn);
+    int prevRight = 0;
+    int prevBot = 0;
+    YOffset* currY = NULL;
+
+    for (; !iter.done(); iter.next()) {
+        const SkIRect& r = iter.rect();
+        SkASSERT(bounds.contains(r));
+
+        int bot = r.fBottom - offsetY;
+        SkASSERT(bot >= prevBot);
+        if (bot > prevBot) {
+            if (currY) {
+                // flush current row
+                append_run(xArray, 0, bounds.width() - prevRight);
+            }
+            // did we introduce an empty-gap from the prev row?
+            int top = r.fTop - offsetY;
+            if (top > prevBot) {
+                currY = yArray.append();
+                currY->fY = top - 1;
+                currY->fOffset = xArray.count();
+                append_run(xArray, 0, bounds.width());
+            }
+            // create a new record for this Y value
+            currY = yArray.append();
+            currY->fY = bot - 1;
+            currY->fOffset = xArray.count();
+            prevRight = 0;
+            prevBot = bot;
+        }
+
+        int x = r.fLeft - offsetX;
+        append_run(xArray, 0, x - prevRight);
+
+        int w = r.fRight - r.fLeft;
+        append_run(xArray, 0xFF, w);
+        prevRight = x + w;
+        SkASSERT(prevRight <= bounds.width());
+    }
+    // flush last row
+    append_run(xArray, 0, bounds.width() - prevRight);
+
+    // now pack everything into a RunHead
+    RunHead* head = RunHead::Alloc(yArray.count(), xArray.bytes());
+    memcpy(head->yoffsets(), yArray.begin(), yArray.bytes());
+    memcpy(head->data(), xArray.begin(), xArray.bytes());
+
+    this->setEmpty();
+    fBounds = bounds;
+    fRunHead = head;
+    this->validate();
+    return true;
+#endif
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 const uint8_t* SkAAClip::findRow(int y, int* lastYForRow) const {
     SkASSERT(fRunHead);
 
     if (!y_in_rect(y, fBounds)) {
@@ -834,16 +921,72 @@ public:
             SkASSERT(row->fWidth < fBounds.width());
         }
 
         AppendRun(data, alpha, count);
         row->fWidth += count;
         SkASSERT(row->fWidth <= fBounds.width());
     }
 
+    void addColumn(int x, int y, U8CPU alpha, int height) {
+        SkASSERT(fBounds.contains(x, y + height - 1));
+
+        this->addRun(x, y, alpha, 1);
+        this->flushRowH(fCurrRow);
+        y -= fBounds.fTop;
+        SkASSERT(y == fCurrRow->fY);
+        fCurrRow->fY = y + height - 1;
+    }
+ 
+    void addRectRun(int x, int y, int width, int height) {
+        SkASSERT(fBounds.contains(x + width - 1, y + height - 1));
+        this->addRun(x, y, 0xFF, width);
+
+        // we assum the rect must be all we'll see for these scanlines
+        // so we ensure our row goes all the way to our right
+        this->flushRowH(fCurrRow);
+
+        y -= fBounds.fTop;
+        SkASSERT(y == fCurrRow->fY);
+        fCurrRow->fY = y + height - 1;
+    }
+
+    void addAntiRectRun(int x, int y, int width, int height,
+                        SkAlpha leftAlpha, SkAlpha rightAlpha) {
+        SkASSERT(fBounds.contains(x + width - 1 +
+                 (leftAlpha > 0 ? 1 : 0) + (rightAlpha > 0 ? 1 : 0),
+                 y + height - 1));
+        SkASSERT(width >= 0);
+
+        // Conceptually we're always adding 3 runs, but we should
+        // merge or omit them if possible.
+        if (leftAlpha == 0xFF) {
+            width++;
+        } else if (leftAlpha > 0) {
+          this->addRun(x++, y, leftAlpha, 1);
+        }
+        if (rightAlpha == 0xFF) {
+            width++;
+        }
+        if (width > 0) {
+            this->addRun(x, y, 0xFF, width);
+        }
+        if (rightAlpha > 0 && rightAlpha < 255) {
+            this->addRun(x + width, y, rightAlpha, 1);
+        }
+
+        // we assume the rect must be all we'll see for these scanlines
+        // so we ensure our row goes all the way to our right
+        this->flushRowH(fCurrRow);
+
+        y -= fBounds.fTop;
+        SkASSERT(y == fCurrRow->fY);
+        fCurrRow->fY = y + height - 1;
+    }
+
     bool finish(SkAAClip* target) {
         this->flushRow(false);
 
         const Row* row = fRows.begin();
         const Row* stop = fRows.end();
 
         size_t dataSize = 0;    
         while (row < stop) {
@@ -873,17 +1016,17 @@ public:
 
             yoffset->fY = row->fY - adjustY;
             yoffset->fOffset = data - baseData;
             yoffset += 1;
             
             size_t n = row->fData->count();
             memcpy(data, row->fData->begin(), n);
 #ifdef SK_DEBUG
-            int bytesNeeded = compute_row_length(data, fBounds.width());
+            size_t bytesNeeded = compute_row_length(data, fBounds.width());
             SkASSERT(bytesNeeded == n);
 #endif
             data += n;
             
             row += 1;
         }
 
         target->freeRuns();
@@ -917,43 +1060,47 @@ public:
             const Row& row = fRows[i];
             SkASSERT(prevY < row.fY);
             SkASSERT(fWidth == row.fWidth);
             int count = row.fData->count();
             const uint8_t* ptr = row.fData->begin();
             SkASSERT(!(count & 1));
             int w = 0;
             for (int x = 0; x < count; x += 2) {
-                w += ptr[0];
+                int n = ptr[0];
+                SkASSERT(n > 0);
+                w += n;
                 SkASSERT(w <= fWidth);
                 ptr += 2;
             }
             SkASSERT(w == fWidth);
             prevY = row.fY;
         }
 #endif
     }
 
     // only called by BuilderBlitter
     void setMinY(int y) {
         fMinY = y;
     }
 
 private:
+    void flushRowH(Row* row) {
+        // flush current row if needed
+        if (row->fWidth < fWidth) {
+            AppendRun(*row->fData, 0, fWidth - row->fWidth);
+            row->fWidth = fWidth;
+        }
+    }
 
     Row* flushRow(bool readyForAnother) {
         Row* next = NULL;
         int count = fRows.count();
         if (count > 0) {
-            // flush current row if needed
-            Row* curr = &fRows[count - 1];
-            if (curr->fWidth < fWidth) {
-                AppendRun(*curr->fData, 0, fWidth - curr->fWidth);
-                curr->fWidth = fWidth;
-            }
+            this->flushRowH(&fRows[count - 1]);
         }
         if (count > 1) {
             // are our last two runs the same?
             Row* prev = &fRows[count - 2];
             Row* curr = &fRows[count - 1];
             SkASSERT(prev->fWidth == fWidth);
             SkASSERT(curr->fWidth == fWidth);
             if (*prev->fData == *curr->fData) {
@@ -1004,21 +1151,38 @@ public:
     }
 
     void finish() {
         if (fMinY < SK_MaxS32) {
             fBuilder->setMinY(fMinY);
         }
     }
 
-    virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE
-        { unexpected(); }
+    /**
+       Must evaluate clips in scan-line order, so don't want to allow blitV(),
+       but an AAClip can be clipped down to a single pixel wide, so we
+       must support it (given AntiRect semantics: minimum width is 2).
+       Instead we'll rely on the runtime asserts to guarantee Y monotonicity;
+       any failure cases that misses may have minor artifacts.
+    */
+    virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE {
+        this->recordMinY(y);
+        fBuilder->addColumn(x, y, alpha, height);
+    }
 
-    //  let the default impl call blitH
-//    virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE
+    virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE {
+        this->recordMinY(y);
+        fBuilder->addRectRun(x, y, width, height);
+    }
+
+    virtual void blitAntiRect(int x, int y, int width, int height,
+                     SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE {
+        this->recordMinY(y);
+        fBuilder->addAntiRectRun(x, y, width, height, leftAlpha, rightAlpha);
+    }
 
     virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE
         { unexpected(); }
 
     virtual const SkBitmap* justAnOpaqueColor(uint32_t*) SK_OVERRIDE {
         return NULL;
     }
 
@@ -1166,17 +1330,17 @@ static AlphaProc find_alpha_proc(SkRegio
             return sectAlphaProc;
         case SkRegion::kDifference_Op:
             return diffAlphaProc;
         case SkRegion::kUnion_Op:
             return unionAlphaProc;
         case SkRegion::kXOR_Op:
             return xorAlphaProc;
         default:
-            SkASSERT(!"unexpected region op");
+            SkDEBUGFAIL("unexpected region op");
             return sectAlphaProc;
     }
 }
 
 static const uint8_t gEmptyRow[] = {
     0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0,
     0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0,
     0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0,
@@ -1439,17 +1603,17 @@ bool SkAAClip::op(const SkAAClip& clipAO
             if (b_empty) {
                 return this->set(*clipA);
             }
             bounds = clipA->fBounds;
             bounds.join(clipB->fBounds);
             break;
 
         default:
-            SkASSERT(!"unknown region op");
+            SkDEBUGFAIL("unknown region op");
             return !this->isEmpty();
     }
 
     SkASSERT(SkIRect::Intersects(bounds, clipB->fBounds));
     SkASSERT(SkIRect::Intersects(bounds, clipB->fBounds));
 
     Builder builder(bounds);
     operateY(builder, *clipA, *clipB, op);
@@ -1556,16 +1720,17 @@ static void expand_row_to_mask(uint8_t* 
     while (width > 0) {
         int n = row[0];
         SkASSERT(width >= n);
         memset(mask, row[1], n);
         mask += n;
         row += 2;
         width -= n;
     }
+    SkASSERT(0 == width);
 }
 
 void SkAAClip::copyToMask(SkMask* mask) const {
     mask->fFormat = SkMask::kA8_Format;
     if (this->isEmpty()) {
         mask->fBounds.setEmpty();
         mask->fImage = NULL;
         mask->fRowBytes = 0;
@@ -1826,33 +1991,33 @@ template <typename T> void mergeT(const 
         row += 2;
         rowN = row[0];
     }
 }
 
 static MergeAAProc find_merge_aa_proc(SkMask::Format format) {
     switch (format) {
         case SkMask::kBW_Format:
-            SkASSERT(!"unsupported");
+            SkDEBUGFAIL("unsupported");
             return NULL;
         case SkMask::kA8_Format:
         case SkMask::k3D_Format: {
             void (*proc8)(const uint8_t*, int, const uint8_t*, int, uint8_t*) = mergeT;
             return (MergeAAProc)proc8;
         }
         case SkMask::kLCD16_Format: {
             void (*proc16)(const uint16_t*, int, const uint8_t*, int, uint16_t*) = mergeT;
             return (MergeAAProc)proc16;
         }
         case SkMask::kLCD32_Format: {
             void (*proc32)(const SkPMColor*, int, const uint8_t*, int, SkPMColor*) = mergeT;
             return (MergeAAProc)proc32;
         }
         default:
-            SkASSERT(!"unsupported");
+            SkDEBUGFAIL("unsupported");
             return NULL;
     }
 }
 
 static U8CPU bit2byte(int bitInAByte) {
     SkASSERT(bitInAByte <= 0xFF);
     // negation turns any non-zero into 0xFFFFFF??, so we just shift down
     // some value >= 8 to get a full FF value
--- a/gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp
+++ b/gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp
@@ -5,33 +5,62 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
 
 #include "SkAdvancedTypefaceMetrics.h"
 #include "SkTypes.h"
 
-#ifdef SK_BUILD_FOR_UNIX
+#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #endif
 
 #ifdef SK_BUILD_FOR_MAC
 #import <ApplicationServices/ApplicationServices.h>
 #endif
 
 #ifdef SK_BUILD_FOR_IOS
 #include <CoreText/CoreText.h>
 #include <CoreGraphics/CoreGraphics.h>
 #include <CoreFoundation/CoreFoundation.h>
 #endif
 
 namespace skia_advanced_typeface_metrics_utils {
 
+const int16_t kInvalidAdvance = SK_MinS16;
+const int16_t kDontCareAdvance = SK_MinS16 + 1;
+
+template <typename Data>
+void stripUninterestingTrailingAdvancesFromRange(
+                                                 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
+    SkASSERT(false);
+}
+
+template <>
+void stripUninterestingTrailingAdvancesFromRange<int16_t>(
+                                                          SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
+    SkASSERT(range);
+    
+    int expectedAdvanceCount = range->fEndId - range->fStartId + 1;
+    if (range->fAdvance.count() < expectedAdvanceCount) {
+        return;
+    }
+    
+    for (int i = expectedAdvanceCount - 1; i >= 0; --i) {
+        if (range->fAdvance[i] != kDontCareAdvance &&
+            range->fAdvance[i] != kInvalidAdvance &&
+            range->fAdvance[i] != 0) {
+            range->fEndId = range->fStartId + i;
+            break;
+        }
+    }
+}
+
 template <typename Data>
 void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
                 int startId) {
     range->fStartId = startId;
     range->fAdvance.setCount(0);
 }
 
 template <typename Data>
@@ -39,124 +68,202 @@ SkAdvancedTypefaceMetrics::AdvanceMetric
         SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
         int startId) {
     nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>);
     resetRange(nextSlot->get(), startId);
     return nextSlot->get();
 }
 
 template <typename Data>
+void zeroWildcardsInRange(
+                          SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
+    SkASSERT(false);
+}
+
+template <>
+void zeroWildcardsInRange<int16_t>(
+                                   SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
+    SkASSERT(range);
+    if (range->fType != SkAdvancedTypefaceMetrics::WidthRange::kRange) {
+        return;
+    }
+    SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1);
+    
+    // Zero out wildcards.
+    for (int i = 0; i < range->fAdvance.count(); ++i) {
+        if (range->fAdvance[i] == kDontCareAdvance) {
+            range->fAdvance[i] = 0;
+        }
+    }
+}
+    
+template <typename Data>
 void finishRange(
         SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
         int endId,
         typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
                 type) {
     range->fEndId = endId;
     range->fType = type;
+    stripUninterestingTrailingAdvancesFromRange(range);
     int newLength;
     if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange) {
-        newLength = endId - range->fStartId + 1;
+        newLength = range->fEndId - range->fStartId + 1;
     } else {
+        if (range->fEndId == range->fStartId) {
+            range->fType =
+                SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange;
+        }
         newLength = 1;
     }
     SkASSERT(range->fAdvance.count() >= newLength);
     range->fAdvance.setCount(newLength);
+    zeroWildcardsInRange(range);
 }
 
 template <typename Data, typename FontHandle>
 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
         FontHandle fontHandle,
         int num_glyphs,
         const uint32_t* subsetGlyphIDs,
         uint32_t subsetGlyphIDsLength,
         bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) {
-    // Assuming that an ASCII representation of a width or a glyph id is,
-    // on average, 3 characters long gives the following cut offs for
-    // using different range types:
-    // When currently in a range
-    //  - Removing 4 0's is a win
-    //  - Removing 5 repeats is a win
-    // When not currently in a range
-    //  - Removing 1 0 is a win
-    //  - Removing 3 repeats is a win
+    // Assuming that on average, the ASCII representation of an advance plus
+    // a space is 8 characters and the ASCII representation of a glyph id is 3
+    // characters, then the following cut offs for using different range types
+    // apply:
+    // The cost of stopping and starting the range is 7 characers
+    //  a. Removing 4 0's or don't care's is a win
+    // The cost of stopping and starting the range plus a run is 22
+    // characters
+    //  b. Removing 3 repeating advances is a win
+    //  c. Removing 2 repeating advances and 3 don't cares is a win
+    // When not currently in a range the cost of a run over a range is 16
+    // characaters, so:
+    //  d. Removing a leading 0/don't cares is a win because it is omitted
+    //  e. Removing 2 repeating advances is a win
 
     SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result;
     SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange;
     SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* prevRange = NULL;
-    curRange = appendRange(&result, 0);
-    Data lastAdvance = SK_MinS16;
-    int repeats = 0;
+    Data lastAdvance = kInvalidAdvance;
+    int repeatedAdvances = 0;
+    int wildCardsInRun = 0;
+    int leadingWildCards = 0;
+    int trailingWildCards = 0;
     uint32_t subsetIndex = 0;
-    for (int gId = 0; gId <= num_glyphs; gId++) {
-        Data advance = 0;
-        if (gId < num_glyphs) {
+
+    // Limit the loop count to glyph id ranges provided.
+    int firstIndex = 0;
+    int lastIndex = num_glyphs;
+    if (subsetGlyphIDs) {
+        firstIndex = static_cast<int>(subsetGlyphIDs[0]);
+        lastIndex =
+                static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1;
+    }
+    curRange = appendRange(&result, firstIndex);
+
+    for (int gId = firstIndex; gId <= lastIndex; gId++) {
+        Data advance = kInvalidAdvance;
+        if (gId < lastIndex) {
             // Get glyph id only when subset is NULL, or the id is in subset.
             if (!subsetGlyphIDs ||
                 (subsetIndex < subsetGlyphIDsLength &&
-                static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) {
+                 static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) {
                 SkAssertResult(getAdvance(fontHandle, gId, &advance));
                 ++subsetIndex;
+            } else {
+                advance = kDontCareAdvance;
             }
-        } else {
-            advance = SK_MinS16;
         }
         if (advance == lastAdvance) {
-            repeats++;
-        } else if (curRange->fAdvance.count() == repeats + 1) {
-            if (lastAdvance == 0 && repeats >= 0) {
+            repeatedAdvances++;
+            trailingWildCards = 0;
+        } else if (advance == kDontCareAdvance) {
+            wildCardsInRun++;
+            trailingWildCards++;
+        } else if (curRange->fAdvance.count() ==
+                   repeatedAdvances + 1 + wildCardsInRun) {  // All in run.
+            if (lastAdvance == 0) {
                 resetRange(curRange, gId);
-            } else if (repeats >= 2) {
+                trailingWildCards = 0;
+            } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) {
                 finishRange(curRange, gId - 1,
                             SkAdvancedTypefaceMetrics::WidthRange::kRun);
                 prevRange = curRange;
                 curRange = appendRange(&curRange->fNext, gId);
+                trailingWildCards = 0;
             }
-            repeats = 0;
+            repeatedAdvances = 0;
+            wildCardsInRun = trailingWildCards;
+            leadingWildCards = trailingWildCards;
+            trailingWildCards = 0;
         } else {
-            if (lastAdvance == 0 && repeats >= 3) {
-                finishRange(curRange, gId - repeats - 2,
+            if (lastAdvance == 0 &&
+                    repeatedAdvances + 1 + wildCardsInRun >= 4) {
+                finishRange(curRange,
+                            gId - repeatedAdvances - wildCardsInRun - 2,
                             SkAdvancedTypefaceMetrics::WidthRange::kRange);
                 prevRange = curRange;
                 curRange = appendRange(&curRange->fNext, gId);
-            } else if (repeats >= 4) {
-                finishRange(curRange, gId - repeats - 2,
+                trailingWildCards = 0;
+            } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) {
+                finishRange(curRange,
+                            gId - trailingWildCards - 1,
                             SkAdvancedTypefaceMetrics::WidthRange::kRange);
-                curRange = appendRange(&curRange->fNext, gId - repeats - 1);
+                prevRange = curRange;
+                curRange = appendRange(&curRange->fNext, gId);
+                trailingWildCards = 0;
+            } else if (lastAdvance != 0 &&
+                       (repeatedAdvances + 1 >= 3 ||
+                        (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) {
+                finishRange(curRange,
+                            gId - repeatedAdvances - wildCardsInRun - 2,
+                            SkAdvancedTypefaceMetrics::WidthRange::kRange);
+                curRange =
+                    appendRange(&curRange->fNext,
+                                gId - repeatedAdvances - wildCardsInRun - 1);
                 curRange->fAdvance.append(1, &lastAdvance);
                 finishRange(curRange, gId - 1,
                             SkAdvancedTypefaceMetrics::WidthRange::kRun);
                 prevRange = curRange;
                 curRange = appendRange(&curRange->fNext, gId);
+                trailingWildCards = 0;
             }
-            repeats = 0;
+            repeatedAdvances = 0;
+            wildCardsInRun = trailingWildCards;
+            leadingWildCards = trailingWildCards;
+            trailingWildCards = 0;
         }
         curRange->fAdvance.append(1, &advance);
-        lastAdvance = advance;
+        if (advance != kDontCareAdvance) {
+            lastAdvance = advance;
+        }
     }
-    if (curRange->fStartId == num_glyphs) {
+    if (curRange->fStartId == lastIndex) {
         SkASSERT(prevRange);
-        SkASSERT(prevRange->fNext->fStartId == num_glyphs);
+        SkASSERT(prevRange->fNext->fStartId == lastIndex);
         prevRange->fNext.reset();
     } else {
-        finishRange(curRange, num_glyphs - 1,
+        finishRange(curRange, lastIndex - 1,
                     SkAdvancedTypefaceMetrics::WidthRange::kRange);
     }
     return result.release();
 }
 
 // Make AdvanceMetric template functions available for linking with typename
 // WidthRange and VerticalAdvanceRange.
 #if defined(SK_BUILD_FOR_WIN)
 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
         HDC hdc,
         int num_glyphs,
         const uint32_t* subsetGlyphIDs,
         uint32_t subsetGlyphIDsLength,
         bool (*getAdvance)(HDC hdc, int gId, int16_t* data));
-#elif defined(SK_BUILD_FOR_UNIX)
+#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
         FT_Face face,
         int num_glyphs,
         const uint32_t* subsetGlyphIDs,
         uint32_t subsetGlyphIDsLength,
         bool (*getAdvance)(FT_Face face, int gId, int16_t* data));
 #elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
--- a/gfx/skia/src/core/SkAntiRun.h
+++ b/gfx/skia/src/core/SkAntiRun.h
@@ -7,41 +7,71 @@
  */
 
 
 #ifndef SkAntiRun_DEFINED
 #define SkAntiRun_DEFINED
 
 #include "SkBlitter.h"
 
+/** Sparse array of run-length-encoded alpha (supersampling coverage) values.
+    Sparseness allows us to independently compose several paths into the
+    same SkAlphaRuns buffer.
+*/
+
 class SkAlphaRuns {
 public:
     int16_t*    fRuns;
     uint8_t*     fAlpha;
 
+    /// Returns true if the scanline contains only a single run,
+    /// of alpha value 0.
     bool empty() const {
         SkASSERT(fRuns[0] > 0);
         return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0;
     }
 
+    /// Reinitialize for a new scanline.
     void    reset(int width);
     
     /**
+     *  Insert into the buffer a run starting at (x-offsetX):
+     *      if startAlpha > 0
+     *          one pixel with value += startAlpha,
+     *              max 255
+     *      if middleCount > 0
+     *          middleCount pixels with value += maxValue
+     *      if stopAlpha > 0
+     *          one pixel with value += stopAlpha
      *  Returns the offsetX value that should be passed on the next call,
      *  assuming we're on the same scanline. If the caller is switching
      *  scanlines, then offsetX should be 0 when this is called.
      */
     int add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
             U8CPU maxValue, int offsetX);
 
     SkDEBUGCODE(void assertValid(int y, int maxStep) const;)
     SkDEBUGCODE(void dump() const;)
 
+    /**
+     * Break the runs in the buffer at offsets x and x+count, properly
+     * updating the runs to the right and left.
+     *   i.e. from the state AAAABBBB, run-length encoded as A4B4,
+     *   Break(..., 2, 5) would produce AAAABBBB rle as A2A2B3B1.
+     * Allows add() to sum another run to some of the new sub-runs.
+     *   i.e. adding ..CCCCC. would produce AADDEEEB, rle as A2D2E3B1.
+     */
     static void Break(int16_t runs[], uint8_t alpha[], int x, int count);
 
+    /**
+     * Cut (at offset x in the buffer) a run into two shorter runs with
+     * matching alpha values.
+     * Used by the RectClipBlitter to trim a RLE encoding to match the
+     * clipping rectangle.
+     */
     static void BreakAt(int16_t runs[], uint8_t alpha[], int x) {
         while (x > 0) {
             int n = runs[0];
             SkASSERT(n > 0);
 
             if (x < n) {
                 alpha[x] = alpha[0];
                 runs[0] = SkToS16(x);
--- a/gfx/skia/src/core/SkBitmap.cpp
+++ b/gfx/skia/src/core/SkBitmap.cpp
@@ -168,17 +168,17 @@ int SkBitmap::ComputeBytesPerPixel(SkBit
         case kRGB_565_Config:
         case kARGB_4444_Config:
             bpp = 2;
             break;
         case kARGB_8888_Config:
             bpp = 4;
             break;
         default:
-            SkASSERT(!"unknown config");
+            SkDEBUGFAIL("unknown config");
             bpp = 0;   // error
             break;
     }
     return bpp;
 }
 
 int SkBitmap::ComputeRowBytes(Config c, int width) {
     if (width < 0) {
@@ -206,17 +206,17 @@ int SkBitmap::ComputeRowBytes(Config c, 
             rowBytes.set(width);
             rowBytes.shiftLeft(1);
             break;
         case kARGB_8888_Config:
             rowBytes.set(width);
             rowBytes.shiftLeft(2);
             break;
         default:
-            SkASSERT(!"unknown config");
+            SkDEBUGFAIL("unknown config");
             break;
     }
     return isPos32Bits(rowBytes) ? rowBytes.get32() : 0;
 }
 
 Sk64 SkBitmap::ComputeSize64(Config c, int width, int height) {
     Sk64 size;
     size.setMul(SkBitmap::ComputeRowBytes(c, width), height);
@@ -404,16 +404,17 @@ uint32_t SkBitmap::getGenerationID() con
         if (fPixels && !fRawPixelGenerationID) {
             fRawPixelGenerationID = SkNextPixelRefGenerationID();
         }
         return fRawPixelGenerationID;
     }
 }
 
 void SkBitmap::notifyPixelsChanged() const {
+    SkASSERT(!this->isImmutable());
     if (fPixelRef) {
         fPixelRef->notifyPixelsChanged();
     } else {
         fRawPixelGenerationID = 0; // will grab next ID in getGenerationID
     }
 }
 
 SkGpuTexture* SkBitmap::getTexture() const {
@@ -451,29 +452,29 @@ size_t SkBitmap::getSafeSize() const {
     return (fHeight ? ((fHeight - 1) * fRowBytes) +
             ComputeRowBytes(getConfig(), fWidth): 0);
 }
 
 Sk64 SkBitmap::getSafeSize64() const {
     return ComputeSafeSize64(getConfig(), fWidth, fHeight, fRowBytes);
 }
 
-bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, int dstRowBytes)
-     const {
+bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, 
+                            int dstRowBytes, bool preserveDstPad) const {
 
     if (dstRowBytes == -1)
         dstRowBytes = fRowBytes;
     SkASSERT(dstRowBytes >= 0);
 
     if (getConfig() == kRLE_Index8_Config ||
         dstRowBytes < ComputeRowBytes(getConfig(), fWidth) ||
         dst == NULL || (getPixels() == NULL && pixelRef() == NULL))
         return false;
 
-    if (static_cast<uint32_t>(dstRowBytes) == fRowBytes) {
+    if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) {
         size_t safeSize = getSafeSize();
         if (safeSize > dstSize || safeSize == 0)
             return false;
         else {
             SkAutoLockPixels lock(*this);
             // This implementation will write bytes beyond the end of each row,
             // excluding the last row, if the bitmap's stride is greater than
             // strictly required by the current config.
@@ -497,52 +498,30 @@ bool SkBitmap::copyPixelsTo(void* const 
                 memcpy(dstP, srcP, rowBytes);
             }
 
             return true;
         }
     }
 }
 
-bool SkBitmap::copyPixelsFrom(const void* const src, size_t srcSize,
-                              int srcRowBytes) {
-
-    if (srcRowBytes == -1)
-        srcRowBytes = fRowBytes;
-    SkASSERT(srcRowBytes >= 0);
-
-    size_t safeSize = getSafeSize();
-    uint32_t rowBytes = ComputeRowBytes(getConfig(), fWidth);
-    if (getConfig() == kRLE_Index8_Config || src == NULL ||
-        static_cast<uint32_t>(srcRowBytes) < rowBytes ||
-        safeSize == 0 ||
-        srcSize < ComputeSafeSize(getConfig(), fWidth, fHeight, srcRowBytes)) {
-        return false;
-    }
+///////////////////////////////////////////////////////////////////////////////
 
-    SkAutoLockPixels lock(*this);
-    if (static_cast<uint32_t>(srcRowBytes) == fRowBytes) {
-        // This implementation will write bytes beyond the end of each row,
-        // excluding the last row, if the bitmap's stride is greater than
-        // strictly required by the current config.
-        memcpy(getPixels(), src, safeSize);
-    } else {
-        // Just copy the bytes we need on each line.
-        const uint8_t* srcP = reinterpret_cast<const uint8_t*>(src);
-        uint8_t* dstP = reinterpret_cast<uint8_t*>(getPixels());
-        for (uint32_t row = 0; row < fHeight;
-             row++, srcP += srcRowBytes, dstP += fRowBytes) {
-            memcpy(dstP, srcP, rowBytes);
-        }
-    }
-
-    return true;
+bool SkBitmap::isImmutable() const { 
+    return fPixelRef ? fPixelRef->isImmutable() :
+        fFlags & kImageIsImmutable_Flag; 
 }
 
-///////////////////////////////////////////////////////////////////////////////
+void SkBitmap::setImmutable() {
+    if (fPixelRef) {
+        fPixelRef->setImmutable();
+    } else {
+        fFlags |= kImageIsImmutable_Flag;
+    }
+}
 
 bool SkBitmap::isOpaque() const {
     switch (fConfig) {
         case kNo_Config:
             return true;
 
         case kA1_Config:
         case kA8_Config:
@@ -563,17 +542,17 @@ bool SkBitmap::isOpaque() const {
 
                 return (flags & SkColorTable::kColorsAreOpaque_Flag) != 0;
             }
 
         case kRGB_565_Config:
             return true;
 
         default:
-            SkASSERT(!"unknown bitmap config pased to isOpaque");
+            SkDEBUGFAIL("unknown bitmap config pased to isOpaque");
             return false;
     }
 }
 
 void SkBitmap::setIsOpaque(bool isOpaque) {
     /*  we record this regardless of fConfig, though it is ignored in
         isOpaque() for configs that can't support per-pixel alpha.
     */
@@ -614,21 +593,21 @@ void* SkBitmap::getAddr(int x, int y) co
             case SkBitmap::kA8_Config:
             case SkBitmap::kIndex8_Config:
                 base += x;
                 break;
             case SkBitmap::kA1_Config:
                 base += x >> 3;
                 break;
             case kRLE_Index8_Config:
-                SkASSERT(!"Can't return addr for kRLE_Index8_Config");
+                SkDEBUGFAIL("Can't return addr for kRLE_Index8_Config");
                 base = NULL;
                 break;
             default:
-                SkASSERT(!"Can't return addr for config");
+                SkDEBUGFAIL("Can't return addr for config");
                 base = NULL;
                 break;
         }
     }
     return base;
 }
 
 SkColor SkBitmap::getColor(int x, int y) const {
@@ -968,16 +947,39 @@ bool SkBitmap::copyTo(SkBitmap* dst, Con
     }
 
     tmpDst.setIsOpaque(src->isOpaque());
 
     dst->swap(tmpDst);
     return true;
 }
 
+bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
+    if (!this->canCopyTo(dstConfig)) {
+        return false;
+    }
+
+    // If we have a PixelRef, and it supports deep copy, use it.
+    // Currently supported only by texture-backed bitmaps.
+    if (fPixelRef) {
+        SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig);
+        if (pixelRef) {
+            dst->setConfig(dstConfig, fWidth, fHeight);
+            dst->setPixelRef(pixelRef)->unref();
+            return true;
+        }
+    }
+
+    if (this->getTexture()) {
+        return false;
+    } else {
+        return this->copyTo(dst, dstConfig, NULL);
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
 static void downsampleby2_proc32(SkBitmap* dst, int x, int y,
                                  const SkBitmap& src) {
     x <<= 1;
     y <<= 1;
     const SkPMColor* p = src.getAddr32(x, y);
@@ -1494,17 +1496,17 @@ void SkBitmap::unflatten(SkFlattenableRe
                 buffer.skip(size); // Still skip the full-sized buffer though.
             }
             SkSafeUnref(ctable);
             break;
         }
         case SERIALIZE_PIXELTYPE_NONE:
             break;
         default:
-            SkASSERT(!"unrecognized pixeltype in serialized data");
+            SkDEBUGFAIL("unrecognized pixeltype in serialized data");
             sk_throw();
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 SkBitmap::RLEPixels::RLEPixels(int width, int height) {
     fHeight = height;
--- a/gfx/skia/src/core/SkBitmapProcShader.cpp
+++ b/gfx/skia/src/core/SkBitmapProcShader.cpp
@@ -76,16 +76,20 @@ void SkBitmapProcShader::flatten(SkFlatt
     buffer.write8(fState.fTileModeY);
 }
 
 static bool only_scale_and_translate(const SkMatrix& matrix) {
     unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
     return (matrix.getType() & ~mask) == 0;
 }
 
+bool SkBitmapProcShader::isOpaque() const {
+    return fRawBitmap.isOpaque();
+}
+
 bool SkBitmapProcShader::setContext(const SkBitmap& device,
                                     const SkPaint& paint,
                                     const SkMatrix& matrix) {
     // do this first, so we have a correct inverse matrix
     if (!this->INHERITED::setContext(device, paint, matrix)) {
         return false;
     }
 
@@ -280,18 +284,17 @@ SkShader* SkShader::CreateBitmapShader(c
                               (color));
     } else {
         SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage,
                               storageSize, (src, tmx, tmy));
     }
     return shader;
 }
 
-static SkFlattenable::Registrar gBitmapProcShaderReg("SkBitmapProcShader",
-                                               SkBitmapProcShader::CreateProc);
+SK_DEFINE_FLATTENABLE_REGISTRAR(SkBitmapProcShader)
 
 ///////////////////////////////////////////////////////////////////////////////
 
 static const char* gTileModeName[] = {
     "clamp", "repeat", "mirror"
 };
 
 bool SkBitmapProcShader::toDumpString(SkString* str) const {
--- a/gfx/skia/src/core/SkBitmapProcShader.h
+++ b/gfx/skia/src/core/SkBitmapProcShader.h
@@ -13,16 +13,17 @@
 #include "SkShader.h"
 #include "SkBitmapProcState.h"
 
 class SkBitmapProcShader : public SkShader {
 public:
     SkBitmapProcShader(const SkBitmap& src, TileMode tx, TileMode ty);
 
     // overrides from SkShader
+    virtual bool isOpaque() const SK_OVERRIDE;
     virtual bool setContext(const SkBitmap&, const SkPaint&, const SkMatrix&);
     virtual uint32_t getFlags() { return fFlags; }
     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count);