Bug 755869 - [1] Update Skia to r4037 r=mattwoodrow
authorGeorge Wright <gwright@mozilla.com>
Wed, 23 May 2012 14:43:41 -0400
changeset 95142 5fb409f61b9358ed34360c80c420376f1c4bca0b
parent 95141 0bf91ba2ddba5f9d143256c8c1576fd97f9d6777
child 95143 477b8a5a716904dba4a86ab89c77505b6ea80670
push id22783
push useremorley@mozilla.com
push dateTue, 29 May 2012 11:53:52 +0000
treeherdermozilla-central@78852a6d11ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs755869
milestone15.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 755869 - [1] Update Skia to r4037 r=mattwoodrow
gfx/skia/README_MOZILLA
gfx/skia/include/config/SkUserConfig.h
gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
gfx/skia/include/core/SkBitmap.h
gfx/skia/include/core/SkBlitRow.h
gfx/skia/include/core/SkCanvas.h
gfx/skia/include/core/SkChunkAlloc.h
gfx/skia/include/core/SkClipStack.h
gfx/skia/include/core/SkColorFilter.h
gfx/skia/include/core/SkColorPriv.h
gfx/skia/include/core/SkColorShader.h
gfx/skia/include/core/SkComposeShader.h
gfx/skia/include/core/SkData.h
gfx/skia/include/core/SkDevice.h
gfx/skia/include/core/SkDeviceProfile.h
gfx/skia/include/core/SkDraw.h
gfx/skia/include/core/SkDrawLooper.h
gfx/skia/include/core/SkEmptyShader.h
gfx/skia/include/core/SkEndian.h
gfx/skia/include/core/SkFixed.h
gfx/skia/include/core/SkFlattenable.h
gfx/skia/include/core/SkFontHost.h
gfx/skia/include/core/SkGraphics.h
gfx/skia/include/core/SkImageFilter.h
gfx/skia/include/core/SkMallocPixelRef.h
gfx/skia/include/core/SkMaskFilter.h
gfx/skia/include/core/SkMath.h
gfx/skia/include/core/SkMatrix.h
gfx/skia/include/core/SkOrderedReadBuffer.h
gfx/skia/include/core/SkOrderedWriteBuffer.h
gfx/skia/include/core/SkPaint.h
gfx/skia/include/core/SkPath.h
gfx/skia/include/core/SkPathEffect.h
gfx/skia/include/core/SkPathMeasure.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/SkPtrRecorder.h
gfx/skia/include/core/SkRasterizer.h
gfx/skia/include/core/SkReader32.h
gfx/skia/include/core/SkRect.h
gfx/skia/include/core/SkRefCnt.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/SkStream.h
gfx/skia/include/core/SkString.h
gfx/skia/include/core/SkTDArray.h
gfx/skia/include/core/SkTSearch.h
gfx/skia/include/core/SkThread.h
gfx/skia/include/core/SkThread_platform.h
gfx/skia/include/core/SkTypeface.h
gfx/skia/include/core/SkTypes.h
gfx/skia/include/core/SkUtils.h
gfx/skia/include/core/SkWeakRefCnt.h
gfx/skia/include/core/SkWriter32.h
gfx/skia/include/core/SkXfermode.h
gfx/skia/include/effects/Sk1DPathEffect.h
gfx/skia/include/effects/Sk2DPathEffect.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/SkEmbossMaskFilter.h
gfx/skia/include/effects/SkGradientShader.h
gfx/skia/include/effects/SkGroupShape.h
gfx/skia/include/effects/SkKernel33MaskFilter.h
gfx/skia/include/effects/SkLayerDrawLooper.h
gfx/skia/include/effects/SkLayerRasterizer.h
gfx/skia/include/effects/SkMorphologyImageFilter.h
gfx/skia/include/effects/SkPaintFlagsDrawFilter.h
gfx/skia/include/effects/SkPixelXorXfermode.h
gfx/skia/include/effects/SkRectShape.h
gfx/skia/include/effects/SkTableColorFilter.h
gfx/skia/include/effects/SkTableMaskFilter.h
gfx/skia/include/effects/SkTestImageFilters.h
gfx/skia/include/effects/SkTransparentShader.h
gfx/skia/include/gpu/GrClip.h
gfx/skia/include/gpu/GrClipIterator.h
gfx/skia/include/gpu/GrConfig.h
gfx/skia/include/gpu/GrContext.h
gfx/skia/include/gpu/GrContextFactory.h
gfx/skia/include/gpu/GrCustomStage.h
gfx/skia/include/gpu/GrGlyph.h
gfx/skia/include/gpu/GrPaint.h
gfx/skia/include/gpu/GrProgramStageFactory.h
gfx/skia/include/gpu/GrRenderTarget.h
gfx/skia/include/gpu/GrResource.h
gfx/skia/include/gpu/GrSamplerState.h
gfx/skia/include/gpu/GrTextContext.h
gfx/skia/include/gpu/GrTexture.h
gfx/skia/include/gpu/GrTypes.h
gfx/skia/include/gpu/SkGpuDevice.h
gfx/skia/include/gpu/SkGr.h
gfx/skia/include/gpu/SkGrTexturePixelRef.h
gfx/skia/include/images/SkFlipPixelRef.h
gfx/skia/include/images/SkImageDecoder.h
gfx/skia/include/images/SkImageEncoder.h
gfx/skia/include/images/SkImageRef.h
gfx/skia/include/images/SkImageRef_GlobalPool.h
gfx/skia/include/pdf/SkPDFDevice.h
gfx/skia/include/pdf/SkPDFDocument.h
gfx/skia/include/ports/SkTypeface_android.h
gfx/skia/include/utils/SkCamera.h
gfx/skia/include/utils/SkDeferredCanvas.h
gfx/skia/include/utils/SkDumpCanvas.h
gfx/skia/include/utils/SkNWayCanvas.h
gfx/skia/include/utils/SkProxyCanvas.h
gfx/skia/include/utils/SkUnitMappers.h
gfx/skia/include/utils/SkWGL.h
gfx/skia/include/utils/mac/SkCGUtils.h
gfx/skia/include/views/SkOSWindow_Android.h
gfx/skia/include/views/SkOSWindow_Mac.h
gfx/skia/include/views/SkOSWindow_Unix.h
gfx/skia/include/views/SkOSWindow_Win.h
gfx/skia/include/views/SkOSWindow_iOS.h
gfx/skia/include/views/SkTextBox.h
gfx/skia/src/animator/SkAnimateActive.cpp
gfx/skia/src/animator/SkAnimator.cpp
gfx/skia/src/animator/SkDisplayEvent.cpp
gfx/skia/src/animator/SkDisplayNumber.cpp
gfx/skia/src/animator/SkDrawExtraPathEffect.cpp
gfx/skia/src/animator/SkDrawGradient.cpp
gfx/skia/src/core/SkAAClip.cpp
gfx/skia/src/core/SkBitmap.cpp
gfx/skia/src/core/SkBitmapProcShader.cpp
gfx/skia/src/core/SkBitmapProcShader.h
gfx/skia/src/core/SkBitmapProcState.cpp
gfx/skia/src/core/SkBitmapProcState.h
gfx/skia/src/core/SkBitmapProcState_matrix.h
gfx/skia/src/core/SkBitmapProcState_matrixProcs.cpp
gfx/skia/src/core/SkBitmapProcState_matrix_clamp.h
gfx/skia/src/core/SkBitmapProcState_matrix_repeat.h
gfx/skia/src/core/SkBitmapSampler.cpp
gfx/skia/src/core/SkBlitMask.h
gfx/skia/src/core/SkBlitMask_D32.cpp
gfx/skia/src/core/SkBlitRow_D32.cpp
gfx/skia/src/core/SkBlitRow_D4444.cpp
gfx/skia/src/core/SkBlitter.cpp
gfx/skia/src/core/SkBlitter_ARGB32.cpp
gfx/skia/src/core/SkCanvas.cpp
gfx/skia/src/core/SkChunkAlloc.cpp
gfx/skia/src/core/SkClipStack.cpp
gfx/skia/src/core/SkColorFilter.cpp
gfx/skia/src/core/SkComposeShader.cpp
gfx/skia/src/core/SkConfig8888.cpp
gfx/skia/src/core/SkConfig8888.h
gfx/skia/src/core/SkCoreBlitters.h
gfx/skia/src/core/SkCubicClipper.cpp
gfx/skia/src/core/SkDevice.cpp
gfx/skia/src/core/SkDeviceProfile.cpp
gfx/skia/src/core/SkDraw.cpp
gfx/skia/src/core/SkDrawProcs.h
gfx/skia/src/core/SkEdgeBuilder.cpp
gfx/skia/src/core/SkEdgeClipper.cpp
gfx/skia/src/core/SkFlate.cpp
gfx/skia/src/core/SkFlattenable.cpp
gfx/skia/src/core/SkGeometry.cpp
gfx/skia/src/core/SkGlyphCache.cpp
gfx/skia/src/core/SkGlyphCache.h
gfx/skia/src/core/SkGraphics.cpp
gfx/skia/src/core/SkLineClipper.cpp
gfx/skia/src/core/SkMMapStream.cpp
gfx/skia/src/core/SkMallocPixelRef.cpp
gfx/skia/src/core/SkMaskFilter.cpp
gfx/skia/src/core/SkMatrix.cpp
gfx/skia/src/core/SkMemory_stdlib.cpp
gfx/skia/src/core/SkOrderedReadBuffer.cpp
gfx/skia/src/core/SkOrderedWriteBuffer.cpp
gfx/skia/src/core/SkPaint.cpp
gfx/skia/src/core/SkPaintDefaults.h
gfx/skia/src/core/SkPath.cpp
gfx/skia/src/core/SkPathEffect.cpp
gfx/skia/src/core/SkPathHeap.cpp
gfx/skia/src/core/SkPathMeasure.cpp
gfx/skia/src/core/SkPictureFlat.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/SkPictureRecord.h
gfx/skia/src/core/SkPixelRef.cpp
gfx/skia/src/core/SkPoint.cpp
gfx/skia/src/core/SkPtrRecorder.cpp
gfx/skia/src/core/SkQuadClipper.cpp
gfx/skia/src/core/SkRasterClip.cpp
gfx/skia/src/core/SkRasterClip.h
gfx/skia/src/core/SkRasterizer.cpp
gfx/skia/src/core/SkRect.cpp
gfx/skia/src/core/SkRegion.cpp
gfx/skia/src/core/SkRegionPriv.h
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_Antihair.cpp
gfx/skia/src/core/SkScan_Hairline.cpp
gfx/skia/src/core/SkScan_Path.cpp
gfx/skia/src/core/SkShader.cpp
gfx/skia/src/core/SkShape.cpp
gfx/skia/src/core/SkString.cpp
gfx/skia/src/core/SkStroke.cpp
gfx/skia/src/core/SkStroke.h
gfx/skia/src/core/SkTLS.cpp
gfx/skia/src/core/SkTLS.h
gfx/skia/src/core/SkTSearch.cpp
gfx/skia/src/core/SkTSort.h
gfx/skia/src/core/SkTextFormatParams.h
gfx/skia/src/core/SkTypeface.cpp
gfx/skia/src/core/SkTypefaceCache.cpp
gfx/skia/src/core/SkTypefaceCache.h
gfx/skia/src/core/SkUtils.cpp
gfx/skia/src/core/SkWriter32.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/SkClampRange.cpp
gfx/skia/src/effects/SkClampRange.h
gfx/skia/src/effects/SkColorFilters.cpp
gfx/skia/src/effects/SkColorMatrix.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/SkEmbossMaskFilter.cpp
gfx/skia/src/effects/SkGradientShader.cpp
gfx/skia/src/effects/SkGroupShape.cpp
gfx/skia/src/effects/SkKernel33MaskFilter.cpp
gfx/skia/src/effects/SkLayerDrawLooper.cpp
gfx/skia/src/effects/SkLayerRasterizer.cpp
gfx/skia/src/effects/SkMorphologyImageFilter.cpp
gfx/skia/src/effects/SkPixelXorXfermode.cpp
gfx/skia/src/effects/SkRectShape.cpp
gfx/skia/src/effects/SkTableColorFilter.cpp
gfx/skia/src/effects/SkTableMaskFilter.cpp
gfx/skia/src/effects/SkTestImageFilters.cpp
gfx/skia/src/effects/SkTransparentShader.cpp
gfx/skia/src/gpu/GrAAConvexPathRenderer.cpp
gfx/skia/src/gpu/GrAAConvexPathRenderer.h
gfx/skia/src/gpu/GrAAHairLinePathRenderer.cpp
gfx/skia/src/gpu/GrAAHairLinePathRenderer.h
gfx/skia/src/gpu/GrAddPathRenderers_default.cpp
gfx/skia/src/gpu/GrAllocator.h
gfx/skia/src/gpu/GrAtlas.cpp
gfx/skia/src/gpu/GrBatchedTextContext.cpp
gfx/skia/src/gpu/GrBatchedTextContext.h
gfx/skia/src/gpu/GrBufferAllocPool.cpp
gfx/skia/src/gpu/GrBufferAllocPool.h
gfx/skia/src/gpu/GrClip.cpp
gfx/skia/src/gpu/GrClipMaskManager.cpp
gfx/skia/src/gpu/GrClipMaskManager.h
gfx/skia/src/gpu/GrContext.cpp
gfx/skia/src/gpu/GrCustomStage.cpp
gfx/skia/src/gpu/GrDefaultPathRenderer.cpp
gfx/skia/src/gpu/GrDefaultPathRenderer.h
gfx/skia/src/gpu/GrDefaultTextContext.cpp
gfx/skia/src/gpu/GrDefaultTextContext.h
gfx/skia/src/gpu/GrDrawState.h
gfx/skia/src/gpu/GrDrawTarget.cpp
gfx/skia/src/gpu/GrDrawTarget.h
gfx/skia/src/gpu/GrGpu.cpp
gfx/skia/src/gpu/GrGpu.h
gfx/skia/src/gpu/GrGpuFactory.cpp
gfx/skia/src/gpu/GrGpuVertex.h
gfx/skia/src/gpu/GrInOrderDrawBuffer.cpp
gfx/skia/src/gpu/GrInOrderDrawBuffer.h
gfx/skia/src/gpu/GrPathRenderer.cpp
gfx/skia/src/gpu/GrPathRenderer.h
gfx/skia/src/gpu/GrPathRendererChain.cpp
gfx/skia/src/gpu/GrPathRendererChain.h
gfx/skia/src/gpu/GrPathUtils.cpp
gfx/skia/src/gpu/GrPathUtils.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/GrSoftwarePathRenderer.cpp
gfx/skia/src/gpu/GrSoftwarePathRenderer.h
gfx/skia/src/gpu/GrStencil.cpp
gfx/skia/src/gpu/GrStencil.h
gfx/skia/src/gpu/SkGpuDevice.cpp
gfx/skia/src/gpu/SkGr.cpp
gfx/skia/src/gpu/SkGrFontScaler.cpp
gfx/skia/src/gpu/SkGrTexturePixelRef.cpp
gfx/skia/src/gpu/app-android.cpp
gfx/skia/src/gpu/gr_hello_world.cpp
gfx/skia/src/gpu/gr_unittests.cpp
gfx/skia/src/images/SkFlipPixelRef.cpp
gfx/skia/src/images/SkImageDecoder_libbmp.cpp
gfx/skia/src/images/SkImageDecoder_libgif.cpp
gfx/skia/src/images/SkImageDecoder_libico.cpp
gfx/skia/src/images/SkImageDecoder_libjpeg.cpp
gfx/skia/src/images/SkImageDecoder_libpng.cpp
gfx/skia/src/images/SkImageDecoder_wbmp.cpp
gfx/skia/src/images/SkImageRef.cpp
gfx/skia/src/images/SkImageRefPool.cpp
gfx/skia/src/images/SkImageRef_GlobalPool.cpp
gfx/skia/src/images/SkJpegUtility.cpp
gfx/skia/src/images/SkScaledBitmapSampler.cpp
gfx/skia/src/opts/SkBitmapProcState_opts_SSE2.cpp
gfx/skia/src/opts/SkBitmapProcState_opts_SSE2.h
gfx/skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp
gfx/skia/src/opts/SkBitmapProcState_opts_SSSE3.h
gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp
gfx/skia/src/opts/SkBlitRect_opts_SSE2.h
gfx/skia/src/opts/SkBlitRow_opts_SSE2.cpp
gfx/skia/src/opts/SkBlitRow_opts_SSE2.h
gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
gfx/skia/src/opts/SkBlitRow_opts_none.cpp
gfx/skia/src/opts/SkUtils_opts_none.cpp
gfx/skia/src/opts/memset.arm.S
gfx/skia/src/opts/opts_check_SSE2.cpp
gfx/skia/src/opts/opts_check_arm.cpp
gfx/skia/src/pdf/SkPDFCatalog.h
gfx/skia/src/pdf/SkPDFDevice.cpp
gfx/skia/src/pdf/SkPDFDocument.cpp
gfx/skia/src/pdf/SkPDFFont.cpp
gfx/skia/src/pdf/SkPDFFont.h
gfx/skia/src/pdf/SkPDFFormXObject.cpp
gfx/skia/src/pdf/SkPDFFormXObject.h
gfx/skia/src/pdf/SkPDFGraphicState.cpp
gfx/skia/src/pdf/SkPDFGraphicState.h
gfx/skia/src/pdf/SkPDFImage.h
gfx/skia/src/pdf/SkPDFPage.cpp
gfx/skia/src/pdf/SkPDFPage.h
gfx/skia/src/pdf/SkPDFShader.cpp
gfx/skia/src/pdf/SkPDFShader.h
gfx/skia/src/pdf/SkPDFStream.cpp
gfx/skia/src/pdf/SkPDFStream.h
gfx/skia/src/pdf/SkPDFTypes.cpp
gfx/skia/src/pdf/SkPDFTypes.h
gfx/skia/src/pdf/SkPDFUtils.cpp
gfx/skia/src/pdf/SkPDFUtils.h
gfx/skia/src/pipe/SkGPipePriv.h
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/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_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_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/SkImageDecoder_CG.cpp
gfx/skia/src/ports/SkImageRef_ashmem.cpp
gfx/skia/src/ports/SkImageRef_ashmem.h
gfx/skia/src/ports/SkOSFile_stdio.cpp
gfx/skia/src/ports/SkThread_none.cpp
gfx/skia/src/ports/SkThread_pthread.cpp
gfx/skia/src/ports/SkThread_win.cpp
gfx/skia/src/ports/SkXMLPullParser_expat.cpp
gfx/skia/src/svg/SkSVGCircle.cpp
gfx/skia/src/svg/SkSVGEllipse.cpp
gfx/skia/src/utils/SkBase64.cpp
gfx/skia/src/utils/SkBase64.h
gfx/skia/src/utils/SkBitSet.cpp
gfx/skia/src/utils/SkBitSet.h
gfx/skia/src/utils/SkCamera.cpp
gfx/skia/src/utils/SkDeferredCanvas.cpp
gfx/skia/src/utils/SkDumpCanvas.cpp
gfx/skia/src/utils/SkMatrix44.cpp
gfx/skia/src/utils/SkNWayCanvas.cpp
gfx/skia/src/utils/SkNinePatch.cpp
gfx/skia/src/utils/SkParsePath.cpp
gfx/skia/src/utils/SkThreadUtils.h
gfx/skia/src/utils/SkThreadUtils_pthread.cpp
gfx/skia/src/utils/SkThreadUtils_pthread.h
gfx/skia/src/utils/SkThreadUtils_pthread_linux.cpp
gfx/skia/src/utils/SkThreadUtils_pthread_mach.cpp
gfx/skia/src/utils/SkThreadUtils_pthread_other.cpp
gfx/skia/src/utils/SkThreadUtils_win.cpp
gfx/skia/src/utils/SkThreadUtils_win.h
gfx/skia/src/utils/SkUnitMappers.cpp
gfx/skia/src/utils/mac/SkStream_mac.cpp
gfx/skia/src/utils/win/SkHRESULT.cpp
gfx/skia/src/utils/win/SkWGL_win.cpp
gfx/skia/src/views/SkEventSink.cpp
gfx/skia/src/xml/SkJS.cpp
gfx/skia/src/xml/SkJSDisplayable.cpp
--- 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 r2980.
+The subversion revision used was r4037.
--- a/gfx/skia/include/config/SkUserConfig.h
+++ b/gfx/skia/include/config/SkUserConfig.h
@@ -81,16 +81,25 @@
 
 
 /*  preconfig will have attempted to determine the endianness of the system,
     but you can change these mutually exclusive flags here.
  */
 //#define SK_CPU_BENDIAN
 //#define SK_CPU_LENDIAN
 
+/*  Most compilers use the same bit endianness for bit flags in a byte as the
+    system byte endianness, and this is the default. If for some reason this
+    needs to be overridden, specify which of the mutually exclusive flags to
+    use. For example, some atom processors in certain configurations have big
+    endian byte order but little endian bit orders.
+*/
+//#define SK_UINT8_BITFIELD_BENDIAN
+//#define SK_UINT8_BITFIELD_LENDIAN
+
 
 /*  Some compilers don't support long long for 64bit integers. If yours does
     not, define this to the appropriate type.
  */
 //#define SkLONGLONG int64_t
 
 
 /*  To write debug messages to a console, skia will call SkDebugf(...) following
@@ -107,19 +116,21 @@
 
 /* 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.
+    include path. Alternatively, define SK_SYSTEM_ZLIB to use the system zlib
+    library specified as "#include <zlib.h>".
  */
 //#define SK_ZLIB_INCLUDE <zlib.h>
+//#define SK_SYSTEM_ZLIB
 
 /*  Define this to allow PDF scalars above 32k.  The PDF/A spec doesn't allow
     them, but modern PDF interpreters should handle them just fine.
  */
 //#define SK_ALLOW_LARGE_PDF_SCALARS
 
 /*  Define this to provide font subsetter in PDF generation.
  */
@@ -140,20 +151,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
 
-/*  Don't dither 32bit gradients, to match what the canvas test suite expects.
- */
-#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,
@@ -165,15 +172,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
 
-/*  Don't include stdint.h on windows as it conflicts with our build system.
- */
-#ifdef SK_BUILD_FOR_WIN32 
-    #define SK_IGNORE_STDINT_DOT_H 
-#endif 
-
 #endif
--- a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
+++ b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
@@ -29,17 +29,17 @@ public:
     SkString fFontName;
 
     enum FontType {
         kType1_Font,
         kType1CID_Font,
         kCFF_Font,
         kTrueType_Font,
         kOther_Font,
-        kNotEmbeddable_Font
+        kNotEmbeddable_Font,
     };
     // The type of the underlying font program.  This field determines which
     // of the following fields are valid.  If it is kOther_Font or
     // kNotEmbeddable_Font, the per glyph information will never be populated.
     FontType fType;
 
     // fMultiMaster may be true for Type1_Font or CFF_Font.
     bool fMultiMaster;
@@ -51,17 +51,17 @@ public:
         kFixedPitch_Style  = 0x00001,
         kSerif_Style       = 0x00002,
         kSymbolic_Style    = 0x00004,
         kScript_Style      = 0x00008,
         kNonsymbolic_Style = 0x00020,
         kItalic_Style      = 0x00040,
         kAllCaps_Style     = 0x10000,
         kSmallCaps_Style   = 0x20000,
-        kForceBold_Style   = 0x40000
+        kForceBold_Style   = 0x40000,
     };
     uint16_t fStyle;        // Font style characteristics.
     int16_t fItalicAngle;   // Counterclockwise degrees from vertical of the
                             // dominant vertical stroke for an Italic face.
     // The following fields are all in font units.
     int16_t fAscent;       // Max height above baseline, not including accents.
     int16_t fDescent;      // Max depth below baseline (negative).
     int16_t fStemV;        // Thickness of dominant vertical stem.
@@ -70,26 +70,26 @@ public:
     SkIRect fBBox;  // The bounding box of all glyphs (in font units).
 
     // The type of advance data wanted.
     enum PerGlyphInfo {
       kNo_PerGlyphInfo         = 0x0, // Don't populate any per glyph info.
       kHAdvance_PerGlyphInfo   = 0x1, // Populate horizontal advance data.
       kVAdvance_PerGlyphInfo   = 0x2, // Populate vertical advance data.
       kGlyphNames_PerGlyphInfo = 0x4, // Populate glyph names (Type 1 only).
-      kToUnicode_PerGlyphInfo  = 0x8  // Populate ToUnicode table, ignored
+      kToUnicode_PerGlyphInfo  = 0x8, // Populate ToUnicode table, ignored
                                       // for Type 1 fonts
     };
 
     template <typename Data>
     struct AdvanceMetric {
         enum MetricType {
             kDefault,  // Default advance: fAdvance.count = 1
             kRange,    // Advances for a range: fAdvance.count = fEndID-fStartID
-            kRun       // fStartID-fEndID have same advance: fAdvance.count = 1
+            kRun,      // fStartID-fEndID have same advance: fAdvance.count = 1
         };
         MetricType fType;
         uint16_t fStartId;
         uint16_t fEndId;
         SkTDArray<Data> fAdvance;
         SkTScopedPtr<AdvanceMetric<Data> > fNext;
     };
 
--- a/gfx/skia/include/core/SkBitmap.h
+++ b/gfx/skia/include/core/SkBitmap.h
@@ -11,16 +11,17 @@
 #define SkBitmap_DEFINED
 
 #include "Sk64.h"
 #include "SkColor.h"
 #include "SkPoint.h"
 #include "SkRefCnt.h"
 
 struct SkIRect;
+struct SkRect;
 class SkColorTable;
 class SkPaint;
 class SkPixelRef;
 class SkRegion;
 class SkFlattenableReadBuffer;
 class SkFlattenableWriteBuffer;
 
 // This is an opaque class, not interpreted by skia
@@ -58,26 +59,31 @@ public:
          *  Cannot be used as a destination (target of a canvas).
          *  i.e. you may be able to draw from one, but you cannot draw into one.
          */
         kRLE_Index8_Config,
 
         kConfigCount
     };
 
-    /** Default construct creates a bitmap with zero width and height, and no pixels.
-        Its config is set to kNo_Config.
-    */
+    /**
+     *  Default construct creates a bitmap with zero width and height, and no pixels.
+     *  Its config is set to kNo_Config.
+     */
     SkBitmap();
-    /** Constructor initializes the new bitmap by copying the src bitmap. All fields are copied,
-        but ownership of the pixels remains with the src bitmap.
-    */
+
+    /**
+     *  Copy the settings from the src into this bitmap. If the src has pixels
+     *  allocated, they will be shared, not copied, so that the two bitmaps will
+     *  reference the same memory for the pixels. If a deep copy is needed,
+     *  where the new bitmap has its own separate copy of the pixels, use
+     *  deepCopyTo().
+     */
     SkBitmap(const SkBitmap& src);
-    /** Decrements our (shared) pixel ownership if needed.
-    */
+
     ~SkBitmap();
 
     /** Copies the src bitmap into this bitmap. Ownership of the src bitmap's pixels remains
         with the src bitmap.
     */
     SkBitmap& operator=(const SkBitmap& src);
     /** Swap the fields of the two bitmaps. This routine is guaranteed to never fail or throw.
     */
@@ -213,16 +219,22 @@ public:
      */
     static int ComputeShiftPerPixel(Config c) {
         return ComputeBytesPerPixel(c) >> 1;
     }
 
     static Sk64 ComputeSize64(Config, int width, int height);
     static size_t ComputeSize(Config, int width, int height);
 
+    /**
+     *  Return the bitmap's bounds [0, 0, width, height] as an SkRect
+     */
+    void getBounds(SkRect* bounds) const;
+    void getBounds(SkIRect* bounds) const;
+
     /** Set the bitmap's config and dimensions. If rowBytes is 0, then
         ComputeRowBytes() is called to compute the optimal value. This resets
         any pixel/colortable ownership, just like reset().
     */
     void setConfig(Config, int width, int height, int rowBytes = 0);
     /** Use this to assign a new pixel address for an existing bitmap. This
         will automatically release any pixelref previously installed. Only call
         this if you are handling ownership/lifetime of the pixel memory.
--- a/gfx/skia/include/core/SkBlitRow.h
+++ b/gfx/skia/include/core/SkBlitRow.h
@@ -31,53 +31,64 @@ public:
         @param alpha A global alpha to be applied to all of the src colors
         @param x The x coordinate of the beginning of the scanline
         @param y THe y coordinate of the scanline
      */
     typedef void (*Proc)(uint16_t* dst,
                          const SkPMColor* src,
                          int count, U8CPU alpha, int x, int y);
 
-   /** Function pointer that blends a single color with a row of 32-bit colors
-       onto a 32-bit destination
-   */
-   typedef void (*ColorProc)(SkPMColor* dst, const SkPMColor* src, int count,
-                             SkPMColor color);
-
-    //! Public entry-point to return a blit function ptr
     static Proc Factory(unsigned flags, SkBitmap::Config);
 
     ///////////// D32 version
 
     enum Flags32 {
         kGlobalAlpha_Flag32     = 1 << 0,
-        kSrcPixelAlpha_Flag32   = 1 << 1
+        kSrcPixelAlpha_Flag32   = 1 << 1,
     };
 
     /** Function pointer that blends 32bit colors onto a 32bit destination.
         @param dst  array of dst 32bit colors
         @param src  array of src 32bit colors (w/ or w/o alpha)
         @param count number of colors to blend
         @param alpha global alpha to be applied to all src colors
      */
     typedef void (*Proc32)(uint32_t* dst,
                          const SkPMColor* src,
                          int count, U8CPU alpha);
 
     static Proc32 Factory32(unsigned flags32);
 
+   /** Function pointer that blends a single color with a row of 32-bit colors
+       onto a 32-bit destination
+   */
+   typedef void (*ColorProc)(SkPMColor* dst, const SkPMColor* src, int count,
+                             SkPMColor color);
+
     /** Blend a single color onto a row of S32 pixels, writing the result
         into a row of D32 pixels. src and dst may be the same memory, but
         if they are not, they may not overlap.
      */
     static void Color32(SkPMColor dst[], const SkPMColor src[],
                         int count, SkPMColor color);
 
+    //! Public entry-point to return a blit function ptr
     static ColorProc ColorProcFactory();
 
+    /** Function pointer that blends a single color onto a 32-bit rectangle.  */
+    typedef void (*ColorRectProc)(SkPMColor* dst, int width, int height,
+                                  size_t rowBytes, SkPMColor color);
+
+    /** Blend a single color into a rectangle of D32 pixels. */
+    static void ColorRect32(SkPMColor* dst, int width, int height,
+                            size_t rowBytes, SkPMColor color);
+
+    //! Public entry-point to return a blit function ptr
+    static ColorRectProc ColorRectProcFactory();
+
     /** These static functions are called by the Factory and Factory32
         functions, and should return either NULL, or a
         platform-specific function-ptr to be used in place of the
         system default.
      */
 
     static Proc32 PlatformProcs32(unsigned flags);
     static Proc PlatformProcs565(unsigned flags);
--- a/gfx/skia/include/core/SkCanvas.h
+++ b/gfx/skia/include/core/SkCanvas.h
@@ -57,54 +57,65 @@ public:
                         structure are copied to the canvas.
     */
     explicit SkCanvas(const SkBitmap& bitmap);
     virtual ~SkCanvas();
 
     ///////////////////////////////////////////////////////////////////////////
 
     /**
+     *  Trigger the immediate execution of all pending draw operations.
+     */
+    void flush();
+
+    /**
      *  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
         device, its reference count is decremented. The new device is returned.
     */
-    SkDevice* setDevice(SkDevice* device);
+    virtual SkDevice* setDevice(SkDevice* device);
 
     /**
      *  saveLayer() can create another device (which is later drawn onto
      *  the previous device). getTopDevice() returns the top-most device current
      *  installed. Note that this can change on other calls like save/restore,
      *  so do not access this device after subsequent canvas calls.
      *  The reference count of the device is not changed.
+     *
+     * @param updateMatrixClip If this is true, then before the device is
+     *        returned, we ensure that its has been notified about the current
+     *        matrix and clip. Note: this happens automatically when the device
+     *        is drawn to, but is optional here, as there is a small perf hit
+     *        sometimes.
      */
-    SkDevice* getTopDevice() const;
+    SkDevice* getTopDevice(bool updateMatrixClip = false) const;
 
     /**
      *  Create a new raster device and make it current. This also returns
      *  the new device.
      */
     SkDevice* setBitmapDevice(const SkBitmap& bitmap);
 
     /**
      *  Shortcut for getDevice()->createCompatibleDevice(...).
      *  If getDevice() == NULL, this method does nothing, and returns NULL.
      */
-    SkDevice* createCompatibleDevice(SkBitmap::Config config, 
+    SkDevice* createCompatibleDevice(SkBitmap::Config config,
                                     int width, int height,
                                     bool isOpaque);
 
     ///////////////////////////////////////////////////////////////////////////
 
     /**
      * 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
@@ -132,32 +143,32 @@ public:
          * 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
+        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 
+     *  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.
      *
@@ -285,17 +296,17 @@ public:
         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;
+    virtual 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);
 
@@ -419,31 +430,40 @@ public:
         that it is possible that if the method returns false, the band may still
         in fact be clipped out, but the converse is not true. If this method
         returns true, then the band is guaranteed to be clipped out.
         @param top  The top of the horizontal band to compare with the clip
         @param bottom The bottom of the horizontal and to compare with the clip
         @return true if the horizontal band is completely clipped out (i.e. does
                      not intersect the current clip)
     */
-    bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const;
+    bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const {
+        SkASSERT(SkScalarToCompareType(top) <= SkScalarToCompareType(bottom));
+        const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType(et);
+        // In the case where the clip is empty and we are provided with a
+        // negative top and positive bottom parameter then this test will return
+        // false even though it will be clipped. We have chosen to exclude that
+        // check as it is rare and would result double the comparisons.
+        return SkScalarToCompareType(top) >= clipR.fBottom
+            || SkScalarToCompareType(bottom) <= clipR.fTop;
+    }
 
     /** Return the bounds of the current clip (in local coordinates) in the
         bounds parameter, and return true if it is non-empty. This can be useful
         in a way similar to quickReject, in that it tells you that drawing
         outside of these bounds will be clipped out.
     */
     bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const;
 
     /** Return the bounds of the current clip, in device coordinates; returns
         true if non-empty. Maybe faster than getting the clip explicitly and
         then taking its bounds.
     */
     bool getClipDeviceBounds(SkIRect* bounds) const;
-       
+
 
     /** Fill the entire canvas' bitmap (restricted to the current clip) with the
         specified ARGB color, using the specified mode.
         @param a    the alpha component (0..255) of the color to fill the canvas
         @param r    the red component (0..255) of the color to fill the canvas
         @param g    the green component (0..255) of the color to fill the canvas
         @param b    the blue component (0..255) of the color to fill the canvas
         @param mode the mode to apply the color in (defaults to SrcOver)
@@ -854,36 +874,37 @@ public:
     };
 
     /** Returns a description of the total clip; may be cheaper than
         getting the clip and querying it directly.
     */
     ClipType getClipType() const;
 
     /** Return the current device clip (concatenation of all clip calls).
-        This does not account for the translate in any of the devices.
-        @return the current device clip (concatenation of all clip calls).
-    */
+     *  This does not account for the translate in any of the devices.
+     *  @return the current device clip (concatenation of all clip calls).
+     *
+     *  DEPRECATED -- call getClipDeviceBounds() instead.
+     */
     const SkRegion& getTotalClip() const;
 
+    void setExternalMatrix(const SkMatrix* = NULL);
+
+    class ClipVisitor {
+    public:
+        virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
+        virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
+    };
+
     /**
-     *  Return true if the current clip is non-empty.
-     *
-     *  If bounds is not NULL, set it to the bounds of the current clip
-     *  in global coordinates.
+     *  Replays the clip operations, back to front, that have been applied to
+     *  the canvas, calling the appropriate method on the visitor for each
+     *  clip. All clips have already been transformed into device space.
      */
-    bool getTotalClipBounds(SkIRect* bounds) const;
-
-    /**
-     *  Return the current clipstack. This mirrors the result in getTotalClip()
-     *  but is represented as a stack of geometric clips + region-ops.
-     */
-    const SkClipStack& getTotalClipStack() const;
-
-    void setExternalMatrix(const SkMatrix* = NULL);
+    void replayClips(ClipVisitor*) const;
 
     ///////////////////////////////////////////////////////////////////////////
 
     /** After calling saveLayer(), there can be any number of devices that make
         up the top-most drawing area. LayerIter can be used to iterate through
         those devices. Note that the iterator is only valid until the next API
         call made on the canvas. Ownership of all pointers in the iterator stays
         with the canvas, so none of them should be modified or deleted.
@@ -916,59 +937,72 @@ public:
         // safely with 32 and 64 bit machines (to ensure the storage is enough)
         intptr_t          fStorage[32];
         class SkDrawIter* fImpl;    // this points at fStorage
         SkPaint           fDefaultPaint;
         bool              fDone;
     };
 
 protected:
+    // Returns the canvas to be used by DrawIter. Default implementation
+    // returns this. Subclasses that encapsulate an indirect canvas may
+    // need to overload this method. The impl must keep track of this, as it
+    // is not released or deleted by the caller.
+    virtual SkCanvas* canvasForDrawIter();
+
     // all of the drawBitmap variants call this guy
-    virtual void commonDrawBitmap(const SkBitmap&, const SkIRect*,
-                                  const SkMatrix&, const SkPaint& paint);
+    void commonDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix&,
+                          const SkPaint& paint);
+
+    // Clip rectangle bounds. Called internally by saveLayer.
+    // returns false if the entire rectangle is entirely clipped out
+    bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
+                        SkIRect* intersection);
 
 private:
     class MCRec;
 
     SkClipStack fClipStack;
     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
+    int         fSaveLayerCount;    // 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()
+    friend class AutoDrawLooper;
 
-    SkDevice* createLayerDevice(SkBitmap::Config, int width, int height, 
+    SkDevice* createLayerDevice(SkBitmap::Config, int width, int height,
                                 bool isOpaque);
 
     SkDevice* init(SkDevice*);
 
     // internal methods are not virtual, so they can safely be called by other
     // canvas apis, without confusing subclasses (like SkPictureRecording)
     void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m,
                                   const SkPaint* paint);
     void internalDrawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
                                 const SkRect& dst, const SkPaint* paint);
     void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
                                 const SkRect& dst, const SkPaint* paint);
     void internalDrawPaint(const SkPaint& paint);
+    int internalSaveLayer(const SkRect* bounds, const SkPaint* paint,
+                          SaveFlags, bool justForImageFilter);
+    void internalDrawDevice(SkDevice*, int x, int y, const SkPaint*);
 
-        
-    void drawDevice(SkDevice*, int x, int y, const SkPaint*);
     // shared by save() and saveLayer()
     int internalSave(SaveFlags flags);
     void internalRestore();
     static void DrawRect(const SkDraw& draw, const SkPaint& paint,
                          const SkRect& r, SkScalar textSize);
     static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint,
                                     const char text[], size_t byteLength,
                                     SkScalar x, SkScalar y);
--- a/gfx/skia/include/core/SkChunkAlloc.h
+++ b/gfx/skia/include/core/SkChunkAlloc.h
@@ -12,28 +12,22 @@
 
 #include "SkTypes.h"
 
 class SkChunkAlloc : SkNoncopyable {
 public:
     SkChunkAlloc(size_t minSize);
     ~SkChunkAlloc();
 
-    /** Free up all allocated blocks. This invalidates all returned
-        pointers.
-    */
+    /**
+     *  Free up all allocated blocks. This invalidates all returned
+     *  pointers.
+     */
     void reset();
 
-    /** Reuse all allocated blocks. This invalidates all returned
-        pointers (like reset) but doesn't necessarily free up all
-        of the privately allocated blocks. This is more efficient
-        if you plan to reuse the allocator multiple times.
-    */
-    void reuse();
-
     enum AllocFailType {
         kReturnNil_AllocFailType,
         kThrow_AllocFailType
     };
     
     void* alloc(size_t bytes, AllocFailType);
     void* allocThrow(size_t bytes) {
         return this->alloc(bytes, kThrow_AllocFailType);
@@ -43,27 +37,30 @@ public:
         success, the number of bytes freed is returned, or 0 if the block could
         not be unallocated. This is a hint to the underlying allocator that
         the previous allocation may be reused, but the implementation is free
         to ignore this call (and return 0).
      */
     size_t unalloc(void* ptr);
     
     size_t totalCapacity() const { return fTotalCapacity; }
+    int blockCount() const { return fBlockCount; }
 
     /**
      *  Returns true if the specified address is within one of the chunks, and
      *  has at least 1-byte following the address (i.e. if addr points to the
      *  end of a chunk, then contains() will return false).
      */
     bool contains(const void* addr) const;
 
 private:
     struct Block;
+
     Block*  fBlock;
     size_t  fMinSize;
-    Block*  fPool;
+    size_t  fChunkSize;
     size_t  fTotalCapacity;
+    int     fBlockCount;
 
     Block* newBlock(size_t bytes, AllocFailType ftype);
 };
 
 #endif
--- a/gfx/skia/include/core/SkClipStack.h
+++ b/gfx/skia/include/core/SkClipStack.h
@@ -13,30 +13,29 @@
 
 struct SkRect;
 class SkPath;
 
 class SK_API SkClipStack {
 public:
     SkClipStack();
     SkClipStack(const SkClipStack& b);
-    ~SkClipStack() {}
+    ~SkClipStack();
 
     SkClipStack& operator=(const SkClipStack& b);
     bool operator==(const SkClipStack& b) const;
     bool operator!=(const SkClipStack& b) const { return !(*this == b); }
 
     void reset();
 
     int getSaveCount() const { return fSaveCount; }
     void save();
     void restore();
 
-    void clipDevRect(const SkIRect& ir,
-                     SkRegion::Op op = SkRegion::kIntersect_Op) {
+    void clipDevRect(const SkIRect& ir, SkRegion::Op op) {
         SkRect r;
         r.set(ir);
         this->clipDevRect(r, op, false);
     }
     void clipDevRect(const SkRect&, SkRegion::Op, bool doAA);
     void clipDevPath(const SkPath&, SkRegion::Op, bool doAA);
 
     class B2FIter {
@@ -44,17 +43,18 @@ public:
         /**
          * Creates an uninitialized iterator. Must be reset()
          */
         B2FIter();
 
         B2FIter(const SkClipStack& stack);
 
         struct Clip {
-            Clip() : fRect(NULL), fPath(NULL), fOp(SkRegion::kIntersect_Op) {}
+            Clip() : fRect(NULL), fPath(NULL), fOp(SkRegion::kIntersect_Op), 
+                     fDoAA(false) {}
             friend bool operator==(const Clip& a, const Clip& b);
             friend bool operator!=(const Clip& a, const Clip& b);
             const SkRect*   fRect;  // if non-null, this is a rect clip
             const SkPath*   fPath;  // if non-null, this is a path clip
             SkRegion::Op    fOp;
             bool            fDoAA;
         };
 
--- a/gfx/skia/include/core/SkColorFilter.h
+++ b/gfx/skia/include/core/SkColorFilter.h
@@ -113,17 +113,17 @@ public:
 
     /** 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()
+    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
 protected:
     SkColorFilter() {}
     SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
 
 private:
     typedef SkFlattenable INHERITED;
 };
 
@@ -138,22 +138,22 @@ public:
     virtual uint32_t getFlags();
     virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
                             const SkMatrix& matrix);
     virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
     virtual void shadeSpan16(int x, int y, uint16_t result[], int count);
     virtual void beginSession();
     virtual void endSession();
 
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkFilterShader)
+
 protected:
     SkFilterShader(SkFlattenableReadBuffer& );
-    virtual void flatten(SkFlattenableWriteBuffer& ) SK_OVERRIDE;
-    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+
 private:
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkFilterShader, (buffer)); }
     SkShader*       fShader;
     SkColorFilter*  fFilter;
 
     typedef SkShader INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/core/SkColorPriv.h
+++ b/gfx/skia/include/core/SkColorPriv.h
@@ -211,16 +211,78 @@ static inline SkPMColor SkPackARGB32(U8C
     SkASSERT(g <= a);
     SkASSERT(b <= a);
 
     return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
            (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
 }
 
 /**
+ * Abstract 4-byte interpolation, implemented on top of SkPMColor
+ * utility functions. Third parameter controls blending of the first two:
+ *   (src, dst, 0) returns dst
+ *   (src, dst, 0xFF) returns src
+ *   srcWeight is [0..256], unlike SkFourByteInterp which takes [0..255]
+ */
+static inline SkPMColor SkFourByteInterp256(SkPMColor src, SkPMColor dst,
+                                         unsigned scale) {
+    unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale);
+    unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale);
+    unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale);
+    unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale);
+    
+    return SkPackARGB32(a, r, g, b);
+}
+
+/**
+ * Abstract 4-byte interpolation, implemented on top of SkPMColor
+ * utility functions. Third parameter controls blending of the first two:
+ *   (src, dst, 0) returns dst
+ *   (src, dst, 0xFF) returns src
+ */
+static inline SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst,
+                                         U8CPU srcWeight) {
+    unsigned scale = SkAlpha255To256(srcWeight);
+    return SkFourByteInterp256(src, dst, scale);
+}
+
+/**
+ * 32b optimized version; currently appears to be 10% faster even on 64b
+ * architectures than an equivalent 64b version and 30% faster than
+ * SkFourByteInterp(). Third parameter controls blending of the first two:
+ *   (src, dst, 0) returns dst
+ *   (src, dst, 0xFF) returns src
+ * ** Does not match the results of SkFourByteInterp() because we use
+ * a more accurate scale computation!
+ * TODO: migrate Skia function to using an accurate 255->266 alpha
+ * conversion.
+ */
+static inline SkPMColor SkFastFourByteInterp(SkPMColor src,
+                                             SkPMColor dst,
+                                             U8CPU srcWeight) {
+    SkASSERT(srcWeight < 256);
+
+    // Reorders ARGB to AG-RB in order to reduce the number of operations.
+    const uint32_t mask = 0xFF00FF;
+    uint32_t src_rb = src & mask;
+    uint32_t src_ag = (src >> 8) & mask;
+    uint32_t dst_rb = dst & mask;
+    uint32_t dst_ag = (dst >> 8) & mask;
+
+    // scale = srcWeight + (srcWeight >> 7) is more accurate than
+    // scale = srcWeight + 1, but 7% slower
+    int scale = srcWeight + (srcWeight >> 7);
+
+    uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb;
+    uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag;
+
+    return (ret_ag & ~mask) | ((ret_rb & ~mask) >> 8);
+}
+
+/**
  *  Same as SkPackARGB32, but this version guarantees to not check that the
  *  values are premultiplied in the debug version.
  */
 static inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
     return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
            (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
 }
 
@@ -658,10 +720,121 @@ static inline uint32_t SkExpand32_4444(S
             (((c >> (SK_B32_SHIFT + 4)) & 0xF) << 16) |
             (((c >> (SK_A32_SHIFT + 4)) & 0xF) <<  0);
 }
 
 // takes two values and alternamtes them as part of a memset16
 // used for cheap 2x2 dithering when the colors are opaque
 void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n);
 
+///////////////////////////////////////////////////////////////////////////////
+
+static inline int SkUpscale31To32(int value) {
+    SkASSERT((unsigned)value <= 31);
+    return value + (value >> 4);
+}
+
+static inline int SkBlend32(int src, int dst, int scale) {
+    SkASSERT((unsigned)src <= 0xFF);
+    SkASSERT((unsigned)dst <= 0xFF);
+    SkASSERT((unsigned)scale <= 32);
+    return dst + ((src - dst) * scale >> 5);
+}
+
+static inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB,
+                                     SkPMColor dst, uint16_t mask) { 
+    if (mask == 0) {
+        return dst;
+    }
+        
+    /*  We want all of these in 5bits, hence the shifts in case one of them
+     *  (green) is 6bits.
+     */
+    int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
+    int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
+    int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
+        
+    // Now upscale them to 0..32, so we can use blend32
+    maskR = SkUpscale31To32(maskR);
+    maskG = SkUpscale31To32(maskG);
+    maskB = SkUpscale31To32(maskB);
+     
+    // srcA has been upscaled to 256 before passed into this function
+    maskR = maskR * srcA >> 8;
+    maskG = maskG * srcA >> 8;
+    maskB = maskB * srcA >> 8;
+        
+    int dstR = SkGetPackedR32(dst);
+    int dstG = SkGetPackedG32(dst);
+    int dstB = SkGetPackedB32(dst);
+        
+    // LCD blitting is only supported if the dst is known/required
+    // to be opaque
+    return SkPackARGB32(0xFF,
+                        SkBlend32(srcR, dstR, maskR),
+                        SkBlend32(srcG, dstG, maskG),
+                        SkBlend32(srcB, dstB, maskB));
+}
+
+static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB,
+                                           SkPMColor dst, uint16_t mask,
+                                           SkPMColor opaqueDst) { 
+    if (mask == 0) {
+        return dst;
+    }
+
+    if (0xFFFF == mask) {
+        return opaqueDst;
+    }
+        
+    /*  We want all of these in 5bits, hence the shifts in case one of them
+     *  (green) is 6bits.
+     */
+    int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
+    int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
+    int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
+        
+    // Now upscale them to 0..32, so we can use blend32
+    maskR = SkUpscale31To32(maskR);
+    maskG = SkUpscale31To32(maskG);
+    maskB = SkUpscale31To32(maskB);
+        
+    int dstR = SkGetPackedR32(dst);
+    int dstG = SkGetPackedG32(dst);
+    int dstB = SkGetPackedB32(dst);
+        
+    // LCD blitting is only supported if the dst is known/required
+    // to be opaque
+    return SkPackARGB32(0xFF,
+                        SkBlend32(srcR, dstR, maskR),
+                        SkBlend32(srcG, dstG, maskG),
+                        SkBlend32(srcB, dstB, maskB));
+}
+
+static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t src[],
+                                  SkColor color, int width, SkPMColor) {
+    int srcA = SkColorGetA(color);
+    int srcR = SkColorGetR(color);
+    int srcG = SkColorGetG(color);
+    int srcB = SkColorGetB(color);
+    
+    srcA = SkAlpha255To256(srcA);
+    
+    for (int i = 0; i < width; i++) {
+        dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], src[i]);
+    }
+}
+
+static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t src[],
+                                        SkColor color, int width, 
+                                        SkPMColor opaqueDst) {
+    int srcR = SkColorGetR(color);
+    int srcG = SkColorGetG(color);
+    int srcB = SkColorGetB(color);
+    
+    for (int i = 0; i < width; i++) {
+        dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], src[i],
+                                    opaqueDst); 
+    }
+}
+
 #endif
 
--- a/gfx/skia/include/core/SkColorShader.h
+++ b/gfx/skia/include/core/SkColorShader.h
@@ -44,24 +44,23 @@ public:
     // we return false for this, use asAGradient
     virtual BitmapType asABitmap(SkBitmap* outTexture,
                                  SkMatrix* outMatrix,
                                  TileMode xy[2],
                                  SkScalar* twoPointRadialParams) const SK_OVERRIDE;
 
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
 
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader)
+
 protected:
     SkColorShader(SkFlattenableReadBuffer&);
-
-    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
-    virtual Factory getFactory() SK_OVERRIDE;
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
-    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/SkComposeShader.h
+++ b/gfx/skia/include/core/SkComposeShader.h
@@ -35,24 +35,23 @@ public:
     virtual ~SkComposeShader();
     
     // override
     virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix);
     virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
     virtual void beginSession();
     virtual void endSession();
 
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader)
+
 protected:
     SkComposeShader(SkFlattenableReadBuffer& );
-    virtual void flatten(SkFlattenableWriteBuffer& );
-    virtual Factory getFactory() { return CreateProc; }
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 
-        return SkNEW_ARGS(SkComposeShader, (buffer)); }
 
     SkShader*   fShaderA;
     SkShader*   fShaderB;
     SkXfermode* fMode;
 
     typedef SkShader INHERITED;
 };
 
--- a/gfx/skia/include/core/SkData.h
+++ b/gfx/skia/include/core/SkData.h
@@ -60,18 +60,18 @@ public:
     /**
      *  Create a new dataref, taking the data ptr as is, and using the
      *  releaseproc to free it. The proc may be NULL.
      */
     static SkData* NewWithProc(const void* data, size_t length,
                                ReleaseProc proc, void* context);
 
     /**
-     *  Create a new dataref, reference the data ptr as is, and calling
-     *  sk_free to delete it.
+     *  Create a new dataref from a pointer allocated by malloc. The Data object
+     *  takes ownership of that allocation, and will handling calling sk_free.
      */
     static SkData* NewFromMalloc(const void* data, size_t length);
 
     /**
      *  Create a new dataref using a subset of the data in the specified
      *  src dataref.
      */
     static SkData* NewSubset(const SkData* src, size_t offset, size_t length);
--- a/gfx/skia/include/core/SkDevice.h
+++ b/gfx/skia/include/core/SkDevice.h
@@ -57,17 +57,17 @@ public:
      *  (e.g. offscreen pixels or FBO or whatever is appropriate).
      *
      *  @param width    width of the device to create
      *  @param height   height of the device to create
      *  @param isOpaque performance hint, set to true if you know that you will
      *                  draw into this device such that all of the pixels will
      *                  be opaque.
      */
-    SkDevice* createCompatibleDevice(SkBitmap::Config config, 
+    SkDevice* createCompatibleDevice(SkBitmap::Config config,
                                      int width, int height,
                                      bool isOpaque);
 
     SkMetaData& getMetaData();
 
     enum Capabilities {
         kGL_Capability     = 0x1,  //!< mask indicating GL support
         kVector_Capability = 0x2,  //!< mask indicating a vector representation
@@ -134,17 +134,17 @@ public:
      *  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
+       kSaveLayer_Usage, // <! internal use only
     };
 
     struct TextFlags {
         uint32_t            fFlags;     // SkPaint::getFlags()
         SkPaint::Hinting    fHinting;
     };
 
     /**
@@ -253,17 +253,17 @@ protected:
      *
      *  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 
+     *  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.
      *
@@ -274,29 +274,32 @@ protected:
      *      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.
+    /** 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.
+        @param bitmap The device's bitmap
+        @return Echo the bitmap parameter, or an alternate (shadow) bitmap 
+            maintained by the subclass.
     */
-    virtual void onAccessBitmap(SkBitmap*);
+    virtual const SkBitmap& 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,
@@ -305,48 +308,80 @@ protected:
 
     /** 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.
+     *  Returns true if the device allows processing of this imagefilter. If
+     *  false is returned, then the filter is ignored. This may happen for
+     *  some subclasses that do not support pixel manipulations after drawing
+     *  has occurred (e.g. printing). The default implementation returns true.
      */
-    virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
-                             const SkMatrix& ctm,
+    virtual bool allowImageFilter(SkImageFilter*);
+
+    /**
+     *  Override and return true for filters that the device can handle
+     *  intrinsically. Doing so means that SkCanvas will pass-through this
+     *  filter to drawSprite and drawDevice (and potentially filterImage).
+     *  Returning false means the SkCanvas will have apply the filter itself,
+     *  and just pass the resulting image to the device.
+     */
+    virtual bool canHandleImageFilter(SkImageFilter*);
+
+    /**
+     *  Related (but not required) to canHandleImageFilter, this method returns
+     *  true if the device could apply the filter to the src bitmap and return
+     *  the result (and updates offset as needed).
+     *  If the device does not recognize or support this filter,
+     *  it just returns false and leaves result and offset unchanged.
+     */
+    virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&,
                              SkBitmap* result, SkIPoint* offset);
 
-    // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if 
+    // 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;
 
+    /**
+     * postSave is called by SkCanvas to inform the device that it has
+     * just completed a save operation. This allows derived
+     * classes to initialize their state-dependent caches.
+     */
+    virtual void postSave() {};
+
+    /**
+     * preRestore is called by SkCanvas right before it executes a restore
+     * operation. As the partner of postSave, it allows
+     * derived classes to clear their state-dependent caches.
+     */
+    virtual void preRestore() {};
+
     // 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, 
+    SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
                                                  int width, int height,
                                                  bool isOpaque);
 
     /**
      * Subclasses should override this to implement createCompatibleDevice.
      */
-    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, 
-                                               int width, int height, 
+    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
+                                               int width, int height,
                                                bool isOpaque,
                                                Usage usage);
 
     /** Causes any deferred drawing to the device to be completed.
      */
     virtual void flush() {}
 
     SkBitmap    fBitmap;
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/core/SkDeviceProfile.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDeviceProfile_DEFINED
+#define SkDeviceProfile_DEFINED
+
+#include "SkRefCnt.h"
+
+class SkDeviceProfile : public SkRefCnt {
+public:
+    enum LCDConfig {
+        kNone_LCDConfig,   // disables LCD text rendering, uses A8 instead
+        kRGB_Horizontal_LCDConfig,
+        kBGR_Horizontal_LCDConfig,
+        kRGB_Vertical_LCDConfig,
+        kBGR_Vertical_LCDConfig,
+    };
+
+    enum FontHintLevel {
+        kNone_FontHintLevel,
+        kSlight_FontHintLevel,
+        kNormal_FontHintLevel,
+        kFull_FontHintLevel,
+        kAuto_FontHintLevel,
+    };
+
+    /**
+     *  gammaExp is typically between 1.0 and 2.2. For no gamma adjustment,
+     *  specify 1.0
+     *
+     *  contrastScale will be pinned between 0.0 and 1.0. For no contrast
+     *  adjustment, specify 0.0
+     *
+     *  @param config   Describes the LCD layout for this device. If this is set
+     *                  to kNone, then all requests for LCD text will be
+     *                  devolved to A8 antialiasing.
+     *
+     *  @param level    The hinting level to be used, IF the paint specifies
+     *                  "default". Otherwise the paint's hinting level will be
+     *                  respected.
+     */
+    static SkDeviceProfile* Create(float gammaExp,
+                                   float contrastScale,
+                                   LCDConfig,
+                                   FontHintLevel);
+
+    /**
+     *  Returns the global default profile, that is used if no global profile is
+     *  specified with SetGlobal(), or if NULL is specified to SetGlobal().
+     *  The references count is *not* incremented, and the caller should not
+     *  call unref().
+     */
+    static SkDeviceProfile* GetDefault();
+
+    /**
+     *  Return the current global profile (or the default if no global had yet
+     *  been set) and increment its reference count. The call *must* call unref()
+     *  when it is done using it.
+     */
+    static SkDeviceProfile* RefGlobal();
+
+    /**
+     *  Make the specified profile be the global value for all subsequently
+     *  instantiated devices. Does not affect any existing devices.
+     *  Increments the reference count on the profile.
+     *  Specify NULL for the "identity" profile (where there is no gamma or
+     *  contrast correction).
+     */
+    static void SetGlobal(SkDeviceProfile*);
+
+    float getFontGammaExponent() const { return fGammaExponent; }
+    float getFontContrastScale() const { return fContrastScale; }
+
+    /**
+     *  Given a luminance byte (0 for black, 0xFF for white), generate a table
+     *  that applies the gamma/contrast settings to linear coverage values.
+     */
+    void generateTableForLuminanceByte(U8CPU lumByte, uint8_t table[256]) const;
+
+private:
+    SkDeviceProfile(float gammaExp, float contrastScale, LCDConfig,
+                    FontHintLevel);
+
+    float           fGammaExponent;
+    float           fContrastScale;
+    LCDConfig       fLCDConfig;
+    FontHintLevel   fFontHintLevel;
+};
+
+#endif
+
--- a/gfx/skia/include/core/SkDraw.h
+++ b/gfx/skia/include/core/SkDraw.h
@@ -72,17 +72,18 @@ public:
 
     /** Helper function that creates a mask from a path and an optional maskfilter.
         Note however, that the resulting mask will not have been actually filtered,
         that must be done afterwards (by calling filterMask). The maskfilter is provided
         solely to assist in computing the mask's bounds (if the mode requests that).
     */
     static bool DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
                            SkMaskFilter* filter, const SkMatrix* filterMatrix,
-                           SkMask* mask, SkMask::CreateMode mode);
+                           SkMask* mask, SkMask::CreateMode mode,
+                           SkPaint::Style style);
 
     enum RectType {
         kHair_RectType,
         kFill_RectType,
         kStroke_RectType,
         kPath_RectType
     };
 
@@ -123,18 +124,18 @@ public:
     void validate() const {}
 #endif
 };
 
 class SkGlyphCache;
 
 class SkTextToPathIter {
 public:
-    SkTextToPathIter(const char text[], size_t length, const SkPaint&,
-                     bool applyStrokeAndPathEffects, bool forceLinearTextOn);
+    SkTextToPathIter(const char text[], size_t length, const SkPaint& paint,
+                     bool applyStrokeAndPathEffects);
     ~SkTextToPathIter();
 
     const SkPaint&  getPaint() const { return fPaint; }
     SkScalar        getPathScale() const { return fScale; }
 
     const SkPath*   next(SkScalar* xpos);   //!< returns nil when there are no more paths
 
 private:
--- a/gfx/skia/include/core/SkDrawLooper.h
+++ b/gfx/skia/include/core/SkDrawLooper.h
@@ -40,16 +40,30 @@ public:
      *  will be as it was following the previous call to next() or init().
      *
      *  The implementation must ensure that, when next() finally returns false,
      *  that the canvas has been restored to the state it was initially, before
      *  init() was first called.
      */
     virtual bool next(SkCanvas*, SkPaint* paint) = 0;
     
+    /**
+     * The fast bounds functions are used to enable the paint to be culled early
+     * in the drawing pipeline. If a subclass can support this feature it must
+     * return true for the canComputeFastBounds() function.  If that function
+     * returns false then computeFastBounds behavior is undefined otherwise it
+     * is expected to have the following behavior. Given the parent paint and
+     * the parent's bounding rect the subclass must fill in and return the
+     * storage rect, where the storage rect is with the union of the src rect
+     * and the looper's bounding rect.
+     */
+    virtual bool canComputeFastBounds(const SkPaint& paint);
+    virtual void computeFastBounds(const SkPaint& paint,
+                                   const SkRect& src, SkRect* dst);
+
 protected:
     SkDrawLooper() {}
     SkDrawLooper(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
 
 private:
     typedef SkFlattenable INHERITED;
 };
 
--- a/gfx/skia/include/core/SkEmptyShader.h
+++ b/gfx/skia/include/core/SkEmptyShader.h
@@ -25,19 +25,18 @@ public:
     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&);
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader)
 
-    virtual Factory getFactory() SK_OVERRIDE;
-    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+protected:
+    SkEmptyShader(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
 
 private:
     typedef SkShader INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/core/SkEndian.h
+++ b/gfx/skia/include/core/SkEndian.h
@@ -26,18 +26,21 @@
     #error "need either LENDIAN or BENDIAN defined"
 #endif
 
 /** Swap the two bytes in the low 16bits of the parameters.
     e.g. 0x1234 -> 0x3412
 */
 static inline uint16_t SkEndianSwap16(U16CPU value) {
     SkASSERT(value == (uint16_t)value);
-    return (uint16_t)((value >> 8) | (value << 8));
+    return static_cast<uint16_t>((value >> 8) | (value << 8));
 }
+template<uint16_t N> struct SkTEndianSwap16 {
+    static const uint16_t value = static_cast<uint16_t>((N >> 8) | ((N & 0xFF) << 8));
+};
 
 /** Vector version of SkEndianSwap16(), which swaps the
     low two bytes of each value in the array.
 */
 static inline void SkEndianSwap16s(uint16_t array[], int count) {
     SkASSERT(count == 0 || array != NULL);
 
     while (--count >= 0) {
@@ -50,16 +53,22 @@ static inline void SkEndianSwap16s(uint1
     e.g. 0x12345678 -> 0x78563412
 */
 static inline uint32_t SkEndianSwap32(uint32_t value) {
     return  ((value & 0xFF) << 24) |
             ((value & 0xFF00) << 8) |
             ((value & 0xFF0000) >> 8) |
             (value >> 24);
 }
+template<uint32_t N> struct SkTEndianSwap32 {
+    static const uint32_t value = ((N & 0xFF) << 24) |
+                                  ((N & 0xFF00) << 8) |
+                                  ((N & 0xFF0000) >> 8) |
+                                  (N >> 24);
+};
 
 /** Vector version of SkEndianSwap16(), which swaps the
     bytes of each value in the array.
 */
 static inline void SkEndianSwap32s(uint32_t array[], int count) {
     SkASSERT(count == 0 || array != NULL);
 
     while (--count >= 0) {
@@ -68,31 +77,76 @@ static inline void SkEndianSwap32s(uint3
     }
 }
 
 #ifdef SK_CPU_LENDIAN
     #define SkEndian_SwapBE16(n)    SkEndianSwap16(n)
     #define SkEndian_SwapBE32(n)    SkEndianSwap32(n)
     #define SkEndian_SwapLE16(n)    (n)
     #define SkEndian_SwapLE32(n)    (n)
+
+    #define SkTEndian_SwapBE16(n)    SkTEndianSwap16<n>::value
+    #define SkTEndian_SwapBE32(n)    SkTEndianSwap32<n>::value
+    #define SkTEndian_SwapLE16(n)    (n)
+    #define SkTEndian_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)
+
+    #define SkTEndian_SwapBE16(n)    (n)
+    #define SkTEndian_SwapBE32(n)    (n)
+    #define SkTEndian_SwapLE16(n)    SkTEndianSwap16<n>::value
+    #define SkTEndian_SwapLE32(n)    SkTEndianSwap32<n>::value
 #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
 
+
+#if defined(SK_UINT8_BITFIELD_LENDIAN) && defined(SK_UINT8_BITFIELD_BENDIAN)
+    #error "can't have both bitfield LENDIAN and BENDIAN defined"
+#endif
+
+#if !defined(SK_UINT8_BITFIELD_LENDIAN) && !defined(SK_UINT8_BITFIELD_BENDIAN)
+    #ifdef SK_CPU_LENDIAN
+        #define SK_UINT8_BITFIELD_LENDIAN
+    #else
+        #define SK_UINT8_BITFIELD_BENDIAN
+    #endif
 #endif
 
+#ifdef SK_UINT8_BITFIELD_LENDIAN
+    #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \
+        SK_OT_BYTE f0 : 1; \
+        SK_OT_BYTE f1 : 1; \
+        SK_OT_BYTE f2 : 1; \
+        SK_OT_BYTE f3 : 1; \
+        SK_OT_BYTE f4 : 1; \
+        SK_OT_BYTE f5 : 1; \
+        SK_OT_BYTE f6 : 1; \
+        SK_OT_BYTE f7 : 1;
+#else
+    #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \
+        SK_OT_BYTE f7 : 1; \
+        SK_OT_BYTE f6 : 1; \
+        SK_OT_BYTE f5 : 1; \
+        SK_OT_BYTE f4 : 1; \
+        SK_OT_BYTE f3 : 1; \
+        SK_OT_BYTE f2 : 1; \
+        SK_OT_BYTE f1 : 1; \
+        SK_OT_BYTE f0 : 1;
+#endif
+
+#endif
+
--- a/gfx/skia/include/core/SkFixed.h
+++ b/gfx/skia/include/core/SkFixed.h
@@ -259,9 +259,25 @@ inline bool SkFixedNearlyZero(SkFixed x,
 #endif
 #ifndef SkFractMul
     #define SkFractMul(x, y)    SkFractMul_portable(x, y)
 #endif
 #ifndef SkFixedMulAdd
     #define SkFixedMulAdd(x, y, a)  (SkFixedMul(x, y) + (a))
 #endif
 
+///////////////////////////////////////////////////////////////////////////////
+
+typedef int64_t SkFixed48;
+
+#define SkIntToFixed48(x)       ((SkFixed48)(x) << 48)
+#define SkFixed48ToInt(x)       ((int)((x) >> 48))
+#define SkFixedToFixed48(x)     ((SkFixed48)(x) << 32)
+#define SkFixed48ToFixed(x)     ((SkFixed)((x) >> 32))
+#define SkFloatToFixed48(x)     ((SkFixed48)((x) * (65536.0f * 65536.0f * 65536.0f)))
+
+#ifdef SK_SCALAR_IS_FLOAT
+    #define SkScalarToFixed48(x)    SkFloatToFixed48(x)
+#else
+    #define SkScalarToFixed48(x)    SkFixedToFixed48(x)
 #endif
+
+#endif
--- a/gfx/skia/include/core/SkFlattenable.h
+++ b/gfx/skia/include/core/SkFlattenable.h
@@ -7,58 +7,64 @@
  */
 
 
 #ifndef SkFlattenable_DEFINED
 #define SkFlattenable_DEFINED
 
 #include "SkRefCnt.h"
 #include "SkBitmap.h"
+#include "SkPath.h"
+#include "SkPoint.h"
 #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)
+                                                       flattenable::CreateProc);
 #define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
     static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
-                                                      flattenable::CreateProc);
+                                                       flattenable::CreateProc);
+
+#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable)
 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
 
 #else
 
-#define SK_DECLARE_FLATTENABLE_REGISTRAR() static void Init();
+#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable)
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
+        SkFlattenable::Registrar(#flattenable, flattenable::CreateProc);
 
-#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \
-    void flattenable::Init() { \
-        SkFlattenable::Registrar(#flattenable, CreateProc); \
-    }
+#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
 
 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
-    void flattenable::Init() {
-    
-#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
-        SkFlattenable::Registrar(#flattenable, flattenable::CreateProc);
-    
+    void flattenable::InitializeFlattenables() {
+
 #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
     }
 
 #endif
 
+#define SK_DECLARE_UNFLATTENABLE_OBJECT() \
+    virtual Factory getFactory() SK_OVERRIDE { return NULL; }; \
+
+#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
+    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }; \
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \
+        return SkNEW_ARGS(flattenable, (buffer)); \
+    }
+
 /** \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:
@@ -66,47 +72,43 @@ public:
     
     SkFlattenable() {}
     
     /** Implement this to return a factory function pointer that can be called
      to recreate your class given a buffer (previously written to by your
      override of flatten().
      */
     virtual Factory getFactory() = 0;
-    /** Override this to write data specific to your subclass into the buffer,
-     being sure to call your super-class' version first. This data will later
-     be passed to your Factory function, returned by getFactory().
-     */
-    virtual void flatten(SkFlattenableWriteBuffer&);
     
-    /** Set the string to describe the sublass and return true. If this is not
-        overridden, ignore the string param and return false.
-     */
-    virtual bool toDumpString(SkString*) const;
-
     static Factory NameToFactory(const char name[]);
     static const char* FactoryToName(Factory);
     static void Register(const char name[], Factory);
-    
+
     class Registrar {
     public:
         Registrar(const char name[], Factory factory) {
             SkFlattenable::Register(name, factory);
         }
     };
-    
+
 protected:
     SkFlattenable(SkFlattenableReadBuffer&) {}
+    /** Override this to write data specific to your subclass into the buffer,
+     being sure to call your super-class' version first. This data will later
+     be passed to your Factory function, returned by getFactory().
+     */
+    virtual void flatten(SkFlattenableWriteBuffer&) const;
 
 private:
 #if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
     static void InitializeFlattenables();
 #endif
 
     friend class SkGraphics;
+    friend class SkFlattenableWriteBuffer;
 };
 
 // helpers for matrix and region
 
 class SkMatrix;
 extern void SkReadMatrix(SkReader32*, SkMatrix*);
 extern void SkWriteMatrix(SkWriter32*, const SkMatrix&);
 
@@ -114,22 +116,48 @@ class SkRegion;
 extern void SkReadRegion(SkReader32*, SkRegion*);
 extern void SkWriteRegion(SkWriter32*, const SkRegion&);
 
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
 class SkTypeface;
 
-class SkFlattenableReadBuffer : public SkReader32 {
+class SkFlattenableReadBuffer {
 public:
     SkFlattenableReadBuffer();
-    explicit SkFlattenableReadBuffer(const void* data);
-    SkFlattenableReadBuffer(const void* data, size_t size);
-    
+    virtual ~SkFlattenableReadBuffer() {}
+
+
+    virtual uint8_t readU8() = 0;
+    virtual uint16_t readU16() = 0;
+    virtual uint32_t readU32() = 0;
+    virtual void read(void* dst, size_t size) = 0;
+    virtual bool readBool() = 0;
+    virtual int32_t readInt() = 0;
+    virtual SkScalar readScalar() = 0;
+    virtual const void* skip(size_t size) = 0;
+
+    virtual int32_t readS32() { return readInt(); }
+    template <typename T> const T& skipT() {
+        SkASSERT(SkAlign4(sizeof(T)) == sizeof(T));
+        return *(const T*)this->skip(sizeof(T));
+    }
+
+    virtual void readMatrix(SkMatrix*) = 0;
+    virtual void readPath(SkPath*) = 0;
+    virtual void readPoint(SkPoint*) = 0;
+
+    // helper function for classes with const SkPoint members
+    SkPoint readPoint() {
+        SkPoint point;
+        this->readPoint(&point);
+        return point;
+    }
+
     void setRefCntArray(SkRefCnt* array[], int count) {
         fRCArray = array;
         fRCCount = count;
     }
     
     void setTypefaceArray(SkTypeface* array[], int count) {
         fTFArray = array;
         fTFCount = count;
@@ -151,102 +179,130 @@ public:
      *  the writer's kInlineFactoryNames_Flag.
      */
     void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) {
         fFactoryTDArray = array;
         fFactoryArray = NULL;
         fFactoryCount = 0;
     }
     
-    SkTypeface* readTypeface();
-    SkRefCnt* readRefCnt();
-    void* readFunctionPtr();
-    SkFlattenable* readFlattenable();
+    virtual SkTypeface* readTypeface() = 0;
+    virtual SkRefCnt* readRefCnt() = 0;
+    virtual void* readFunctionPtr() = 0;
+    virtual SkFlattenable* readFlattenable() = 0;
     
-private:
+protected:
     SkRefCnt** fRCArray;
     int        fRCCount;
     
     SkTypeface** fTFArray;
     int        fTFCount;
     
     SkTDArray<SkFlattenable::Factory>* fFactoryTDArray;
     SkFlattenable::Factory* fFactoryArray;
     int                     fFactoryCount;
-    
-    typedef SkReader32 INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "SkPtrRecorder.h"
 
 /**
  *  Subclass of SkTPtrSet specialed to call ref() and unref() when the
  *  base class's incPtr() and decPtr() are called. This makes it a valid owner
  *  of each ptr, which is released when the set is reset or destroyed.
  */
 class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
 public:
     virtual ~SkRefCntSet();
-    
+
 protected:
     // overrides
     virtual void incPtr(void*);
     virtual void decPtr(void*);
 };
 
 class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
 
-class SkFlattenableWriteBuffer : public SkWriter32 {
+class SkFlattenableWriteBuffer {
 public:
-    SkFlattenableWriteBuffer(size_t minSize);
+    SkFlattenableWriteBuffer();
     virtual ~SkFlattenableWriteBuffer();
 
+    // deprecated naming convention that will be removed after callers are updated
+    virtual bool writeBool(bool value) = 0;
+    virtual void writeInt(int32_t value) = 0;
+    virtual void write8(int32_t value) = 0;
+    virtual void write16(int32_t value) = 0;
+    virtual void write32(int32_t value) = 0;
+    virtual void writeScalar(SkScalar value) = 0;
+    virtual void writeMul4(const void* values, size_t size) = 0;
+
+    virtual void writePad(const void* src, size_t size) = 0;
+    virtual void writeString(const char* str, size_t len = (size_t)-1) = 0;
+    virtual uint32_t* reserve(size_t size) = 0;
+    virtual void flatten(void* dst) = 0;
+    virtual uint32_t size() = 0;
+    virtual void write(const void* values, size_t size) = 0;
+    virtual void writeRect(const SkRect& rect) = 0;
+    virtual size_t readFromStream(SkStream*, size_t length) = 0;
+
+    virtual void writeMatrix(const SkMatrix& matrix) = 0;
+    virtual void writePath(const SkPath& path) = 0;
+    virtual void writePoint(const SkPoint& point) = 0;
+
+    virtual bool writeToStream(SkWStream*) = 0;
+
+    virtual void writeFunctionPtr(void*)= 0;
+    virtual void writeFlattenable(SkFlattenable* flattenable)= 0;
+
     void writeTypeface(SkTypeface*);
-    void writeRefCnt(SkRefCnt*);
-    void writeFunctionPtr(void*);
-    void writeFlattenable(SkFlattenable* flattenable);
-    
+    void writeRefCnt(SkRefCnt* obj);
+
     SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
     SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
-    
+
     SkRefCntSet* getRefCntRecorder() const { return fRCSet; }
     SkRefCntSet* setRefCntRecorder(SkRefCntSet*);
-    
+
     SkFactorySet* getFactoryRecorder() const { return fFactorySet; }
     SkFactorySet* setFactoryRecorder(SkFactorySet*);
 
     enum Flags {
         kCrossProcess_Flag       = 0x01,
         /**
          *  Instructs the writer to inline Factory names as there are seen the
          *  first time (after that we store an index). The pipe code uses this.
          */
-        kInlineFactoryNames_Flag = 0x02
+        kInlineFactoryNames_Flag = 0x02,
     };
     Flags getFlags() const { return (Flags)fFlags; }
     void setFlags(Flags flags) { fFlags = flags; }
-    
+
     bool isCrossProcess() const {
         return SkToBool(fFlags & kCrossProcess_Flag);
     }
     bool inlineFactoryNames() const {
         return SkToBool(fFlags & kInlineFactoryNames_Flag);
     }
 
     bool persistBitmapPixels() const {
         return (fFlags & kCrossProcess_Flag) != 0;
     }
-    
+
     bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
 
-private:
+protected:
+
+    // A helper function so that each subclass does not have to be a friend of
+    // SkFlattenable.
+    void flattenObject(SkFlattenable* obj, SkFlattenableWriteBuffer& buffer) {
+        obj->flatten(buffer);
+    }
+
     uint32_t        fFlags;
     SkRefCntSet*    fTFSet;
     SkRefCntSet*    fRCSet;
     SkFactorySet*   fFactorySet;
-    
-    typedef SkWriter32 INHERITED;
 };
 
 #endif
 
--- a/gfx/skia/include/core/SkFontHost.h
+++ b/gfx/skia/include/core/SkFontHost.h
@@ -12,18 +12,16 @@
 
 #include "SkScalerContext.h"
 #include "SkTypeface.h"
 
 class SkDescriptor;
 class SkStream;
 class SkWStream;
 
-typedef uint32_t SkFontTableTag;
-
 /** \class SkFontHost
 
     This class is ported to each environment. It is responsible for bridging
     the gap between the (sort of) abstract class SkTypeface and the
     platform-specific implementation that provides access to font files.
 
     One basic task is for each create (subclass of) SkTypeface, the FontHost is
     resonsible for assigning a uniqueID. The ID should be unique for the
@@ -47,25 +45,23 @@ typedef uint32_t SkFontTableTag;
     4) Given a font ID, return a subclass of SkScalerContext, which connects a
         font scaler (e.g. freetype or other) to the font's data.
     5) Utilites to manage the font cache (budgeting) and gamma correction
 */
 class SK_API SkFontHost {
 public:
     /** Return a new, closest matching typeface given either an existing family
         (specified by a typeface in that family) or by a familyName and a
-        requested style, or by a set of Unicode codepoitns to cover in a given
-        style.
+        requested style.
         1) If familyFace is null, use familyName.
         2) If familyName is null, use data (UTF-16 to cover).
         3) If all are null, return the default font that best matches style
      */
     static SkTypeface* CreateTypeface(const SkTypeface* familyFace,
                                       const char familyName[],
-                                      const void* data, size_t bytelength,
                                       SkTypeface::Style style);
 
     /** Return a new typeface given the data buffer. If the data does not
         represent a valid font, returns null.
 
         If a typeface instance is returned, the caller is responsible for
         calling unref() on the typeface when they are finished with it.
 
@@ -79,22 +75,16 @@ public:
     /** Return a new typeface from the specified file path. If the file does not
         represent a valid font, this returns null. If a typeface is returned,
         the caller is responsible for calling unref() when it is no longer used.
      */
     static SkTypeface* CreateTypefaceFromFile(const char path[]);
 
     ///////////////////////////////////////////////////////////////////////////
 
-    /** Returns true if the specified unique ID matches an existing font.
-        Returning false is similar to calling OpenStream with an invalid ID,
-        which will return NULL in that case.
-    */
-    static bool ValidFontID(SkFontID uniqueID);
-
     /** Return a new stream to read the font data, or null if the uniqueID does
         not match an existing typeface. .The caller must call stream->unref()
         when it is finished reading the data.
     */
     static SkStream* OpenStream(SkFontID uniqueID);
 
     /** Some fonts are stored in files. If that is true for the fontID, then
         this returns the byte length of the full file path. If path is not null,
@@ -245,17 +235,17 @@ public:
         vertically. When rendering subpixel glyphs we need to know which way
         round they are.
 
         Note, if you change this after startup, you'll need to flush the glyph
         cache because it'll have the wrong type of masks cached.
     */
     enum LCDOrientation {
         kHorizontal_LCDOrientation = 0,    //!< this is the default
-        kVertical_LCDOrientation   = 1
+        kVertical_LCDOrientation   = 1,
     };
 
     static void SetSubpixelOrientation(LCDOrientation orientation);
     static LCDOrientation GetSubpixelOrientation();
 
     /** LCD color elements can vary in order. For subpixel text we need to know
         the order which the LCDs uses so that the color fringes are in the
         correct place.
@@ -264,17 +254,17 @@ public:
         cache because it'll have the wrong type of masks cached.
 
         kNONE_LCDOrder means that the subpixel elements are not spatially
         separated in any usable fashion.
      */
     enum LCDOrder {
         kRGB_LCDOrder = 0,    //!< this is the default
         kBGR_LCDOrder = 1,
-        kNONE_LCDOrder = 2
+        kNONE_LCDOrder = 2,
     };
 
     static void SetSubpixelOrder(LCDOrder order);
     static LCDOrder GetSubpixelOrder();
 
 #ifdef SK_BUILD_FOR_ANDROID
     ///////////////////////////////////////////////////////////////////////////
 
--- a/gfx/skia/include/core/SkGraphics.h
+++ b/gfx/skia/include/core/SkGraphics.h
@@ -7,17 +7,17 @@
  */
 
 
 #ifndef SkGraphics_DEFINED
 #define SkGraphics_DEFINED
 
 #include "SkTypes.h"
 
-class SkGraphics {
+class SK_API 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();
 
@@ -60,16 +60,36 @@ public:
      *  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);
     
+    /**
+     *  Return the max number of bytes that should be used by the thread-local
+     *  font cache.
+     *  If the cache needs to allocate more, it will purge previous entries.
+     *  This max can be changed by calling SetFontCacheLimit().
+     *
+     *  If this thread has never called SetTLSFontCacheLimit, or has called it
+     *  with 0, then this thread is using the shared font cache. In that case,
+     *  this function will always return 0, and the caller may want to call
+     *  GetFontCacheLimit.
+     */
+    static size_t GetTLSFontCacheLimit();
+    
+    /**
+     *  Specify the max number of bytes that should be used by the thread-local
+     *  font cache. If this value is 0, then this thread will use the shared
+     *  global font cache.
+     */
+    static void SetTLSFontCacheLimit(size_t bytes);
+    
 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
@@ -35,18 +35,21 @@ struct SkPoint;
  *  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 ~Proxy() {};
+
         virtual SkDevice* createDevice(int width, int height) = 0;
-        
+        // returns true if the proxy can handle this filter natively
+        virtual bool canHandleImageFilter(SkImageFilter*) = 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;
     };
 
     /**
@@ -74,16 +77,32 @@ public:
     /**
      *  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;
 
+    /**
+     *  Experimental.
+     *
+     *  If the filter can be expressed as an erode, return true and
+     *  set the radius in X and Y.
+     */
+    virtual bool asAnErode(SkISize* radius) const;
+
+    /**
+     *  Experimental.
+     *
+     *  If the filter can be expressed as a dilation, return true and
+     *  set the radius in X and Y.
+     */
+    virtual bool asADilate(SkISize* radius) const;
+
 protected:
     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
--- a/gfx/skia/include/core/SkMallocPixelRef.h
+++ b/gfx/skia/include/core/SkMallocPixelRef.h
@@ -23,32 +23,25 @@ public:
      */
     SkMallocPixelRef(void* addr, size_t size, SkColorTable* ctable);
     virtual ~SkMallocPixelRef();
     
     //! Return the allocation size for the pixels
     size_t getSize() const { return fSize; }
     void* getAddr() const { return fStorage; }
 
-    // overrides from SkPixelRef
-    virtual void flatten(SkFlattenableWriteBuffer&) const;
-    virtual Factory getFactory() const {
-        return Create;
-    }
-    static SkPixelRef* Create(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkMallocPixelRef, (buffer));
-    }
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMallocPixelRef)
 
-    SK_DECLARE_PIXEL_REF_REGISTRAR()
 protected:
     // overrides from SkPixelRef
     virtual void* onLockPixels(SkColorTable**);
     virtual void onUnlockPixels();
 
     SkMallocPixelRef(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
     void*           fStorage;
     size_t          fSize;
     SkColorTable*   fCTable;
 
     typedef SkPixelRef INHERITED;
 };
--- a/gfx/skia/include/core/SkMaskFilter.h
+++ b/gfx/skia/include/core/SkMaskFilter.h
@@ -7,16 +7,17 @@
  */
 
 
 #ifndef SkMaskFilter_DEFINED
 #define SkMaskFilter_DEFINED
 
 #include "SkFlattenable.h"
 #include "SkMask.h"
+#include "SkPaint.h"
 
 class SkBlitter;
 class SkBounder;
 class SkMatrix;
 class SkPath;
 class SkRasterClip;
 
 /** \class SkMaskFilter
@@ -50,50 +51,64 @@ public:
         @param margin   if not null, return the buffer dx/dy need when calculating the effect. Used when
                         drawing a clipped object to know how much larger to allocate the src before
                         applying the filter. If returning false, ignore this parameter.
         @return true if the dst mask was correctly created.
     */
     virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
                             SkIPoint* margin);
 
-    virtual void flatten(SkFlattenableWriteBuffer& ) {}
-
     enum BlurType {
         kNone_BlurType,    //!< this maskfilter is not a blur
         kNormal_BlurType,  //!< fuzzy inside and outside
         kSolid_BlurType,   //!< solid inside, fuzzy outside
         kOuter_BlurType,   //!< nothing inside, fuzzy outside
-        kInner_BlurType    //!< fuzzy inside, nothing outside
+        kInner_BlurType,   //!< fuzzy inside, nothing outside
     };
 
     struct BlurInfo {
         SkScalar fRadius;
         bool     fIgnoreTransform;
         bool     fHighQuality;
     };
 
     /**
      *  Optional method for maskfilters that can be described as a blur. If so,
      *  they return the corresponding BlurType and set the fields in BlurInfo
      *  (if not null). If they cannot be described as a blur, they return
      *  kNone_BlurType and ignore the info parameter.
      */
     virtual BlurType asABlur(BlurInfo*) const;
 
+    /**
+     * The fast bounds function is used to enable the paint to be culled early
+     * in the drawing pipeline. This function accepts the current bounds of the
+     * paint as its src param and the filter adjust those bounds using its
+     * current mask and returns the result using the dest param. Callers are
+     * allowed to provide the same struct for both src and dest so each
+     * implementation must accomodate that behavior.
+     *
+     *  The default impl calls filterMask with the src mask having no image,
+     *  but subclasses may override this if they can compute the rect faster.
+     */
+    virtual void computeFastBounds(const SkRect& src, SkRect* dest);
+
 protected:
     // empty for now, but lets get our subclass to remember to init us for the future
-    SkMaskFilter(SkFlattenableReadBuffer&) {}
+    SkMaskFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
 
 private:
     friend class SkDraw;
 
     /** Helper method that, given a path in device space, will rasterize it into a kA8_Format mask
      and then call filterMask(). If this returns true, the specified blitter will be called
      to render that mask. Returns false if filterMask() returned false.
      This method is not exported to java.
      */
     bool filterPath(const SkPath& devPath, const SkMatrix& devMatrix,
-                    const SkRasterClip&, SkBounder*, SkBlitter* blitter);
+                    const SkRasterClip&, SkBounder*, SkBlitter* blitter,
+                    SkPaint::Style style);
+
+    typedef SkFlattenable INHERITED;
 };
 
 #endif
 
--- a/gfx/skia/include/core/SkMath.h
+++ b/gfx/skia/include/core/SkMath.h
@@ -148,17 +148,20 @@ static inline bool SkIsPow2(int value) {
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /** SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t.
     With this requirement, we can generate faster instructions on some
     architectures.
 */
-#ifdef SK_ARM_HAS_EDSP
+#if defined(__arm__) \
+  && !defined(__thumb__) \
+  && !defined(__ARM_ARCH_4T__) \
+  && !defined(__ARM_ARCH_5T__)
     static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
         SkASSERT((int16_t)x == x);
         SkASSERT((int16_t)y == y);
         int32_t product;
         asm("smulbb %0, %1, %2 \n"
             : "=r"(product)
             : "r"(x), "r"(y)
             );
--- a/gfx/skia/include/core/SkMatrix.h
+++ b/gfx/skia/include/core/SkMatrix.h
@@ -331,17 +331,17 @@ public:
         @return true if the matrix was set to the specified transformation
     */
     bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count);
 
     /** If this matrix can be inverted, return true and if inverse is not null,
         set inverse to be the inverse of this matrix. If this matrix cannot be
         inverted, ignore inverse and return false
     */
-    bool invert(SkMatrix* inverse) const;
+    bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const;
 
     /** Fills the passed array with affine identity values
         in column major order.
         @param affine  The array to fill with affine identity values.
         Must not be NULL.
     */
     static void SetAffineIdentity(SkScalar affine[6]);
 
@@ -478,30 +478,38 @@ public:
     }
 
     /** If the matrix can be stepped in X (not complex perspective)
         then return true and if step[XY] is not null, return the step[XY] value.
         If it cannot, return false and ignore step.
     */
     bool fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const;
 
-#ifdef SK_SCALAR_IS_FIXED
-    friend bool operator==(const SkMatrix& a, const SkMatrix& b) {
-        return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) == 0;
+    /** Efficient comparison of two matrices. It distinguishes between zero and
+     *  negative zero. It will return false when the sign of zero values is the
+     *  only difference between the two matrices. It considers NaN values to be
+     *  equal to themselves. So a matrix full of NaNs is "cheap equal" to
+     *  another matrix full of NaNs iff the NaN values are bitwise identical
+     *  while according to strict the strict == test a matrix with a NaN value
+     *  is equal to nothing, including itself.
+     */
+    bool cheapEqualTo(const SkMatrix& m) const {
+        return 0 == memcmp(fMat, m.fMat, sizeof(fMat));
     }
 
-    friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
-        return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) != 0;
+#ifdef SK_SCALAR_IS_FIXED
+    friend bool operator==(const SkMatrix& a, const SkMatrix& b) {
+        return a.cheapEqualTo(b);
     }
 #else
-    friend bool operator==(const SkMatrix& a, const SkMatrix& b);    
+    friend bool operator==(const SkMatrix& a, const SkMatrix& b);
+#endif
     friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
         return !(a == b);
     }
-#endif
 
     enum {
         // flatten/unflatten will never return a value larger than this
         kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t)
     };
     // return the number of bytes written, whether or not buffer is null
     uint32_t flatten(void* buffer) const;
     // return the number of bytes read
@@ -536,17 +544,17 @@ public:
     void dirtyMatrixTypeCache() {
         this->setTypeMask(kUnknown_Mask);
     }
 
 private:
     enum {
         /** Set if the matrix will map a rectangle to another rectangle. This
             can be true if the matrix is scale-only, or rotates a multiple of
-            90 degrees. This bit is not set if the matrix is identity.
+            90 degrees.
              
             This bit will be set on identity matrices
         */
         kRectStaysRect_Mask = 0x10,
 
         /** Set if the perspective bit is valid even though the rest of
             the matrix is Unknown.
         */
@@ -561,18 +569,18 @@ private:
 
         kAllMasks = kTranslate_Mask |
                     kScale_Mask |
                     kAffine_Mask |
                     kPerspective_Mask |
                     kRectStaysRect_Mask
     };
 
-    SkScalar        fMat[9];
-    mutable uint8_t fTypeMask;
+    SkScalar         fMat[9];
+    mutable uint32_t fTypeMask;
 
     uint8_t computeTypeMask() const;
     uint8_t computePerspectiveTypeMask() const;
 
     void setTypeMask(int mask) {
         // allow kUnknown or a valid mask
         SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask ||
                  ((kUnknown_Mask | kOnlyPerspectiveValid_Mask | kPerspective_Mask) & mask)
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/core/SkOrderedReadBuffer.h
@@ -0,0 +1,61 @@
+
+/*
+ * 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 SkOrderedReadBuffer_DEFINED
+#define SkOrderedReadBuffer_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkBitmap.h"
+#include "SkFlattenable.h"
+#include "SkWriter32.h"
+#include "SkPath.h"
+
+class SkOrderedReadBuffer : public SkFlattenableReadBuffer {
+public:
+    SkOrderedReadBuffer() : INHERITED() {}
+    SkOrderedReadBuffer(const void* data, size_t size);
+
+    void setMemory(const void* data, size_t size) { fReader.setMemory(data, size); }
+    uint32_t size() { return fReader.size(); }
+    const void* base() { return fReader.base(); }
+    uint32_t offset() { return fReader.offset(); }
+    bool eof() { return fReader.eof(); }
+    void rewind() { fReader.rewind(); }
+    void setOffset(size_t offset) { fReader.setOffset(offset); }
+
+    SkReader32* getReader32() { return &fReader; }
+
+    virtual uint8_t readU8() { return fReader.readU8(); }
+    virtual uint16_t readU16() { return fReader.readU16(); }
+    virtual uint32_t readU32() { return fReader.readU32(); }
+    virtual void read(void* dst, size_t size) { return fReader.read(dst, size); }
+    virtual bool readBool() { return fReader.readBool(); }
+    virtual int32_t readInt() { return fReader.readInt(); }
+    virtual SkScalar readScalar() { return fReader.readScalar(); }
+    virtual const void* skip(size_t size) { return fReader.skip(size); }
+
+    virtual void readMatrix(SkMatrix* m) { fReader.readMatrix(m); }
+    virtual void readPath(SkPath* p) { p->unflatten(fReader); }
+    virtual void readPoint(SkPoint* p) {
+        p->fX = fReader.readScalar();
+        p->fY = fReader.readScalar();
+    }
+
+    virtual SkTypeface* readTypeface();
+    virtual SkRefCnt* readRefCnt();
+    virtual void* readFunctionPtr();
+    virtual SkFlattenable* readFlattenable();
+
+private:
+    SkReader32 fReader;
+
+    typedef SkFlattenableReadBuffer INHERITED;
+};
+
+#endif // SkOrderedReadBuffer_DEFINED
+
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/core/SkOrderedWriteBuffer.h
@@ -0,0 +1,61 @@
+
+/*
+ * 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 SkOrderedWriteBuffer_DEFINED
+#define SkOrderedWriteBuffer_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkBitmap.h"
+#include "SkFlattenable.h"
+#include "SkWriter32.h"
+#include "SkPath.h"
+
+class SkOrderedWriteBuffer : public SkFlattenableWriteBuffer {
+public:
+    SkOrderedWriteBuffer(size_t minSize);
+    SkOrderedWriteBuffer(size_t minSize, void* initialStorage,
+                         size_t storageSize);
+    virtual ~SkOrderedWriteBuffer() {}
+
+    // deprecated naming convention that will be removed after callers are updated
+    virtual bool writeBool(bool value) { return fWriter.writeBool(value); }
+    virtual void writeInt(int32_t value) { fWriter.writeInt(value); }
+    virtual void write8(int32_t value) { fWriter.write8(value); }
+    virtual void write16(int32_t value) { fWriter.write16(value); }
+    virtual void write32(int32_t value) { fWriter.write32(value); }
+    virtual void writeScalar(SkScalar value) { fWriter.writeScalar(value); }
+    virtual void writeMul4(const void* values, size_t size) { fWriter.writeMul4(values, size); }
+
+    virtual void writePad(const void* src, size_t size) { fWriter.writePad(src, size); }
+    virtual void writeString(const char* str, size_t len = (size_t)-1) { fWriter.writeString(str, len); }
+    virtual bool writeToStream(SkWStream* stream) { return fWriter.writeToStream(stream); }
+    virtual void write(const void* values, size_t size) { fWriter.write(values, size); }
+    virtual void writeRect(const SkRect& rect) { fWriter.writeRect(rect); }
+    virtual size_t readFromStream(SkStream* s, size_t length) { return fWriter.readFromStream(s, length); }
+
+    virtual void writeMatrix(const SkMatrix& matrix) { fWriter.writeMatrix(matrix); }
+    virtual void writePath(const SkPath& path) { path.flatten(fWriter); };
+    virtual void writePoint(const SkPoint& point) {
+        fWriter.writeScalar(point.fX);
+        fWriter.writeScalar(point.fY);
+    }
+
+    virtual uint32_t* reserve(size_t size) { return fWriter.reserve(size); }
+    virtual void flatten(void* dst) { fWriter.flatten(dst); }
+    virtual uint32_t size() { return fWriter.size(); }
+
+    virtual void writeFunctionPtr(void*);
+    virtual void writeFlattenable(SkFlattenable* flattenable);
+
+private:
+    SkWriter32 fWriter;
+    typedef SkFlattenableWriteBuffer INHERITED;
+};
+
+#endif // SkOrderedWriteBuffer_DEFINED
+
--- a/gfx/skia/include/core/SkPaint.h
+++ b/gfx/skia/include/core/SkPaint.h
@@ -1,21 +1,23 @@
+
 
 /*
  * Copyright 2006 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 SkPaint_DEFINED
 #define SkPaint_DEFINED
 
 #include "SkColor.h"
+#include "SkDrawLooper.h"
 #include "SkXfermode.h"
 
 class SkAutoGlyphCache;
 class SkColorFilter;
 class SkDescriptor;
 class SkFlattenableReadBuffer;
 class SkFlattenableWriteBuffer;
 struct SkGlyph;
@@ -23,17 +25,16 @@ struct SkRect;
 class SkGlyphCache;
 class SkImageFilter;
 class SkMaskFilter;
 class SkMatrix;
 class SkPath;
 class SkPathEffect;
 class SkRasterizer;
 class SkShader;
-class SkDrawLooper;
 class SkTypeface;
 
 typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**,
                                            SkFixed x, SkFixed y);
 
 typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**);
 
 /** \class SkPaint
@@ -70,17 +71,17 @@ public:
            kFull_Hinting   -> <same as kNormalHinting, unless we are rendering
                               subpixel glyphs, in which case TARGET_LCD or
                               TARGET_LCD_V is used>
     */
     enum Hinting {
         kNo_Hinting            = 0,
         kSlight_Hinting        = 1,
         kNormal_Hinting        = 2,     //!< this is the default
-        kFull_Hinting          = 3
+        kFull_Hinting          = 3,
     };
 
     Hinting getHinting() const {
         return static_cast<Hinting>(fHinting);
     }
 
     void setHinting(Hinting hintingLevel);
 
@@ -95,21 +96,22 @@ public:
         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
         kVerticalText_Flag    = 0x1000,
+        kGenA8FromLCD_Flag    = 0x2000, // hack for GDI -- do not use if you can help it
 
         // when adding extra flags, note that the fFlags member is specified
         // with a bit-width and you'll have to expand it.
 
-        kAllFlags = 0x1FFF
+        kAllFlags = 0x3FFF
     };
 
     /** Return the paint's flags. Use the Flag enum to test flag values.
         @return the paint's flags (see enums ending in _Flag for bit masks)
     */
     uint32_t getFlags() const { return fFlags; }
 
     /** Set the paint's flags. Use the Flag enum to specific flag values.
@@ -282,17 +284,17 @@ public:
         results may not appear the same as if it was drawn twice, filled and
         then stroked.
     */
     enum Style {
         kFill_Style,            //!< fill the geometry
         kStroke_Style,          //!< stroke the geometry
         kStrokeAndFill_Style,   //!< fill and stroke the geometry
 
-        kStyleCount
+        kStyleCount,
     };
 
     /** Return the paint's style, used for controlling how primitives'
         geometries are interpreted (except for drawBitmap, which always assumes
         kFill_Style).
         @return the paint's Style
     */
     Style getStyle() const { return (Style)fStyle; }
@@ -427,70 +429,39 @@ public:
         geometric perspective).
         @param src  input path
         @param dst  output path (may be the same as src)
         @return     true if the path should be filled, or false if it should be
                     drawn with a hairline (width == 0)
     */
     bool getFillPath(const SkPath& src, SkPath* dst) const;
 
-    /** Returns true if the current paint settings allow for fast computation of
-        bounds (i.e. there is nothing complex like a patheffect that would make
-        the bounds computation expensive.
-    */
-    bool canComputeFastBounds() const {
-        // use bit-or since no need for early exit
-        return (reinterpret_cast<uintptr_t>(this->getMaskFilter()) |
-                reinterpret_cast<uintptr_t>(this->getLooper()) |
-                reinterpret_cast<uintptr_t>(this->getRasterizer()) |
-                reinterpret_cast<uintptr_t>(this->getPathEffect())) == 0;
-    }
-
-    /** Only call this if canComputeFastBounds() returned true. This takes a
-        raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
-        effects in the paint (e.g. stroking). If needed, it uses the storage
-        rect parameter. It returns the adjusted bounds that can then be used
-        for quickReject tests.
-
-        The returned rect will either be orig or storage, thus the caller
-        should not rely on storage being set to the result, but should always
-        use the retured value. It is legal for orig and storage to be the same
-        rect.
-
-        e.g.
-        if (paint.canComputeFastBounds()) {
-            SkRect r, storage;
-            path.computeBounds(&r, SkPath::kFast_BoundsType);
-            const SkRect& fastR = paint.computeFastBounds(r, &storage);
-            if (canvas->quickReject(fastR, ...)) {
-                // don't draw the path
-            }
-        }
-    */
-    const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
-        return this->getStyle() == kFill_Style ? orig :
-                    this->computeStrokeFastBounds(orig, storage);
-    }
-
     /** Get the paint's shader object.
         <p />
       The shader's reference count is not affected.
         @return the paint's shader (or NULL)
     */
     SkShader* getShader() const { return fShader; }
 
     /** Set or clear the shader object.
-        <p />
-        Pass NULL to clear any previous shader.
-        As a convenience, the parameter passed is also returned.
-        If a previous shader exists, its reference count is decremented.
-        If shader is not NULL, its reference count is incremented.
-        @param shader   May be NULL. The shader to be installed in the paint
-        @return         shader
-    */
+     *  Shaders specify the source color(s) for what is being drawn. If a paint
+     *  has no shader, then the paint's color is used. If the paint has a
+     *  shader, then the shader's color(s) are use instead, but they are
+     *  modulated by the paint's alpha. This makes it easy to create a shader
+     *  once (e.g. bitmap tiling or gradient) and then change its transparency
+     *  w/o having to modify the original shader... only the paint's alpha needs
+     *  to be modified.
+     *  <p />
+     *  Pass NULL to clear any previous shader.
+     *  As a convenience, the parameter passed is also returned.
+     *  If a previous shader exists, its reference count is decremented.
+     *  If shader is not NULL, its reference count is incremented.
+     *  @param shader   May be NULL. The shader to be installed in the paint
+     *  @return         shader
+     */
     SkShader* setShader(SkShader* shader);
 
     /** Get the paint's colorfilter. If there is a colorfilter, its reference
         count is not changed.
         @return the paint's colorfilter (or NULL)
     */
     SkColorFilter* getColorFilter() const { return fColorFilter; }
 
@@ -685,16 +656,17 @@ public:
     void setTextSkewX(SkScalar skewX);
 
     /** Describes how to interpret the text parameters that are passed to paint
         methods like measureText() and getTextWidths().
     */
     enum TextEncoding {
         kUTF8_TextEncoding,     //!< the text parameters are UTF8
         kUTF16_TextEncoding,    //!< the text parameters are UTF16
+        kUTF32_TextEncoding,    //!< the text parameters are UTF32
         kGlyphID_TextEncoding   //!< the text parameters are glyph indices
     };
 
     TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; }
 
     void setTextEncoding(TextEncoding encoding);
 
     struct FontMetrics {
@@ -775,17 +747,17 @@ public:
                          SkRect* bounds, SkScalar scale = 0) const;
 
     /** 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
+     *  @return         The advance 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 {
@@ -836,30 +808,92 @@ public:
 
     /** 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 SK_BUILD_FOR_ANDROID
     const SkGlyph& getUnicharMetrics(SkUnichar);
+    const SkGlyph& getGlyphMetrics(uint16_t);
     const void* findImage(const SkGlyph&);
 
     uint32_t getGenerationID() const;
+
+    /** Returns the base glyph count for the strike associated with this paint
+    */
+    unsigned getBaseGlyphCount(SkUnichar text) 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)
     bool nothingToDraw() const;
 
+    ///////////////////////////////////////////////////////////////////////////
+    // would prefer to make these private...
+
+    /** Returns true if the current paint settings allow for fast computation of
+     bounds (i.e. there is nothing complex like a patheffect that would make
+     the bounds computation expensive.
+     */
+    bool canComputeFastBounds() const {
+        if (this->getLooper()) {
+            return this->getLooper()->canComputeFastBounds(*this);
+        }
+        return !this->getRasterizer();
+    }
+    
+    /** Only call this if canComputeFastBounds() returned true. This takes a
+     raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
+     effects in the paint (e.g. stroking). If needed, it uses the storage
+     rect parameter. It returns the adjusted bounds that can then be used
+     for quickReject tests.
+     
+     The returned rect will either be orig or storage, thus the caller
+     should not rely on storage being set to the result, but should always
+     use the retured value. It is legal for orig and storage to be the same
+     rect.
+     
+     e.g.
+     if (paint.canComputeFastBounds()) {
+     SkRect r, storage;
+     path.computeBounds(&r, SkPath::kFast_BoundsType);
+     const SkRect& fastR = paint.computeFastBounds(r, &storage);
+     if (canvas->quickReject(fastR, ...)) {
+     // don't draw the path
+     }
+     }
+     */
+    const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
+        SkPaint::Style style = this->getStyle();
+        // ultra fast-case: filling with no effects that affect geometry
+        if (kFill_Style == style) {
+            uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper());
+            effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
+            effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
+            if (!effects) {
+                return orig;
+            }
+        }
+        
+        return this->doComputeFastBounds(orig, storage, style);
+    }
+    
+    const SkRect& computeFastStrokeBounds(const SkRect& orig,
+                                          SkRect* storage) const {
+        return this->doComputeFastBounds(orig, storage, kStroke_Style);
+    }
+    
+    // Take the style explicitly, so the caller can force us to be stroked
+    // without having to make a copy of the paint just to change that field.
+    const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
+                                      Style) const;
+    
 private:
     SkTypeface*     fTypeface;
     SkScalar        fTextSize;
     SkScalar        fTextScaleX;
     SkScalar        fTextSkewX;
 
     SkPathEffect*   fPathEffect;
     SkShader*       fShader;
@@ -868,17 +902,17 @@ private:
     SkColorFilter*  fColorFilter;
     SkRasterizer*   fRasterizer;
     SkDrawLooper*   fLooper;
     SkImageFilter*  fImageFilter;
 
     SkColor         fColor;
     SkScalar        fWidth;
     SkScalar        fMiterLimit;
-    unsigned        fFlags : 14;
+    unsigned        fFlags : 15;
     unsigned        fTextAlign : 2;
     unsigned        fCapType : 2;
     unsigned        fJoinType : 2;
     unsigned        fStyle : 2;
     unsigned        fTextEncoding : 2;  // 3 values
     unsigned        fHinting : 2;
 
     SkDrawCacheProc    getDrawCacheProc() const;
@@ -889,68 +923,26 @@ private:
                           int* count, SkRect* bounds) const;
 
     SkGlyphCache*   detachCache(const SkMatrix*) const;
 
     void descriptorProc(const SkMatrix* deviceMatrix,
                         void (*proc)(const SkDescriptor*, void*),
                         void* context, bool ignoreGamma = false) const;
 
-    const SkRect& computeStrokeFastBounds(const SkRect& orig,
-                                          SkRect* storage) const;
-
     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
-
-    SkStrokePathEffect simulates stroking inside a patheffect, allowing the
-    caller to have explicit control of when to stroke a path. Typically this is
-    used if the caller wants to stroke before another patheffect is applied
-    (using SkComposePathEffect or SkSumPathEffect).
-*/
-class SkStrokePathEffect : public SkPathEffect {
-public:
-    SkStrokePathEffect(const SkPaint&);
-    SkStrokePathEffect(SkScalar width, SkPaint::Style, SkPaint::Join,
-                       SkPaint::Cap, SkScalar miterLimit = -1);
-
-    // overrides
-    virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
-
-    // overrides for SkFlattenable
-    virtual void flatten(SkFlattenableWriteBuffer&);
-    virtual Factory getFactory();
-
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
-
-private:
-    SkScalar    fWidth, fMiter;
-    uint8_t     fStyle, fJoin, fCap;
-
-    SkStrokePathEffect(SkFlattenableReadBuffer&);
-
-    typedef SkPathEffect INHERITED;
-
-    // illegal
-    SkStrokePathEffect(const SkStrokePathEffect&);
-    SkStrokePathEffect& operator=(const SkStrokePathEffect&);
-};
-
 #endif
 
--- a/gfx/skia/include/core/SkPath.h
+++ b/gfx/skia/include/core/SkPath.h
@@ -156,16 +156,28 @@ public:
      *  this flag is set, though setting this to true on a path that is in fact
      *  not convex can give undefined results when drawn. Paths default to
      *  isConvex == false
      */
     void setIsConvex(bool isConvex) {
         this->setConvexity(isConvex ? kConvex_Convexity : kConcave_Convexity);
     }
 
+    /** Returns true if the path is an oval.
+     *
+     * @param rect      returns the bounding rect of this oval. It's a circle
+     *                  if the height and width are the same.
+     *
+     * @return true if this path is an oval.
+     *              Tracking whether a path is an oval is considered an
+     *              optimization for performance and so some paths that are in
+     *              fact ovals can report false.
+     */
+    bool isOval(SkRect* rect) const;
+
     /** Clear any lines and curves from the path, making it empty. This frees up
         internal storage associated with those segments.
         This does NOT change the fill-type setting nor isConvex
     */
     void reset();
     
     /** Similar to reset(), in that all lines and curves are removed from the
         path. However, any internal storage for those lines/curves is retained,
@@ -180,40 +192,48 @@ public:
     */
     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);
+        return p1.equalsWithinTolerance(p2);
     }
 
     /** 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);
+        return p1.equalsWithinTolerance(p2) &&
+               p2.equalsWithinTolerance(p3);
     }
 
     /** 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);
+        return p1.equalsWithinTolerance(p2) &&
+               p2.equalsWithinTolerance(p3) &&
+               p3.equalsWithinTolerance(p4);
     }
 
+    /**
+     *  Returns true if the path specifies a single line (i.e. it contains just
+     *  a moveTo and a lineTo). If so, and line[] is not null, it sets the 2
+     *  points in line[] to the end-points of the line. If the path is not a
+     *  line, returns false and ignores line[].
+     */
+    bool isLine(SkPoint line[2]) const;
+
     /** 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
     */
@@ -448,16 +468,34 @@ public:
 
     enum Direction {
         /** clockwise direction for adding closed contours */
         kCW_Direction,
         /** counter-clockwise direction for adding closed contours */
         kCCW_Direction
     };
 
+    /**
+     *  Tries to quickly compute the direction of the first non-degenerate
+     *  contour. If it can be computed, return true and set dir to that
+     *  direction. If it cannot be (quickly) determined, return false and ignore
+     *  the dir parameter.
+     */
+    bool cheapComputeDirection(Direction* dir) const;
+
+    /**
+     *  Returns true if the path's direction can be computed via
+     *  cheapComputDirection() and if that computed direction matches the
+     *  specified direction.
+     */
+    bool cheapIsDirection(Direction dir) const {
+        Direction computedDir;
+        return this->cheapComputeDirection(&computedDir) && computedDir == dir;
+    }
+
     /** Add a closed rectangle contour to the path
         @param rect The rectangle to add as a closed contour to the path
         @param dir  The direction to wind the rectangle's contour
     */
     void    addRect(const SkRect& rect, Direction dir = kCW_Direction);
 
     /** Add a closed rectangle contour to the path
 
@@ -521,31 +559,36 @@ public:
     void addRoundRect(const SkRect& rect, const SkScalar radii[],
                       Direction dir = kCW_Direction);
 
     /** Add a copy of src to the path, offset by (dx,dy)
         @param src  The path to add as a new contour
         @param dx   The amount to translate the path in X as it is added
         @param dx   The amount to translate the path in Y as it is added
     */
-    void    addPath(const SkPath& src, SkScalar dx, SkScalar dy);
+    void addPath(const SkPath& src, SkScalar dx, SkScalar dy);
 
     /** Add a copy of src to the path
     */
     void addPath(const SkPath& src) {
         SkMatrix m;
         m.reset();
         this->addPath(src, m);
     }
 
     /** Add a copy of src to the path, transformed by matrix
         @param src  The path to add as a new contour
     */
     void addPath(const SkPath& src, const SkMatrix& matrix);
 
+    /**
+     *  Same as addPath(), but reverses the src input
+     */
+    void reverseAddPath(const SkPath& src);
+
     /** Offset the path by (dx,dy), returning true on success
      
         @param dx   The amount in the X direction to offset the entire path 
         @param dy   The amount in the Y direction to offset the entire path 
         @param dst  The translated path is written here
     */
     void offset(SkScalar dx, SkScalar dy, SkPath* dst) const;
 
@@ -636,19 +679,26 @@ public:
         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
+            @param doConsumeDegerates If true, first scan for segments that are
+                   deemed degenerate (too short) and skip those.
             @return The verb for the current segment
         */
-        Verb next(SkPoint pts[4]);
+        Verb next(SkPoint pts[4], bool doConsumeDegerates = true) {
+            if (doConsumeDegerates) {
+                this->consumeDegenerateSegments();
+            }
+            return this->doNext(pts);
+        }
 
         /** 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.
@@ -666,19 +716,20 @@ public:
         const uint8_t*  fVerbStop;
         SkPoint         fMoveTo;
         SkPoint         fLastPt;
         SkBool8         fForceClose;
         SkBool8         fNeedClose;
         SkBool8         fCloseLine;
         SkBool8         fSegmentState;
 
-        bool cons_moveTo(SkPoint pts[1]);
+        inline const SkPoint& cons_moveTo();
         Verb autoClose(SkPoint pts[2]);
         void consumeDegenerateSegments();
+        Verb doNext(SkPoint pts[4]);
     };
 
     /** Iterate through the verbs in the path, providing the associated points.
     */
     class SK_API RawIter {
     public:
         RawIter();
         RawIter(const SkPath&);
@@ -704,48 +755,63 @@ public:
     void dump(bool forceClose, const char title[] = NULL) const;
     void dump() const;
 
     void flatten(SkWriter32&) const;
     void unflatten(SkReader32&);
 
 #ifdef SK_BUILD_FOR_ANDROID
     uint32_t getGenerationID() const;
+    const SkPath* getSourcePath() const;
+    void setSourcePath(const SkPath* path);
 #endif
 
     SkDEBUGCODE(void validate() const;)
 
 private:
     SkTDArray<SkPoint>  fPts;
     SkTDArray<uint8_t>  fVerbs;
     mutable SkRect      fBounds;
+    int                 fLastMoveToIndex;
     uint8_t             fFillType;
     uint8_t             fSegmentMask;
     mutable uint8_t     fBoundsIsDirty;
     mutable uint8_t     fConvexity;
+
+    mutable SkBool8     fIsOval;
 #ifdef SK_BUILD_FOR_ANDROID
     uint32_t            fGenerationID;
+    const SkPath*       fSourcePath;
 #endif
 
     // called, if dirty, by getBounds()
     void computeBounds() const;
 
     friend class Iter;
-    void cons_moveto();
 
     friend class SkPathStroker;
     /*  Append the first contour of path, ignoring path's initial point. If no
         moveTo() call has been made for this contour, the first point is
         automatically set to (0,0).
     */
     void pathTo(const SkPath& path);
 
     /*  Append, in reverse order, the first contour of path, ignoring path's
         last point. If no moveTo() call has been made for this contour, the
         first point is automatically set to (0,0).
     */
     void reversePathTo(const SkPath&);
 
-    friend const SkPoint* sk_get_path_points(const SkPath&, int index);
+    // called before we add points for lineTo, quadTo, cubicTo, checking to see
+    // if we need to inject a leading moveTo first
+    //
+    //  SkPath path; path.lineTo(...);   <--- need a leading moveTo(0, 0)
+    // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo)
+    //
+    inline void injectMoveToIfNeeded();
+
+    inline bool hasOnlyMoveTos() const;
+
     friend class SkAutoPathBoundsUpdate;
+    friend class SkAutoDisableOvalCheck;
 };
 
 #endif
--- a/gfx/skia/include/core/SkPathEffect.h
+++ b/gfx/skia/include/core/SkPathEffect.h
@@ -29,37 +29,48 @@ 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()
+    /**
+     *  Compute a conservative bounds for its effect, given the src bounds.
+     *  The baseline implementation just assigns src to dst.
+     */
+    virtual void computeFastBounds(SkRect* dst, const SkRect& src);
+
+protected:
+    SkPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
+
 private:
     // illegal
     SkPathEffect(const SkPathEffect&);
     SkPathEffect& operator=(const SkPathEffect&);
+
+    typedef SkFlattenable INHERITED;
 };
 
 /** \class SkPairPathEffect
 
     Common baseclass for Compose and Sum. This subclass manages two pathEffects,
     including flattening them. It does nothing in filterPath, and is only useful
     for managing the lifetimes of its two arguments.
 */
 class SkPairPathEffect : public SkPathEffect {
 public:
     SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1);
     virtual ~SkPairPathEffect();
 
 protected:
     SkPairPathEffect(SkFlattenableReadBuffer&);
-    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+
     // these are visible to our subclasses
     SkPathEffect* fPE0, *fPE1;
     
 private:
     typedef SkPathEffect INHERITED;
 };
 
 /** \class SkComposePathEffect
@@ -76,26 +87,22 @@ public:
     */
     SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
         : INHERITED(outer, inner) {}
 
     // overrides
     
     virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
 
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkComposePathEffect, (buffer));
-    }
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect)
 
 protected:
-    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
+    SkComposePathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
 
 private:
-    SkComposePathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
-
     // illegal
     SkComposePathEffect(const SkComposePathEffect&);
     SkComposePathEffect& operator=(const SkComposePathEffect&);
     
     typedef SkPairPathEffect INHERITED;
 };
 
 /** \class SkSumPathEffect
@@ -111,26 +118,22 @@ public:
         and decremented in the destructor.
     */
     SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
         : INHERITED(first, second) {}
 
     // overrides
     virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
 
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)  {
-        return SkNEW_ARGS(SkSumPathEffect, (buffer));
-    }
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect)
 
 protected:
-    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
+    SkSumPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
 
 private:
-    SkSumPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
-
     // illegal
     SkSumPathEffect(const SkSumPathEffect&);
     SkSumPathEffect& operator=(const SkSumPathEffect&);
 
     typedef SkPairPathEffect INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/core/SkPathMeasure.h
+++ b/gfx/skia/include/core/SkPathMeasure.h
@@ -24,41 +24,45 @@ public:
     SkPathMeasure(const SkPath& path, bool forceClosed);
     ~SkPathMeasure();
 
     /** Reset the pathmeasure with the specified path. The path must remain valid
         for the lifetime of the measure object, or until setPath() is called with
         a different path (or null), since the measure object keeps a pointer to the
         path object (does not copy its data).
     */
-    void    setPath(const SkPath*, bool forceClosed);
+    void setPath(const SkPath*, bool forceClosed);
 
     /** Return the total length of the current contour, or 0 if no path
         is associated (e.g. resetPath(null))
     */
     SkScalar getLength();
 
     /** Pins distance to 0 <= distance <= getLength(), and then computes
         the corresponding position and tangent.
         Returns false if there is no path, or a zero-length path was specified, in which case
         position and tangent are unchanged.
     */
-    bool getPosTan(SkScalar distance, SkPoint* position, SkVector* tangent);
+    bool SK_WARN_UNUSED_RESULT getPosTan(SkScalar distance, SkPoint* position, 
+                                         SkVector* tangent);
 
     enum MatrixFlags {
         kGetPosition_MatrixFlag     = 0x01,
         kGetTangent_MatrixFlag      = 0x02,
         kGetPosAndTan_MatrixFlag    = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
     };
+
     /** Pins distance to 0 <= distance <= getLength(), and then computes
         the corresponding matrix (by calling getPosTan).
         Returns false if there is no path, or a zero-length path was specified, in which case
         matrix is unchanged.
     */
-    bool getMatrix(SkScalar distance, SkMatrix* matrix, MatrixFlags flags = kGetPosAndTan_MatrixFlag);
+    bool SK_WARN_UNUSED_RESULT getMatrix(SkScalar distance, SkMatrix* matrix, 
+                                  MatrixFlags flags = kGetPosAndTan_MatrixFlag);
+
     /** Given a start and stop distance, return in dst the intervening segment(s).
         If the segment is zero-length, return false, else return true.
         startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD
         then return false (and leave dst untouched).
         Begin the segment with a moveTo if startWithMoveTo is true
     */
     bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
 
@@ -80,28 +84,28 @@ private:
     const SkPath*   fPath;
     SkScalar        fLength;            // relative to the current contour
     int             fFirstPtIndex;      // relative to the current contour
     bool            fIsClosed;          // relative to the current contour
     bool            fForceClosed;
 
     struct Segment {
         SkScalar    fDistance;  // total distance up to this point
-        unsigned    fPtIndex : 15;
+        unsigned    fPtIndex : 15; // index into the fPts array
         unsigned    fTValue : 15;
         unsigned    fType : 2;
 
         SkScalar getScalarT() const;
     };
     SkTDArray<Segment>  fSegments;
+    SkTDArray<SkPoint>  fPts; // Points used to define the segments
 
     static const Segment* NextSegment(const Segment*);
 
     void     buildSegments();
     SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance,
                                 int mint, int maxt, int ptIndex);
     SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance,
                                 int mint, int maxt, int ptIndex);
     const Segment* distanceToSegment(SkScalar distance, SkScalar* t);
 };
 
 #endif
-
--- a/gfx/skia/include/core/SkPixelRef.h
+++ b/gfx/skia/include/core/SkPixelRef.h
@@ -8,69 +8,50 @@
 
 
 #ifndef SkPixelRef_DEFINED
 #define SkPixelRef_DEFINED
 
 #include "SkBitmap.h"
 #include "SkRefCnt.h"
 #include "SkString.h"
+#include "SkFlattenable.h"
 
 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.
 */
-class SkPixelRef : public SkRefCnt {
+class SK_API SkPixelRef : public SkFlattenable {
 public:
-    explicit SkPixelRef(SkMutex* mutex = NULL);
+    explicit SkPixelRef(SkBaseMutex* mutex = NULL);
 
     /** Return the pixel memory returned from lockPixels, or null if the
         lockCount is 0.
     */
     void* pixels() const { return fPixels; }
 
     /** Return the current colorTable (if any) if pixels are locked, or null.
     */
     SkColorTable* colorTable() const { return fColorTable; }
 
-    /** Return the current lockcount (defaults to 0)
-    */
-    int getLockCount() const { return fLockCount; }
+    /**
+     *  Returns true if the lockcount > 0
+     */
+    bool isLocked() const { return fLockCount > 0; }
 
     /** Call to access the pixel memory, which is returned. Balance with a call
         to unlockPixels().
     */
     void lockPixels();
     /** Call to balanace a previous call to lockPixels(). Returns the pixels
         (or null) after the unlock. NOTE: lock calls can be nested, but the
         matching number of unlock calls must be made in order to free the
@@ -137,50 +118,32 @@ public:
     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 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);
 
     /**
      *  Release a "global" ref on this object.
      *  The default implementation just calls unref(), but subclasses can override
      *  this method to implement additional behavior.
      */
     virtual void globalUnref();
 #endif
 
-    static Factory NameToFactory(const char name[]);
-    static const char* FactoryToName(Factory);
-    static void Register(const char name[], Factory);
-
-    class Registrar {
-    public:
-        Registrar(const char name[], Factory factory) {
-            SkPixelRef::Register(name, factory);
-        }
-    };
-
 protected:
     /** Called when the lockCount goes from 0 to 1. The caller will have already
         acquire a mutex for thread safety, so this method need not do that.
     */
     virtual void* onLockPixels(SkColorTable**) = 0;
     /** Called when the lock count goes from 1 to 0. The caller will have
         already acquire a mutex for thread safety, so this method need not do
         that.
@@ -196,33 +159,48 @@ protected:
      *
      *  The base class implementation returns false;
      */
     virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull);
 
     /** 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; }
+    SkBaseMutex* mutex() const { return fMutex; }
+
+    // serialization
+    SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
-    SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
+    // only call from constructor. Flags this to always be locked, removing
+    // the need to grab the mutex and call onLockPixels/onUnlockPixels.
+    // Performance tweak to avoid those calls (esp. in multi-thread use case).
+    void setPreLocked(void* pixels, SkColorTable* ctable);
+
+    /**
+     *  If a subclass passed a particular mutex to the base constructor, it can
+     *  override that to go back to the default mutex by calling this. However,
+     *  this should only be called from within the subclass' constructor.
+     */
+    void useDefaultMutex() { this->setMutex(NULL); }
 
 private:
-#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
-    static void InitializeFlattenables();
-#endif
 
-    SkMutex*        fMutex; // must remain in scope for the life of this object
+    SkBaseMutex*    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;
+    // only ever set in constructor, const after that
+    bool    fPreLocked;
 
-    friend class SkGraphics;
+    void setMutex(SkBaseMutex* mutex);
+
+    typedef SkFlattenable INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/core/SkPoint.h
+++ b/gfx/skia/include/core/SkPoint.h
@@ -208,17 +208,23 @@ struct SK_API SkPoint {
     */
     SkScalar length() const { return SkPoint::Length(fX, fY); }
     SkScalar distanceToOrigin() const { return this->length(); }
 
     /**
      *  Return true if the computed length of the vector is >= the internal
      *  tolerance (used to avoid dividing by tiny values).
      */
-    static bool CanNormalize(SkScalar dx, SkScalar dy);
+    static bool CanNormalize(SkScalar dx, SkScalar dy)
+#ifdef SK_SCALAR_IS_FLOAT
+    // Simple enough (and performance critical sometimes) so we inline it.
+    { return (dx*dx + dy*dy) > (SK_ScalarNearlyZero * SK_ScalarNearlyZero); }
+#else
+    ;
+#endif
 
     bool canNormalize() const {
         return CanNormalize(fX, fY);
     }
 
     /** Set the point (vector) to be unit-length in the same direction as it
         already points.  If the point has a degenerate length (i.e. nearly 0)
         then return false and do nothing; otherwise return true.
@@ -310,21 +316,39 @@ 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.
+    /** Return true if this point and the given point are far enough apart
+        such that a vector between them would be non-degenerate.
+
+        WARNING: Unlike the deprecated version of equalsWithinTolerance(),
+        this method does not use componentwise comparison.  Instead, it
+        uses a comparison designed to match judgments elsewhere regarding
+        degeneracy ("points A and B are so close that the vector between them
+        is essentially zero").
     */
-    bool equalsWithinTolerance(const SkPoint& v, SkScalar tol) const {
-        return SkScalarNearlyZero(fX - v.fX, tol)
-               && SkScalarNearlyZero(fY - v.fY, tol);
+    bool equalsWithinTolerance(const SkPoint& p) const {
+        return !CanNormalize(fX - p.fX, fY - p.fY);
+    }
+
+    /** DEPRECATED: Return true if this and the given point are componentwise
+        within tolerance "tol".
+
+        WARNING: There is no guarantee that the result will reflect judgments
+        elsewhere regarding degeneracy ("points A and B are so close that the
+        vector between them is essentially zero").
+    */
+    bool equalsWithinTolerance(const SkPoint& p, SkScalar tol) const {
+        return SkScalarNearlyZero(fX - p.fX, tol)
+               && SkScalarNearlyZero(fY - p.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);
@@ -437,21 +461,21 @@ struct SK_API SkPoint {
     /**
      * Make this vector be orthogonal to vec. Looking down vec the
      * new vector will point in direction indicated by side (which
      * must be kLeft_Side or kRight_Side).
      */
     void setOrthog(const SkPoint& vec, Side side = kLeft_Side) {
         // vec could be this
         SkScalar tmp = vec.fX;
-        if (kLeft_Side == side) {
+        if (kRight_Side == side) {
             fX = -vec.fY;
             fY = tmp;
         } else {
-            SkASSERT(kRight_Side == side);
+            SkASSERT(kLeft_Side == side);
             fX = vec.fY;
             fY = -tmp;
         }
     }
 };
 
 typedef SkPoint SkVector;
 
--- a/gfx/skia/include/core/SkPostConfig.h
+++ b/gfx/skia/include/core/SkPostConfig.h
@@ -77,16 +77,22 @@
             inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
             void SkNO_RETURN_HINT() {}
         }
     #else
         #define SkNO_RETURN_HINT() do {} while (false)
     #endif
 #endif
 
+#if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB)
+    #error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB"
+#elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB)
+    #define SK_HAS_ZLIB
+#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
@@ -277,76 +283,22 @@
 #endif
 
 //////////////////////////////////////////////////////////////////////
 
 #ifndef SK_OVERRIDE
 #if defined(_MSC_VER)
 #define SK_OVERRIDE override
 #elif defined(__clang__)
-#if __has_feature(cxx_override_control)
 // Some documentation suggests we should be using __attribute__((override)),
 // but it doesn't work.
 #define SK_OVERRIDE override
-#elif defined(__has_extension)
-#if __has_extension(cxx_override_control)
-#define SK_OVERRIDE override
-#endif
-#endif
-#ifndef SK_OVERRIDE
-#define SK_OVERRIDE
-#endif
 #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
-
-//////////////////////////////////////////////////////////////////////
-// ARM defines
-
-#if defined(__GNUC__) && defined(__arm__)
-
-#  define SK_ARM_ARCH 3
-
-#  if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) \
-   || defined(_ARM_ARCH_4)
-#    undef SK_ARM_ARCH
-#    define SK_ARM_ARCH 4
-#  endif
-
-#  if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
-   || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
-   || defined(__ARM_ARCH_5TEJ__) || defined(_ARM_ARCH_5)
-#    undef SK_ARM_ARCH
-#    define SK_ARM_ARCH 5
-#  endif
- 
-#  if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
-   || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
-   || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
-   || defined(__ARM_ARCH_6M__) || defined(_ARM_ARCH_6)
-#    undef SK_ARM_ARCH
-#    define SK_ARM_ARCH 6
-#  endif
-
-#  if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
-   || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
-   || defined(__ARM_ARCH_7EM__) || defined(_ARM_ARCH_7)
-#    undef SK_ARM_ARCH
-#    define SK_ARM_ARCH 7
-#  endif
-
-#  undef SK_ARM_HAS_EDSP
-#  if defined(__thumb2__) && (SK_ARM_ARCH >= 6) \
-   || !defined(__thumb__) \
-   && ((SK_ARM_ARCH > 5) || defined(__ARM_ARCH_5E__) \
-       || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__))
-#    define SK_ARM_HAS_EDSP 1
-#  endif
-
-#endif
--- a/gfx/skia/include/core/SkPreConfig.h
+++ b/gfx/skia/include/core/SkPreConfig.h
@@ -25,26 +25,25 @@
     #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(__FreeBSD__) || defined(__OpenBSD__) || \
-          defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__) || \
-          defined(__GLIBC__) || defined(__GNU__)
-        #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(ANDROID)
         #define SK_BUILD_FOR_ANDROID
+    #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
     #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
@@ -64,25 +63,32 @@
         #define SK_DEBUG
     #endif
 #endif
 
 #ifdef SK_BUILD_FOR_WIN32
     #if !defined(SK_RESTRICT)
         #define SK_RESTRICT __restrict
     #endif
+    #if !defined(SK_WARN_UNUSED_RESULT)
+        #define SK_WARN_UNUSED_RESULT
+    #endif
     #include "sk_stdint.h"
 #endif
 
 //////////////////////////////////////////////////////////////////////
 
 #if !defined(SK_RESTRICT)
     #define SK_RESTRICT __restrict__
 #endif
 
+#if !defined(SK_WARN_UNUSED_RESULT)
+    #define SK_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#endif
+
 //////////////////////////////////////////////////////////////////////
 
 #if !defined(SK_SCALAR_IS_FLOAT) && !defined(SK_SCALAR_IS_FIXED)
     #define SK_SCALAR_IS_FLOAT
     #define SK_CAN_USE_FLOAT
 #endif
 
 //////////////////////////////////////////////////////////////////////
--- a/gfx/skia/include/core/SkPtrRecorder.h
+++ b/gfx/skia/include/core/SkPtrRecorder.h
@@ -66,17 +66,17 @@ private:
     };
 
     // we store the ptrs in sorted-order (using Cmp) so that we can efficiently
     // detect duplicates when add() is called. Hence we need to store the
     // ptr and its ID/fIndex explicitly, since the ptr's position in the array
     // is not related to its "index".
     SkTDArray<Pair>  fList;
     
-    static int Cmp(const Pair& a, const Pair& b);
+    static int Cmp(const Pair* a, const Pair* b);
     
     typedef SkRefCnt INHERITED;
 };
 
 /**
  *  Templated wrapper for SkPtrSet, just meant to automate typecasting
  *  parameters to and from void* (which the base class expects).
  */
--- a/gfx/skia/include/core/SkRasterizer.h
+++ b/gfx/skia/include/core/SkRasterizer.h
@@ -23,19 +23,18 @@ public:
     SkRasterizer() {}
 
     /** Turn the path into a mask, respecting the specified local->device matrix.
     */
     bool rasterize(const SkPath& path, const SkMatrix& matrix,
                    const SkIRect* clipBounds, SkMaskFilter* filter,
                    SkMask* mask, SkMask::CreateMode mode);
 
-    virtual void flatten(SkFlattenableWriteBuffer& ) SK_OVERRIDE {}
 protected:
-    SkRasterizer(SkFlattenableReadBuffer&);
+    SkRasterizer(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
 
     virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
                              const SkIRect* clipBounds,
                              SkMask* mask, SkMask::CreateMode mode);
 
 private:
     typedef SkFlattenable INHERITED;
 };
--- a/gfx/skia/include/core/SkReader32.h
+++ b/gfx/skia/include/core/SkReader32.h
@@ -5,16 +5,18 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
 
 #ifndef SkReader32_DEFINED
 #define SkReader32_DEFINED
 
+#include "SkMatrix.h"
+#include "SkRegion.h"
 #include "SkScalar.h"
 
 class SkString;
 
 class SkReader32 : SkNoncopyable {
 public:
     SkReader32() : fCurr(NULL), fStop(NULL), fBase(NULL) {}
     SkReader32(const void* data, size_t size)  {
@@ -85,16 +87,28 @@ public:
         SkASSERT(fCurr <= fStop);
     }
     
     uint8_t readU8() { return (uint8_t)this->readInt(); }
     uint16_t readU16() { return (uint16_t)this->readInt(); }
     int32_t readS32() { return this->readInt(); }
     uint32_t readU32() { return this->readInt(); }
 
+    void readMatrix(SkMatrix* matrix) {
+        size_t size = matrix->unflatten(this->peek());
+        SkASSERT(SkAlign4(size) == size);
+        (void)this->skip(size);
+    }
+
+    void readRegion(SkRegion* rgn) {
+        size_t size = rgn->unflatten(this->peek());
+        SkASSERT(SkAlign4(size) == size);
+        (void)this->skip(size);
+    }
+
     /**
      *  Read the length of a string (written by SkWriter32::writeString) into
      *  len (if len is not NULL) and return the null-ternimated address of the
      *  string within the reader's buffer.
      */
     const char* readString(size_t* len = NULL);
 
     /**
--- a/gfx/skia/include/core/SkRect.h
+++ b/gfx/skia/include/core/SkRect.h
@@ -15,41 +15,41 @@
 
 /** \struct SkIRect
 
     SkIRect holds four 32 bit integer coordinates for a rectangle
 */
 struct SK_API SkIRect {
     int32_t fLeft, fTop, fRight, fBottom;
 
-    static SkIRect MakeEmpty() {
+    static SkIRect SK_WARN_UNUSED_RESULT MakeEmpty() {
         SkIRect r;
         r.setEmpty();
         return r;
     }
     
-    static SkIRect MakeWH(int32_t w, int32_t h) {
+    static SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h) {
         SkIRect r;
         r.set(0, 0, w, h);
         return r;
     }
     
-    static SkIRect MakeSize(const SkISize& size) {
+    static SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size) {
         SkIRect r;
         r.set(0, 0, size.width(), size.height());
         return r;
     }
     
-    static SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b) {
+    static SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b) {
         SkIRect rect;
         rect.set(l, t, r, b);
         return rect;
     }
     
-    static SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h) {
+    static SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h) {
         SkIRect r;
         r.set(x, y, x + w, y + h);
         return r;
     }
 
     int left() const { return fLeft; }
     int top() const { return fTop; }
     int right() const { return fRight; }
@@ -70,17 +70,17 @@ struct SK_API SkIRect {
      *  (i.e. top <= bottom) so the result may be negative.
      */
     int height() const { return fBottom - fTop; }
     
     /**
      *  Return true if the rectangle's width or height are <= 0
      */
     bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
-
+    
     friend bool operator==(const SkIRect& a, const SkIRect& b) {
         return !memcmp(&a, &b, sizeof(a));
     }
 
     friend bool operator!=(const SkIRect& a, const SkIRect& b) {
         return !(a == b);
     }
 
@@ -139,25 +139,32 @@ struct SK_API SkIRect {
     }
 
     void offset(const SkIPoint& delta) {
         this->offset(delta.fX, delta.fY);
     }
 
     /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
         making the rectangle narrower. If dx is negative, then the sides are moved outwards,
-        making the rectangle wider. The same hods true for dy and the top and bottom.
+        making the rectangle wider. The same holds true for dy and the top and bottom.
     */
     void inset(int32_t dx, int32_t dy) {
         fLeft   += dx;
         fTop    += dy;
         fRight  -= dx;
         fBottom -= dy;
     }
 
+   /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are
+       moved outwards, making the rectangle wider. If dx is negative, then the
+       sides are moved inwards, making the rectangle narrower. The same holds
+       true for dy and the top and bottom.
+    */
+    void outset(int32_t dx, int32_t dy)  { this->inset(-dx, -dy); }
+
     bool quickReject(int l, int t, int r, int b) const {
         return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
     }
     
     /** Returns true if (x,y) is inside the rectangle and the rectangle is not
         empty. The left and top are considered to be inside, while the right
         and bottom are not. Thus for the rectangle (0, 0, 5, 10), the
         points (0,0) and (0,9) are inside, while (-1,0) and (5,9) are not.
@@ -180,28 +187,28 @@ struct SK_API SkIRect {
     */
     bool contains(const SkIRect& r) const {
         return  !r.isEmpty() && !this->isEmpty() &&     // check for empties
                 fLeft <= r.fLeft && fTop <= r.fTop &&
                 fRight >= r.fRight && fBottom >= r.fBottom;
     }
 
     /** Return true if this rectangle contains the specified rectangle.
-		For speed, this method does not check if either this or the specified
-		rectangles are empty, and if either is, its return value is undefined.
-		In the debugging build however, we assert that both this and the
-		specified rectangles are non-empty.
+        For speed, this method does not check if either this or the specified
+        rectangles are empty, and if either is, its return value is undefined.
+        In the debugging build however, we assert that both this and the
+        specified rectangles are non-empty.
     */
     bool containsNoEmptyCheck(int32_t left, int32_t top,
-							  int32_t right, int32_t bottom) const {
-		SkASSERT(fLeft < fRight && fTop < fBottom);
+                              int32_t right, int32_t bottom) const {
+        SkASSERT(fLeft < fRight && fTop < fBottom);
         SkASSERT(left < right && top < bottom);
 
         return fLeft <= left && fTop <= top &&
-			   fRight >= right && fBottom >= bottom;
+               fRight >= right && fBottom >= bottom;
     }
     
     /** If r intersects this rectangle, return true and set this rectangle to that
         intersection, otherwise return false and do not change this rectangle.
         If either rectangle is empty, do nothing and return false.
     */
     bool intersect(const SkIRect& r) {
         SkASSERT(&r);
@@ -289,52 +296,52 @@ struct SK_API SkIRect {
 
     /** Swap top/bottom or left/right if there are flipped.
         This can be called if the edges are computed separately,
         and may have crossed over each other.
         When this returns, left <= right && top <= bottom
     */
     void sort();
 
-    static const SkIRect& EmptyIRect() {
+    static const SkIRect& SK_WARN_UNUSED_RESULT EmptyIRect() {
         static const SkIRect gEmpty = { 0, 0, 0, 0 };
         return gEmpty;
     }
 };
 
 /** \struct SkRect
 */
 struct SK_API SkRect {
     SkScalar    fLeft, fTop, fRight, fBottom;
 
-    static SkRect MakeEmpty() {
+    static SkRect SK_WARN_UNUSED_RESULT MakeEmpty() {
         SkRect r;
         r.setEmpty();
         return r;
     }
 
-    static SkRect MakeWH(SkScalar w, SkScalar h) {
+    static SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h) {
         SkRect r;
         r.set(0, 0, w, h);
         return r;
     }
 
-    static SkRect MakeSize(const SkSize& size) {
+    static SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size) {
         SkRect r;
         r.set(0, 0, size.width(), size.height());
         return r;
     }
 
-    static SkRect MakeLTRB(SkScalar l, SkScalar t, SkScalar r, SkScalar b) {
+    static SkRect SK_WARN_UNUSED_RESULT MakeLTRB(SkScalar l, SkScalar t, SkScalar r, SkScalar b) {
         SkRect rect;
         rect.set(l, t, r, b);
         return rect;
     }
 
-    static SkRect MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h) {
+    static SkRect SK_WARN_UNUSED_RESULT 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
      */
@@ -342,32 +349,39 @@ struct SK_API SkRect {
     
     /**
      *  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;
+        float accum = 0;
+        accum *= fLeft;
+        accum *= fTop;
+        accum *= fRight;
+        accum *= fBottom;
         
-        // value is either NaN or it is finite (zero).
+        // accum is either NaN or it is finite (zero).
+        SkASSERT(0 == accum || !(accum == accum));
+
         // value==value will be true iff value is not NaN
-        return value == value;
+        // TODO: is it faster to say !accum or accum==accum?
+        return accum == accum;
 #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    x() const { return fLeft; }
+    SkScalar    y() const { return fTop; }
     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); }
@@ -422,16 +436,23 @@ struct SK_API SkRect {
     */
     void set(const SkPoint pts[], int count);
 
     // alias for set(pts, count)
     void setBounds(const SkPoint pts[], int count) {
         this->set(pts, count);
     }
 
+    void set(const SkPoint& p0, const SkPoint& p1) {
+        fLeft =   SkMinScalar(p0.fX, p1.fX);
+        fRight =  SkMaxScalar(p0.fX, p1.fX);
+        fTop =    SkMinScalar(p0.fY, p1.fY);
+        fBottom = SkMaxScalar(p0.fY, p1.fY);
+    }
+
     void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height) {
         fLeft = x;
         fTop = y;
         fRight = x + width;
         fBottom = y + height;
     }
 
     /**
@@ -474,17 +495,17 @@ struct SK_API SkRect {
         fLeft   += dx;
         fTop    += dy;
         fRight  -= dx;
         fBottom -= dy;
     }
 
    /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are
        moved outwards, making the rectangle wider. If dx is negative, then the
-       sides are moved inwards, making the rectangle narrower. The same hods
+       sides are moved inwards, making the rectangle narrower. The same holds
        true for dy and the top and bottom.
     */
     void outset(SkScalar dx, SkScalar dy)  { this->inset(-dx, -dy); }
 
     /** If this rectangle intersects r, return true and set this rectangle to that
         intersection, otherwise return false and do not change this rectangle.
         If either rectangle is empty, do nothing and return false.
     */
--- a/gfx/skia/include/core/SkRefCnt.h
+++ b/gfx/skia/include/core/SkRefCnt.h
@@ -10,67 +10,80 @@
 #ifndef SkRefCnt_DEFINED
 #define SkRefCnt_DEFINED
 
 #include "SkThread.h"
 
 /** \class SkRefCnt
 
     SkRefCnt is the base class for objects that may be shared by multiple
-    objects. When a new owner wants a reference, it calls ref(). When an owner
-    wants to release its reference, it calls unref(). When the shared object's
-    reference count goes to zero as the result of an unref() call, its (virtual)
-    destructor is called. It is an error for the destructor to be called
-    explicitly (or via the object going out of scope on the stack or calling
-    delete) if getRefCnt() > 1.
+    objects. When an existing owner wants to share a reference, it calls ref().
+    When an owner wants to release its reference, it calls unref(). When the
+    shared object's reference count goes to zero as the result of an unref()
+    call, its (virtual) destructor is called. It is an error for the
+    destructor to be called explicitly (or via the object going out of scope on
+    the stack or calling delete) if getRefCnt() > 1.
 */
 class SK_API SkRefCnt : SkNoncopyable {
 public:
     /** Default construct, initializing the reference count to 1.
     */
     SkRefCnt() : fRefCnt(1) {}
 
-    /**  Destruct, asserting that the reference count is 1.
+    /** Destruct, asserting that the reference count is 1.
     */
     virtual ~SkRefCnt() {
 #ifdef SK_DEBUG
         SkASSERT(fRefCnt == 1);
         fRefCnt = 0;    // illegal value, to catch us if we reuse after delete
 #endif
     }
 
     /** Return the reference count.
     */
     int32_t getRefCnt() const { return fRefCnt; }
 
     /** Increment the reference count. Must be balanced by a call to unref().
     */
     void ref() const {
         SkASSERT(fRefCnt > 0);
-        sk_atomic_inc(&fRefCnt);
+        sk_atomic_inc(&fRefCnt);  // No barrier required.
     }
 
     /** Decrement the reference count. If the reference count is 1 before the
-        decrement, then call delete on the object. Note that if this is the
-        case, then the object needs to have been allocated via new, and not on
-        the stack.
+        decrement, then delete the object. Note that if this is the case, then
+        the object needs to have been allocated via new, and not on the stack.
     */
     void unref() const {
         SkASSERT(fRefCnt > 0);
+        // Release barrier (SL/S), if not provided below.
         if (sk_atomic_dec(&fRefCnt) == 1) {
-            fRefCnt = 1;    // so our destructor won't complain
-            SkDELETE(this);
+            // Aquire barrier (L/SL), if not provided above.
+            // Prevents code in dispose from happening before the decrement.
+            sk_membar_aquire__after_atomic_dec();
+            internal_dispose();
         }
     }
 
     void validate() const {
         SkASSERT(fRefCnt > 0);
     }
 
 private:
+    /** Called when the ref count goes to 0.
+    */
+    virtual void internal_dispose() const {
+#ifdef SK_DEBUG
+        // so our destructor won't complain
+        fRefCnt = 1;
+#endif
+        SkDELETE(this);
+    }
+    friend class SkWeakRefCnt;
+
     mutable int32_t fRefCnt;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /** Helper macro to safely assign one SkRefCnt[TS]* to another, checking for
     null in on each side of the assignment, and ensuring that ref() is called
     before unref(), in case the two pointers point to the same object.
@@ -123,16 +136,19 @@ public:
      *  detach() will do nothing and return null.
      */
     T* detach() {
         T* obj = fObj;
         fObj = NULL;
         return obj;
     }
 
+    T* operator->() { return fObj; }
+    operator T*() { return fObj; }
+
 private:
     T*  fObj;
 };
 
 class SkAutoUnref : public SkAutoTUnref<SkRefCnt> {
 public:
     SkAutoUnref(SkRefCnt* obj) : SkAutoTUnref<SkRefCnt>(obj) {}
 };
--- a/gfx/skia/include/core/SkRegion.h
+++ b/gfx/skia/include/core/SkRegion.h
@@ -40,23 +40,23 @@ public:
     ~SkRegion();
 
     SkRegion& operator=(const SkRegion&);
 
     /**
      *  Return true if the two regions are equal. i.e. The enclose exactly
      *  the same area.
      */
-    friend bool operator==(const SkRegion& a, const SkRegion& b);
+    bool operator==(const SkRegion& other) const;
 
     /**
      *  Return true if the two regions are not equal.
      */
-    friend bool operator!=(const SkRegion& a, const SkRegion& b) {
-        return !(a == b);
+    bool operator!=(const SkRegion& other) const {
+        return !(*this == other);
     }
     
     /**
      *  Replace this region with the specified region, and return true if the
      *  resulting region is non-empty.
      */
     bool set(const SkRegion& src) {
         SkASSERT(&src);
@@ -373,38 +373,63 @@ public:
     SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);)
 
 private:
     enum {
         kOpCount = kReplace_Op + 1
     };
 
     enum {
-        kRectRegionRuns = 6 // need to store a region of a rect [T B L R S S]        
+        // T
+        // [B N L R S]
+        // S
+        kRectRegionRuns = 7
     };
 
     friend class android::Region;    // needed for marshalling efficiently
-    void allocateRuns(int count); // allocate space for count runs
 
     struct RunHead;
+    
+    // allocate space for count runs
+    void allocateRuns(int count);
+    void allocateRuns(int count, int ySpanCount, int intervalCount);
+    void allocateRuns(const RunHead& src);
 
     SkIRect     fBounds;
     RunHead*    fRunHead;
 
-    void            freeRuns();
-    const RunType*  getRuns(RunType tmpStorage[], int* count) const;
-    bool            setRuns(RunType runs[], int count);
+    void freeRuns();
+    
+    /**
+     *  Return the runs from this region, consing up fake runs if the region
+     *  is empty or a rect. In those 2 cases, we use tmpStorage to hold the
+     *  run data.
+     */
+    const RunType*  getRuns(RunType tmpStorage[], int* intervals) const;
+    
+    // This is called with runs[] that do not yet have their interval-count
+    // field set on each scanline. That is computed as part of this call
+    // (inside ComputeRunBounds).
+    bool setRuns(RunType runs[], int count);
 
     int count_runtype_values(int* itop, int* ibot) const;
     
     static void BuildRectRuns(const SkIRect& bounds,
                               RunType runs[kRectRegionRuns]);
-    // returns true if runs are just a rect
-    static bool ComputeRunBounds(const RunType runs[], int count,
-                                 SkIRect* bounds);
+
+    // If the runs define a simple rect, return true and set bounds to that
+    // rect. If not, return false and ignore bounds.
+    static bool RunsAreARect(const SkRegion::RunType runs[], int count,
+                             SkIRect* bounds);
+
+    /**
+     *  If the last arg is null, just return if the result is non-empty,
+     *  else store the result in the last arg.
+     */
+    static bool Oper(const SkRegion&, const SkRegion&, SkRegion::Op, SkRegion*);
 
     friend struct RunHead;
     friend class Iterator;
     friend class Spanerator;
     friend class SkRgnBuilder;
     friend class SkFlatRegion;
 };
 
--- a/gfx/skia/include/core/SkScalar.h
+++ b/gfx/skia/include/core/SkScalar.h
@@ -300,29 +300,26 @@ static inline int SkScalarSignAsInt(SkSc
 
 // Scalar result version of above
 static inline SkScalar SkScalarSignAsScalar(SkScalar x) {
     return x < 0 ? -SK_Scalar1 : ((x > 0) ? SK_Scalar1 : 0);
 }
 
 #define SK_ScalarNearlyZero         (SK_Scalar1 / (1 << 12))
 
-/*  <= is slower than < for floats, so we use < for our tolerance test
-*/
-
 static inline bool SkScalarNearlyZero(SkScalar x,
                                     SkScalar tolerance = SK_ScalarNearlyZero) {
-    SkASSERT(tolerance > 0);
-    return SkScalarAbs(x) < tolerance;
+    SkASSERT(tolerance >= 0);
+    return SkScalarAbs(x) <= tolerance;
 }
 
 static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y,
                                      SkScalar tolerance = SK_ScalarNearlyZero) {
-    SkASSERT(tolerance > 0);
-    return SkScalarAbs(x-y) < tolerance;
+    SkASSERT(tolerance >= 0);
+    return SkScalarAbs(x-y) <= tolerance;
 }
 
 /** Linearly interpolate between A and B, based on t.
     If t is 0, return A
     If t is 1, return B
     else interpolate.
     t must be [0..SK_Scalar1]
 */
--- a/gfx/skia/include/core/SkScalerContext.h
+++ b/gfx/skia/include/core/SkScalerContext.h
@@ -11,16 +11,18 @@
 #define SkScalerContext_DEFINED
 
 #include "SkMask.h"
 #include "SkMatrix.h"
 #include "SkPaint.h"
 #include "SkPath.h"
 #include "SkPoint.h"
 
+//#define SK_USE_COLOR_LUMINANCE
+
 class SkDescriptor;
 class SkMaskFilter;
 class SkPathEffect;
 class SkRasterizer;
 
 // needs to be != to any valid SkMask::Format
 #define MASK_FORMAT_UNKNOWN         (0xFF)
 #define MASK_FORMAT_JUST_ADVANCE    MASK_FORMAT_UNKNOWN
@@ -170,34 +172,48 @@ public:
         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        = 0x0200,    // else Horizontal
         kLCD_BGROrder_Flag        = 0x0400,    // else RGB order
 
+        // Generate A8 from LCD source (for GDI), only meaningful if fMaskFormat is kA8
+        // Perhaps we can store this (instead) in fMaskFormat, in hight bit?
+        kGenA8FromLCD_Flag        = 0x0800,
+
+#ifdef SK_USE_COLOR_LUMINANCE
+        kLuminance_Bits           = 3,
+#else
         // 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
+        kLuminance_Shift          = 13, // shift to land in the high 3-bits of Flags
+        kLuminance_Bits           = 3,  // ensure Flags doesn't exceed 16bits
+#endif
     };
     
     // computed values
     enum {
         kHinting_Mask   = kHintingBit1_Flag | kHintingBit2_Flag,
+#ifdef SK_USE_COLOR_LUMINANCE
+#else
         kLuminance_Max  = (1 << kLuminance_Bits) - 1,
-        kLuminance_Mask = kLuminance_Max << kLuminance_Shift
+        kLuminance_Mask = kLuminance_Max << kLuminance_Shift,
+#endif
     };
 
     struct Rec {
         uint32_t    fOrigFontID;
         uint32_t    fFontID;
         SkScalar    fTextSize, fPreScaleX, fPreSkewX;
         SkScalar    fPost2x2[2][2];
         SkScalar    fFrameWidth, fMiterLimit;
+#ifdef SK_USE_COLOR_LUMINANCE
+        uint32_t    fLumBits;
+#endif
         uint8_t     fMaskFormat;
         uint8_t     fStrokeJoin;
         uint16_t    fFlags;
         // Warning: when adding members note that the size of this structure
         // must be a multiple of 4. SkDescriptor requires that its arguments be
         // multiples of four and this structure is put in an SkDescriptor in
         // SkPaint::MakeRec.
 
@@ -208,37 +224,47 @@ public:
         SkPaint::Hinting getHinting() const {
             unsigned hint = (fFlags & kHinting_Mask) >> kHinting_Shift;
             return static_cast<SkPaint::Hinting>(hint);
         }
 
         void setHinting(SkPaint::Hinting hinting) {
             fFlags = (fFlags & ~kHinting_Mask) | (hinting << kHinting_Shift);
         }
-
+        
+        SkMask::Format getFormat() const {
+            return static_cast<SkMask::Format>(fMaskFormat);
+        }
+        
+#ifdef SK_USE_COLOR_LUMINANCE
+        SkColor getLuminanceColor() const {
+            return fLumBits;
+        }
+        
+        void setLuminanceColor(SkColor c) {
+            fLumBits = c;
+        }
+#else
         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);
-        }
+#endif
     };
 
     SkScalerContext(const SkDescriptor* desc);
     virtual ~SkScalerContext();
 
     SkMask::Format getMaskFormat() const {
         return (SkMask::Format)fRec.fMaskFormat;
     }
@@ -267,17 +293,23 @@ public:
     unsigned    getGlyphCount() { return this->generateGlyphCount(); }
     void        getAdvance(SkGlyph*);
     void        getMetrics(SkGlyph*);
     void        getImage(const SkGlyph&);
     void        getPath(const SkGlyph&, SkPath*);
     void        getFontMetrics(SkPaint::FontMetrics* mX,
                                SkPaint::FontMetrics* mY);
 
+#ifdef SK_BUILD_FOR_ANDROID
+    unsigned getBaseGlyphCount(SkUnichar charCode);
+#endif
+
     static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
+    static inline void PostMakeRec(Rec*);
+
     static SkScalerContext* Create(const SkDescriptor*);
 
 protected:
     Rec         fRec;
     unsigned    fBaseGlyphCount;
 
     virtual unsigned generateGlyphCount() = 0;
     virtual uint16_t generateCharToGlyph(SkUnichar) = 0;
@@ -291,17 +323,16 @@ protected:
     virtual SkUnichar generateGlyphToChar(uint16_t);
 
     void forceGenerateImageFromPath() { fGenerateImageFromPath = true; }
 
 private:
     SkPathEffect*   fPathEffect;
     SkMaskFilter*   fMaskFilter;
     SkRasterizer*   fRasterizer;
-    SkScalar        fDevFrameWidth;
 
     // if this is set, we draw the image from a path, rather than
     // calling generateImage.
     bool fGenerateImageFromPath;
 
     void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
                          SkPath* devPath, SkMatrix* fillToDevMatrix);
 
--- a/gfx/skia/include/core/SkShader.h
+++ b/gfx/skia/include/core/SkShader.h
@@ -15,20 +15,23 @@
 #include "SkMask.h"
 #include "SkMatrix.h"
 #include "SkPaint.h"
 
 class SkPath;
 
 /** \class SkShader
  *
- *  SkShader is the based class for objects that return horizontal spans of
- *  colors during drawing. A subclass of SkShader is installed in a SkPaint
- *  calling paint.setShader(shader). After that any object (other than a bitmap)
- *  that is drawn with that paint will get its color(s) from the shader.
+ *  Shaders specify the source color(s) for what is being drawn. If a paint
+ *  has no shader, then the paint's color is used. If the paint has a
+ *  shader, then the shader's color(s) are use instead, but they are
+ *  modulated by the paint's alpha. This makes it easy to create a shader
+ *  once (e.g. bitmap tiling or gradient) and then change its transparency
+ *  w/o having to modify the original shader... only the paint's alpha needs
+ *  to be modified.
  */
 class SK_API SkShader : public SkFlattenable {
 public:
             SkShader();
     virtual ~SkShader();
 
     /**
      *  Return true if the shader has a non-identity local matrix.
@@ -44,19 +47,33 @@ public:
     void setLocalMatrix(const SkMatrix& localM);
 
     /**
      *  Reset the shader's local matrix to identity.
      */
     void resetLocalMatrix();
 
     enum TileMode {
-        kClamp_TileMode,    //!< replicate the edge color if the shader draws outside of its original bounds
-        kRepeat_TileMode,   //!< repeat the shader's image horizontally and vertically
-        kMirror_TileMode,   //!< repeat the shader's image horizontally and vertically, alternating mirror images so that adjacent images always seam
+        /** replicate the edge color if the shader draws outside of its
+         *  original bounds
+         */
+        kClamp_TileMode,
+
+        /** repeat the shader's image horizontally and vertically */
+        kRepeat_TileMode,
+
+        /** repeat the shader's image horizontally and vertically, alternating
+         *  mirror images so that adjacent images always seam
+         */
+        kMirror_TileMode,
+
+#if 0
+        /** only draw within the original domain, return 0 everywhere else */
+        kDecal_TileMode,
+#endif
 
         kTileModeCount
     };
 
     // override these in your subclass
 
     enum Flags {
         //!< set if all of the colors will be opaque
@@ -266,40 +283,45 @@ public:
     };
 
     virtual GradientType asAGradient(GradientInfo* info) const;
 
     //////////////////////////////////////////////////////////////////////////
     //  Factory methods for stock shaders
 
     /** Call this to create a new shader that will draw with the specified bitmap.
-        @param src  The bitmap to use inside the shader
-        @param tmx  The tiling mode to use when sampling the bitmap in the x-direction.
-        @param tmy  The tiling mode to use when sampling the bitmap in the y-direction.
-        @return     Returns a new shader object. Note: this function never returns null.
+     *
+     *  If the bitmap cannot be used (e.g. has no pixels, or its dimensions
+     *  exceed implementation limits (currently at 64K - 1)) then SkEmptyShader
+     *  may be returned.
+     *
+     *  @param src  The bitmap to use inside the shader
+     *  @param tmx  The tiling mode to use when sampling the bitmap in the x-direction.
+     *  @param tmy  The tiling mode to use when sampling the bitmap in the y-direction.
+     *  @return     Returns a new shader object. Note: this function never returns null.
     */
     static SkShader* CreateBitmapShader(const SkBitmap& src,
                                         TileMode tmx, TileMode tmy);
 
-    virtual void flatten(SkFlattenableWriteBuffer& ) SK_OVERRIDE;
 protected:
     enum MatrixClass {
         kLinear_MatrixClass,            // no perspective
         kFixedStepInX_MatrixClass,      // fast perspective, need to call fixedStepInX() each scanline
         kPerspective_MatrixClass        // slow perspective, need to mappoints each pixel
     };
     static MatrixClass ComputeMatrixClass(const SkMatrix&);
 
     // These can be called by your subclass after setContext() has been called
     uint8_t             getPaintAlpha() const { return fPaintAlpha; }
     SkBitmap::Config    getDeviceConfig() const { return (SkBitmap::Config)fDeviceConfig; }
     const SkMatrix&     getTotalInverse() const { return fTotalInverse; }
     MatrixClass         getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
 
     SkShader(SkFlattenableReadBuffer& );
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 private:
     SkMatrix*           fLocalMatrix;
     SkMatrix            fTotalInverse;
     uint8_t             fPaintAlpha;
     uint8_t             fDeviceConfig;
     uint8_t             fTotalInverseClass;
     SkDEBUGCODE(SkBool8 fInSession;)
 
--- a/gfx/skia/include/core/SkShape.h
+++ b/gfx/skia/include/core/SkShape.h
@@ -26,24 +26,17 @@ public:
      */
     void drawXY(SkCanvas*, SkScalar dx, SkScalar dy);
 
     /** Draw the shape with the specified matrix, applied before the shape's
         matrix (if any).
      */
     void drawMatrix(SkCanvas*, const SkMatrix&);
 
-    // overrides
-    virtual Factory getFactory();
-    virtual void flatten(SkFlattenableWriteBuffer&);
-
-    // public for Registrar
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
-
-    SK_DECLARE_FLATTENABLE_REGISTRAR()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkShape)
 
 protected:
     virtual void onDraw(SkCanvas*);
 
     SkShape(SkFlattenableReadBuffer&);
 
 private:
 
--- a/gfx/skia/include/core/SkStream.h
+++ b/gfx/skia/include/core/SkStream.h
@@ -267,17 +267,18 @@ public:
 private:
     SkFILE* fFILE;
 };
 
 class SkMemoryWStream : public SkWStream {
 public:
     SkMemoryWStream(void* buffer, size_t size);
     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
-    
+    size_t bytesWritten() const { return fBytesWritten; }
+
 private:
     char*   fBuffer;
     size_t  fMaxLength;
     size_t  fBytesWritten;
 };
 
 class SK_API SkDynamicMemoryWStream : public SkWStream {
 public:
--- a/gfx/skia/include/core/SkString.h
+++ b/gfx/skia/include/core/SkString.h
@@ -10,19 +10,28 @@
 #ifndef SkString_DEFINED
 #define SkString_DEFINED
 
 #include "SkScalar.h"
 
 /*  Some helper functions for C strings
 */
 
-bool SkStrStartsWith(const char string[], const char prefix[]);
+static bool SkStrStartsWith(const char string[], const char prefix[]) {
+    SkASSERT(string);
+    SkASSERT(prefix);
+    return !strncmp(string, prefix, strlen(prefix));
+}
 bool SkStrEndsWith(const char string[], const char suffix[]);
 int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
+static bool SkStrContains(const char string[], const char substring[]) {
+    SkASSERT(string);
+    SkASSERT(substring);
+    return (NULL != strstr(string, substring));
+}
 
 #define SkStrAppendS32_MaxSize  11
 char*   SkStrAppendS32(char buffer[], int32_t);
 #define SkStrAppendS64_MaxSize  20
 char*   SkStrAppendS64(char buffer[], int64_t, int minDigits);
 
 /**
  *  Floats have at most 8 significant digits, so we limit our %g to that.
@@ -76,16 +85,19 @@ public:
     bool equals(const char text[], size_t len) const;
 
     bool startsWith(const char prefix[]) const {
         return SkStrStartsWith(fRec->data(), prefix);
     }
     bool endsWith(const char suffix[]) const {
         return SkStrEndsWith(fRec->data(), suffix);
     }
+    bool contains(const char substring[]) const {
+        return SkStrContains(fRec->data(), substring);
+    }
 
     friend bool operator==(const SkString& a, const SkString& b) {
         return a.equals(b);
     }
     friend bool operator!=(const SkString& a, const SkString& b) {
         return !a.equals(b);
     }
 
--- a/gfx/skia/include/core/SkTDArray.h
+++ b/gfx/skia/include/core/SkTDArray.h
@@ -149,17 +149,17 @@ public:
         memmove(fArray + 1, fArray, (fCount - 1) * sizeof(T));
         return fArray;
     }
 
     T* append() {
         return this->append(1, NULL);
     }
     T* append(size_t count, const T* src = NULL) {
-        unsigned oldCount = fCount;
+        size_t oldCount = fCount;
         if (count)  {
             SkASSERT(src == NULL || fArray == NULL ||
                     src + count <= fArray || fArray + oldCount <= src);
 
             this->growBy(count);
             if (src) {
                 memcpy(fArray + oldCount, src, sizeof(T) * count);
             }
@@ -174,17 +174,17 @@ public:
     }
 
     T* insert(size_t index) {
         return this->insert(index, 1, NULL);
     }
     T* insert(size_t index, size_t count, const T* src = NULL) {
         SkASSERT(count);
         SkASSERT(index <= fCount);
-        int oldCount = fCount;
+        size_t oldCount = fCount;
         this->growBy(count);
         T* dst = fArray + index;
         memmove(dst + count, dst, sizeof(T) * (oldCount - index));
         if (src) {
             memcpy(dst, src, sizeof(T) * count);
         }
         return dst;
     }
@@ -192,17 +192,17 @@ public:
     void remove(size_t index, size_t count = 1) {
         SkASSERT(index + count <= fCount);
         fCount = fCount - count;
         memmove(fArray + index, fArray + index + count, sizeof(T) * (fCount - index));
     }
 
     void removeShuffle(size_t index) {
         SkASSERT(index < fCount);
-        unsigned newCount = fCount - 1;
+        size_t newCount = fCount - 1;
         fCount = newCount;
         if (index != newCount) {
             memcpy(fArray + index, fArray + newCount, sizeof(T));
         }
     }
 
     int find(const T& elem) const {
         const T* iter = fArray;
--- a/gfx/skia/include/core/SkTSearch.h
+++ b/gfx/skia/include/core/SkTSearch.h
@@ -7,16 +7,34 @@
  */
 
 
 #ifndef SkTSearch_DEFINED
 #define SkTSearch_DEFINED
 
 #include "SkTypes.h"
 
+/**
+ *  All of the SkTSearch variants want to return the index (0...N-1) of the
+ *  found element, or the bit-not of where to insert the element.
+ *
+ *  At a simple level, if the return value is negative, it was not found.
+ *
+ *  For clients that want to insert the new element if it was not found, use
+ *  the following logic:
+ *
+ *  int index = SkTSearch(...);
+ *  if (index >= 0) {
+ *      // found at index
+ *  } else {
+ *      index = ~index; // now we are positive
+ *      // insert at index
+ *  }
+ */
+
 template <typename T>
 int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
 {
     SkASSERT(count >= 0);
     if (count <= 0)
         return ~0;
 
     SkASSERT(base != NULL); // base may be NULL if count is zero
@@ -42,40 +60,40 @@ int SkTSearch(const T* base, int count, 
             hi += 1;
         hi = ~hi;
     }
     return hi;
 }
 
 template <typename T>
 int SkTSearch(const T* base, int count, const T& target, size_t elemSize,
-              int (*compare)(const T&, const T&))
+              int (*compare)(const T*, const T*))
 {
     SkASSERT(count >= 0);
     if (count <= 0) {
         return ~0;
     }
 
     SkASSERT(base != NULL); // base may be NULL if count is zero
 
     int lo = 0;
     int hi = count - 1;
 
     while (lo < hi) {
         int mid = (hi + lo) >> 1;
         const T* elem = (const T*)((const char*)base + mid * elemSize);
 
-        if ((*compare)(*elem, target) < 0)
+        if ((*compare)(elem, &target) < 0)
             lo = mid + 1;
         else
             hi = mid;
     }
 
     const T* elem = (const T*)((const char*)base + hi * elemSize);
-    int pred = (*compare)(*elem, target);
+    int pred = (*compare)(elem, &target);
     if (pred != 0) {
         if (pred < 0)
             hi += 1;
         hi = ~hi;
     }
     return hi;
 }
 
@@ -144,15 +162,13 @@ private:
     char*   fLC;    // points to either the heap or fStorage
     size_t  fLength;
     enum {
         STORAGE = 64
     };
     char    fStorage[STORAGE+1];
 };
 
-extern "C" {
-    typedef int (*SkQSortCompareProc)(const void*, const void*);
-    void SkQSort(void* base, size_t count, size_t elemSize, SkQSortCompareProc);
-}
+// Helper when calling qsort with a compare proc that has typed its arguments
+#define SkCastForQSort(compare) reinterpret_cast<int (*)(const void*, const void*)>(compare)
 
 #endif
 
--- a/gfx/skia/include/core/SkThread.h
+++ b/gfx/skia/include/core/SkThread.h
@@ -12,50 +12,56 @@
 
 #include "SkTypes.h"
 #include "SkThread_platform.h"
 
 /****** SkThread_platform needs to define the following...
 
 int32_t sk_atomic_inc(int32_t*);
 int32_t sk_atomic_dec(int32_t*);
+int32_t sk_atomic_conditional_inc(int32_t*);
 
 class SkMutex {
 public:
     SkMutex();
     ~SkMutex();
 
     void    acquire();
     void    release();
 };
 
 ****************/
 
 class SkAutoMutexAcquire : SkNoncopyable {
 public:
-    explicit SkAutoMutexAcquire(SkMutex& mutex) : fMutex(&mutex)
-    {
+    explicit SkAutoMutexAcquire(SkBaseMutex& mutex) : fMutex(&mutex) {
         SkASSERT(fMutex != NULL);
         mutex.acquire();
     }
+    
+    SkAutoMutexAcquire(SkBaseMutex* mutex) : fMutex(mutex) {
+        if (mutex) {
+            mutex->acquire();
+        }
+    }
+
     /** If the mutex has not been release, release it now.
     */
-    ~SkAutoMutexAcquire()
-    {
-        if (fMutex)
+    ~SkAutoMutexAcquire() {
+        if (fMutex) {
             fMutex->release();
+        }
     }
+
     /** If the mutex has not been release, release it now.
     */
-    void release()
-    {
-        if (fMutex)
-        {
+    void release() {
+        if (fMutex) {
             fMutex->release();
             fMutex = NULL;
         }
     }
         
 private:
-    SkMutex* fMutex;
+    SkBaseMutex* fMutex;
 };
 
 #endif
--- a/gfx/skia/include/core/SkThread_platform.h
+++ b/gfx/skia/include/core/SkThread_platform.h
@@ -5,60 +5,179 @@
  * 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(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK)
+#if defined(SK_BUILD_FOR_ANDROID)
+
+#if defined(SK_BUILD_FOR_ANDROID_NDK)
+
+#include <stdint.h>
+
+/* Just use the GCC atomic intrinsics. They're supported by the NDK toolchain,
+ * have reasonable performance, and provide full memory barriers
+ */
+static inline __attribute__((always_inline)) int32_t sk_atomic_inc(int32_t *addr) {
+    return __sync_fetch_and_add(addr, 1);
+}
+
+static inline __attribute__((always_inline)) int32_t sk_atomic_dec(int32_t *addr) {
+    return __sync_fetch_and_add(addr, -1);
+}
+static inline __attribute__((always_inline)) void sk_membar_aquire__after_atomic_dec() { }
+
+static inline __attribute__((always_inline)) int32_t sk_atomic_conditional_inc(int32_t* addr) {
+    int32_t value = *addr;
 
-#include <utils/threads.h>
+    while (true) {
+        if (value == 0) {
+            return 0;
+        }
+
+        int32_t before = __sync_val_compare_and_swap(addr, value, value + 1);
+
+        if (before == value) {
+            return value;
+        } else {
+            value = before;
+        }
+    }
+}
+static inline __attribute__((always_inline)) void sk_membar_aquire__after_atomic_conditional_inc() { }
+
+#else // !SK_BUILD_FOR_ANDROID_NDK
+
+/* The platform atomics operations are slightly more efficient than the
+ * GCC built-ins, so use them.
+ */
 #include <utils/Atomic.h>
 
 #define sk_atomic_inc(addr)     android_atomic_inc(addr)
 #define sk_atomic_dec(addr)     android_atomic_dec(addr)
+void sk_membar_aquire__after_atomic_dec() {
+    //HACK: Android is actually using full memory barriers.
+    //      Should this change, uncomment below.
+    //int dummy;
+    //android_atomic_aquire_store(0, &dummy);
+}
+int32_t sk_atomic_conditional_inc(int32_t* addr) {
+    while (true) {
+        int32_t value = *addr;
+        if (value == 0) {
+            return 0;
+        }
+        if (0 == android_atomic_release_cas(value, value + 1, addr)) {
+            return value;
+        }
+    }
+}
+void sk_membar_aquire__after_atomic_conditional_inc() {
+    //HACK: Android is actually using full memory barriers.
+    //      Should this change, uncomment below.
+    //int dummy;
+    //android_atomic_aquire_store(0, &dummy);
+}
 
-class SkMutex : android::Mutex {
-public:
-    // if isGlobal is true, then ignore any errors in the platform-specific
-    // destructor
-    SkMutex(bool isGlobal = true) {}
-    ~SkMutex() {}
+#endif // !SK_BUILD_FOR_ANDROID_NDK
+
+#else  // !SK_BUILD_FOR_ANDROID
+
+/** Implemented by the porting layer, this function adds one to the int
+    specified by the address (in a thread-safe manner), and returns the
+    previous value.
+    No additional memory barrier is required.
+    This must act as a compiler barrier.
+*/
+SK_API int32_t sk_atomic_inc(int32_t* addr);
+
+/** Implemented by the porting layer, this function subtracts one from the int
+    specified by the address (in a thread-safe manner), and returns the
+    previous value.
+    Expected to act as a release (SL/S) memory barrier and a compiler barrier.
+*/
+SK_API int32_t sk_atomic_dec(int32_t* addr);
+/** If sk_atomic_dec does not act as an aquire (L/SL) barrier, this is expected
+    to act as an aquire (L/SL) memory barrier and as a compiler barrier.
+*/
+SK_API void sk_membar_aquire__after_atomic_dec();
 
-    void    acquire() { this->lock(); }
-    void    release() { this->unlock(); }
+/** Implemented by the porting layer, this function adds one to the int
+    specified by the address iff the int specified by the address is not zero
+    (in a thread-safe manner), and returns the previous value.
+    No additional memory barrier is required.
+    This must act as a compiler barrier.
+*/
+SK_API int32_t sk_atomic_conditional_inc(int32_t*);
+/** If sk_atomic_conditional_inc does not act as an aquire (L/SL) barrier, this
+    is expected to act as an aquire (L/SL) memory barrier and as a compiler
+    barrier.
+*/
+SK_API void sk_membar_aquire__after_atomic_conditional_inc();
+
+#endif // !SK_BUILD_FOR_ANDROID
+
+#ifdef SK_USE_POSIX_THREADS
+
+#include <pthread.h>
+
+// A SkBaseMutex is a POD structure that can be directly initialized
+// at declaration time with SK_DECLARE_STATIC/GLOBAL_MUTEX. This avoids the
+// generation of a static initializer in the final machine code (and
+// a corresponding static finalizer).
+//
+struct SkBaseMutex {
+    void    acquire() { pthread_mutex_lock(&fMutex); }
+    void    release() { pthread_mutex_unlock(&fMutex); }
+    pthread_mutex_t  fMutex;
 };
 
-#else
+// Using POD-style initialization prevents the generation of a static initializer
+// and keeps the acquire() implementation small and fast.
+#define SK_DECLARE_STATIC_MUTEX(name)   static SkBaseMutex  name = { PTHREAD_MUTEX_INITIALIZER }
+
+// Special case used when the static mutex must be available globally.
+#define SK_DECLARE_GLOBAL_MUTEX(name)   SkBaseMutex  name = { PTHREAD_MUTEX_INITIALIZER }
+
+#define SK_DECLARE_MUTEX_ARRAY(name, count)    SkBaseMutex name[count] = { PTHREAD_MUTEX_INITIALIZER }
 
-/** Implemented by the porting layer, this function adds 1 to the int specified
-    by the address (in a thread-safe manner), and returns the previous value.
-*/
-SK_API int32_t sk_atomic_inc(int32_t* addr);
-/** Implemented by the porting layer, this function subtracts 1 to the int
-    specified by the address (in a thread-safe manner), and returns the previous
-    value.
-*/
-SK_API int32_t sk_atomic_dec(int32_t* addr);
+// A normal mutex that requires to be initialized through normal C++ construction,
+// i.e. when it's a member of another class, or allocated on the heap.
+class SkMutex : public SkBaseMutex, SkNoncopyable {
+public:
+    SkMutex();
+    ~SkMutex();
+};
 
-class SkMutex {
+#else // !SK_USE_POSIX_THREADS
+
+// In the generic case, SkBaseMutex and SkMutex are the same thing, and we
+// can't easily get rid of static initializers.
+//
+class SkMutex : SkNoncopyable {
 public:
-    // if isGlobal is true, then ignore any errors in the platform-specific
-    // destructor
-    SkMutex(bool isGlobal = true);
+    SkMutex();
     ~SkMutex();
 
     void    acquire();
     void    release();
 
 private:
     bool fIsGlobal;
     enum {
         kStorageIntCount = 64
     };
     uint32_t    fStorage[kStorageIntCount];
 };
 
-#endif
+typedef SkMutex SkBaseMutex;
+
+#define SK_DECLARE_STATIC_MUTEX(name)           static SkBaseMutex  name
+#define SK_DECLARE_GLOBAL_MUTEX(name)           SkBaseMutex  name
+#define SK_DECLARE_MUTEX_ARRAY(name, count)     SkBaseMutex name[count]
+
+#endif // !SK_USE_POSIX_THREADS
+
 
 #endif
--- a/gfx/skia/include/core/SkTypeface.h
+++ b/gfx/skia/include/core/SkTypeface.h
@@ -6,34 +6,35 @@
  * found in the LICENSE file.
  */
 
 
 #ifndef SkTypeface_DEFINED
 #define SkTypeface_DEFINED
 
 #include "SkAdvancedTypefaceMetrics.h"
-#include "SkRefCnt.h"
+#include "SkWeakRefCnt.h"
 
 class SkStream;
 class SkAdvancedTypefaceMetrics;
 class SkWStream;
 
 typedef uint32_t SkFontID;
+typedef uint32_t SkFontTableTag;
 
 /** \class SkTypeface
 
     The SkTypeface class specifies the typeface and intrinsic style of a font.
     This is used in the paint, along with optionally algorithmic settings like
     textSize, textSkewX, textScaleX, kFakeBoldText_Mask, to specify
     how text appears when drawn (and measured).
 
     Typeface objects are immutable, and so they can be shared between threads.
 */
-class SK_API SkTypeface : public SkRefCnt {
+class SK_API SkTypeface : public SkWeakRefCnt {
 public:
     /** Style specifies the intrinsic style attributes of a given typeface
     */
     enum Style {
         kNormal = 0,
         kBold   = 0x01,
         kItalic = 0x02,
 
@@ -56,17 +57,17 @@ public:
     /** Returns true if the typeface is fixed-width
      */
     bool isFixedWidth() const { return fIsFixedWidth; }
 
     /** Return a 32bit value for this typeface, unique for the underlying font
         data. Will never return 0.
      */
     SkFontID uniqueID() const { return fUniqueID; }
-
+    
     /** Return the uniqueID for the specified typeface. If the face is null,
         resolve it to the default font and return its uniqueID. Will never
         return 0.
     */
     static SkFontID UniqueID(const SkTypeface* face);
 
     /** Returns true if the two typefaces reference the same underlying font,
         handling either being null (treating null as the default font)
@@ -79,28 +80,16 @@ public:
 
         @param familyName  May be NULL. The name of the font family.
         @param style       The style (normal, bold, italic) of the typeface.
         @return reference to the closest-matching typeface. Call must call
                 unref() when they are done.
     */
     static SkTypeface* CreateFromName(const char familyName[], Style style);
 
-    /** Return a new reference to the typeface that covers a set of Unicode
-        code points with the specified Style. Use this call if you want to
-        pick any font that covers a given string of text.
-
-        @param data        UTF-16 characters
-        @param bytelength  length of data, in bytes
-        @return reference to the closest-matching typeface. Call must call
-                unref() when they are done.
-    */
-    static SkTypeface* CreateForChars(const void* data, size_t bytelength,
-                                      Style s);
-
     /** Return a new reference to the typeface that most closely matches the
         requested typeface and specified Style. Use this call if you want to
         pick a new style from the same family of the existing typeface.
         If family is NULL, this selects from the default font's family.
 
         @param family  May be NULL. The name of the existing type face.
         @param s       The style (normal, bold, italic) of the type face.
         @return reference to the closest-matching typeface. Call must call
@@ -141,23 +130,63 @@ public:
                              glyphIDs is NULL.
         @return The returned object has already been referenced.
      */
     SkAdvancedTypefaceMetrics* getAdvancedTypefaceMetrics(
             SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
             const uint32_t* glyphIDs = NULL,
             uint32_t glyphIDsCount = 0) const;
 
+    // Table getters -- may fail if the underlying font format is not organized
+    // as 4-byte tables.
+
+    /** Return the number of tables in the font. */
+    int countTables() const;
+    
+    /** Copy into tags[] (allocated by the caller) the list of table tags in
+     *  the font, and return the number. This will be the same as CountTables()
+     *  or 0 if an error occured. If tags == NULL, this only returns the count
+     *  (the same as calling countTables()).
+     */
+    int getTableTags(SkFontTableTag tags[]) const;
+    
+    /** Given a table tag, return the size of its contents, or 0 if not present
+     */
+    size_t getTableSize(SkFontTableTag) const;
+    
+    /** Copy the contents of a table into data (allocated by the caller). Note
+     *  that the contents of the table will be in their native endian order
+     *  (which for most truetype tables is big endian). If the table tag is
+     *  not found, or there is an error copying the data, then 0 is returned.
+     *  If this happens, it is possible that some or all of the memory pointed
+     *  to by data may have been written to, even though an error has occured.
+     *  
+     *  @param fontID the font to copy the table from
+     *  @param tag  The table tag whose contents are to be copied
+     *  @param offset The offset in bytes into the table's contents where the
+     *  copy should start from.
+     *  @param length The number of bytes, starting at offset, of table data
+     *  to copy.
+     *  @param data storage address where the table contents are copied to
+     *  @return the number of bytes actually copied into data. If offset+length
+     *  exceeds the table's size, then only the bytes up to the table's
+     *  size are actually copied, and this is the value returned. If
+     *  offset > the table's size, or tag is not a valid table,
+     *  then 0 is returned.
+     */
+    size_t getTableData(SkFontTableTag tag, size_t offset, size_t length,
+                        void* data) const;
+    
 protected:
     /** uniqueID must be unique (please!) and non-zero
     */
     SkTypeface(Style style, SkFontID uniqueID, bool isFixedWidth = false);
     virtual ~SkTypeface();
 
 private:
     SkFontID    fUniqueID;
     Style       fStyle;
     bool        fIsFixedWidth;
 
-    typedef SkRefCnt INHERITED;
+    typedef SkWeakRefCnt INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/core/SkTypes.h
+++ b/gfx/skia/include/core/SkTypes.h
@@ -199,17 +199,17 @@ static inline bool SkIsS16(long x) {
 /** Returns true if the value can be represented with unsigned 16bits
  */
 static inline bool SkIsU16(long x) {
     return (uint16_t)x == x;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 #ifndef SK_OFFSETOF
-    #define SK_OFFSETOF(type, field)    ((char*)&(((type*)1)->field) - (char*)1)
+    #define SK_OFFSETOF(type, field)    (size_t)((char*)&(((type*)1)->field) - (char*)1)
 #endif
 
 /** Returns the number of entries in an array (not a pointer)
 */
 #define SK_ARRAY_COUNT(array)       (sizeof(array) / sizeof(array[0]))
 
 /** Returns x rounded up to a multiple of 2
 */
@@ -433,17 +433,17 @@ public:
          */
         kAlloc_OnShrink,
         
         /**
          *  If the requested size is smaller than the current size, and the
          *  current block is dynamically allocated, just return the old
          *  block.
          */
-        kReuse_OnShrink
+        kReuse_OnShrink,
     };
 
     /**
      *  Reallocates the block to a new size. The ptr may or may not change.
      */
     void* reset(size_t size, OnShrink shrink = kAlloc_OnShrink) {
         if (size == fSize || (kReuse_OnShrink == shrink && size < fSize)) {
             return fPtr;
--- a/gfx/skia/include/core/SkUtils.h
+++ b/gfx/skia/include/core/SkUtils.h
@@ -27,23 +27,16 @@ 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(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;
 #endif
 
 #ifndef sk_memset32
 extern SkMemset32Proc sk_memset32;
 #endif
 
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/core/SkWeakRefCnt.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkWeakRefCnt_DEFINED
+#define SkWeakRefCnt_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkThread.h"
+
+/** \class SkWeakRefCnt
+
+    SkWeakRefCnt is the base class for objects that may be shared by multiple
+    objects. When an existing strong owner wants to share a reference, it calls
+    ref(). When a strong owner wants to release its reference, it calls
+    unref(). When the shared object's strong reference count goes to zero as
+    the result of an unref() call, its (virtual) weak_dispose method is called.
+    It is an error for the destructor to be called explicitly (or via the
+    object going out of scope on the stack or calling delete) if
+    getRefCnt() > 1.
+
+    In addition to strong ownership, an owner may instead obtain a weak
+    reference by calling weak_ref(). A call to weak_ref() must be balanced my a
+    call to weak_unref(). To obtain a strong reference from a weak reference,
+    call try_ref(). If try_ref() returns true, the owner's pointer is now also
+    a strong reference on which unref() must be called. Note that this does not
+    affect the original weak reference, weak_unref() must still be called. When
+    the weak reference count goes to zero, the object is deleted. While the
+    weak reference count is positive and the strong reference count is zero the
+    object still exists, but will be in the disposed state. It is up to the
+    object to define what this means.
+
+    Note that a strong reference implicitly implies a weak reference. As a
+    result, it is allowable for the owner of a strong ref to call try_ref().
+    This will have the same effect as calling ref(), but may be more expensive.
+
+    Example:
+
+    SkWeakRefCnt myRef = strongRef.weak_ref();
+    ... // strongRef.unref() may or may not be called
+    if (myRef.try_ref()) {
+        ... // use myRef
+        myRef.unref();
+    } else {
+        // myRef is in the disposed state
+    }
+    myRef.weak_unref();
+*/
+class SK_API SkWeakRefCnt : public SkRefCnt {
+public:
+    /** Default construct, initializing the reference counts to 1.
+        The strong references collectively hold one weak reference. When the
+        strong reference count goes to zero, the collectively held weak
+        reference is released.
+    */
+    SkWeakRefCnt() : SkRefCnt(), fWeakCnt(1) {}
+
+    /** Destruct, asserting that the weak reference count is 1.
+    */
+    virtual ~SkWeakRefCnt() {
+#ifdef SK_DEBUG
+        SkASSERT(fWeakCnt == 1);
+        fWeakCnt = 0;
+#endif
+    }
+
+    /** Return the weak reference count.
+    */
+    int32_t getWeakCnt() const { return fWeakCnt; }
+
+    void validate() const {
+        SkRefCnt::validate();
+        SkASSERT(fWeakCnt > 0);
+    }
+
+    /** Creates a strong reference from a weak reference, if possible. The
+        caller must already be an owner. If try_ref() returns true the owner
+        is in posession of an additional strong reference. Both the original
+        reference and new reference must be properly unreferenced. If try_ref()
+        returns false, no strong reference could be created and the owner's
+        reference is in the same state as before the call.
+    */
+    bool SK_WARN_UNUSED_RESULT try_ref() const {
+        if (sk_atomic_conditional_inc(&fRefCnt) != 0) {
+            // Aquire barrier (L/SL), if not provided above.
+            // Prevents subsequent code from happening before the increment.
+            sk_membar_aquire__after_atomic_conditional_inc();
+            return true;
+        }
+        return false;
+    }
+
+    /** Increment the weak reference count. Must be balanced by a call to
+        weak_unref().
+    */
+    void weak_ref() const {
+        SkASSERT(fRefCnt > 0);
+        SkASSERT(fWeakCnt > 0);
+        sk_atomic_inc(&fWeakCnt);  // No barrier required.
+    }
+
+    /** Decrement the weak reference count. If the weak reference count is 1
+        before the decrement, then call delete on the object. Note that if this
+        is the case, then the object needs to have been allocated via new, and
+        not on the stack.
+    */
+    void weak_unref() const {
+        SkASSERT(fWeakCnt > 0);
+        // Release barrier (SL/S), if not provided below.
+        if (sk_atomic_dec(&fWeakCnt) == 1) {
+            // Aquire barrier (L/SL), if not provided above.
+            // Prevents code in destructor from happening before the decrement.
+            sk_membar_aquire__after_atomic_dec();
+#ifdef SK_DEBUG
+            // so our destructor won't complain
+            fWeakCnt = 1;
+#endif
+            SkRefCnt::internal_dispose();
+        }
+    }
+
+    /** Returns true if there are no strong references to the object. When this
+        is the case all future calls to try_ref() will return false.
+    */
+    bool weak_expired() const {
+        return fRefCnt == 0;
+    }
+
+protected:
+    /** Called when the strong reference count goes to zero. This allows the
+        object to free any resources it may be holding. Weak references may
+        still exist and their level of allowed access to the object is defined
+        by the object's class.
+    */
+    virtual void weak_dispose() const {
+    }
+
+private:
+    /** Called when the strong reference count goes to zero. Calls weak_dispose
+        on the object and releases the implicit weak reference held
+        collectively by the strong references.
+    */
+    virtual void internal_dispose() const SK_OVERRIDE {
+        weak_dispose();
+        weak_unref();
+    }
+
+    /* Invariant: fWeakCnt = #weak + (fRefCnt > 0 ? 1 : 0) */
+    mutable int32_t fWeakCnt;
+};
+
+#endif
--- a/gfx/skia/include/core/SkWriter32.h
+++ b/gfx/skia/include/core/SkWriter32.h
@@ -10,45 +10,56 @@
 #ifndef SkWriter32_DEFINED
 #define SkWriter32_DEFINED
 
 #include "SkTypes.h"
 
 #include "SkScalar.h"
 #include "SkPoint.h"
 #include "SkRect.h"
+#include "SkMatrix.h"
+#include "SkRegion.h"
 
 class SkStream;
 class SkWStream;
 
 class SkWriter32 : SkNoncopyable {
 public:
+    /**
+     *  The caller can specify an initial block of storage, which the caller manages.
+     *  SkWriter32 will not attempt to free this in its destructor. It is up to the
+     *  implementation to decide if, and how much, of the storage to utilize, and it
+     *  is possible that it may be ignored entirely.
+     */
+    SkWriter32(size_t minSize, void* initialStorage, size_t storageSize);
+
     SkWriter32(size_t minSize)
         : fMinSize(minSize),
           fSize(0),
           fSingleBlock(NULL),
           fSingleBlockSize(0),
           fHead(NULL),
-          fTail(NULL) {
-    }
+          fTail(NULL),
+          fHeadIsExternalStorage(false) {}
+
     ~SkWriter32();
 
     /**
      *  Returns the single block backing the writer, or NULL if the memory is
      *  to be dynamically allocated.
      */
     void* getSingleBlock() const { return fSingleBlock; }
 
     /**
      *  Specify the single block to back the writer, rathern than dynamically
      *  allocating the memory. If block == NULL, then the writer reverts to
      *  dynamic allocation (and resets).
      */
     void reset(void* block, size_t size);
-                    
+
     bool writeBool(bool value) {
         this->writeInt(value);
         return value;
     }
     
     void writeInt(int32_t value) {
         *(int32_t*)this->reserve(sizeof(value)) = value;
     }
@@ -71,17 +82,29 @@ public:
     
     void writePoint(const SkPoint& pt) {
         *(SkPoint*)this->reserve(sizeof(pt)) = pt;
     }
     
     void writeRect(const SkRect& rect) {
         *(SkRect*)this->reserve(sizeof(rect)) = rect;
     }
+
+    void writeMatrix(const SkMatrix& matrix) {
+        size_t size = matrix.flatten(NULL);
+        SkASSERT(SkAlign4(size) == size);
+        matrix.flatten(this->reserve(size));
+    }
     
+    void writeRegion(const SkRegion& rgn) {
+        size_t size = rgn.flatten(NULL);
+        SkASSERT(SkAlign4(size) == size);
+        rgn.flatten(this->reserve(size));
+    }
+
     // write count bytes (must be a multiple of 4)
     void writeMul4(const void* values, size_t size) {
         this->write(values, size);
     }
 
     /**
      *  Write size bytes from values. size must be a multiple of 4, though
      *  values need not be 4-byte aligned.
@@ -131,17 +154,19 @@ public:
     bool writeToStream(SkWStream*);
 
 private:
     size_t      fMinSize;
     uint32_t    fSize;
 
     char*       fSingleBlock;
     uint32_t    fSingleBlockSize;
-    
+
     struct Block;
     Block*  fHead;
     Block*  fTail;
 
+    bool fHeadIsExternalStorage;
+
     Block* newBlock(size_t bytes);
 };
 
 #endif
--- a/gfx/skia/include/core/SkXfermode.h
+++ b/gfx/skia/include/core/SkXfermode.h
@@ -167,17 +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()
+    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
 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.
 
@@ -209,30 +209,26 @@ public:
                         const SkAlpha aa[]) SK_OVERRIDE;
     virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
                         const SkAlpha aa[]) SK_OVERRIDE;
     virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count,
                           const SkAlpha aa[]) SK_OVERRIDE;
     virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
                         const SkAlpha aa[]) SK_OVERRIDE;
 
-    // overrides from SkFlattenable
-    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
-    virtual void    flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcXfermode)
 
 protected:
     SkProcXfermode(SkFlattenableReadBuffer&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
     // allow subclasses to update this after we unflatten
     void setProc(SkXfermodeProc proc) {
         fProc = proc;
     }
 
 private:
     SkXfermodeProc  fProc;
 
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkProcXfermode, (buffer)); }
-
     typedef SkXfermode INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/effects/Sk1DPathEffect.h
+++ b/gfx/skia/include/effects/Sk1DPathEffect.h
@@ -54,31 +54,25 @@ public:
         @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*, const SkPath&, SkScalar* width) SK_OVERRIDE;
 
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkPath1DPathEffect, (buffer));
-    }
-
-    SK_DECLARE_FLATTENABLE_REGISTRAR()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPath1DPathEffect)
 
 protected:
     SkPath1DPathEffect(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
     // overrides from Sk1DPathEffect
     virtual SkScalar begin(SkScalar contourLength) SK_OVERRIDE;
     virtual SkScalar next(SkPath*, SkScalar distance, SkPathMeasure&) SK_OVERRIDE;
-    // overrides from SkFlattenable
-    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
@@ -16,19 +16,17 @@
 
 class Sk2DPathEffect : public SkPathEffect {
 public:
     Sk2DPathEffect(const SkMatrix& mat);
 
     // overrides
     virtual bool filterPath(SkPath*, const SkPath&, SkScalar* width) SK_OVERRIDE;
 
-    // overrides from SkFlattenable
-    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
-    virtual Factory getFactory() SK_OVERRIDE;
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk2DPathEffect)
 
 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.
     */
@@ -41,48 +39,44 @@ protected:
         location.
     */
     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()
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
     SkMatrix    fMatrix, fInverse;
+    bool        fMatrixIsInvertible;
+
     // illegal
     Sk2DPathEffect(const Sk2DPathEffect&);
     Sk2DPathEffect& operator=(const Sk2DPathEffect&);
 
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
-
     friend class Sk2DPathEffectBlitter;
     typedef SkPathEffect INHERITED;
 };
 
 class SkPath2DPathEffect : public Sk2DPathEffect {
 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()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPath2DPathEffect)
 
 protected:
     SkPath2DPathEffect(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
-    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;
 };
 
--- a/gfx/skia/include/effects/SkAvoidXfermode.h
+++ b/gfx/skia/include/effects/SkAvoidXfermode.h
@@ -46,32 +46,23 @@ public:
                         const SkAlpha aa[]) SK_OVERRIDE;
     virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
                         const SkAlpha aa[]) SK_OVERRIDE;
     virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count,
                           const SkAlpha aa[]) SK_OVERRIDE;
     virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
                         const SkAlpha aa[]) SK_OVERRIDE;
 
-    // overrides from SkFlattenable
-    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()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAvoidXfermode)
 
 protected:
     SkAvoidXfermode(SkFlattenableReadBuffer&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
     SkColor     fOpColor;
     uint32_t    fDistMul;   // x.14
     Mode        fMode;
 
-    static SkFlattenable* Create(SkFlattenableReadBuffer&);
-
     typedef SkXfermode INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/effects/SkBlurDrawLooper.h
+++ b/gfx/skia/include/effects/SkBlurDrawLooper.h
@@ -39,27 +39,21 @@ public:
     SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color, 
                      uint32_t flags = kNone_BlurFlag);
     virtual ~SkBlurDrawLooper();
 
     // 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()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurDrawLooper)
 
 protected:
     SkBlurDrawLooper(SkFlattenableReadBuffer&);
-    // overrides from SkFlattenable
-    virtual void flatten(SkFlattenableWriteBuffer& );
-    virtual Factory getFactory() { return CreateProc; }
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
     SkMaskFilter*   fBlur;
     SkColorFilter*  fColorFilter;
     SkScalar        fDx, fDy;
     SkColor         fBlurColor;
     uint32_t        fBlurFlags;  
 
--- a/gfx/skia/include/effects/SkBlurImageFilter.h
+++ b/gfx/skia/include/effects/SkBlurImageFilter.h
@@ -12,29 +12,24 @@
 #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()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurImageFilter)
 
 protected:
     explicit SkBlurImageFilter(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
     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,16 +50,15 @@ 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()
-
+    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
 private:
     SkBlurMaskFilter(); // can't be instantiated
 };
 
 #endif
 
--- a/gfx/skia/include/effects/SkColorMatrixFilter.h
+++ b/gfx/skia/include/effects/SkColorMatrixFilter.h
@@ -8,49 +8,42 @@
 
 
 #ifndef SkColorMatrixFilter_DEFINED
 #define SkColorMatrixFilter_DEFINED
 
 #include "SkColorFilter.h"
 #include "SkColorMatrix.h"
 
-class SkColorMatrixFilter : public SkColorFilter {
+class SK_API SkColorMatrixFilter : public SkColorFilter {
 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[]) 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) SK_OVERRIDE;
-
     struct State {
         int32_t fArray[20];
         int     fShift;
         int32_t fResult[4];
     };
 
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer);
-
-    SK_DECLARE_FLATTENABLE_REGISTRAR()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorMatrixFilter)
 
 protected:
-    // overrides for SkFlattenable
-    virtual Factory getFactory();
-
     SkColorMatrixFilter(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
 
     typedef void (*Proc)(State*, unsigned r, unsigned g, unsigned b,
                          unsigned a);
 
     Proc        fProc;
     State       fState;
--- a/gfx/skia/include/effects/SkCornerPathEffect.h
+++ b/gfx/skia/include/effects/SkCornerPathEffect.h
@@ -24,28 +24,21 @@ public:
     */
     SkCornerPathEffect(SkScalar radius);
     virtual ~SkCornerPathEffect();
 
     // overrides for SkPathEffect
     //  This method is not exported to java.
     virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
 
-    // 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()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkCornerPathEffect)
 
 protected:
     SkCornerPathEffect(SkFlattenableReadBuffer&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
     SkScalar    fRadius;
     
     typedef SkPathEffect INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/effects/SkDashPathEffect.h
+++ b/gfx/skia/include/effects/SkDashPathEffect.h
@@ -13,41 +13,51 @@
 #include "SkPathEffect.h"
 
 /** \class SkDashPathEffect
 
     SkDashPathEffect is a subclass of SkPathEffect that implements dashing
 */
 class SK_API SkDashPathEffect : public SkPathEffect {
 public:
-    /** The intervals array must contain an even number of entries (>=2), with the even
-        indices specifying the "on" intervals, and the odd indices specifying the "off"
-        intervals. phase is an offset into the intervals array (mod the sum of all of the
-        intervals).
-        Note: only affects framed paths
+    /** intervals: array containing an even number of entries (>=2), with
+         the even indices specifying the length of "on" intervals, and the odd
+         indices specifying the length of "off" intervals.
+        count: number of elements in the intervals array 
+        phase: offset into the intervals array (mod the sum of all of the
+         intervals).
+
+        For example: if intervals[] = {10, 20}, count = 2, and phase = 25,
+         this will set up a dashed path like so:
+         5 pixels off
+         10 pixels on
+         20 pixels off
+         10 pixels on
+         20 pixels off
+         ...
+        A phase of -5, 25, 55, 85, etc. would all result in the same path,
+         because the sum of all the intervals is 30.
+
+        Note: only affects stroked paths.
     */
     SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase, bool scaleToFit = false);
     virtual ~SkDashPathEffect();
 
     // overrides for SkPathEffect
     //  This method is not exported to java.
     virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
 
     // 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&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
     
 private:
     SkScalar*   fIntervals;
     int32_t     fCount;
     // computed from phase
     SkScalar    fInitialDashLength;
     int32_t     fInitialDashIndex;
     SkScalar    fIntervalLength;
--- a/gfx/skia/include/effects/SkDiscretePathEffect.h
+++ b/gfx/skia/include/effects/SkDiscretePathEffect.h
@@ -23,28 +23,21 @@ public:
         Note: works on filled or framed paths
     */
     SkDiscretePathEffect(SkScalar segLength, SkScalar deviation);
 
     // overrides for SkPathEffect
     //  This method is not exported to java.
     virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
 
-    // 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()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiscretePathEffect)
 
 protected:
     SkDiscretePathEffect(SkFlattenableReadBuffer&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
     SkScalar fSegLength, fPerterb;
     
     typedef SkPathEffect INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/effects/SkEmbossMaskFilter.h
+++ b/gfx/skia/include/effects/SkEmbossMaskFilter.h
@@ -29,31 +29,23 @@ public:
 
     // overrides from SkMaskFilter
     //  This method is not exported to java.
     virtual SkMask::Format getFormat();
     //  This method is not exported to java.
     virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
                             SkIPoint* margin);
 
-    // 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()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmbossMaskFilter)
 
 protected:
     SkEmbossMaskFilter(SkFlattenableReadBuffer&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
     Light       fLight;
     SkScalar    fBlurRadius;
-
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
     
     typedef SkMaskFilter INHERITED;
 };
 
 #endif
 
--- a/gfx/skia/include/effects/SkGradientShader.h
+++ b/gfx/skia/include/effects/SkGradientShader.h
@@ -108,13 +108,13 @@ public:
                         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()
+    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
 };
 
 #endif
 
--- a/gfx/skia/include/effects/SkGroupShape.h
+++ b/gfx/skia/include/effects/SkGroupShape.h
@@ -126,30 +126,24 @@ public:
         is out of range, does nothing.
      */
     void removeShape(int index);
 
     /** Unrefs and removes all of the child shapes
      */
     void removeAllShapes();
 
-    // overrides
-    virtual Factory getFactory();
-    virtual void flatten(SkFlattenableWriteBuffer&);
-
-    // public for Registrar
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
-
-    SK_DECLARE_FLATTENABLE_REGISTRAR()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkGroupShape)
 
 protected:
     // overrides
     virtual void onDraw(SkCanvas*);
 
     SkGroupShape(SkFlattenableReadBuffer&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
     struct Rec {
         SkShape*     fShape;
         SkMatrixRef* fMatrixRef;
     };
     SkTDArray<Rec> fList;
 
--- a/gfx/skia/include/effects/SkKernel33MaskFilter.h
+++ b/gfx/skia/include/effects/SkKernel33MaskFilter.h
@@ -18,21 +18,19 @@ public:
         : fPercent256(percent256) {}
 
     virtual uint8_t computeValue(uint8_t* const* srcRows) = 0;
     
     // overrides from SkMaskFilter
     virtual SkMask::Format getFormat();
     virtual bool filterMask(SkMask*, const SkMask&, const SkMatrix&, SkIPoint*);
 
-    // overrides from SkFlattenable
-    virtual void flatten(SkFlattenableWriteBuffer& wb);
-
 protected:
     SkKernel33ProcMaskFilter(SkFlattenableReadBuffer& rb);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
     int fPercent256;
     
     typedef SkMaskFilter INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -43,23 +41,21 @@ public:
             : SkKernel33ProcMaskFilter(percent256) {
         memcpy(fKernel, coeff, 9 * sizeof(int));
         fShift = shift;
     }
     
     // override from SkKernel33ProcMaskFilter
     virtual uint8_t computeValue(uint8_t* const* srcRows);
     
-    // overrides from SkFlattenable
-    virtual void flatten(SkFlattenableWriteBuffer& wb);
-    virtual Factory getFactory();
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkKernel33MaskFilter)
     
 private:
     int fKernel[3][3];
     int fShift;
 
     SkKernel33MaskFilter(SkFlattenableReadBuffer& rb);
-    static SkFlattenable* Create(SkFlattenableReadBuffer& rb);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
     
     typedef SkKernel33ProcMaskFilter INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/effects/SkLayerDrawLooper.h
+++ b/gfx/skia/include/effects/SkLayerDrawLooper.h
@@ -36,17 +36,17 @@ public:
         
         /**
          *  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
+        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.
@@ -96,29 +96,21 @@ public:
      *  This layer will with the original paint and no offset.
      */
     void addLayer() { this->addLayer(0, 0); }
     
     // overrides from SkDrawLooper
     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_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLayerDrawLooper)
     
-    SK_DECLARE_FLATTENABLE_REGISTRAR()
-
 protected:
     SkLayerDrawLooper(SkFlattenableReadBuffer&);
-
-    // overrides from SkFlattenable
-    virtual void flatten(SkFlattenableWriteBuffer& );
-    virtual Factory getFactory() { return CreateProc; }
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
     
 private:
     struct Rec {
         Rec*    fNext;
         SkPaint fPaint;
         LayerInfo fInfo;
 
         static Rec* Reverse(Rec*);
--- a/gfx/skia/include/effects/SkLayerRasterizer.h
+++ b/gfx/skia/include/effects/SkLayerRasterizer.h
@@ -27,26 +27,21 @@ public:
 
 	/**	Add a new layer (above any previous layers) to the rasterizer.
 		The layer will extract those fields that affect the mask from
 		the specified paint, but will not retain a reference to the paint
 		object itself, so it may be reused without danger of side-effects.
 	*/
     void addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy);
 
-    // overrides from SkFlattenable
-    virtual Factory getFactory();
-    virtual void    flatten(SkFlattenableWriteBuffer&);
-
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
-
-    SK_DECLARE_FLATTENABLE_REGISTRAR()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLayerRasterizer)
 
 protected:
     SkLayerRasterizer(SkFlattenableReadBuffer&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
     // override from SkRasterizer
     virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
                              const SkIRect* clipBounds,
                              SkMask* mask, SkMask::CreateMode mode);
 
 private:
     SkDeque fLayers;
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/effects/SkMorphologyImageFilter.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMorphologyImageFilter_DEFINED
+#define SkMorphologyImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+
+class SK_API SkMorphologyImageFilter : public SkImageFilter {
+public:
+    SkMorphologyImageFilter(int radiusX, int radiusY);
+
+protected:
+    SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+
+    SkISize    radius() const { return fRadius; }
+
+private:
+    SkISize    fRadius;
+    typedef SkImageFilter INHERITED;
+};
+
+class SK_API SkDilateImageFilter : public SkMorphologyImageFilter {
+public:
+    SkDilateImageFilter(int radiusX, int radiusY) : INHERITED(radiusX, radiusY) {}
+
+    virtual bool asADilate(SkISize* radius) const SK_OVERRIDE;
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+                               SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
+
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDilateImageFilter)
+
+protected:
+    SkDilateImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
+
+private:
+    typedef SkMorphologyImageFilter INHERITED;
+};
+
+class SK_API SkErodeImageFilter : public SkMorphologyImageFilter {
+public:
+    SkErodeImageFilter(int radiusX, int radiusY) : INHERITED(radiusX, radiusY) {}
+
+    virtual bool asAnErode(SkISize* radius) const SK_OVERRIDE;
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+                               SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
+
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkErodeImageFilter)
+
+protected:
+    SkErodeImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
+
+private:
+    typedef SkMorphologyImageFilter INHERITED;
+};
+
+#endif
+
--- a/gfx/skia/include/effects/SkPaintFlagsDrawFilter.h
+++ b/gfx/skia/include/effects/SkPaintFlagsDrawFilter.h
@@ -15,15 +15,14 @@
 class SkPaintFlagsDrawFilter : public SkDrawFilter {
 public:
     SkPaintFlagsDrawFilter(uint32_t clearFlags, uint32_t setFlags);
     
     // overrides
     virtual void filter(SkPaint*, Type);
     
 private:
-    uint32_t    fPrevFlags;     // local cache for filter/restore
     uint16_t    fClearFlags;    // user specified
     uint16_t    fSetFlags;      // user specified
 };
 
 #endif
 
--- a/gfx/skia/include/effects/SkPixelXorXfermode.h
+++ b/gfx/skia/include/effects/SkPixelXorXfermode.h
@@ -16,33 +16,24 @@
     This transformation does not follow premultiplied conventions, therefore
     this proc *always* returns an opaque color (alpha == 255). Thus it is
     not really usefull for operating on blended colors.
 */
 class SkPixelXorXfermode : public SkXfermode {
 public:
     SkPixelXorXfermode(SkColor opColor) : fOpColor(opColor) {}
 
-    // override from SkFlattenable
-    virtual Factory getFactory();
-    virtual void flatten(SkFlattenableWriteBuffer&);
-
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
-        return SkNEW_ARGS(SkPixelXorXfermode, (buffer));
-    }
-
-    SK_DECLARE_FLATTENABLE_REGISTRAR()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPixelXorXfermode)
 
 protected:
+    SkPixelXorXfermode(SkFlattenableReadBuffer& rb);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+
     // override from SkXfermode
     virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst);
 
 private:
     SkColor fOpColor;
 
-    SkPixelXorXfermode(SkFlattenableReadBuffer& rb);
-    // our private factory
-    static SkFlattenable* Create(SkFlattenableReadBuffer&);
-
     typedef SkXfermode INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/effects/SkRectShape.h
+++ b/gfx/skia/include/effects/SkRectShape.h
@@ -14,48 +14,40 @@
 
 class SkPaintShape : public SkShape {
 public:
     SkPaintShape();
 
     SkPaint& paint() { return fPaint; }
     const SkPaint& paint() const { return fPaint; }
 
-    // overrides
-    virtual void flatten(SkFlattenableWriteBuffer&);
-    
 protected:
     SkPaintShape(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
     
 private:
     SkPaint fPaint;
     
     typedef SkShape INHERITED;
 };
 
 class SkRectShape : public SkPaintShape {
 public:
     SkRectShape();
     
     void setRect(const SkRect&);
     void setOval(const SkRect&);
     void setCircle(SkScalar x, SkScalar y, SkScalar radius);
     void setRRect(const SkRect&, SkScalar rx, SkScalar ry);
 
-    // overrides
-    virtual Factory getFactory();
-    virtual void flatten(SkFlattenableWriteBuffer&);
-
-    // public for Registrar
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
-
-    SK_DECLARE_FLATTENABLE_REGISTRAR()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRectShape)
 
 protected:
     SkRectShape(SkFlattenableReadBuffer&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
     // overrides
     virtual void onDraw(SkCanvas*);
 
 private:
     SkRect  fBounds;
     SkSize  fRadii;
 
--- a/gfx/skia/include/effects/SkTableColorFilter.h
+++ b/gfx/skia/include/effects/SkTableColorFilter.h
@@ -1,15 +1,15 @@
 
 #ifndef SkTableColorFilter_DEFINED
 #define SkTableColorFilter_DEFINED
 
 #include "SkColorFilter.h"
 
-class SkTableColorFilter {
+class SK_API 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];
@@ -24,11 +24,13 @@ public:
      *  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]);
+
+    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
 };
 
 #endif
--- a/gfx/skia/include/effects/SkTableMaskFilter.h
+++ b/gfx/skia/include/effects/SkTableMaskFilter.h
@@ -46,23 +46,21 @@ public:
         MakeClipTable(table, min, max);
         return SkNEW_ARGS(SkTableMaskFilter, (table));
     }
 
     // overrides from SkMaskFilter
     virtual SkMask::Format getFormat();
     virtual bool filterMask(SkMask*, const SkMask&, const SkMatrix&, SkIPoint*);
     
-    // overrides from SkFlattenable
-    virtual void flatten(SkFlattenableWriteBuffer& wb);
-    virtual Factory getFactory();
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTableMaskFilter)
 
 protected:
     SkTableMaskFilter(SkFlattenableReadBuffer& rb);
-    static SkFlattenable* Factory(SkFlattenableReadBuffer&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
     uint8_t fTable[256];
     
     typedef SkMaskFilter INHERITED;
 };
 
 #endif
--- a/gfx/skia/include/effects/SkTestImageFilters.h
+++ b/gfx/skia/include/effects/SkTestImageFilters.h
@@ -1,33 +1,30 @@
 
 #ifndef _SkTestImageFilters_h
 #define _SkTestImageFilters_h
 
 #include "SkImageFilter.h"
+#include "SkColorFilter.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));
-    }
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOffsetImageFilter)
 
 protected:
     SkOffsetImageFilter(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
     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 {
@@ -35,29 +32,25 @@ 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));
-    }
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeImageFilter)
     
 protected:
     SkComposeImageFilter(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
     
     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;
 };
 
@@ -66,92 +59,78 @@ private:
 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));
-    }
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMergeImageFilter)
     
 protected:
     SkMergeImageFilter(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
     
     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));
-    }
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorFilterImageFilter)
     
 protected:
     SkColorFilterImageFilter(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
     
     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));
-    }
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDownSampleImageFilter)
     
 protected:
     SkDownSampleImageFilter(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
     
     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
@@ -18,28 +18,22 @@ public:
 
     virtual uint32_t getFlags() SK_OVERRIDE;
     virtual bool    setContext( const SkBitmap& device,
                                 const SkPaint& paint,
                                 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() SK_OVERRIDE;
-    virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTransparentShader)
 
 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) {
-        return SkNEW_ARGS(SkTransparentShader, (buffer));
-    }
-
     typedef SkShader INHERITED;
 };
 
 #endif
 
--- a/gfx/skia/include/gpu/GrClip.h
+++ b/gfx/skia/include/gpu/GrClip.h
@@ -8,19 +8,19 @@
 
 
 
 #ifndef GrClip_DEFINED
 #define GrClip_DEFINED
 
 #include "GrClipIterator.h"
 #include "GrRect.h"
-#include "GrPath.h"
 #include "GrTemplates.h"
 
+#include "SkPath.h"
 #include "SkTArray.h"
 
 class GrClip {
 public:
     GrClip();
     GrClip(const GrClip& src);
     /**
      *  If specified, the conservativeBounds parameter already takes (tx,ty)
@@ -34,41 +34,45 @@ public:
     ~GrClip();
 
     GrClip& operator=(const GrClip& src);
 
     bool hasConservativeBounds() const { return fConservativeBoundsValid; }
 
     const GrRect& getConservativeBounds() const { return fConservativeBounds; }
 
+    bool requiresAA() const { return fRequiresAA; }
+
     int getElementCount() const { return fList.count(); }
 
     GrClipType getElementType(int i) const { return fList[i].fType; }
 
-    const GrPath& getPath(int i) const {
+    const SkPath& getPath(int i) const {
         GrAssert(kPath_ClipType == fList[i].fType);
         return fList[i].fPath;
     }
 
     GrPathFill getPathFill(int i) const {
         GrAssert(kPath_ClipType == fList[i].fType);
         return fList[i].fPathFill;
     }
 
     const GrRect& getRect(int i) const {
         GrAssert(kRect_ClipType == fList[i].fType);
         return fList[i].fRect;
     }
 
-    GrSetOp getOp(int i) const { return fList[i].fOp; }
+    SkRegion::Op getOp(int i) const { return fList[i].fOp; }
+
+    bool getDoAA(int i) const   { return fList[i].fDoAA; }
 
     bool isRect() const {
         if (1 == fList.count() && kRect_ClipType == fList[0].fType && 
-            (kIntersect_SetOp == fList[0].fOp ||
-             kReplace_SetOp == fList[0].fOp)) {
+            (SkRegion::kIntersect_Op == fList[0].fOp ||
+             SkRegion::kReplace_Op == fList[0].fOp)) {
             // if we determined that the clip is a single rect
             // we ought to have also used that rect as the bounds.
             GrAssert(fConservativeBoundsValid);
             GrAssert(fConservativeBounds == fList[0].fRect);
             return true;
         } else {
             return false;
         }
@@ -102,23 +106,24 @@ public:
         return true;
     }
     friend bool operator!=(const GrClip& a, const GrClip& b) {
         return !(a == b);
     }
 
 private:
     struct Element {
-        GrClipType  fType;
-        GrRect      fRect;
-        GrPath      fPath;
-        GrPathFill  fPathFill;
-        GrSetOp     fOp;
+        GrClipType   fType;
+        GrRect       fRect;
+        SkPath       fPath;
+        GrPathFill   fPathFill;
+        SkRegion::Op fOp;
+        bool         fDoAA;
         bool operator ==(const Element& e) const {
-            if (e.fType != fType || e.fOp != fOp) {
+            if (e.fType != fType || e.fOp != fOp || e.fDoAA != fDoAA) {
                 return false;
             }
             switch (fType) {
                 case kRect_ClipType:
                     return fRect == e.fRect;
                 case kPath_ClipType:
                     return fPath == e.fPath;
                 default:
@@ -127,15 +132,17 @@ private:
             }
         }
         bool operator !=(const Element& e) const { return !(*this == e); }
     };
 
     GrRect              fConservativeBounds;
     bool                fConservativeBoundsValid;
 
+    bool                fRequiresAA;
+
     enum {
         kPreAllocElements = 4,
     };
     SkSTArray<kPreAllocElements, Element>   fList;
 };
 #endif
 
--- a/gfx/skia/include/gpu/GrClipIterator.h
+++ b/gfx/skia/include/gpu/GrClipIterator.h
@@ -6,18 +6,19 @@
  * found in the LICENSE file.
  */
 
 
 
 #ifndef GrClipIterator_DEFINED
 #define GrClipIterator_DEFINED
 
-#include "GrPath.h"
 #include "GrRect.h"
+#include "SkPath.h"
+#include "SkRegion.h"
 
 /**
  * A clip is a list of paths and/or rects with set operations to combine them.
  */
 class GrClipIterator {
 public:
     virtual ~GrClipIterator() {}
 
@@ -35,17 +36,17 @@ public:
      * Get the type of the current clip element
      */
     virtual GrClipType getType() const = 0;
 
     /**
      * Return the current path. It is an error to call this when isDone() is
      * true or when getType() is kRect_Type.
      */
-    virtual const GrPath* getPath() = 0;
+    virtual const SkPath* getPath() = 0;
 
     /**
      * Return the fill rule for the path. It is an error to call this when
      * isDone() is true or when getType is kRect_Type.
      */
     virtual GrPathFill getPathFill() const = 0;
 
     /**
@@ -53,17 +54,22 @@ public:
     * or when getType() is kPath_Type.
     */
     virtual void getRect(GrRect* rect) const = 0;
 
     /**
      * Gets the operation used to apply the current item to previously iterated
      * items. Iterators should not produce a Replace op.
      */
-    virtual GrSetOp getOp() const = 0;
+    virtual SkRegion::Op getOp() const = 0;
+
+    /**
+     * Gets anti-aliasing setting desired for the current clip
+     */
+    virtual bool getDoAA() const = 0;
 
     /**
      *  Call to move to the next element in the list, previous path iter can be
      *  made invalid.
      */
     virtual void next() = 0;
 };
 
--- a/gfx/skia/include/gpu/GrConfig.h
+++ b/gfx/skia/include/gpu/GrConfig.h
@@ -177,17 +177,17 @@ typedef unsigned __int64 uint64_t;
 #else
     #define GR_API
 #endif
 
 // By now we must have a GR_..._BUILD symbol set to 1, and a decision about
 // debug -vs- release
 //
 
-extern GR_API void GrPrintf(const char format[], ...);
+#define GrPrintf SkDebugf
 
 /**
  *  GR_STRING makes a string of X where X is expanded before conversion to a string
  *  if X itself contains macros.
  */
 #define GR_STRING(X) GR_STRING_IMPL(X)
 #define GR_STRING_IMPL(X) #X
 
@@ -359,33 +359,16 @@ inline void GrCrash(const char* msg) { G
  * 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().
  */
 #if !defined(GR_GEOM_BUFFER_LOCK_THRESHOLD)
     #define GR_GEOM_BUFFER_LOCK_THRESHOLD (1 << 15)
 #endif
 
-/**
- * Enables/disables use of offscreen AA
- */
-#if !defined(GR_USE_OFFSCREEN_AA)
-    #define GR_USE_OFFSCREEN_AA 1
-#endif
-
-/**
- * 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
@@ -11,30 +11,33 @@
 #define GrContext_DEFINED
 
 #include "GrClip.h"
 #include "GrPaint.h"
 // not strictly needed but requires WK change in LayerTextureUpdaterCanvas to
 // remove.
 #include "GrRenderTarget.h" 
 
+class GrAutoScratchTexture;
+class GrDrawState;
 class GrDrawTarget;
 class GrFontCache;
 class GrGpu;
 struct GrGpuStats;
 class GrIndexBuffer;
 class GrIndexBufferAllocPool;
 class GrInOrderDrawBuffer;
 class GrPathRenderer;
 class GrPathRendererChain;
 class GrResourceEntry;
 class GrResourceCache;
 class GrStencilBuffer;
 class GrVertexBuffer;
 class GrVertexBufferAllocPool;
+class GrSoftwarePathRenderer;
 
 class GR_API GrContext : public GrRefCnt {
 public:
     /**
      * Creates a GrContext from within a 3D context.
      */
     static GrContext* Create(GrEngine engine,
                              GrPlatform3DContext context3D);
@@ -70,24 +73,29 @@ public:
     void contextDestroyed();
 
     /**
      * Frees gpu created by the context. Can be called to reduce GPU memory
      * pressure.
      */
     void freeGpuResources();
 
+    /**
+     * Returns the number of bytes of GPU memory hosted by the texture cache.
+     */
+    size_t getGpuTextureCacheBytes() const;
+
     ///////////////////////////////////////////////////////////////////////////
     // Textures
 
     /**
      * Token that refers to an entry in the texture cache. Returned by
      * functions that lock textures. Passed to unlockTexture.
      */
-    class TextureCacheEntry {
+    class SK_API TextureCacheEntry {
     public:
         TextureCacheEntry() : fEntry(NULL) {}
         TextureCacheEntry(const TextureCacheEntry& e) : fEntry(e.fEntry) {}
         TextureCacheEntry& operator= (const TextureCacheEntry& e) {
             fEntry = e.fEntry;
             return *this;
         }
         GrTexture* texture() const;
@@ -262,16 +270,21 @@ public:
 
     /**
      * Gets the current render target.
      * @return the currently bound render target. Should never be NULL.
      */
     const GrRenderTarget* getRenderTarget() const;
     GrRenderTarget* getRenderTarget();
 
+    /**
+     * Can the provided configuration act as a color render target?
+     */
+    bool isConfigRenderable(GrPixelConfig config) const;
+
     ///////////////////////////////////////////////////////////////////////////
     // 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.
@@ -290,36 +303,16 @@ public:
      *
      * @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.
-     *
-     * @param   desc    description of the object to create.
-     * @return either a GrTexture* or GrRenderTarget* depending on desc. NULL
-     *         on failure.
-     */
-    GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
-
     ///////////////////////////////////////////////////////////////////////////
     // Matrix state
 
     /**
      * Gets the current transformation matrix.
      * @return the current matrix.
      */
     const GrMatrix& getMatrix() const;
@@ -414,17 +407,17 @@ public:
      * Draws a path.
      *
      * @param paint         describes how to color pixels.
      * @param path          the path to draw
      * @param fill          the path filling rule to use.
      * @param translate     optional additional translation applied to the
      *                      path.
      */
-    void drawPath(const GrPaint& paint, const GrPath& path, GrPathFill fill,
+    void drawPath(const GrPaint& paint, const SkPath& path, GrPathFill fill,
                   const GrPoint* translate = NULL);
 
     /**
      * Draws vertices with a paint.
      *
      * @param   paint           describes how to color pixels.
      * @param   primitiveType   primitives type to draw.
      * @param   vertexCount     number of vertices.
@@ -442,25 +435,34 @@ public:
                       GrPrimitiveType primitiveType,
                       int vertexCount,
                       const GrPoint positions[],
                       const GrPoint texs[],
                       const GrColor colors[],
                       const uint16_t indices[],
                       int indexCount);
 
+    /**
+     * Draws an oval.
+     *
+     * @param paint         describes how to color pixels.
+     * @param rect          the bounding rect of the oval.
+     * @param strokeWidth   if strokeWidth < 0, then the oval is filled, else
+     *                      the rect is stroked based on strokeWidth. If
+     *                      strokeWidth == 0, then the stroke is always a single
+     *                      pixel thick.
+     */
+    void drawOval(const GrPaint& paint,
+                  const GrRect& rect,
+                  SkScalar strokeWidth);
+
     ///////////////////////////////////////////////////////////////////////////
     // Misc.
 
     /**
-     * Currently needed by SkGpuDevice. Ideally this shouldn't be exposed.
-     */
-    bool supportsShaders() const;
-
-    /**
      * Flags that affect flush() behavior.
      */
     enum FlushBits {