diff options
Diffstat (limited to 'gfx/skia/patches/archive')
57 files changed, 8502 insertions, 0 deletions
diff --git a/gfx/skia/patches/archive/0001-Bug-687189-Implement-SkPaint-getPosTextPath.patch b/gfx/skia/patches/archive/0001-Bug-687189-Implement-SkPaint-getPosTextPath.patch new file mode 100644 index 0000000000..f8e76dbb90 --- /dev/null +++ b/gfx/skia/patches/archive/0001-Bug-687189-Implement-SkPaint-getPosTextPath.patch @@ -0,0 +1,66 @@ +From 27a914815e757ed12523edf968c9da134dabeaf8 Mon Sep 17 00:00:00 2001 +From: George Wright <gwright@mozilla.com> +Date: Fri, 18 May 2012 14:10:44 -0400 +Subject: [PATCH 01/10] Bug 755869 - [4] Re-apply bug 687189 - Implement + SkPaint::getPosTextPath r=mattwoodrow + +--- + gfx/skia/include/core/SkPaint.h | 3 +++ + gfx/skia/src/core/SkPaint.cpp | 27 +++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+), 0 deletions(-) + +diff --git a/gfx/skia/include/core/SkPaint.h b/gfx/skia/include/core/SkPaint.h +index 1930db1..ff37d77 100644 +--- a/gfx/skia/include/core/SkPaint.h ++++ b/gfx/skia/include/core/SkPaint.h +@@ -813,6 +813,9 @@ public: + 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); +diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp +index 1b74fa1..4c119aa 100644 +--- a/gfx/skia/src/core/SkPaint.cpp ++++ b/gfx/skia/src/core/SkPaint.cpp +@@ -1355,6 +1355,33 @@ void SkPaint::getTextPath(const void* textData, size_t length, + } + } + ++void SkPaint::getPosTextPath(const void* textData, size_t length, ++ const SkPoint pos[], SkPath* path) const { ++ SkASSERT(length == 0 || textData != NULL); ++ ++ const char* text = (const char*)textData; ++ if (text == NULL || length == 0 || path == NULL) { ++ return; ++ } ++ ++ SkTextToPathIter iter(text, length, *this, false); ++ SkMatrix matrix; ++ SkPoint prevPos; ++ prevPos.set(0, 0); ++ ++ matrix.setScale(iter.getPathScale(), iter.getPathScale()); ++ path->reset(); ++ ++ unsigned int i = 0; ++ const SkPath* iterPath; ++ while ((iterPath = iter.next(NULL)) != NULL) { ++ matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); ++ path->addPath(*iterPath, matrix); ++ prevPos = pos[i]; ++ i++; ++ } ++} ++ + static void add_flattenable(SkDescriptor* desc, uint32_t tag, + SkFlattenableWriteBuffer* buffer) { + buffer->flatten(desc->addEntry(tag, buffer->size(), NULL)); +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0001-Bug-777614-Re-add-our-SkUserConfig.h-r-nrc.patch b/gfx/skia/patches/archive/0001-Bug-777614-Re-add-our-SkUserConfig.h-r-nrc.patch new file mode 100644 index 0000000000..8fe0135fbb --- /dev/null +++ b/gfx/skia/patches/archive/0001-Bug-777614-Re-add-our-SkUserConfig.h-r-nrc.patch @@ -0,0 +1,34 @@ +From 2dd8c789fc4ad3b5323c2c29f3e982d185f5b5d9 Mon Sep 17 00:00:00 2001 +From: George Wright <gw@gwright.org.uk> +Date: Thu, 13 Sep 2012 22:33:38 -0400 +Subject: [PATCH 1/9] Bug 777614 - Re-add our SkUserConfig.h r=nrc + +--- + gfx/skia/include/config/SkUserConfig.h | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h +index 353272c..fbfbfe0 100644 +--- a/gfx/skia/include/config/SkUserConfig.h ++++ b/gfx/skia/include/config/SkUserConfig.h +@@ -184,5 +184,16 @@ + directories from your include search path when you're not building the GPU + backend. Defaults to 1 (build the GPU code). + */ +-//#define SK_SUPPORT_GPU 1 ++#define SK_SUPPORT_GPU 0 ++ ++/* Don't dither 32bit gradients, to match what the canvas test suite expects. ++ */ ++#define SK_DISABLE_DITHER_32BIT_GRADIENT ++ ++/* 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 +-- +1.7.11.4 + diff --git a/gfx/skia/patches/archive/0001-Bug-803063-Skia-cross-compilation-for-Windows-fails-.patch b/gfx/skia/patches/archive/0001-Bug-803063-Skia-cross-compilation-for-Windows-fails-.patch new file mode 100644 index 0000000000..20155977e2 --- /dev/null +++ b/gfx/skia/patches/archive/0001-Bug-803063-Skia-cross-compilation-for-Windows-fails-.patch @@ -0,0 +1,26 @@ +From 81ff1a8f5c2a7cc9e8b853101b995433a0c0fa37 Mon Sep 17 00:00:00 2001 +From: Jacek Caban <jacek@codeweavers.com> +Date: Thu, 18 Oct 2012 15:25:08 +0200 +Subject: [PATCH] Bug 803063 - Skia cross compilation for Windows fails on + case sensitive OS + +--- + gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp b/gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp +index 370616e..b647ada 100644 +--- a/gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp ++++ b/gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp +@@ -13,7 +13,7 @@ + SK_DEFINE_INST_COUNT(SkAdvancedTypefaceMetrics) + + #if defined(SK_BUILD_FOR_WIN) +-#include <DWrite.h> ++#include <dwrite.h> + #endif + + #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) +-- +1.7.8.6 + diff --git a/gfx/skia/patches/archive/0001-Bug-895086-Remove-unused-find_from_uniqueID-function.patch b/gfx/skia/patches/archive/0001-Bug-895086-Remove-unused-find_from_uniqueID-function.patch new file mode 100644 index 0000000000..aa1fadb435 --- /dev/null +++ b/gfx/skia/patches/archive/0001-Bug-895086-Remove-unused-find_from_uniqueID-function.patch @@ -0,0 +1,38 @@ +From 58861c38751adf1f4ef3f67f8e85f5c36f1c43a5 Mon Sep 17 00:00:00 2001 +From: George Wright <gw@gwright.org.uk> +Date: Wed, 17 Jul 2013 16:28:07 -0400 +Subject: [PATCH] Bug 895086 - Remove unused find_from_uniqueID() function from + SkFontHost_linux + +--- + gfx/skia/src/ports/SkFontHost_linux.cpp | 14 -------------- + 1 file changed, 14 deletions(-) + +diff --git a/gfx/skia/src/ports/SkFontHost_linux.cpp b/gfx/skia/src/ports/SkFontHost_linux.cpp +index df21014..05b73dc 100644 +--- a/gfx/skia/src/ports/SkFontHost_linux.cpp ++++ b/gfx/skia/src/ports/SkFontHost_linux.cpp +@@ -117,20 +117,6 @@ static FamilyRec* find_family(const SkTypeface* member) { + return NULL; + } + +-static SkTypeface* find_from_uniqueID(uint32_t uniqueID) { +- FamilyRec* curr = gFamilyHead; +- while (curr != NULL) { +- for (int i = 0; i < 4; i++) { +- SkTypeface* face = curr->fFaces[i]; +- if (face != NULL && face->uniqueID() == uniqueID) { +- return face; +- } +- } +- curr = curr->fNext; +- } +- return NULL; +-} +- + /* Remove reference to this face from its family. If the resulting family + is empty (has no faces), return that family, otherwise return NULL + */ +-- +1.8.3.1 + diff --git a/gfx/skia/patches/archive/0002-Bug-688366-Dont-invalidate-all-radial-gradients.patch b/gfx/skia/patches/archive/0002-Bug-688366-Dont-invalidate-all-radial-gradients.patch new file mode 100644 index 0000000000..d396b4ed12 --- /dev/null +++ b/gfx/skia/patches/archive/0002-Bug-688366-Dont-invalidate-all-radial-gradients.patch @@ -0,0 +1,30 @@ +From f310d7e8b8d9cf6870c739650324bb585b591c0c Mon Sep 17 00:00:00 2001 +From: George Wright <gwright@mozilla.com> +Date: Fri, 18 May 2012 14:11:32 -0400 +Subject: [PATCH 02/10] Bug 755869 - [5] Re-apply bug 688366 - Fix Skia + marking radial gradients with the same radius as + invalid. r=mattwoodrow + +--- + gfx/skia/src/effects/SkGradientShader.cpp | 5 ++++- + 1 files changed, 4 insertions(+), 1 deletions(-) + +diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp +index 6de820b..59ba48c 100644 +--- a/gfx/skia/src/effects/SkGradientShader.cpp ++++ b/gfx/skia/src/effects/SkGradientShader.cpp +@@ -1911,7 +1911,10 @@ public: + SkPMColor* SK_RESTRICT dstC = dstCParam; + + // Zero difference between radii: fill with transparent black. +- if (fDiffRadius == 0) { ++ // TODO: Is removing this actually correct? Two circles with the ++ // same radius, but different centers doesn't sound like it ++ // should be cleared ++ if (fDiffRadius == 0 && fCenter1 == fCenter2) { + sk_bzero(dstC, count * sizeof(*dstC)); + return; + } +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0002-Bug-848491-Re-apply-Bug-795549-Move-TileProc-functio.patch b/gfx/skia/patches/archive/0002-Bug-848491-Re-apply-Bug-795549-Move-TileProc-functio.patch new file mode 100644 index 0000000000..6ac2c9179d --- /dev/null +++ b/gfx/skia/patches/archive/0002-Bug-848491-Re-apply-Bug-795549-Move-TileProc-functio.patch @@ -0,0 +1,50 @@ +From: George Wright <george@mozilla.com> +Date: Mon, 14 Jan 2013 17:59:09 -0500 +Subject: Bug 848491 - Re-apply Bug 795549 - Move TileProc functions into their own file to ensure they only exist once in a library + + +diff --git a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h +index b9dbf1b..729ce4e 100644 +--- a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h ++++ b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h +@@ -37,34 +37,9 @@ static inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1, + } + } + +-// Clamp +- +-static inline SkFixed clamp_tileproc(SkFixed x) { +- return SkClampMax(x, 0xFFFF); +-} +- +-// Repeat +- +-static inline SkFixed repeat_tileproc(SkFixed x) { +- return x & 0xFFFF; +-} +- +-// Mirror +- +-// Visual Studio 2010 (MSC_VER=1600) optimizes bit-shift code incorrectly. +-// See http://code.google.com/p/skia/issues/detail?id=472 +-#if defined(_MSC_VER) && (_MSC_VER >= 1600) +-#pragma optimize("", off) +-#endif +- +-static inline SkFixed mirror_tileproc(SkFixed x) { +- int s = x << 15 >> 31; +- return (x ^ s) & 0xFFFF; +-} +- +-#if defined(_MSC_VER) && (_MSC_VER >= 1600) +-#pragma optimize("", on) +-#endif ++SkFixed clamp_tileproc(SkFixed x); ++SkFixed repeat_tileproc(SkFixed x); ++SkFixed mirror_tileproc(SkFixed x); + + /////////////////////////////////////////////////////////////////////////////// + +-- +1.7.11.7 + diff --git a/gfx/skia/patches/archive/0003-SkUserConfig-for-Mozilla.patch b/gfx/skia/patches/archive/0003-SkUserConfig-for-Mozilla.patch new file mode 100644 index 0000000000..dc52a8d3d0 --- /dev/null +++ b/gfx/skia/patches/archive/0003-SkUserConfig-for-Mozilla.patch @@ -0,0 +1,39 @@ +From ef53776c06cffc7607c3777702f93e04c0852981 Mon Sep 17 00:00:00 2001 +From: George Wright <gwright@mozilla.com> +Date: Fri, 18 May 2012 14:13:49 -0400 +Subject: [PATCH 03/10] Bug 755869 - [6] Re-apply SkUserConfig (no + original bug) r=mattwoodrow + +--- + gfx/skia/include/config/SkUserConfig.h | 10 ++++++++++ + 1 files changed, 10 insertions(+), 0 deletions(-) + +diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h +index 9fdbd0a..f98ba85 100644 +--- a/gfx/skia/include/config/SkUserConfig.h ++++ b/gfx/skia/include/config/SkUserConfig.h +@@ -156,6 +156,10 @@ + //#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: +@@ -177,4 +181,10 @@ + #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 +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0004-Bug-722011-Fix-trailing-commas-in-enums.patch b/gfx/skia/patches/archive/0004-Bug-722011-Fix-trailing-commas-in-enums.patch new file mode 100644 index 0000000000..179aeded5d --- /dev/null +++ b/gfx/skia/patches/archive/0004-Bug-722011-Fix-trailing-commas-in-enums.patch @@ -0,0 +1,280 @@ +From 81d61682a94d47be5b47fb7882ea7e7c7e6c3351 Mon Sep 17 00:00:00 2001 +From: George Wright <gwright@mozilla.com> +Date: Fri, 18 May 2012 14:15:28 -0400 +Subject: [PATCH 04/10] Bug 755869 - [7] Re-apply bug 722011 - Fix + trailing commas at end of enum lists r=mattwoodrow + +--- + gfx/skia/include/core/SkAdvancedTypefaceMetrics.h | 8 ++++---- + gfx/skia/include/core/SkBlitRow.h | 2 +- + gfx/skia/include/core/SkCanvas.h | 2 +- + gfx/skia/include/core/SkDevice.h | 2 +- + gfx/skia/include/core/SkDeviceProfile.h | 4 ++-- + gfx/skia/include/core/SkFlattenable.h | 2 +- + gfx/skia/include/core/SkFontHost.h | 4 ++-- + gfx/skia/include/core/SkMaskFilter.h | 2 +- + gfx/skia/include/core/SkPaint.h | 4 ++-- + gfx/skia/include/core/SkScalerContext.h | 9 +++++---- + gfx/skia/include/core/SkTypes.h | 2 +- + gfx/skia/include/effects/SkLayerDrawLooper.h | 2 +- + gfx/skia/src/core/SkBitmap.cpp | 2 +- + gfx/skia/src/core/SkGlyphCache.cpp | 2 +- + 14 files changed, 24 insertions(+), 23 deletions(-) + +diff --git a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h +index 09fc9a9..5ffdb45 100644 +--- a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h ++++ b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h +@@ -34,7 +34,7 @@ public: + 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 +@@ -56,7 +56,7 @@ public: + 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 +@@ -75,7 +75,7 @@ public: + 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 + }; + +@@ -84,7 +84,7 @@ public: + 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; +diff --git a/gfx/skia/include/core/SkBlitRow.h b/gfx/skia/include/core/SkBlitRow.h +index 973ab4c..febc405 100644 +--- a/gfx/skia/include/core/SkBlitRow.h ++++ b/gfx/skia/include/core/SkBlitRow.h +@@ -42,7 +42,7 @@ public: + + enum Flags32 { + kGlobalAlpha_Flag32 = 1 << 0, +- kSrcPixelAlpha_Flag32 = 1 << 1, ++ kSrcPixelAlpha_Flag32 = 1 << 1 + }; + + /** Function pointer that blends 32bit colors onto a 32bit destination. +diff --git a/gfx/skia/include/core/SkCanvas.h b/gfx/skia/include/core/SkCanvas.h +index 25cc94a..d942783 100644 +--- a/gfx/skia/include/core/SkCanvas.h ++++ b/gfx/skia/include/core/SkCanvas.h +@@ -148,7 +148,7 @@ public: + * low byte to high byte: R, G, B, A. + */ + kRGBA_Premul_Config8888, +- kRGBA_Unpremul_Config8888, ++ kRGBA_Unpremul_Config8888 + }; + + /** +diff --git a/gfx/skia/include/core/SkDevice.h b/gfx/skia/include/core/SkDevice.h +index 1e4e0a3..b4d44bf 100644 +--- a/gfx/skia/include/core/SkDevice.h ++++ b/gfx/skia/include/core/SkDevice.h +@@ -139,7 +139,7 @@ public: + protected: + enum Usage { + kGeneral_Usage, +- kSaveLayer_Usage, // <! internal use only ++ kSaveLayer_Usage // <! internal use only + }; + + struct TextFlags { +diff --git a/gfx/skia/include/core/SkDeviceProfile.h b/gfx/skia/include/core/SkDeviceProfile.h +index 46b9781..f6a0bca 100644 +--- a/gfx/skia/include/core/SkDeviceProfile.h ++++ b/gfx/skia/include/core/SkDeviceProfile.h +@@ -17,7 +17,7 @@ public: + kRGB_Horizontal_LCDConfig, + kBGR_Horizontal_LCDConfig, + kRGB_Vertical_LCDConfig, +- kBGR_Vertical_LCDConfig, ++ kBGR_Vertical_LCDConfig + }; + + enum FontHintLevel { +@@ -25,7 +25,7 @@ public: + kSlight_FontHintLevel, + kNormal_FontHintLevel, + kFull_FontHintLevel, +- kAuto_FontHintLevel, ++ kAuto_FontHintLevel + }; + + /** +diff --git a/gfx/skia/include/core/SkFlattenable.h b/gfx/skia/include/core/SkFlattenable.h +index 5714f9d..dc115fc 100644 +--- a/gfx/skia/include/core/SkFlattenable.h ++++ b/gfx/skia/include/core/SkFlattenable.h +@@ -272,7 +272,7 @@ public: + * 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; } +diff --git a/gfx/skia/include/core/SkFontHost.h b/gfx/skia/include/core/SkFontHost.h +index 732de5c..10f9bdf 100644 +--- a/gfx/skia/include/core/SkFontHost.h ++++ b/gfx/skia/include/core/SkFontHost.h +@@ -240,7 +240,7 @@ public: + */ + enum LCDOrientation { + kHorizontal_LCDOrientation = 0, //!< this is the default +- kVertical_LCDOrientation = 1, ++ kVertical_LCDOrientation = 1 + }; + + static void SetSubpixelOrientation(LCDOrientation orientation); +@@ -259,7 +259,7 @@ public: + enum LCDOrder { + kRGB_LCDOrder = 0, //!< this is the default + kBGR_LCDOrder = 1, +- kNONE_LCDOrder = 2, ++ kNONE_LCDOrder = 2 + }; + + static void SetSubpixelOrder(LCDOrder order); +diff --git a/gfx/skia/include/core/SkMaskFilter.h b/gfx/skia/include/core/SkMaskFilter.h +index 9a470a4..3422e27 100644 +--- a/gfx/skia/include/core/SkMaskFilter.h ++++ b/gfx/skia/include/core/SkMaskFilter.h +@@ -61,7 +61,7 @@ public: + 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 { +diff --git a/gfx/skia/include/core/SkPaint.h b/gfx/skia/include/core/SkPaint.h +index ff37d77..7c96e193 100644 +--- a/gfx/skia/include/core/SkPaint.h ++++ b/gfx/skia/include/core/SkPaint.h +@@ -76,7 +76,7 @@ public: + kNo_Hinting = 0, + kSlight_Hinting = 1, + kNormal_Hinting = 2, //!< this is the default +- kFull_Hinting = 3, ++ kFull_Hinting = 3 + }; + + Hinting getHinting() const { +@@ -289,7 +289,7 @@ public: + kStroke_Style, //!< stroke the geometry + kStrokeAndFill_Style, //!< fill and stroke the geometry + +- kStyleCount, ++ kStyleCount + }; + + /** Return the paint's style, used for controlling how primitives' +diff --git a/gfx/skia/include/core/SkScalerContext.h b/gfx/skia/include/core/SkScalerContext.h +index 2cb171b..3dbce27 100644 +--- a/gfx/skia/include/core/SkScalerContext.h ++++ b/gfx/skia/include/core/SkScalerContext.h +@@ -182,21 +182,22 @@ public: + kGenA8FromLCD_Flag = 0x0800, + + #ifdef SK_USE_COLOR_LUMINANCE +- kLuminance_Bits = 3, ++ kLuminance_Bits = 3 + #else + // luminance : 0 for black text, kLuminance_Max for white text + kLuminance_Shift = 13, // shift to land in the high 3-bits of Flags +- kLuminance_Bits = 3, // ensure Flags doesn't exceed 16bits ++ kLuminance_Bits = 3 // ensure Flags doesn't exceed 16bits + #endif + }; + + // computed values + enum { +- kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag, + #ifdef SK_USE_COLOR_LUMINANCE ++ kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag + #else ++ kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag, + kLuminance_Max = (1 << kLuminance_Bits) - 1, +- kLuminance_Mask = kLuminance_Max << kLuminance_Shift, ++ kLuminance_Mask = kLuminance_Max << kLuminance_Shift + #endif + }; + +diff --git a/gfx/skia/include/core/SkTypes.h b/gfx/skia/include/core/SkTypes.h +index 7963a7d..0c5c2d7 100644 +--- a/gfx/skia/include/core/SkTypes.h ++++ b/gfx/skia/include/core/SkTypes.h +@@ -438,7 +438,7 @@ public: + * current block is dynamically allocated, just return the old + * block. + */ +- kReuse_OnShrink, ++ kReuse_OnShrink + }; + + /** +diff --git a/gfx/skia/include/effects/SkLayerDrawLooper.h b/gfx/skia/include/effects/SkLayerDrawLooper.h +index 0bc4af2..6cb8ef6 100644 +--- a/gfx/skia/include/effects/SkLayerDrawLooper.h ++++ b/gfx/skia/include/effects/SkLayerDrawLooper.h +@@ -41,7 +41,7 @@ public: + * - Flags and Color are always computed using the LayerInfo's + * fFlagsMask and fColorMode. + */ +- kEntirePaint_Bits = -1, ++ kEntirePaint_Bits = -1 + + }; + typedef int32_t BitFlags; +diff --git a/gfx/skia/src/core/SkBitmap.cpp b/gfx/skia/src/core/SkBitmap.cpp +index 6b99145..aff52fd 100644 +--- a/gfx/skia/src/core/SkBitmap.cpp ++++ b/gfx/skia/src/core/SkBitmap.cpp +@@ -1376,7 +1376,7 @@ enum { + SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE, + SERIALIZE_PIXELTYPE_RAW_NO_CTABLE, + SERIALIZE_PIXELTYPE_REF_DATA, +- SERIALIZE_PIXELTYPE_REF_PTR, ++ SERIALIZE_PIXELTYPE_REF_PTR + }; + + /* +diff --git a/gfx/skia/src/core/SkGlyphCache.cpp b/gfx/skia/src/core/SkGlyphCache.cpp +index f3363cd..1fddc9d 100644 +--- a/gfx/skia/src/core/SkGlyphCache.cpp ++++ b/gfx/skia/src/core/SkGlyphCache.cpp +@@ -417,7 +417,7 @@ class SkGlyphCache_Globals { + public: + enum UseMutex { + kNo_UseMutex, // thread-local cache +- kYes_UseMutex, // shared cache ++ kYes_UseMutex // shared cache + }; + + SkGlyphCache_Globals(UseMutex um) { +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0004-Bug-777614-Re-apply-bug-719872-Fix-crash-on-Android-.patch b/gfx/skia/patches/archive/0004-Bug-777614-Re-apply-bug-719872-Fix-crash-on-Android-.patch new file mode 100644 index 0000000000..ad6e181274 --- /dev/null +++ b/gfx/skia/patches/archive/0004-Bug-777614-Re-apply-bug-719872-Fix-crash-on-Android-.patch @@ -0,0 +1,684 @@ +From 0d730a94e9f6676d5cde45f955fe025a4549817e Mon Sep 17 00:00:00 2001 +From: George Wright <gw@gwright.org.uk> +Date: Thu, 23 Aug 2012 16:45:38 -0400 +Subject: [PATCH 4/9] Bug 777614 - Re-apply bug 719872 - Fix crash on Android + by reverting to older FontHost r=nrc + +--- + gfx/skia/src/ports/SkFontHost_android_old.cpp | 664 ++++++++++++++++++++++++++ + 1 file changed, 664 insertions(+) + create mode 100644 gfx/skia/src/ports/SkFontHost_android_old.cpp + +diff --git a/gfx/skia/src/ports/SkFontHost_android_old.cpp b/gfx/skia/src/ports/SkFontHost_android_old.cpp +new file mode 100644 +index 0000000..b5c4f3c +--- /dev/null ++++ b/gfx/skia/src/ports/SkFontHost_android_old.cpp +@@ -0,0 +1,664 @@ ++ ++/* ++ * 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. ++ */ ++ ++ ++#include "SkFontHost.h" ++#include "SkDescriptor.h" ++#include "SkMMapStream.h" ++#include "SkPaint.h" ++#include "SkString.h" ++#include "SkStream.h" ++#include "SkThread.h" ++#include "SkTSearch.h" ++#include <stdio.h> ++ ++#define FONT_CACHE_MEMORY_BUDGET (768 * 1024) ++ ++#ifndef SK_FONT_FILE_PREFIX ++ #define SK_FONT_FILE_PREFIX "/fonts/" ++#endif ++ ++bool find_name_and_attributes(SkStream* stream, SkString* name, SkTypeface::Style* style, ++ bool* isFixedWidth); ++ ++static void GetFullPathForSysFonts(SkString* full, const char name[]) { ++ full->set(getenv("ANDROID_ROOT")); ++ full->append(SK_FONT_FILE_PREFIX); ++ full->append(name); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++struct FamilyRec; ++ ++/* This guy holds a mapping of a name -> family, used for looking up fonts. ++ Since it is stored in a stretchy array that doesn't preserve object ++ semantics, we don't use constructor/destructors, but just have explicit ++ helpers to manage our internal bookkeeping. ++*/ ++struct NameFamilyPair { ++ const char* fName; // we own this ++ FamilyRec* fFamily; // we don't own this, we just reference it ++ ++ void construct(const char name[], FamilyRec* family) { ++ fName = strdup(name); ++ fFamily = family; // we don't own this, so just record the referene ++ } ++ ++ void destruct() { ++ free((char*)fName); ++ // we don't own family, so just ignore our reference ++ } ++}; ++ ++// we use atomic_inc to grow this for each typeface we create ++static int32_t gUniqueFontID; ++ ++// this is the mutex that protects these globals ++static SkMutex gFamilyMutex; ++static FamilyRec* gFamilyHead; ++static SkTDArray<NameFamilyPair> gNameList; ++ ++struct FamilyRec { ++ FamilyRec* fNext; ++ SkTypeface* fFaces[4]; ++ ++ FamilyRec() ++ { ++ fNext = gFamilyHead; ++ memset(fFaces, 0, sizeof(fFaces)); ++ gFamilyHead = this; ++ } ++}; ++ ++static SkTypeface* find_best_face(const FamilyRec* family, ++ SkTypeface::Style style) { ++ SkTypeface* const* faces = family->fFaces; ++ ++ if (faces[style] != NULL) { // exact match ++ return faces[style]; ++ } ++ // look for a matching bold ++ style = (SkTypeface::Style)(style ^ SkTypeface::kItalic); ++ if (faces[style] != NULL) { ++ return faces[style]; ++ } ++ // look for the plain ++ if (faces[SkTypeface::kNormal] != NULL) { ++ return faces[SkTypeface::kNormal]; ++ } ++ // look for anything ++ for (int i = 0; i < 4; i++) { ++ if (faces[i] != NULL) { ++ return faces[i]; ++ } ++ } ++ // should never get here, since the faces list should not be empty ++ SkASSERT(!"faces list is empty"); ++ return NULL; ++} ++ ++static FamilyRec* find_family(const SkTypeface* member) { ++ FamilyRec* curr = gFamilyHead; ++ while (curr != NULL) { ++ for (int i = 0; i < 4; i++) { ++ if (curr->fFaces[i] == member) { ++ return curr; ++ } ++ } ++ curr = curr->fNext; ++ } ++ return NULL; ++} ++ ++/* Returns the matching typeface, or NULL. If a typeface is found, its refcnt ++ is not modified. ++ */ ++static SkTypeface* find_from_uniqueID(uint32_t uniqueID) { ++ FamilyRec* curr = gFamilyHead; ++ while (curr != NULL) { ++ for (int i = 0; i < 4; i++) { ++ SkTypeface* face = curr->fFaces[i]; ++ if (face != NULL && face->uniqueID() == uniqueID) { ++ return face; ++ } ++ } ++ curr = curr->fNext; ++ } ++ return NULL; ++} ++ ++/* Remove reference to this face from its family. If the resulting family ++ is empty (has no faces), return that family, otherwise return NULL ++*/ ++static FamilyRec* remove_from_family(const SkTypeface* face) { ++ FamilyRec* family = find_family(face); ++ SkASSERT(family->fFaces[face->style()] == face); ++ family->fFaces[face->style()] = NULL; ++ ++ for (int i = 0; i < 4; i++) { ++ if (family->fFaces[i] != NULL) { // family is non-empty ++ return NULL; ++ } ++ } ++ return family; // return the empty family ++} ++ ++// maybe we should make FamilyRec be doubly-linked ++static void detach_and_delete_family(FamilyRec* family) { ++ FamilyRec* curr = gFamilyHead; ++ FamilyRec* prev = NULL; ++ ++ while (curr != NULL) { ++ FamilyRec* next = curr->fNext; ++ if (curr == family) { ++ if (prev == NULL) { ++ gFamilyHead = next; ++ } else { ++ prev->fNext = next; ++ } ++ SkDELETE(family); ++ return; ++ } ++ prev = curr; ++ curr = next; ++ } ++ SkASSERT(!"Yikes, couldn't find family in our list to remove/delete"); ++} ++ ++static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) { ++ NameFamilyPair* list = gNameList.begin(); ++ int count = gNameList.count(); ++ ++ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); ++ ++ if (index >= 0) { ++ return find_best_face(list[index].fFamily, style); ++ } ++ return NULL; ++} ++ ++static SkTypeface* find_typeface(const SkTypeface* familyMember, ++ SkTypeface::Style style) { ++ const FamilyRec* family = find_family(familyMember); ++ return family ? find_best_face(family, style) : NULL; ++} ++ ++static void add_name(const char name[], FamilyRec* family) { ++ SkAutoAsciiToLC tolc(name); ++ name = tolc.lc(); ++ ++ NameFamilyPair* list = gNameList.begin(); ++ int count = gNameList.count(); ++ ++ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); ++ ++ if (index < 0) { ++ list = gNameList.insert(~index); ++ list->construct(name, family); ++ } ++} ++ ++static void remove_from_names(FamilyRec* emptyFamily) ++{ ++#ifdef SK_DEBUG ++ for (int i = 0; i < 4; i++) { ++ SkASSERT(emptyFamily->fFaces[i] == NULL); ++ } ++#endif ++ ++ SkTDArray<NameFamilyPair>& list = gNameList; ++ ++ // must go backwards when removing ++ for (int i = list.count() - 1; i >= 0; --i) { ++ NameFamilyPair* pair = &list[i]; ++ if (pair->fFamily == emptyFamily) { ++ pair->destruct(); ++ list.remove(i); ++ } ++ } ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++class FamilyTypeface : public SkTypeface { ++public: ++ FamilyTypeface(Style style, bool sysFont, SkTypeface* familyMember, ++ bool isFixedWidth) ++ : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedWidth) { ++ fIsSysFont = sysFont; ++ ++ SkAutoMutexAcquire ac(gFamilyMutex); ++ ++ FamilyRec* rec = NULL; ++ if (familyMember) { ++ rec = find_family(familyMember); ++ SkASSERT(rec); ++ } else { ++ rec = SkNEW(FamilyRec); ++ } ++ rec->fFaces[style] = this; ++ } ++ ++ virtual ~FamilyTypeface() { ++ SkAutoMutexAcquire ac(gFamilyMutex); ++ ++ // remove us from our family. If the family is now empty, we return ++ // that and then remove that family from the name list ++ FamilyRec* family = remove_from_family(this); ++ if (NULL != family) { ++ remove_from_names(family); ++ detach_and_delete_family(family); ++ } ++ } ++ ++ bool isSysFont() const { return fIsSysFont; } ++ ++ virtual SkStream* openStream() = 0; ++ virtual const char* getUniqueString() const = 0; ++ virtual const char* getFilePath() const = 0; ++ ++private: ++ bool fIsSysFont; ++ ++ typedef SkTypeface INHERITED; ++}; ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++class StreamTypeface : public FamilyTypeface { ++public: ++ StreamTypeface(Style style, bool sysFont, SkTypeface* familyMember, ++ SkStream* stream, bool isFixedWidth) ++ : INHERITED(style, sysFont, familyMember, isFixedWidth) { ++ SkASSERT(stream); ++ stream->ref(); ++ fStream = stream; ++ } ++ virtual ~StreamTypeface() { ++ fStream->unref(); ++ } ++ ++ // overrides ++ virtual SkStream* openStream() { ++ // we just ref our existing stream, since the caller will call unref() ++ // when they are through ++ fStream->ref(); ++ // must rewind each time, since the caller assumes a "new" stream ++ fStream->rewind(); ++ return fStream; ++ } ++ virtual const char* getUniqueString() const { return NULL; } ++ virtual const char* getFilePath() const { return NULL; } ++ ++private: ++ SkStream* fStream; ++ ++ typedef FamilyTypeface INHERITED; ++}; ++ ++class FileTypeface : public FamilyTypeface { ++public: ++ FileTypeface(Style style, bool sysFont, SkTypeface* familyMember, ++ const char path[], bool isFixedWidth) ++ : INHERITED(style, sysFont, familyMember, isFixedWidth) { ++ SkString fullpath; ++ ++ if (sysFont) { ++ GetFullPathForSysFonts(&fullpath, path); ++ path = fullpath.c_str(); ++ } ++ fPath.set(path); ++ } ++ ++ // overrides ++ virtual SkStream* openStream() { ++ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str())); ++ ++ // check for failure ++ if (stream->getLength() <= 0) { ++ SkDELETE(stream); ++ // maybe MMAP isn't supported. try FILE ++ stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str())); ++ if (stream->getLength() <= 0) { ++ SkDELETE(stream); ++ stream = NULL; ++ } ++ } ++ return stream; ++ } ++ virtual const char* getUniqueString() const { ++ const char* str = strrchr(fPath.c_str(), '/'); ++ if (str) { ++ str += 1; // skip the '/' ++ } ++ return str; ++ } ++ virtual const char* getFilePath() const { ++ return fPath.c_str(); ++ } ++ ++private: ++ SkString fPath; ++ ++ typedef FamilyTypeface INHERITED; ++}; ++ ++/////////////////////////////////////////////////////////////////////////////// ++/////////////////////////////////////////////////////////////////////////////// ++ ++static bool get_name_and_style(const char path[], SkString* name, ++ SkTypeface::Style* style, ++ bool* isFixedWidth, bool isExpected) { ++ SkString fullpath; ++ GetFullPathForSysFonts(&fullpath, path); ++ ++ SkMMAPStream stream(fullpath.c_str()); ++ if (stream.getLength() > 0) { ++ find_name_and_attributes(&stream, name, style, isFixedWidth); ++ return true; ++ } ++ else { ++ SkFILEStream stream(fullpath.c_str()); ++ if (stream.getLength() > 0) { ++ find_name_and_attributes(&stream, name, style, isFixedWidth); ++ return true; ++ } ++ } ++ ++ if (isExpected) { ++ SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str()); ++ } ++ return false; ++} ++ ++// used to record our notion of the pre-existing fonts ++struct FontInitRec { ++ const char* fFileName; ++ const char* const* fNames; // null-terminated list ++}; ++ ++static const char* gSansNames[] = { ++ "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL ++}; ++ ++static const char* gSerifNames[] = { ++ "serif", "times", "times new roman", "palatino", "georgia", "baskerville", ++ "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL ++}; ++ ++static const char* gMonoNames[] = { ++ "monospace", "courier", "courier new", "monaco", NULL ++}; ++ ++// deliberately empty, but we use the address to identify fallback fonts ++static const char* gFBNames[] = { NULL }; ++ ++/* Fonts must be grouped by family, with the first font in a family having the ++ list of names (even if that list is empty), and the following members having ++ null for the list. The names list must be NULL-terminated ++*/ ++static const FontInitRec gSystemFonts[] = { ++ { "DroidSans.ttf", gSansNames }, ++ { "DroidSans-Bold.ttf", NULL }, ++ { "DroidSerif-Regular.ttf", gSerifNames }, ++ { "DroidSerif-Bold.ttf", NULL }, ++ { "DroidSerif-Italic.ttf", NULL }, ++ { "DroidSerif-BoldItalic.ttf", NULL }, ++ { "DroidSansMono.ttf", gMonoNames }, ++ /* These are optional, and can be ignored if not found in the file system. ++ These are appended to gFallbackFonts[] as they are seen, so we list ++ them in the order we want them to be accessed by NextLogicalFont(). ++ */ ++ { "DroidSansArabic.ttf", gFBNames }, ++ { "DroidSansHebrew.ttf", gFBNames }, ++ { "DroidSansThai.ttf", gFBNames }, ++ { "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font ++ { "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font ++ { "DroidSansJapanese.ttf", gFBNames }, ++ { "DroidSansFallback.ttf", gFBNames } ++}; ++ ++#define DEFAULT_NAMES gSansNames ++ ++// these globals are assigned (once) by load_system_fonts() ++static FamilyRec* gDefaultFamily; ++static SkTypeface* gDefaultNormal; ++ ++/* This is sized conservatively, assuming that it will never be a size issue. ++ It will be initialized in load_system_fonts(), and will be filled with the ++ fontIDs that can be used for fallback consideration, in sorted order (sorted ++ meaning element[0] should be used first, then element[1], etc. When we hit ++ a fontID==0 in the array, the list is done, hence our allocation size is ++ +1 the total number of possible system fonts. Also see NextLogicalFont(). ++ */ ++static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1]; ++ ++/* Called once (ensured by the sentinel check at the beginning of our body). ++ Initializes all the globals, and register the system fonts. ++ */ ++static void load_system_fonts() { ++ // check if we've already be called ++ if (NULL != gDefaultNormal) { ++ return; ++ } ++ ++ const FontInitRec* rec = gSystemFonts; ++ SkTypeface* firstInFamily = NULL; ++ int fallbackCount = 0; ++ ++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { ++ // if we're the first in a new family, clear firstInFamily ++ if (rec[i].fNames != NULL) { ++ firstInFamily = NULL; ++ } ++ ++ bool isFixedWidth; ++ SkString name; ++ SkTypeface::Style style; ++ ++ // we expect all the fonts, except the "fallback" fonts ++ bool isExpected = (rec[i].fNames != gFBNames); ++ if (!get_name_and_style(rec[i].fFileName, &name, &style, ++ &isFixedWidth, isExpected)) { ++ continue; ++ } ++ ++ SkTypeface* tf = SkNEW_ARGS(FileTypeface, ++ (style, ++ true, // system-font (cannot delete) ++ firstInFamily, // what family to join ++ rec[i].fFileName, ++ isFixedWidth) // filename ++ ); ++ ++ if (rec[i].fNames != NULL) { ++ // see if this is one of our fallback fonts ++ if (rec[i].fNames == gFBNames) { ++ // SkDebugf("---- adding %s as fallback[%d] fontID %d\n", ++ // rec[i].fFileName, fallbackCount, tf->uniqueID()); ++ gFallbackFonts[fallbackCount++] = tf->uniqueID(); ++ } ++ ++ firstInFamily = tf; ++ FamilyRec* family = find_family(tf); ++ const char* const* names = rec[i].fNames; ++ ++ // record the default family if this is it ++ if (names == DEFAULT_NAMES) { ++ gDefaultFamily = family; ++ } ++ // add the names to map to this family ++ while (*names) { ++ add_name(*names, family); ++ names += 1; ++ } ++ } ++ } ++ ++ // do this after all fonts are loaded. This is our default font, and it ++ // acts as a sentinel so we only execute load_system_fonts() once ++ gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal); ++ // now terminate our fallback list with the sentinel value ++ gFallbackFonts[fallbackCount] = 0; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { ++ const char* name = ((FamilyTypeface*)face)->getUniqueString(); ++ ++ stream->write8((uint8_t)face->style()); ++ ++ if (NULL == name || 0 == *name) { ++ stream->writePackedUInt(0); ++// SkDebugf("--- fonthost serialize null\n"); ++ } else { ++ uint32_t len = strlen(name); ++ stream->writePackedUInt(len); ++ stream->write(name, len); ++// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style()); ++ } ++} ++ ++SkTypeface* SkFontHost::Deserialize(SkStream* stream) { ++ load_system_fonts(); ++ ++ int style = stream->readU8(); ++ ++ int len = stream->readPackedUInt(); ++ if (len > 0) { ++ SkString str; ++ str.resize(len); ++ stream->read(str.writable_str(), len); ++ ++ const FontInitRec* rec = gSystemFonts; ++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { ++ if (strcmp(rec[i].fFileName, str.c_str()) == 0) { ++ // backup until we hit the fNames ++ for (int j = i; j >= 0; --j) { ++ if (rec[j].fNames != NULL) { ++ return SkFontHost::CreateTypeface(NULL, ++ rec[j].fNames[0], (SkTypeface::Style)style); ++ } ++ } ++ } ++ } ++ } ++ return NULL; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, ++ const char familyName[], ++ SkTypeface::Style style) { ++ load_system_fonts(); ++ ++ SkAutoMutexAcquire ac(gFamilyMutex); ++ ++ // clip to legal style bits ++ style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic); ++ ++ SkTypeface* tf = NULL; ++ ++ if (NULL != familyFace) { ++ tf = find_typeface(familyFace, style); ++ } else if (NULL != familyName) { ++// SkDebugf("======= familyName <%s>\n", familyName); ++ tf = find_typeface(familyName, style); ++ } ++ ++ if (NULL == tf) { ++ tf = find_best_face(gDefaultFamily, style); ++ } ++ ++ // we ref(), since the symantic is to return a new instance ++ tf->ref(); ++ return tf; ++} ++ ++SkStream* SkFontHost::OpenStream(uint32_t fontID) { ++ SkAutoMutexAcquire ac(gFamilyMutex); ++ ++ FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID); ++ SkStream* stream = tf ? tf->openStream() : NULL; ++ ++ if (stream && stream->getLength() == 0) { ++ stream->unref(); ++ stream = NULL; ++ } ++ return stream; ++} ++ ++size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length, ++ int32_t* index) { ++ SkAutoMutexAcquire ac(gFamilyMutex); ++ ++ FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID); ++ const char* src = tf ? tf->getFilePath() : NULL; ++ ++ if (src) { ++ size_t size = strlen(src); ++ if (path) { ++ memcpy(path, src, SkMin32(size, length)); ++ } ++ if (index) { ++ *index = 0; // we don't have collections (yet) ++ } ++ return size; ++ } else { ++ return 0; ++ } ++} ++ ++SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) { ++ load_system_fonts(); ++ ++ /* First see if fontID is already one of our fallbacks. If so, return ++ its successor. If fontID is not in our list, then return the first one ++ in our list. Note: list is zero-terminated, and returning zero means ++ we have no more fonts to use for fallbacks. ++ */ ++ const uint32_t* list = gFallbackFonts; ++ for (int i = 0; list[i] != 0; i++) { ++ if (list[i] == currFontID) { ++ return list[i+1]; ++ } ++ } ++ return list[0]; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { ++ if (NULL == stream || stream->getLength() <= 0) { ++ return NULL; ++ } ++ ++ bool isFixedWidth; ++ SkString name; ++ SkTypeface::Style style; ++ find_name_and_attributes(stream, &name, &style, &isFixedWidth); ++ ++ if (!name.isEmpty()) { ++ return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream, isFixedWidth)); ++ } else { ++ return NULL; ++ } ++} ++ ++SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { ++ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path)); ++ SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream); ++ // since we created the stream, we let go of our ref() here ++ stream->unref(); ++ return face; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// +-- +1.7.11.4 + diff --git a/gfx/skia/patches/archive/0005-Bug-731384-Fix-clang-SK_OVERRIDE.patch b/gfx/skia/patches/archive/0005-Bug-731384-Fix-clang-SK_OVERRIDE.patch new file mode 100644 index 0000000000..e8b5df635b --- /dev/null +++ b/gfx/skia/patches/archive/0005-Bug-731384-Fix-clang-SK_OVERRIDE.patch @@ -0,0 +1,36 @@ +From 80350275c72921ed5ac405c029ae33727467d7c5 Mon Sep 17 00:00:00 2001 +From: George Wright <gwright@mozilla.com> +Date: Fri, 18 May 2012 14:15:50 -0400 +Subject: [PATCH 05/10] Bug 755869 - [8] Re-apply bug 731384 - Fix compile + errors on older versions of clang r=mattwoodrow + +--- + gfx/skia/include/core/SkPostConfig.h | 9 +++++++++ + 1 files changed, 9 insertions(+), 0 deletions(-) + +diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h +index 8316f7a..041fe2a 100644 +--- a/gfx/skia/include/core/SkPostConfig.h ++++ b/gfx/skia/include/core/SkPostConfig.h +@@ -288,9 +288,18 @@ + #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 +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch b/gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch new file mode 100644 index 0000000000..cd2f67131c --- /dev/null +++ b/gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch @@ -0,0 +1,449 @@ +From: George Wright <george@mozilla.com> +Date: Wed, 1 Aug 2012 16:43:15 -0400 +Subject: Bug 736276 - Add a new SkFontHost that takes a cairo_scaled_font_t r=karl + + +diff --git a/gfx/skia/include/ports/SkTypeface_cairo.h b/gfx/skia/include/ports/SkTypeface_cairo.h +new file mode 100644 +index 0000000..7e44f04 +--- /dev/null ++++ b/gfx/skia/include/ports/SkTypeface_cairo.h +@@ -0,0 +1,11 @@ ++#ifndef SkTypeface_cairo_DEFINED ++#define SkTypeface_cairo_DEFINED ++ ++#include <cairo.h> ++ ++#include "SkTypeface.h" ++ ++SK_API extern SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth); ++ ++#endif ++ +diff --git a/gfx/skia/moz.build b/gfx/skia/moz.build +index 9ceba59..66efd52 100644 +--- a/gfx/skia/moz.build ++++ b/gfx/skia/moz.build +@@ -171,10 +171,12 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': + 'SkTime_win.cpp', + ] + elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2': ++ EXPORTS.skia += [ ++ 'include/ports/SkTypeface_cairo.h', ++ ] + CPP_SOURCES += [ +- 'SkFontHost_FreeType.cpp', ++ 'SkFontHost_cairo.cpp', + 'SkFontHost_FreeType_common.cpp', +- 'SkFontHost_linux.cpp', + 'SkThread_pthread.cpp', + 'SkThreadUtils_pthread.cpp', + 'SkThreadUtils_pthread_linux.cpp', +@@ -183,14 +185,15 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2': + ] + elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt': + CPP_SOURCES += [ +- 'SkFontHost_FreeType.cpp', ++ 'SkFontHost_cairo.cpp', + 'SkFontHost_FreeType_common.cpp', + 'SkOSFile.cpp', + ] + if CONFIG['OS_TARGET'] == 'Linux': ++ EXPORTS.skia += [ ++ 'include/ports/SkTypeface_cairo.h', ++ ] + CPP_SOURCES += [ +- 'SkFontHost_linux.cpp', +- 'SkFontHost_tables.cpp', + 'SkThread_pthread.cpp', + 'SkThreadUtils_pthread.cpp', + 'SkThreadUtils_pthread_linux.cpp', +@@ -204,11 +207,13 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': + # Separate 'if' from above, since the else below applies to all != 'android' + # toolkits. + if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': ++ EXPORTS.skia += [ ++ 'include/ports/SkTypeface_cairo.h', ++ ] + CPP_SOURCES += [ + 'ashmem.cpp', + 'SkDebug_android.cpp', +- 'SkFontHost_android_old.cpp', +- 'SkFontHost_FreeType.cpp', ++ 'SkFontHost_cairo.cpp', + 'SkFontHost_FreeType_common.cpp', + 'SkImageRef_ashmem.cpp', + 'SkTime_Unix.cpp', +diff --git a/gfx/skia/src/ports/SkFontHost_cairo.cpp b/gfx/skia/src/ports/SkFontHost_cairo.cpp +new file mode 100644 +index 0000000..bb5b778 +--- /dev/null ++++ b/gfx/skia/src/ports/SkFontHost_cairo.cpp +@@ -0,0 +1,364 @@ ++ ++/* ++ * Copyright 2012 Mozilla Foundation ++ * ++ * Use of this source code is governed by a BSD-style license that can be ++ * found in the LICENSE file. ++ */ ++ ++#include "cairo.h" ++#include "cairo-ft.h" ++ ++#include "SkFontHost_FreeType_common.h" ++ ++#include "SkAdvancedTypefaceMetrics.h" ++#include "SkFontHost.h" ++#include "SkPath.h" ++#include "SkScalerContext.h" ++#include "SkTypefaceCache.h" ++ ++#include <ft2build.h> ++#include FT_FREETYPE_H ++ ++static cairo_user_data_key_t kSkTypefaceKey; ++ ++class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base { ++public: ++ SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc); ++ virtual ~SkScalerContext_CairoFT(); ++ ++protected: ++ virtual unsigned generateGlyphCount() SK_OVERRIDE; ++ virtual uint16_t generateCharToGlyph(SkUnichar uniChar) SK_OVERRIDE; ++ virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE; ++ virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE; ++ virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE; ++ virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE; ++ virtual void generateFontMetrics(SkPaint::FontMetrics* mx, ++ SkPaint::FontMetrics* my) SK_OVERRIDE; ++ virtual SkUnichar generateGlyphToChar(uint16_t glyph) SK_OVERRIDE; ++private: ++ cairo_scaled_font_t* fScaledFont; ++ uint32_t fLoadGlyphFlags; ++}; ++ ++class CairoLockedFTFace { ++public: ++ CairoLockedFTFace(cairo_scaled_font_t* scaledFont) ++ : fScaledFont(scaledFont) ++ , fFace(cairo_ft_scaled_font_lock_face(scaledFont)) ++ {} ++ ++ ~CairoLockedFTFace() ++ { ++ cairo_ft_scaled_font_unlock_face(fScaledFont); ++ } ++ ++ FT_Face getFace() ++ { ++ return fFace; ++ } ++ ++private: ++ cairo_scaled_font_t* fScaledFont; ++ FT_Face fFace; ++}; ++ ++class SkCairoFTTypeface : public SkTypeface { ++public: ++ static SkTypeface* CreateTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth) { ++ SkASSERT(fontFace != NULL); ++ SkASSERT(cairo_font_face_get_type(fontFace) == CAIRO_FONT_TYPE_FT); ++ ++ SkFontID newId = SkTypefaceCache::NewFontID(); ++ ++ return SkNEW_ARGS(SkCairoFTTypeface, (fontFace, style, newId, isFixedWidth)); ++ } ++ ++ cairo_font_face_t* getFontFace() { ++ return fFontFace; ++ } ++ ++ virtual SkStream* onOpenStream(int*) const SK_OVERRIDE { return NULL; } ++ ++ virtual SkAdvancedTypefaceMetrics* ++ onGetAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::PerGlyphInfo, ++ const uint32_t*, uint32_t) const SK_OVERRIDE ++ { ++ SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onGetAdvancedTypefaceMetrics unimplemented\n")); ++ return NULL; ++ } ++ ++ virtual SkScalerContext* onCreateScalerContext(const SkDescriptor* desc) const SK_OVERRIDE ++ { ++ return SkNEW_ARGS(SkScalerContext_CairoFT, (const_cast<SkCairoFTTypeface*>(this), desc)); ++ } ++ ++ virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE ++ { ++ SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onFilterRec unimplemented\n")); ++ } ++ ++ virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE ++ { ++ SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onGetFontDescriptor unimplemented\n")); ++ } ++ ++ ++private: ++ ++ SkCairoFTTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, SkFontID id, bool isFixedWidth) ++ : SkTypeface(style, id, isFixedWidth) ++ , fFontFace(fontFace) ++ { ++ cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, this, NULL); ++ cairo_font_face_reference(fFontFace); ++ } ++ ++ ~SkCairoFTTypeface() ++ { ++ cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, NULL, NULL); ++ cairo_font_face_destroy(fFontFace); ++ } ++ ++ cairo_font_face_t* fFontFace; ++}; ++ ++SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth) ++{ ++ SkTypeface* typeface = reinterpret_cast<SkTypeface*>(cairo_font_face_get_user_data(fontFace, &kSkTypefaceKey)); ++ ++ if (typeface) { ++ typeface->ref(); ++ } else { ++ typeface = SkCairoFTTypeface::CreateTypeface(fontFace, style, isFixedWidth); ++ SkTypefaceCache::Add(typeface, style); ++ } ++ ++ return typeface; ++} ++ ++SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, ++ const char famillyName[], ++ SkTypeface::Style style) ++{ ++ SkDEBUGFAIL("SkFontHost::FindTypeface unimplemented"); ++ return NULL; ++} ++ ++SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*) ++{ ++ SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented"); ++ return NULL; ++} ++ ++SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) ++{ ++ SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented"); ++ return NULL; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++static bool isLCD(const SkScalerContext::Rec& rec) { ++ switch (rec.fMaskFormat) { ++ case SkMask::kLCD16_Format: ++ case SkMask::kLCD32_Format: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++SkScalerContext_CairoFT::SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc) ++ : SkScalerContext_FreeType_Base(typeface, desc) ++{ ++ SkMatrix matrix; ++ fRec.getSingleMatrix(&matrix); ++ ++ cairo_font_face_t* fontFace = static_cast<SkCairoFTTypeface*>(typeface)->getFontFace(); ++ ++ cairo_matrix_t fontMatrix, ctMatrix; ++ cairo_matrix_init(&fontMatrix, matrix.getScaleX(), matrix.getSkewY(), matrix.getSkewX(), matrix.getScaleY(), 0.0, 0.0); ++ cairo_matrix_init_scale(&ctMatrix, 1.0, 1.0); ++ ++ // We need to ensure that the font options match for hinting, as generateMetrics() ++ // uses the fScaledFont which uses these font options ++ cairo_font_options_t *fontOptions = cairo_font_options_create(); ++ ++ FT_Int32 loadFlags = FT_LOAD_DEFAULT; ++ ++ if (SkMask::kBW_Format == fRec.fMaskFormat) { ++ // See http://code.google.com/p/chromium/issues/detail?id=43252#c24 ++ loadFlags = FT_LOAD_TARGET_MONO; ++ if (fRec.getHinting() == SkPaint::kNo_Hinting) { ++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE); ++ loadFlags = FT_LOAD_NO_HINTING; ++ } ++ } else { ++ switch (fRec.getHinting()) { ++ case SkPaint::kNo_Hinting: ++ loadFlags = FT_LOAD_NO_HINTING; ++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE); ++ break; ++ case SkPaint::kSlight_Hinting: ++ loadFlags = FT_LOAD_TARGET_LIGHT; // This implies FORCE_AUTOHINT ++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_SLIGHT); ++ break; ++ case SkPaint::kNormal_Hinting: ++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_MEDIUM); ++ if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) { ++ loadFlags = FT_LOAD_FORCE_AUTOHINT; ++ } ++ break; ++ case SkPaint::kFull_Hinting: ++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL); ++ if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) { ++ loadFlags = FT_LOAD_FORCE_AUTOHINT; ++ } ++ if (isLCD(fRec)) { ++ if (SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag)) { ++ loadFlags = FT_LOAD_TARGET_LCD_V; ++ } else { ++ loadFlags = FT_LOAD_TARGET_LCD; ++ } ++ } ++ break; ++ default: ++ SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting()); ++ break; ++ } ++ } ++ ++ fScaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctMatrix, fontOptions); ++ ++ if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) { ++ loadFlags |= FT_LOAD_NO_BITMAP; ++ } ++ ++ // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct ++ // advances, as fontconfig and cairo do. ++ // See http://code.google.com/p/skia/issues/detail?id=222. ++ loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; ++ ++ fLoadGlyphFlags = loadFlags; ++} ++ ++SkScalerContext_CairoFT::~SkScalerContext_CairoFT() ++{ ++ cairo_scaled_font_destroy(fScaledFont); ++} ++ ++unsigned SkScalerContext_CairoFT::generateGlyphCount() ++{ ++ CairoLockedFTFace faceLock(fScaledFont); ++ return faceLock.getFace()->num_glyphs; ++} ++ ++uint16_t SkScalerContext_CairoFT::generateCharToGlyph(SkUnichar uniChar) ++{ ++ CairoLockedFTFace faceLock(fScaledFont); ++ return SkToU16(FT_Get_Char_Index(faceLock.getFace(), uniChar)); ++} ++ ++void SkScalerContext_CairoFT::generateAdvance(SkGlyph* glyph) ++{ ++ generateMetrics(glyph); ++} ++ ++void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph) ++{ ++ SkASSERT(fScaledFont != NULL); ++ cairo_text_extents_t extents; ++ cairo_glyph_t cairoGlyph = { glyph->getGlyphID(fBaseGlyphCount), 0.0, 0.0 }; ++ cairo_scaled_font_glyph_extents(fScaledFont, &cairoGlyph, 1, &extents); ++ ++ glyph->fAdvanceX = SkDoubleToFixed(extents.x_advance); ++ glyph->fAdvanceY = SkDoubleToFixed(extents.y_advance); ++ glyph->fWidth = SkToU16(SkScalarCeil(extents.width)); ++ glyph->fHeight = SkToU16(SkScalarCeil(extents.height)); ++ glyph->fLeft = SkToS16(SkScalarCeil(extents.x_bearing)); ++ glyph->fTop = SkToS16(SkScalarCeil(extents.y_bearing)); ++ glyph->fLsbDelta = 0; ++ glyph->fRsbDelta = 0; ++} ++ ++void SkScalerContext_CairoFT::generateImage(const SkGlyph& glyph) ++{ ++ SkASSERT(fScaledFont != NULL); ++ CairoLockedFTFace faceLock(fScaledFont); ++ FT_Face face = faceLock.getFace(); ++ ++ FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFlags); ++ ++ if (err != 0) { ++ memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); ++ return; ++ } ++ ++ generateGlyphImage(face, glyph); ++} ++ ++void SkScalerContext_CairoFT::generatePath(const SkGlyph& glyph, SkPath* path) ++{ ++ SkASSERT(fScaledFont != NULL); ++ CairoLockedFTFace faceLock(fScaledFont); ++ FT_Face face = faceLock.getFace(); ++ ++ SkASSERT(&glyph && path); ++ ++ uint32_t flags = fLoadGlyphFlags; ++ flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline ++ flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline) ++ ++ FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), flags); ++ ++ if (err != 0) { ++ path->reset(); ++ return; ++ } ++ ++ generateGlyphPath(face, path); ++} ++ ++void SkScalerContext_CairoFT::generateFontMetrics(SkPaint::FontMetrics* mx, ++ SkPaint::FontMetrics* my) ++{ ++ SkDEBUGCODE(SkDebugf("SkScalerContext_CairoFT::generateFontMetrics unimplemented\n")); ++} ++ ++SkUnichar SkScalerContext_CairoFT::generateGlyphToChar(uint16_t glyph) ++{ ++ SkASSERT(fScaledFont != NULL); ++ CairoLockedFTFace faceLock(fScaledFont); ++ FT_Face face = faceLock.getFace(); ++ ++ FT_UInt glyphIndex; ++ SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex); ++ while (glyphIndex != 0) { ++ if (glyphIndex == glyph) { ++ return charCode; ++ } ++ charCode = FT_Get_Next_Char(face, charCode, &glyphIndex); ++ } ++ ++ return 0; ++} ++ ++#ifdef SK_BUILD_FOR_ANDROID ++SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID, ++ SkFontID origFontID) { ++ return NULL; ++} ++#endif ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++#include "SkFontMgr.h" ++ ++SkFontMgr* SkFontMgr::Factory() { ++ // todo ++ return NULL; ++} ++ +-- +1.7.11.7 + diff --git a/gfx/skia/patches/archive/0005-Bug-777614-Re-apply-bug-687188-Expand-the-gradient-c.patch b/gfx/skia/patches/archive/0005-Bug-777614-Re-apply-bug-687188-Expand-the-gradient-c.patch new file mode 100644 index 0000000000..cfcb40b9d7 --- /dev/null +++ b/gfx/skia/patches/archive/0005-Bug-777614-Re-apply-bug-687188-Expand-the-gradient-c.patch @@ -0,0 +1,198 @@ +From 1ab13a923399aa638388231baca784ba89f2c82b Mon Sep 17 00:00:00 2001 +From: George Wright <gw@gwright.org.uk> +Date: Wed, 12 Sep 2012 12:30:29 -0400 +Subject: [PATCH 5/9] Bug 777614 - Re-apply bug 687188 - Expand the gradient + cache by 2 to store 0/1 colour stop values for + clamping. r=nrc + +--- + .../src/effects/gradients/SkGradientShader.cpp | 22 +++++++++++---- + .../src/effects/gradients/SkGradientShaderPriv.h | 5 +++- + .../src/effects/gradients/SkLinearGradient.cpp | 32 ++++++++++++++++------ + .../gradients/SkTwoPointConicalGradient.cpp | 11 ++++++-- + .../effects/gradients/SkTwoPointRadialGradient.cpp | 11 ++++++-- + 5 files changed, 61 insertions(+), 20 deletions(-) + +diff --git a/gfx/skia/src/effects/gradients/SkGradientShader.cpp b/gfx/skia/src/effects/gradients/SkGradientShader.cpp +index f0dac4d..79e7202 100644 +--- a/gfx/skia/src/effects/gradients/SkGradientShader.cpp ++++ b/gfx/skia/src/effects/gradients/SkGradientShader.cpp +@@ -426,15 +426,15 @@ static void complete_32bit_cache(SkPMColor* cache, int stride) { + + const SkPMColor* SkGradientShaderBase::getCache32() const { + if (fCache32 == NULL) { +- // double the count for dither entries +- const int entryCount = kCache32Count * 2; ++ // double the count for dither entries, and have an extra two entries for clamp values ++ const int entryCount = kCache32Count * 2 + 2; + const size_t allocSize = sizeof(SkPMColor) * entryCount; + + if (NULL == fCache32PixelRef) { + fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef, + (NULL, allocSize, NULL)); + } +- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr(); ++ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1; + if (fColorCount == 2) { + Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1], + kGradient32Length, fCacheAlpha); +@@ -458,7 +458,7 @@ const SkPMColor* SkGradientShaderBase::getCache32() const { + SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef, + (NULL, allocSize, NULL)); + SkPMColor* linear = fCache32; // just computed linear data +- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data ++ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data + SkUnitMapper* map = fMapper; + for (int i = 0; i < kGradient32Length; i++) { + int index = map->mapUnit16((i << 8) | i) >> 8; +@@ -467,10 +467,22 @@ const SkPMColor* SkGradientShaderBase::getCache32() const { + } + fCache32PixelRef->unref(); + fCache32PixelRef = newPR; +- fCache32 = (SkPMColor*)newPR->getAddr(); ++ fCache32 = (SkPMColor*)newPR->getAddr() + 1; + } + complete_32bit_cache(fCache32, kCache32Count); + } ++ ++ // Write the clamp colours into the first and last entries of fCache32 ++ fCache32[kCache32ClampLower] = SkPackARGB32(fCacheAlpha, ++ SkColorGetR(fOrigColors[0]), ++ SkColorGetG(fOrigColors[0]), ++ SkColorGetB(fOrigColors[0])); ++ ++ fCache32[kCache32ClampUpper] = SkPackARGB32(fCacheAlpha, ++ SkColorGetR(fOrigColors[fColorCount - 1]), ++ SkColorGetG(fOrigColors[fColorCount - 1]), ++ SkColorGetB(fOrigColors[fColorCount - 1])); ++ + return fCache32; + } + +diff --git a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h +index 0e7c2fc..7427935 100644 +--- a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h ++++ b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h +@@ -133,7 +133,10 @@ public: + kDitherStride32 = 0, + #endif + kDitherStride16 = kCache16Count, +- kLerpRemainderMask32 = (1 << (16 - kCache32Bits)) - 1 ++ kLerpRemainderMask32 = (1 << (16 - kCache32Bits)) - 1, ++ ++ kCache32ClampLower = -1, ++ kCache32ClampUpper = kCache32Count * 2 + }; + + +diff --git a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp +index bcebc26..d400b4d 100644 +--- a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp ++++ b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp +@@ -126,6 +126,17 @@ void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx, + SkPMColor* SK_RESTRICT dstC, + const SkPMColor* SK_RESTRICT cache, + int toggle, int count) { ++ if (proc == clamp_tileproc) { ++ // No need to lerp or dither for clamp values ++ if (fx < 0) { ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count); ++ return; ++ } else if (fx > 0xffff) { ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count); ++ return; ++ } ++ } ++ + // We're a vertical gradient, so no change in a span. + // If colors change sharply across the gradient, dithering is + // insufficient (it subsamples the color space) and we need to lerp. +@@ -144,6 +155,17 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx, + SkPMColor* SK_RESTRICT dstC, + const SkPMColor* SK_RESTRICT cache, + int toggle, int count) { ++ if (proc == clamp_tileproc) { ++ // No need to lerp or dither for clamp values ++ if (fx < 0) { ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count); ++ return; ++ } else if (fx > 0xffff) { ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count); ++ return; ++ } ++ } ++ + // We're a vertical gradient, so no change in a span. + // If colors change sharply across the gradient, dithering is + // insufficient (it subsamples the color space) and we need to lerp. +@@ -169,10 +191,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, + range.init(fx, dx, count, 0, SkGradientShaderBase::kGradient32Length); + + if ((count = range.fCount0) > 0) { +- sk_memset32_dither(dstC, +- cache[toggle + range.fV0], +- cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + range.fV0], +- count); ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count); + dstC += count; + } + if ((count = range.fCount1) > 0) { +@@ -191,10 +210,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, + } + } + if ((count = range.fCount2) > 0) { +- sk_memset32_dither(dstC, +- cache[toggle + range.fV1], +- cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + range.fV1], +- count); ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count); + } + } + +diff --git a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp +index 3466d2c..764a444 100644 +--- a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp ++++ b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp +@@ -123,9 +123,14 @@ static void twopoint_clamp(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC, + if (TwoPtRadial::DontDrawT(t)) { + *dstC++ = 0; + } else { +- SkFixed index = SkClampMax(t, 0xFFFF); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift]; ++ if (t < 0) { ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower]; ++ } else if (t > 0xFFFF) { ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper]; ++ } else { ++ SkASSERT(t <= 0xFFFF); ++ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift]; ++ } + } + } + } +diff --git a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp +index 9362ded..22b028e 100644 +--- a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp ++++ b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp +@@ -120,9 +120,14 @@ void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx, + for (; count > 0; --count) { + SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, + fOneOverTwoA, posRoot); +- SkFixed index = SkClampMax(t, 0xFFFF); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift]; ++ if (t < 0) { ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower]; ++ } else if (t > 0xFFFF) { ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper]; ++ } else { ++ SkASSERT(t <= 0xFFFF); ++ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift]; ++ } + fx += dx; + fy += dy; + b += db; +-- +1.7.11.4 + diff --git a/gfx/skia/patches/archive/0006-Bug-751814-ARM-EDSP-ARMv6-Skia-fixes.patch b/gfx/skia/patches/archive/0006-Bug-751814-ARM-EDSP-ARMv6-Skia-fixes.patch new file mode 100644 index 0000000000..eb75691ad7 --- /dev/null +++ b/gfx/skia/patches/archive/0006-Bug-751814-ARM-EDSP-ARMv6-Skia-fixes.patch @@ -0,0 +1,147 @@ +From 94916fbbc7865c6fe23a57d6edc48c6daf93dda8 Mon Sep 17 00:00:00 2001 +From: George Wright <gwright@mozilla.com> +Date: Fri, 18 May 2012 14:16:08 -0400 +Subject: [PATCH 06/10] Bug 755869 - [9] Re-apply bug 751814 - Various + Skia fixes for ARM without EDSP and ARMv6+ + r=mattwoodrow + +--- + gfx/skia/include/core/SkMath.h | 5 +-- + gfx/skia/include/core/SkPostConfig.h | 45 ++++++++++++++++++++++ + gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp | 6 +- + gfx/skia/src/opts/SkBlitRow_opts_arm.cpp | 9 ++++ + 4 files changed, 58 insertions(+), 7 deletions(-) + +diff --git a/gfx/skia/include/core/SkMath.h b/gfx/skia/include/core/SkMath.h +index 5889103..7a4b707 100644 +--- a/gfx/skia/include/core/SkMath.h ++++ b/gfx/skia/include/core/SkMath.h +@@ -153,10 +153,7 @@ static inline bool SkIsPow2(int value) { + With this requirement, we can generate faster instructions on some + architectures. + */ +-#if defined(__arm__) \ +- && !defined(__thumb__) \ +- && !defined(__ARM_ARCH_4T__) \ +- && !defined(__ARM_ARCH_5T__) ++#ifdef SK_ARM_HAS_EDSP + static inline int32_t SkMulS16(S16CPU x, S16CPU y) { + SkASSERT((int16_t)x == x); + SkASSERT((int16_t)y == y); +diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h +index 041fe2a..03105e4 100644 +--- a/gfx/skia/include/core/SkPostConfig.h ++++ b/gfx/skia/include/core/SkPostConfig.h +@@ -311,3 +311,48 @@ + #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 +diff --git a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp +index 20d62e1..deb1bfe 100644 +--- a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp ++++ b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp +@@ -11,7 +11,7 @@ + #include "SkColorPriv.h" + #include "SkUtils.h" + +-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN) ++#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN) + void SI8_D16_nofilter_DX_arm( + const SkBitmapProcState& s, + const uint32_t* SK_RESTRICT xy, +@@ -182,7 +182,7 @@ void SI8_opaque_D32_nofilter_DX_arm(const SkBitmapProcState& s, + + s.fBitmap->getColorTable()->unlockColors(false); + } +-#endif //__ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN) ++#endif // SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN) + + /////////////////////////////////////////////////////////////////////////////// + +@@ -200,7 +200,7 @@ void SkBitmapProcState::platformProcs() { + + switch (fBitmap->config()) { + case SkBitmap::kIndex8_Config: +-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN) ++#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN) + if (justDx && !doFilter) { + #if 0 /* crashing on android device */ + fSampleProc16 = SI8_D16_nofilter_DX_arm; +diff --git a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp +index 2490371..c928888 100644 +--- a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp ++++ b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp +@@ -675,8 +675,13 @@ static void __attribute((noinline,optimize("-fomit-frame-pointer"))) S32A_Blend_ + /* dst1_scale and dst2_scale*/ + "lsr r9, r5, #24 \n\t" /* src >> 24 */ + "lsr r10, r6, #24 \n\t" /* src >> 24 */ ++#ifdef SK_ARM_HAS_EDSP + "smulbb r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */ + "smulbb r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */ ++#else ++ "mul r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */ ++ "mul r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */ ++#endif + "lsr r9, r9, #8 \n\t" /* r9 >> 8 */ + "lsr r10, r10, #8 \n\t" /* r10 >> 8 */ + "rsb r9, r9, #256 \n\t" /* dst1_scale = r9 = 255 - r9 + 1 */ +@@ -745,7 +750,11 @@ static void __attribute((noinline,optimize("-fomit-frame-pointer"))) S32A_Blend_ + + "lsr r6, r5, #24 \n\t" /* src >> 24 */ + "and r8, r12, r5, lsr #8 \n\t" /* ag = r8 = r5 masked by r12 lsr by #8 */ ++#ifdef SK_ARM_HAS_EDSP + "smulbb r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */ ++#else ++ "mul r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */ ++#endif + "and r9, r12, r5 \n\t" /* rb = r9 = r5 masked by r12 */ + "lsr r6, r6, #8 \n\t" /* r6 >> 8 */ + "mul r8, r8, %[alpha] \n\t" /* ag = r8 times scale */ +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0006-Bug-848491-Re-apply-Bug-777614-Add-our-SkUserConfig..patch b/gfx/skia/patches/archive/0006-Bug-848491-Re-apply-Bug-777614-Add-our-SkUserConfig..patch new file mode 100644 index 0000000000..2850000ace --- /dev/null +++ b/gfx/skia/patches/archive/0006-Bug-848491-Re-apply-Bug-777614-Add-our-SkUserConfig..patch @@ -0,0 +1,27 @@ +From: George Wright <gw@gwright.org.uk> +Date: Thu, 25 Apr 2013 20:40:12 -0400 +Subject: Bug 848491 - Re-apply Bug 777614 - Add our SkUserConfig.h + + +diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h +index 63fc90d..c965e91 100644 +--- a/gfx/skia/include/config/SkUserConfig.h ++++ b/gfx/skia/include/config/SkUserConfig.h +@@ -201,4 +201,14 @@ + */ + //#define SK_SUPPORT_GPU 1 + ++/* Don't dither 32bit gradients, to match what the canvas test suite expects. ++ */ ++#define SK_DISABLE_DITHER_32BIT_GRADIENT ++ ++/* 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 +-- +1.7.11.7 + diff --git a/gfx/skia/patches/archive/0007-Bug-719872-Old-Android-FontHost.patch b/gfx/skia/patches/archive/0007-Bug-719872-Old-Android-FontHost.patch new file mode 100644 index 0000000000..ca34e1a457 --- /dev/null +++ b/gfx/skia/patches/archive/0007-Bug-719872-Old-Android-FontHost.patch @@ -0,0 +1,702 @@ +From 6982ad469adcdfa2b7bdbf8bbd843bc22d3832fc Mon Sep 17 00:00:00 2001 +From: George Wright <gwright@mozilla.com> +Date: Fri, 18 May 2012 14:52:40 -0400 +Subject: [PATCH 07/10] Bug 755869 - [10] Re-apply bug 719872 - Fix crash + on Android by reverting to older FontHost impl + r=mattwoodrow + +--- + gfx/skia/Makefile.in | 5 +- + gfx/skia/src/ports/SkFontHost_android_old.cpp | 664 +++++++++++++++++++++++++ + 2 files changed, 668 insertions(+), 1 deletions(-) + create mode 100644 gfx/skia/src/ports/SkFontHost_android_old.cpp + +diff --git a/gfx/skia/Makefile.in b/gfx/skia/Makefile.in +index 9da098a..8184f1c 100644 +--- a/gfx/skia/Makefile.in ++++ b/gfx/skia/Makefile.in +@@ -327,7 +327,10 @@ endif + ifeq (android,$(MOZ_WIDGET_TOOLKIT)) + CPPSRCS += \ + SkDebug_android.cpp \ +- SkFontHost_none.cpp \ ++ SkFontHost_android_old.cpp \ ++ SkFontHost_gamma.cpp \ ++ SkFontHost_FreeType.cpp \ ++ SkFontHost_tables.cpp \ + SkMMapStream.cpp \ + SkTime_Unix.cpp \ + SkThread_pthread.cpp \ +diff --git a/gfx/skia/src/ports/SkFontHost_android_old.cpp b/gfx/skia/src/ports/SkFontHost_android_old.cpp +new file mode 100644 +index 0000000..b5c4f3c +--- /dev/null ++++ b/gfx/skia/src/ports/SkFontHost_android_old.cpp +@@ -0,0 +1,664 @@ ++ ++/* ++ * 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. ++ */ ++ ++ ++#include "SkFontHost.h" ++#include "SkDescriptor.h" ++#include "SkMMapStream.h" ++#include "SkPaint.h" ++#include "SkString.h" ++#include "SkStream.h" ++#include "SkThread.h" ++#include "SkTSearch.h" ++#include <stdio.h> ++ ++#define FONT_CACHE_MEMORY_BUDGET (768 * 1024) ++ ++#ifndef SK_FONT_FILE_PREFIX ++ #define SK_FONT_FILE_PREFIX "/fonts/" ++#endif ++ ++bool find_name_and_attributes(SkStream* stream, SkString* name, SkTypeface::Style* style, ++ bool* isFixedWidth); ++ ++static void GetFullPathForSysFonts(SkString* full, const char name[]) { ++ full->set(getenv("ANDROID_ROOT")); ++ full->append(SK_FONT_FILE_PREFIX); ++ full->append(name); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++struct FamilyRec; ++ ++/* This guy holds a mapping of a name -> family, used for looking up fonts. ++ Since it is stored in a stretchy array that doesn't preserve object ++ semantics, we don't use constructor/destructors, but just have explicit ++ helpers to manage our internal bookkeeping. ++*/ ++struct NameFamilyPair { ++ const char* fName; // we own this ++ FamilyRec* fFamily; // we don't own this, we just reference it ++ ++ void construct(const char name[], FamilyRec* family) { ++ fName = strdup(name); ++ fFamily = family; // we don't own this, so just record the referene ++ } ++ ++ void destruct() { ++ free((char*)fName); ++ // we don't own family, so just ignore our reference ++ } ++}; ++ ++// we use atomic_inc to grow this for each typeface we create ++static int32_t gUniqueFontID; ++ ++// this is the mutex that protects these globals ++static SkMutex gFamilyMutex; ++static FamilyRec* gFamilyHead; ++static SkTDArray<NameFamilyPair> gNameList; ++ ++struct FamilyRec { ++ FamilyRec* fNext; ++ SkTypeface* fFaces[4]; ++ ++ FamilyRec() ++ { ++ fNext = gFamilyHead; ++ memset(fFaces, 0, sizeof(fFaces)); ++ gFamilyHead = this; ++ } ++}; ++ ++static SkTypeface* find_best_face(const FamilyRec* family, ++ SkTypeface::Style style) { ++ SkTypeface* const* faces = family->fFaces; ++ ++ if (faces[style] != NULL) { // exact match ++ return faces[style]; ++ } ++ // look for a matching bold ++ style = (SkTypeface::Style)(style ^ SkTypeface::kItalic); ++ if (faces[style] != NULL) { ++ return faces[style]; ++ } ++ // look for the plain ++ if (faces[SkTypeface::kNormal] != NULL) { ++ return faces[SkTypeface::kNormal]; ++ } ++ // look for anything ++ for (int i = 0; i < 4; i++) { ++ if (faces[i] != NULL) { ++ return faces[i]; ++ } ++ } ++ // should never get here, since the faces list should not be empty ++ SkASSERT(!"faces list is empty"); ++ return NULL; ++} ++ ++static FamilyRec* find_family(const SkTypeface* member) { ++ FamilyRec* curr = gFamilyHead; ++ while (curr != NULL) { ++ for (int i = 0; i < 4; i++) { ++ if (curr->fFaces[i] == member) { ++ return curr; ++ } ++ } ++ curr = curr->fNext; ++ } ++ return NULL; ++} ++ ++/* Returns the matching typeface, or NULL. If a typeface is found, its refcnt ++ is not modified. ++ */ ++static SkTypeface* find_from_uniqueID(uint32_t uniqueID) { ++ FamilyRec* curr = gFamilyHead; ++ while (curr != NULL) { ++ for (int i = 0; i < 4; i++) { ++ SkTypeface* face = curr->fFaces[i]; ++ if (face != NULL && face->uniqueID() == uniqueID) { ++ return face; ++ } ++ } ++ curr = curr->fNext; ++ } ++ return NULL; ++} ++ ++/* Remove reference to this face from its family. If the resulting family ++ is empty (has no faces), return that family, otherwise return NULL ++*/ ++static FamilyRec* remove_from_family(const SkTypeface* face) { ++ FamilyRec* family = find_family(face); ++ SkASSERT(family->fFaces[face->style()] == face); ++ family->fFaces[face->style()] = NULL; ++ ++ for (int i = 0; i < 4; i++) { ++ if (family->fFaces[i] != NULL) { // family is non-empty ++ return NULL; ++ } ++ } ++ return family; // return the empty family ++} ++ ++// maybe we should make FamilyRec be doubly-linked ++static void detach_and_delete_family(FamilyRec* family) { ++ FamilyRec* curr = gFamilyHead; ++ FamilyRec* prev = NULL; ++ ++ while (curr != NULL) { ++ FamilyRec* next = curr->fNext; ++ if (curr == family) { ++ if (prev == NULL) { ++ gFamilyHead = next; ++ } else { ++ prev->fNext = next; ++ } ++ SkDELETE(family); ++ return; ++ } ++ prev = curr; ++ curr = next; ++ } ++ SkASSERT(!"Yikes, couldn't find family in our list to remove/delete"); ++} ++ ++static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) { ++ NameFamilyPair* list = gNameList.begin(); ++ int count = gNameList.count(); ++ ++ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); ++ ++ if (index >= 0) { ++ return find_best_face(list[index].fFamily, style); ++ } ++ return NULL; ++} ++ ++static SkTypeface* find_typeface(const SkTypeface* familyMember, ++ SkTypeface::Style style) { ++ const FamilyRec* family = find_family(familyMember); ++ return family ? find_best_face(family, style) : NULL; ++} ++ ++static void add_name(const char name[], FamilyRec* family) { ++ SkAutoAsciiToLC tolc(name); ++ name = tolc.lc(); ++ ++ NameFamilyPair* list = gNameList.begin(); ++ int count = gNameList.count(); ++ ++ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); ++ ++ if (index < 0) { ++ list = gNameList.insert(~index); ++ list->construct(name, family); ++ } ++} ++ ++static void remove_from_names(FamilyRec* emptyFamily) ++{ ++#ifdef SK_DEBUG ++ for (int i = 0; i < 4; i++) { ++ SkASSERT(emptyFamily->fFaces[i] == NULL); ++ } ++#endif ++ ++ SkTDArray<NameFamilyPair>& list = gNameList; ++ ++ // must go backwards when removing ++ for (int i = list.count() - 1; i >= 0; --i) { ++ NameFamilyPair* pair = &list[i]; ++ if (pair->fFamily == emptyFamily) { ++ pair->destruct(); ++ list.remove(i); ++ } ++ } ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++class FamilyTypeface : public SkTypeface { ++public: ++ FamilyTypeface(Style style, bool sysFont, SkTypeface* familyMember, ++ bool isFixedWidth) ++ : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedWidth) { ++ fIsSysFont = sysFont; ++ ++ SkAutoMutexAcquire ac(gFamilyMutex); ++ ++ FamilyRec* rec = NULL; ++ if (familyMember) { ++ rec = find_family(familyMember); ++ SkASSERT(rec); ++ } else { ++ rec = SkNEW(FamilyRec); ++ } ++ rec->fFaces[style] = this; ++ } ++ ++ virtual ~FamilyTypeface() { ++ SkAutoMutexAcquire ac(gFamilyMutex); ++ ++ // remove us from our family. If the family is now empty, we return ++ // that and then remove that family from the name list ++ FamilyRec* family = remove_from_family(this); ++ if (NULL != family) { ++ remove_from_names(family); ++ detach_and_delete_family(family); ++ } ++ } ++ ++ bool isSysFont() const { return fIsSysFont; } ++ ++ virtual SkStream* openStream() = 0; ++ virtual const char* getUniqueString() const = 0; ++ virtual const char* getFilePath() const = 0; ++ ++private: ++ bool fIsSysFont; ++ ++ typedef SkTypeface INHERITED; ++}; ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++class StreamTypeface : public FamilyTypeface { ++public: ++ StreamTypeface(Style style, bool sysFont, SkTypeface* familyMember, ++ SkStream* stream, bool isFixedWidth) ++ : INHERITED(style, sysFont, familyMember, isFixedWidth) { ++ SkASSERT(stream); ++ stream->ref(); ++ fStream = stream; ++ } ++ virtual ~StreamTypeface() { ++ fStream->unref(); ++ } ++ ++ // overrides ++ virtual SkStream* openStream() { ++ // we just ref our existing stream, since the caller will call unref() ++ // when they are through ++ fStream->ref(); ++ // must rewind each time, since the caller assumes a "new" stream ++ fStream->rewind(); ++ return fStream; ++ } ++ virtual const char* getUniqueString() const { return NULL; } ++ virtual const char* getFilePath() const { return NULL; } ++ ++private: ++ SkStream* fStream; ++ ++ typedef FamilyTypeface INHERITED; ++}; ++ ++class FileTypeface : public FamilyTypeface { ++public: ++ FileTypeface(Style style, bool sysFont, SkTypeface* familyMember, ++ const char path[], bool isFixedWidth) ++ : INHERITED(style, sysFont, familyMember, isFixedWidth) { ++ SkString fullpath; ++ ++ if (sysFont) { ++ GetFullPathForSysFonts(&fullpath, path); ++ path = fullpath.c_str(); ++ } ++ fPath.set(path); ++ } ++ ++ // overrides ++ virtual SkStream* openStream() { ++ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str())); ++ ++ // check for failure ++ if (stream->getLength() <= 0) { ++ SkDELETE(stream); ++ // maybe MMAP isn't supported. try FILE ++ stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str())); ++ if (stream->getLength() <= 0) { ++ SkDELETE(stream); ++ stream = NULL; ++ } ++ } ++ return stream; ++ } ++ virtual const char* getUniqueString() const { ++ const char* str = strrchr(fPath.c_str(), '/'); ++ if (str) { ++ str += 1; // skip the '/' ++ } ++ return str; ++ } ++ virtual const char* getFilePath() const { ++ return fPath.c_str(); ++ } ++ ++private: ++ SkString fPath; ++ ++ typedef FamilyTypeface INHERITED; ++}; ++ ++/////////////////////////////////////////////////////////////////////////////// ++/////////////////////////////////////////////////////////////////////////////// ++ ++static bool get_name_and_style(const char path[], SkString* name, ++ SkTypeface::Style* style, ++ bool* isFixedWidth, bool isExpected) { ++ SkString fullpath; ++ GetFullPathForSysFonts(&fullpath, path); ++ ++ SkMMAPStream stream(fullpath.c_str()); ++ if (stream.getLength() > 0) { ++ find_name_and_attributes(&stream, name, style, isFixedWidth); ++ return true; ++ } ++ else { ++ SkFILEStream stream(fullpath.c_str()); ++ if (stream.getLength() > 0) { ++ find_name_and_attributes(&stream, name, style, isFixedWidth); ++ return true; ++ } ++ } ++ ++ if (isExpected) { ++ SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str()); ++ } ++ return false; ++} ++ ++// used to record our notion of the pre-existing fonts ++struct FontInitRec { ++ const char* fFileName; ++ const char* const* fNames; // null-terminated list ++}; ++ ++static const char* gSansNames[] = { ++ "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL ++}; ++ ++static const char* gSerifNames[] = { ++ "serif", "times", "times new roman", "palatino", "georgia", "baskerville", ++ "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL ++}; ++ ++static const char* gMonoNames[] = { ++ "monospace", "courier", "courier new", "monaco", NULL ++}; ++ ++// deliberately empty, but we use the address to identify fallback fonts ++static const char* gFBNames[] = { NULL }; ++ ++/* Fonts must be grouped by family, with the first font in a family having the ++ list of names (even if that list is empty), and the following members having ++ null for the list. The names list must be NULL-terminated ++*/ ++static const FontInitRec gSystemFonts[] = { ++ { "DroidSans.ttf", gSansNames }, ++ { "DroidSans-Bold.ttf", NULL }, ++ { "DroidSerif-Regular.ttf", gSerifNames }, ++ { "DroidSerif-Bold.ttf", NULL }, ++ { "DroidSerif-Italic.ttf", NULL }, ++ { "DroidSerif-BoldItalic.ttf", NULL }, ++ { "DroidSansMono.ttf", gMonoNames }, ++ /* These are optional, and can be ignored if not found in the file system. ++ These are appended to gFallbackFonts[] as they are seen, so we list ++ them in the order we want them to be accessed by NextLogicalFont(). ++ */ ++ { "DroidSansArabic.ttf", gFBNames }, ++ { "DroidSansHebrew.ttf", gFBNames }, ++ { "DroidSansThai.ttf", gFBNames }, ++ { "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font ++ { "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font ++ { "DroidSansJapanese.ttf", gFBNames }, ++ { "DroidSansFallback.ttf", gFBNames } ++}; ++ ++#define DEFAULT_NAMES gSansNames ++ ++// these globals are assigned (once) by load_system_fonts() ++static FamilyRec* gDefaultFamily; ++static SkTypeface* gDefaultNormal; ++ ++/* This is sized conservatively, assuming that it will never be a size issue. ++ It will be initialized in load_system_fonts(), and will be filled with the ++ fontIDs that can be used for fallback consideration, in sorted order (sorted ++ meaning element[0] should be used first, then element[1], etc. When we hit ++ a fontID==0 in the array, the list is done, hence our allocation size is ++ +1 the total number of possible system fonts. Also see NextLogicalFont(). ++ */ ++static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1]; ++ ++/* Called once (ensured by the sentinel check at the beginning of our body). ++ Initializes all the globals, and register the system fonts. ++ */ ++static void load_system_fonts() { ++ // check if we've already be called ++ if (NULL != gDefaultNormal) { ++ return; ++ } ++ ++ const FontInitRec* rec = gSystemFonts; ++ SkTypeface* firstInFamily = NULL; ++ int fallbackCount = 0; ++ ++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { ++ // if we're the first in a new family, clear firstInFamily ++ if (rec[i].fNames != NULL) { ++ firstInFamily = NULL; ++ } ++ ++ bool isFixedWidth; ++ SkString name; ++ SkTypeface::Style style; ++ ++ // we expect all the fonts, except the "fallback" fonts ++ bool isExpected = (rec[i].fNames != gFBNames); ++ if (!get_name_and_style(rec[i].fFileName, &name, &style, ++ &isFixedWidth, isExpected)) { ++ continue; ++ } ++ ++ SkTypeface* tf = SkNEW_ARGS(FileTypeface, ++ (style, ++ true, // system-font (cannot delete) ++ firstInFamily, // what family to join ++ rec[i].fFileName, ++ isFixedWidth) // filename ++ ); ++ ++ if (rec[i].fNames != NULL) { ++ // see if this is one of our fallback fonts ++ if (rec[i].fNames == gFBNames) { ++ // SkDebugf("---- adding %s as fallback[%d] fontID %d\n", ++ // rec[i].fFileName, fallbackCount, tf->uniqueID()); ++ gFallbackFonts[fallbackCount++] = tf->uniqueID(); ++ } ++ ++ firstInFamily = tf; ++ FamilyRec* family = find_family(tf); ++ const char* const* names = rec[i].fNames; ++ ++ // record the default family if this is it ++ if (names == DEFAULT_NAMES) { ++ gDefaultFamily = family; ++ } ++ // add the names to map to this family ++ while (*names) { ++ add_name(*names, family); ++ names += 1; ++ } ++ } ++ } ++ ++ // do this after all fonts are loaded. This is our default font, and it ++ // acts as a sentinel so we only execute load_system_fonts() once ++ gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal); ++ // now terminate our fallback list with the sentinel value ++ gFallbackFonts[fallbackCount] = 0; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { ++ const char* name = ((FamilyTypeface*)face)->getUniqueString(); ++ ++ stream->write8((uint8_t)face->style()); ++ ++ if (NULL == name || 0 == *name) { ++ stream->writePackedUInt(0); ++// SkDebugf("--- fonthost serialize null\n"); ++ } else { ++ uint32_t len = strlen(name); ++ stream->writePackedUInt(len); ++ stream->write(name, len); ++// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style()); ++ } ++} ++ ++SkTypeface* SkFontHost::Deserialize(SkStream* stream) { ++ load_system_fonts(); ++ ++ int style = stream->readU8(); ++ ++ int len = stream->readPackedUInt(); ++ if (len > 0) { ++ SkString str; ++ str.resize(len); ++ stream->read(str.writable_str(), len); ++ ++ const FontInitRec* rec = gSystemFonts; ++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { ++ if (strcmp(rec[i].fFileName, str.c_str()) == 0) { ++ // backup until we hit the fNames ++ for (int j = i; j >= 0; --j) { ++ if (rec[j].fNames != NULL) { ++ return SkFontHost::CreateTypeface(NULL, ++ rec[j].fNames[0], (SkTypeface::Style)style); ++ } ++ } ++ } ++ } ++ } ++ return NULL; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, ++ const char familyName[], ++ SkTypeface::Style style) { ++ load_system_fonts(); ++ ++ SkAutoMutexAcquire ac(gFamilyMutex); ++ ++ // clip to legal style bits ++ style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic); ++ ++ SkTypeface* tf = NULL; ++ ++ if (NULL != familyFace) { ++ tf = find_typeface(familyFace, style); ++ } else if (NULL != familyName) { ++// SkDebugf("======= familyName <%s>\n", familyName); ++ tf = find_typeface(familyName, style); ++ } ++ ++ if (NULL == tf) { ++ tf = find_best_face(gDefaultFamily, style); ++ } ++ ++ // we ref(), since the symantic is to return a new instance ++ tf->ref(); ++ return tf; ++} ++ ++SkStream* SkFontHost::OpenStream(uint32_t fontID) { ++ SkAutoMutexAcquire ac(gFamilyMutex); ++ ++ FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID); ++ SkStream* stream = tf ? tf->openStream() : NULL; ++ ++ if (stream && stream->getLength() == 0) { ++ stream->unref(); ++ stream = NULL; ++ } ++ return stream; ++} ++ ++size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length, ++ int32_t* index) { ++ SkAutoMutexAcquire ac(gFamilyMutex); ++ ++ FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID); ++ const char* src = tf ? tf->getFilePath() : NULL; ++ ++ if (src) { ++ size_t size = strlen(src); ++ if (path) { ++ memcpy(path, src, SkMin32(size, length)); ++ } ++ if (index) { ++ *index = 0; // we don't have collections (yet) ++ } ++ return size; ++ } else { ++ return 0; ++ } ++} ++ ++SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) { ++ load_system_fonts(); ++ ++ /* First see if fontID is already one of our fallbacks. If so, return ++ its successor. If fontID is not in our list, then return the first one ++ in our list. Note: list is zero-terminated, and returning zero means ++ we have no more fonts to use for fallbacks. ++ */ ++ const uint32_t* list = gFallbackFonts; ++ for (int i = 0; list[i] != 0; i++) { ++ if (list[i] == currFontID) { ++ return list[i+1]; ++ } ++ } ++ return list[0]; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++ ++SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { ++ if (NULL == stream || stream->getLength() <= 0) { ++ return NULL; ++ } ++ ++ bool isFixedWidth; ++ SkString name; ++ SkTypeface::Style style; ++ find_name_and_attributes(stream, &name, &style, &isFixedWidth); ++ ++ if (!name.isEmpty()) { ++ return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream, isFixedWidth)); ++ } else { ++ return NULL; ++ } ++} ++ ++SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { ++ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path)); ++ SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream); ++ // since we created the stream, we let go of our ref() here ++ stream->unref(); ++ return face; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0007-Bug-848491-Re-apply-bug-687188-Expand-the-gradient-c.patch b/gfx/skia/patches/archive/0007-Bug-848491-Re-apply-bug-687188-Expand-the-gradient-c.patch new file mode 100644 index 0000000000..73bca9a48d --- /dev/null +++ b/gfx/skia/patches/archive/0007-Bug-848491-Re-apply-bug-687188-Expand-the-gradient-c.patch @@ -0,0 +1,168 @@ +From: George Wright <gw@gwright.org.uk> +Date: Thu, 25 Apr 2013 20:47:06 -0400 +Subject: Bug 848491 - Re-apply bug 687188 - Expand the gradient cache by 2 to store 0/1 colour stop values for clamping. + + +diff --git a/gfx/skia/src/effects/gradients/SkGradientShader.cpp b/gfx/skia/src/effects/gradients/SkGradientShader.cpp +index 684355d..27a9c46 100644 +--- a/gfx/skia/src/effects/gradients/SkGradientShader.cpp ++++ b/gfx/skia/src/effects/gradients/SkGradientShader.cpp +@@ -453,15 +453,15 @@ const uint16_t* SkGradientShaderBase::getCache16() const { + + const SkPMColor* SkGradientShaderBase::getCache32() const { + if (fCache32 == NULL) { +- // double the count for dither entries +- const int entryCount = kCache32Count * 4; ++ // double the count for dither entries, and have an extra two entries for clamp values ++ const int entryCount = kCache32Count * 4 + 2; + const size_t allocSize = sizeof(SkPMColor) * entryCount; + + if (NULL == fCache32PixelRef) { + fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef, + (NULL, allocSize, NULL)); + } +- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr(); ++ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1; + if (fColorCount == 2) { + Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1], + kCache32Count, fCacheAlpha); +@@ -484,7 +484,7 @@ const SkPMColor* SkGradientShaderBase::getCache32() const { + SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef, + (NULL, allocSize, NULL)); + SkPMColor* linear = fCache32; // just computed linear data +- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data ++ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data + SkUnitMapper* map = fMapper; + for (int i = 0; i < kCache32Count; i++) { + int index = map->mapUnit16((i << 8) | i) >> 8; +@@ -495,9 +495,21 @@ const SkPMColor* SkGradientShaderBase::getCache32() const { + } + fCache32PixelRef->unref(); + fCache32PixelRef = newPR; +- fCache32 = (SkPMColor*)newPR->getAddr(); ++ fCache32 = (SkPMColor*)newPR->getAddr() + 1; + } + } ++ ++ // Write the clamp colours into the first and last entries of fCache32 ++ fCache32[kCache32ClampLower] = SkPackARGB32(fCacheAlpha, ++ SkColorGetR(fOrigColors[0]), ++ SkColorGetG(fOrigColors[0]), ++ SkColorGetB(fOrigColors[0])); ++ ++ fCache32[kCache32ClampUpper] = SkPackARGB32(fCacheAlpha, ++ SkColorGetR(fOrigColors[fColorCount - 1]), ++ SkColorGetG(fOrigColors[fColorCount - 1]), ++ SkColorGetB(fOrigColors[fColorCount - 1])); ++ + return fCache32; + } + +diff --git a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h +index 729ce4e..2cb6a9d 100644 +--- a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h ++++ b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h +@@ -86,6 +86,9 @@ public: + /// if dithering is disabled. + kDitherStride32 = kCache32Count, + kDitherStride16 = kCache16Count, ++ ++ kCache32ClampLower = -1, ++ kCache32ClampUpper = kCache32Count * 4 + }; + + +diff --git a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp +index e0f216c..40ab918 100644 +--- a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp ++++ b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp +@@ -127,6 +127,17 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx, + SkPMColor* SK_RESTRICT dstC, + const SkPMColor* SK_RESTRICT cache, + int toggle, int count) { ++ if (proc == clamp_tileproc) { ++ // No need to lerp or dither for clamp values ++ if (fx < 0) { ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count); ++ return; ++ } else if (fx > 0xffff) { ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count); ++ return; ++ } ++ } ++ + // We're a vertical gradient, so no change in a span. + // If colors change sharply across the gradient, dithering is + // insufficient (it subsamples the color space) and we need to lerp. +@@ -154,10 +165,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, + range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1); + + if ((count = range.fCount0) > 0) { +- sk_memset32_dither(dstC, +- cache[toggle + range.fV0], +- cache[next_dither_toggle(toggle) + range.fV0], +- count); ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count); + dstC += count; + } + if ((count = range.fCount1) > 0) { +@@ -176,10 +184,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, + } + } + if ((count = range.fCount2) > 0) { +- sk_memset32_dither(dstC, +- cache[toggle + range.fV1], +- cache[next_dither_toggle(toggle) + range.fV1], +- count); ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count); + } + } + +diff --git a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp +index abd974b..601fff4 100644 +--- a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp ++++ b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp +@@ -124,10 +124,14 @@ static void twopoint_clamp(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC, + if (TwoPtRadial::DontDrawT(t)) { + *dstC++ = 0; + } else { +- SkFixed index = SkClampMax(t, 0xFFFF); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[toggle + +- (index >> SkGradientShaderBase::kCache32Shift)]; ++ if (t < 0) { ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower]; ++ } else if (t > 0xFFFF) { ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper]; ++ } else { ++ SkASSERT(t <= 0xFFFF); ++ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift]; ++ } + } + toggle = next_dither_toggle(toggle); + } +diff --git a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp +index f70b67d..ec2ae75 100644 +--- a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp ++++ b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp +@@ -120,9 +120,14 @@ void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx, + for (; count > 0; --count) { + SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, + fOneOverTwoA, posRoot); +- SkFixed index = SkClampMax(t, 0xFFFF); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift]; ++ if (t < 0) { ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower]; ++ } else if (t > 0xFFFF) { ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper]; ++ } else { ++ SkASSERT(t <= 0xFFFF); ++ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift]; ++ } + fx += dx; + fy += dy; + b += db; +-- +1.7.11.7 + diff --git a/gfx/skia/patches/archive/0008-Bug-687188-Skia-radial-gradients.patch b/gfx/skia/patches/archive/0008-Bug-687188-Skia-radial-gradients.patch new file mode 100644 index 0000000000..0f60dbd8ea --- /dev/null +++ b/gfx/skia/patches/archive/0008-Bug-687188-Skia-radial-gradients.patch @@ -0,0 +1,173 @@ +From f941ea32e44a2436d235e83ef1a434289a9d9c1e Mon Sep 17 00:00:00 2001 +From: George Wright <gwright@mozilla.com> +Date: Wed, 23 May 2012 11:40:25 -0400 +Subject: [PATCH 08/10] Bug 755869 - [11] Re-apply bug 687188 - Skia + radial gradients should use the 0/1 color stop values + for clamping. r=mattwoodrow + +--- + gfx/skia/src/effects/SkGradientShader.cpp | 76 +++++++++++++++++++++++------ + 1 files changed, 61 insertions(+), 15 deletions(-) + +diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp +index 59ba48c..ea05a39 100644 +--- a/gfx/skia/src/effects/SkGradientShader.cpp ++++ b/gfx/skia/src/effects/SkGradientShader.cpp +@@ -204,6 +204,7 @@ private: + mutable SkMallocPixelRef* fCache32PixelRef; + mutable unsigned fCacheAlpha; // the alpha value we used when we computed the cache. larger than 8bits so we can store uninitialized value + ++ static SkPMColor PremultiplyColor(SkColor c0, U8CPU alpha); + static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count); + static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count, + U8CPU alpha); +@@ -507,6 +508,21 @@ static inline U8CPU dither_ceil_fixed_to_8(SkFixed n) { + return ((n << 1) - (n | (n >> 8))) >> 8; + } + ++SkPMColor Gradient_Shader::PremultiplyColor(SkColor c0, U8CPU paintAlpha) ++{ ++ SkFixed a = SkMulDiv255Round(SkColorGetA(c0), paintAlpha); ++ SkFixed r = SkColorGetR(c0); ++ SkFixed g = SkColorGetG(c0); ++ SkFixed b = SkColorGetB(c0); ++ ++ a = SkIntToFixed(a) + 0x8000; ++ r = SkIntToFixed(r) + 0x8000; ++ g = SkIntToFixed(g) + 0x8000; ++ b = SkIntToFixed(b) + 0x8000; ++ ++ return SkPremultiplyARGBInline(a >> 16, r >> 16, g >> 16, b >> 16); ++} ++ + void Gradient_Shader::Build32bitCache(SkPMColor cache[], SkColor c0, SkColor c1, + int count, U8CPU paintAlpha) { + SkASSERT(count > 1); +@@ -628,14 +644,14 @@ static void complete_32bit_cache(SkPMColor* cache, int stride) { + const SkPMColor* Gradient_Shader::getCache32() const { + if (fCache32 == NULL) { + // double the count for dither entries +- const int entryCount = kCache32Count * 2; ++ const int entryCount = kCache32Count * 2 + 2; + const size_t allocSize = sizeof(SkPMColor) * entryCount; + + if (NULL == fCache32PixelRef) { + fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef, + (NULL, allocSize, NULL)); + } +- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr(); ++ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1; + if (fColorCount == 2) { + Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1], + kGradient32Length, fCacheAlpha); +@@ -659,7 +675,7 @@ const SkPMColor* Gradient_Shader::getCache32() const { + SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef, + (NULL, allocSize, NULL)); + SkPMColor* linear = fCache32; // just computed linear data +- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data ++ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data + SkUnitMapper* map = fMapper; + for (int i = 0; i < kGradient32Length; i++) { + int index = map->mapUnit16((i << 8) | i) >> 8; +@@ -668,10 +684,13 @@ const SkPMColor* Gradient_Shader::getCache32() const { + } + fCache32PixelRef->unref(); + fCache32PixelRef = newPR; +- fCache32 = (SkPMColor*)newPR->getAddr(); ++ fCache32 = (SkPMColor*)newPR->getAddr() + 1; + } + complete_32bit_cache(fCache32, kCache32Count); + } ++ //Write the clamp colours into the first and last entries of fCache32 ++ fCache32[-1] = PremultiplyColor(fOrigColors[0], fCacheAlpha); ++ fCache32[kCache32Count * 2] = PremultiplyColor(fOrigColors[fColorCount - 1], fCacheAlpha); + return fCache32; + } + +@@ -857,6 +876,18 @@ void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx, + SkPMColor* SK_RESTRICT dstC, + const SkPMColor* SK_RESTRICT cache, + int toggle, int count) { ++ if (proc == clamp_tileproc) { ++ // Read out clamp values from beginning/end of the cache. No need to lerp ++ // or dither ++ if (fx < 0) { ++ sk_memset32(dstC, cache[-1], count); ++ return; ++ } else if (fx > 0xFFFF) { ++ sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count); ++ return; ++ } ++ } ++ + // We're a vertical gradient, so no change in a span. + // If colors change sharply across the gradient, dithering is + // insufficient (it subsamples the color space) and we need to lerp. +@@ -875,6 +906,18 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx, + SkPMColor* SK_RESTRICT dstC, + const SkPMColor* SK_RESTRICT cache, + int toggle, int count) { ++ if (proc == clamp_tileproc) { ++ // Read out clamp values from beginning/end of the cache. No need to lerp ++ // or dither ++ if (fx < 0) { ++ sk_memset32(dstC, cache[-1], count); ++ return; ++ } else if (fx > 0xFFFF) { ++ sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count); ++ return; ++ } ++ } ++ + // We're a vertical gradient, so no change in a span. + // If colors change sharply across the gradient, dithering is + // insufficient (it subsamples the color space) and we need to lerp. +@@ -900,10 +943,8 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, + range.init(fx, dx, count, 0, Gradient_Shader::kGradient32Length); + + if ((count = range.fCount0) > 0) { +- sk_memset32_dither(dstC, +- cache[toggle + range.fV0], +- cache[(toggle ^ Gradient_Shader::kDitherStride32) + range.fV0], +- count); ++ // Shouldn't be any need to dither for clamping? ++ sk_memset32(dstC, cache[-1], count); + dstC += count; + } + if ((count = range.fCount1) > 0) { +@@ -922,10 +963,8 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, + } + } + if ((count = range.fCount2) > 0) { +- sk_memset32_dither(dstC, +- cache[toggle + range.fV1], +- cache[(toggle ^ Gradient_Shader::kDitherStride32) + range.fV1], +- count); ++ // Shouldn't be any need to dither for clamping? ++ sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count); + } + } + +@@ -1796,9 +1835,16 @@ void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx, + for (; count > 0; --count) { + SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, + fOneOverTwoA, posRoot); +- SkFixed index = SkClampMax(t, 0xFFFF); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> Gradient_Shader::kCache32Shift]; ++ ++ if (t < 0) { ++ *dstC++ = cache[-1]; ++ } else if (t > 0xFFFF) { ++ *dstC++ = cache[Gradient_Shader::kCache32Count * 2]; ++ } else { ++ SkASSERT(t <= 0xFFFF); ++ *dstC++ = cache[t >> Gradient_Shader::kCache32Shift]; ++ } ++ + fx += dx; + fy += dy; + b += db; +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0008-Bug-848491-Re-apply-759683-Handle-compilers-that-don.patch b/gfx/skia/patches/archive/0008-Bug-848491-Re-apply-759683-Handle-compilers-that-don.patch new file mode 100644 index 0000000000..58961d6e06 --- /dev/null +++ b/gfx/skia/patches/archive/0008-Bug-848491-Re-apply-759683-Handle-compilers-that-don.patch @@ -0,0 +1,35 @@ +From: George Wright <gw@gwright.org.uk> +Date: Thu, 25 Apr 2013 20:49:45 -0400 +Subject: Bug 848491 - Re-apply 759683 - Handle compilers that don't support SSSE3 intrinsics + + +diff --git a/gfx/skia/src/opts/opts_check_SSE2.cpp b/gfx/skia/src/opts/opts_check_SSE2.cpp +index 6370058..18f68d6 100644 +--- a/gfx/skia/src/opts/opts_check_SSE2.cpp ++++ b/gfx/skia/src/opts/opts_check_SSE2.cpp +@@ -86,9 +86,13 @@ static inline bool hasSSSE3() { + #else + + static inline bool hasSSSE3() { ++#if defined(SK_BUILD_SSSE3) + int cpu_info[4] = { 0 }; + getcpuid(1, cpu_info); + return (cpu_info[2] & 0x200) != 0; ++#else ++ return false; ++#endif + } + #endif + +@@ -104,7 +108,7 @@ static bool cachedHasSSSE3() { + + void SkBitmapProcState::platformProcs() { + if (cachedHasSSSE3()) { +-#if !defined(SK_BUILD_FOR_ANDROID) ++#if !defined(SK_BUILD_FOR_ANDROID) && defined(SK_BUILD_SSSE3) + // Disable SSSE3 optimization for Android x86 + if (fSampleProc32 == S32_opaque_D32_filter_DX) { + fSampleProc32 = S32_opaque_D32_filter_DX_SSSE3; +-- +1.7.11.7 + diff --git a/gfx/skia/patches/archive/0009-Bug-755869-FreeBSD-Hurd.patch b/gfx/skia/patches/archive/0009-Bug-755869-FreeBSD-Hurd.patch new file mode 100644 index 0000000000..1e9a93f20a --- /dev/null +++ b/gfx/skia/patches/archive/0009-Bug-755869-FreeBSD-Hurd.patch @@ -0,0 +1,28 @@ +From df3be24040f7cb2f9c7ed86ad3e47206630e885f Mon Sep 17 00:00:00 2001 +From: George Wright <gwright@mozilla.com> +Date: Wed, 23 May 2012 14:49:57 -0400 +Subject: [PATCH 09/10] Bug 755869 - [12] Re-apply bug 749533 - Add + support for GNU/kFreeBSD and Hurd in Skia. + r=mattwoodrow + +--- + gfx/skia/include/core/SkPreConfig.h | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/gfx/skia/include/core/SkPreConfig.h b/gfx/skia/include/core/SkPreConfig.h +index 46c6929..16c4d6c 100644 +--- a/gfx/skia/include/core/SkPreConfig.h ++++ b/gfx/skia/include/core/SkPreConfig.h +@@ -35,7 +35,8 @@ + #elif defined(ANDROID) + #define SK_BUILD_FOR_ANDROID + #elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ +- defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__) ++ 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 +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0009-Bug-777614-Re-apply-759683-Handle-compilers-that-don.patch b/gfx/skia/patches/archive/0009-Bug-777614-Re-apply-759683-Handle-compilers-that-don.patch new file mode 100644 index 0000000000..1da208ed18 --- /dev/null +++ b/gfx/skia/patches/archive/0009-Bug-777614-Re-apply-759683-Handle-compilers-that-don.patch @@ -0,0 +1,40 @@ +From 2c5a8cebc806ed287ce7c3723ea64a233266cd9e Mon Sep 17 00:00:00 2001 +From: George Wright <gw@gwright.org.uk> +Date: Thu, 13 Sep 2012 14:55:33 -0400 +Subject: [PATCH 9/9] Bug 777614 - Re-apply 759683 - Handle compilers that + don't support SSSE3 intrinsics r=nrc + +--- + gfx/skia/src/opts/opts_check_SSE2.cpp | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/gfx/skia/src/opts/opts_check_SSE2.cpp b/gfx/skia/src/opts/opts_check_SSE2.cpp +index 96d0dea..add6d5f 100644 +--- a/gfx/skia/src/opts/opts_check_SSE2.cpp ++++ b/gfx/skia/src/opts/opts_check_SSE2.cpp +@@ -86,9 +86,13 @@ static inline bool hasSSSE3() { + #else + + static inline bool hasSSSE3() { ++#if defined(SK_BUILD_SSSE3) + int cpu_info[4] = { 0 }; + getcpuid(1, cpu_info); + return (cpu_info[2] & 0x200) != 0; ++#else ++ return false; ++#endif + } + #endif + +@@ -104,7 +108,7 @@ static bool cachedHasSSSE3() { + + void SkBitmapProcState::platformProcs() { + if (cachedHasSSSE3()) { +-#if !defined(SK_BUILD_FOR_ANDROID) ++#if !defined(SK_BUILD_FOR_ANDROID) && defined(SK_BUILD_SSSE3) + // Disable SSSE3 optimization for Android x86 + if (fSampleProc32 == S32_opaque_D32_filter_DX) { + fSampleProc32 = S32_opaque_D32_filter_DX_SSSE3; +-- +1.7.11.4 + diff --git a/gfx/skia/patches/archive/0009-Bug-848491-Re-apply-bug-751418-Add-our-own-GrUserCon.patch b/gfx/skia/patches/archive/0009-Bug-848491-Re-apply-bug-751418-Add-our-own-GrUserCon.patch new file mode 100644 index 0000000000..9778015c4f --- /dev/null +++ b/gfx/skia/patches/archive/0009-Bug-848491-Re-apply-bug-751418-Add-our-own-GrUserCon.patch @@ -0,0 +1,23 @@ +From: George Wright <gw@gwright.org.uk> +Date: Thu, 25 Apr 2013 20:52:32 -0400 +Subject: Bug 848491 - Re-apply bug 751418 - Add our own GrUserConfig + + +diff --git a/gfx/skia/include/gpu/GrUserConfig.h b/gfx/skia/include/gpu/GrUserConfig.h +index 11d4feb..77ab850 100644 +--- a/gfx/skia/include/gpu/GrUserConfig.h ++++ b/gfx/skia/include/gpu/GrUserConfig.h +@@ -43,6 +43,10 @@ + */ + //#define GR_DEFAULT_TEXTURE_CACHE_MB_LIMIT 96 + ++/* ++ * This allows us to set a callback to be called before each GL call to ensure ++ * that our context is set correctly ++ */ + #define GR_GL_PER_GL_FUNC_CALLBACK 1 + + #endif +-- +1.7.11.7 + diff --git a/gfx/skia/patches/archive/0010-Bug-689069-ARM-Opts.patch b/gfx/skia/patches/archive/0010-Bug-689069-ARM-Opts.patch new file mode 100644 index 0000000000..bd6604b4bd --- /dev/null +++ b/gfx/skia/patches/archive/0010-Bug-689069-ARM-Opts.patch @@ -0,0 +1,36 @@ +From dc1292fc8c2b9da900ebcac953120eaffd0d329e Mon Sep 17 00:00:00 2001 +From: George Wright <gwright@mozilla.com> +Date: Wed, 23 May 2012 14:52:36 -0400 +Subject: [PATCH 10/10] Bug 755869 - [13] Re-apply bug 750733 - Use + handles in API object hooks where possible + r=mattwoodrow + +--- + gfx/skia/src/xml/SkJS.cpp | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gfx/skia/src/xml/SkJS.cpp b/gfx/skia/src/xml/SkJS.cpp +index f2e7a83..b2717d7 100644 +--- a/gfx/skia/src/xml/SkJS.cpp ++++ b/gfx/skia/src/xml/SkJS.cpp +@@ -74,7 +74,7 @@ extern "C" { + #endif + + static bool +-global_enumerate(JSContext *cx, JSObject *obj) ++global_enumerate(JSContext *cx, JSHandleObject *obj) + { + #ifdef LAZY_STANDARD_CLASSES + return JS_EnumerateStandardClasses(cx, obj); +@@ -84,7 +84,7 @@ global_enumerate(JSContext *cx, JSObject *obj) + } + + static bool +-global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp) ++global_resolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags, JSObject **objp) + { + #ifdef LAZY_STANDARD_CLASSES + if ((flags & JSRESOLVE_ASSIGNING) == 0) { +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0010-Bug-836892-Add-new-blending-modes-to-SkXfermode.patch b/gfx/skia/patches/archive/0010-Bug-836892-Add-new-blending-modes-to-SkXfermode.patch new file mode 100644 index 0000000000..a446037de0 --- /dev/null +++ b/gfx/skia/patches/archive/0010-Bug-836892-Add-new-blending-modes-to-SkXfermode.patch @@ -0,0 +1,698 @@ +# HG changeset patch +# User Rik Cabanier <cabanier@adobe.com> +# Date 1360273929 -46800 +# Node ID 3ac8edca3a03b3d22240b5a5b95ae3b5ada9877d +# Parent cbb67fe70b864b36165061e1fd3b083cd09af087 +Bug 836892 - Add new blending modes to SkXfermode. r=gw280 + +diff --git a/gfx/skia/include/core/SkXfermode.h b/gfx/skia/include/core/SkXfermode.h +--- a/gfx/skia/include/core/SkXfermode.h ++++ b/gfx/skia/include/core/SkXfermode.h +@@ -96,33 +96,37 @@ public: + kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] + kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] + kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] + kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] + + // all remaining modes are defined in the SVG Compositing standard + // http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/ + kPlus_Mode, +- kMultiply_Mode, + + // all above modes can be expressed as pair of src/dst Coeffs + kCoeffModesCnt, + +- kScreen_Mode = kCoeffModesCnt, ++ kMultiply_Mode = kCoeffModesCnt, ++ kScreen_Mode, + kOverlay_Mode, + kDarken_Mode, + kLighten_Mode, + kColorDodge_Mode, + kColorBurn_Mode, + kHardLight_Mode, + kSoftLight_Mode, + kDifference_Mode, + kExclusion_Mode, ++ kHue_Mode, ++ kSaturation_Mode, ++ kColor_Mode, ++ kLuminosity_Mode, + +- kLastMode = kExclusion_Mode ++ kLastMode = kLuminosity_Mode + }; + + /** + * If the xfermode is one of the modes in the Mode enum, then asMode() + * returns true and sets (if not null) mode accordingly. Otherwise it + * returns false and ignores the mode parameter. + */ + virtual bool asMode(Mode* mode); +diff --git a/gfx/skia/src/core/SkXfermode.cpp b/gfx/skia/src/core/SkXfermode.cpp +--- a/gfx/skia/src/core/SkXfermode.cpp ++++ b/gfx/skia/src/core/SkXfermode.cpp +@@ -7,16 +7,18 @@ + */ + + + #include "SkXfermode.h" + #include "SkColorPriv.h" + #include "SkFlattenableBuffers.h" + #include "SkMathPriv.h" + ++#include <algorithm> ++ + SK_DEFINE_INST_COUNT(SkXfermode) + + #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) + + #if 0 + // idea for higher precision blends in xfer procs (and slightly faster) + // see DstATop as a probable caller + static U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) { +@@ -176,244 +178,439 @@ static SkPMColor xor_modeproc(SkPMColor + static SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) { + unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); + unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); + unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); + unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); + return SkPackARGB32(a, r, g, b); + } + ++static inline int srcover_byte(int a, int b) { ++ return a + b - SkAlphaMulAlpha(a, b); ++} ++ ++#define blendfunc_byte(sc, dc, sa, da, blendfunc) \ ++ clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendfunc(sc, dc, sa, da)) ++ + // kMultiply_Mode ++static inline int multiply_byte(int sc, int dc, int sa, int da) { ++ return sc * dc; ++} + static SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) { +- int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst)); +- int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst)); +- int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst)); +- int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst)); ++ int sa = SkGetPackedA32(src); ++ int da = SkGetPackedA32(dst); ++ int a = srcover_byte(sa, da); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, multiply_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, multiply_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, multiply_byte); + return SkPackARGB32(a, r, g, b); + } + + // kScreen_Mode +-static inline int srcover_byte(int a, int b) { +- return a + b - SkAlphaMulAlpha(a, b); ++static inline int screen_byte(int sc, int dc, int sa, int da) { ++ return sc * da + sa * dc - sc * dc; + } + static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { +- int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); +- int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); +- int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst)); +- int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst)); ++ int sa = SkGetPackedA32(src); ++ int da = SkGetPackedA32(dst); ++ int a = srcover_byte(sa, da); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, screen_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, screen_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, screen_byte); ++ return SkPackARGB32(a, r, g, b); ++} ++ ++// kHardLight_Mode ++static inline int hardlight_byte(int sc, int dc, int sa, int da) { ++ if(!sa || !da) ++ return sc * da; ++ float Sc = (float)sc/sa; ++ float Dc = (float)dc/da; ++ if(Sc <= 0.5) ++ Sc *= 2 * Dc; ++ else ++ Sc = -1 + 2 * Sc + 2 * Dc - 2 * Sc * Dc; ++ ++ return Sc * sa * da; ++} ++static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { ++ int sa = SkGetPackedA32(src); ++ int da = SkGetPackedA32(dst); ++ int a = srcover_byte(sa, da); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, hardlight_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, hardlight_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, hardlight_byte); + return SkPackARGB32(a, r, g, b); + } + + // kOverlay_Mode + static inline int overlay_byte(int sc, int dc, int sa, int da) { +- int tmp = sc * (255 - da) + dc * (255 - sa); +- int rc; +- if (2 * dc <= da) { +- rc = 2 * sc * dc; +- } else { +- rc = sa * da - 2 * (da - dc) * (sa - sc); +- } +- return clamp_div255round(rc + tmp); ++ return hardlight_byte(dc, sc, da, sa); + } + static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { + int sa = SkGetPackedA32(src); + int da = SkGetPackedA32(dst); + int a = srcover_byte(sa, da); +- int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); +- int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); +- int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, overlay_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, overlay_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, overlay_byte); + return SkPackARGB32(a, r, g, b); + } + + // kDarken_Mode + static inline int darken_byte(int sc, int dc, int sa, int da) { +- int sd = sc * da; +- int ds = dc * sa; +- if (sd < ds) { +- // srcover +- return sc + dc - SkDiv255Round(ds); +- } else { +- // dstover +- return dc + sc - SkDiv255Round(sd); +- } ++ return SkMin32(sc * da, sa * dc); + } + static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { + int sa = SkGetPackedA32(src); + int da = SkGetPackedA32(dst); + int a = srcover_byte(sa, da); +- int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); +- int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); +- int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, darken_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, darken_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, darken_byte); + return SkPackARGB32(a, r, g, b); + } + + // kLighten_Mode + static inline int lighten_byte(int sc, int dc, int sa, int da) { +- int sd = sc * da; +- int ds = dc * sa; +- if (sd > ds) { +- // srcover +- return sc + dc - SkDiv255Round(ds); +- } else { +- // dstover +- return dc + sc - SkDiv255Round(sd); +- } ++ return SkMax32(sc * da, sa * dc); + } + static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { + int sa = SkGetPackedA32(src); + int da = SkGetPackedA32(dst); + int a = srcover_byte(sa, da); +- int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); +- int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); +- int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, lighten_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, lighten_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, lighten_byte); + return SkPackARGB32(a, r, g, b); + } + + // kColorDodge_Mode + static inline int colordodge_byte(int sc, int dc, int sa, int da) { +- int diff = sa - sc; +- int rc; +- if (0 == diff) { +- rc = sa * da + sc * (255 - da) + dc * (255 - sa); +- rc = SkDiv255Round(rc); +- } else { +- int tmp = (dc * sa << 15) / (da * diff); +- rc = SkDiv255Round(sa * da) * tmp >> 15; +- // don't clamp here, since we'll do it in our modeproc +- } +- return rc; ++ if (dc == 0) ++ return 0; ++ // Avoid division by 0 ++ if (sc == sa) ++ return da * sa; ++ ++ return SkMin32(sa * da, sa * sa * dc / (sa - sc)); + } + static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { +- // added to avoid div-by-zero in colordodge_byte +- if (0 == dst) { +- return src; +- } +- + int sa = SkGetPackedA32(src); + int da = SkGetPackedA32(dst); + int a = srcover_byte(sa, da); +- int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); +- int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); +- int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); +- r = clamp_max(r, a); +- g = clamp_max(g, a); +- b = clamp_max(b, a); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, colordodge_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, colordodge_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, colordodge_byte); + return SkPackARGB32(a, r, g, b); + } + + // kColorBurn_Mode + static inline int colorburn_byte(int sc, int dc, int sa, int da) { +- int rc; +- if (dc == da && 0 == sc) { +- rc = sa * da + dc * (255 - sa); +- } else if (0 == sc) { +- return SkAlphaMulAlpha(dc, 255 - sa); +- } else { +- int tmp = (sa * (da - dc) * 256) / (sc * da); +- if (tmp > 256) { +- tmp = 256; +- } +- int tmp2 = sa * da; +- rc = tmp2 - (tmp2 * tmp >> 8) + sc * (255 - da) + dc * (255 - sa); +- } +- return SkDiv255Round(rc); ++ // Avoid division by 0 ++ if(dc == da) ++ return sa * da; ++ if(sc == 0) ++ return 0; ++ ++ return sa * da - SkMin32(sa * da, sa * sa * (da - dc) / sc); + } + static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { +- // added to avoid div-by-zero in colorburn_byte +- if (0 == dst) { +- return src; +- } +- + int sa = SkGetPackedA32(src); + int da = SkGetPackedA32(dst); + int a = srcover_byte(sa, da); +- int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); +- int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); +- int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); +- return SkPackARGB32(a, r, g, b); +-} +- +-// kHardLight_Mode +-static inline int hardlight_byte(int sc, int dc, int sa, int da) { +- int rc; +- if (2 * sc <= sa) { +- rc = 2 * sc * dc; +- } else { +- rc = sa * da - 2 * (da - dc) * (sa - sc); +- } +- return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); +-} +-static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { +- int sa = SkGetPackedA32(src); +- int da = SkGetPackedA32(dst); +- int a = srcover_byte(sa, da); +- int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); +- int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); +- int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, colorburn_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, colorburn_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, colorburn_byte); + return SkPackARGB32(a, r, g, b); + } + + // returns 255 * sqrt(n/255) + static U8CPU sqrt_unit_byte(U8CPU n) { + return SkSqrtBits(n, 15+4); + } + + // kSoftLight_Mode + static inline int softlight_byte(int sc, int dc, int sa, int da) { + int m = da ? dc * 256 / da : 0; + int rc; +- if (2 * sc <= sa) { +- rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); +- } else if (4 * dc <= da) { ++ if (2 * sc <= sa) ++ return dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); ++ ++ if (4 * dc <= da) { + int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m; +- rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); +- } else { +- int tmp = sqrt_unit_byte(m) - m; +- rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); ++ return dc * sa + (da * (2 * sc - sa) * tmp >> 8); + } +- return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); ++ int tmp = sqrt_unit_byte(m) - m; ++ return rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); + } + static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { + int sa = SkGetPackedA32(src); + int da = SkGetPackedA32(dst); + int a = srcover_byte(sa, da); +- int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); +- int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); +- int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, softlight_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, softlight_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, softlight_byte); + return SkPackARGB32(a, r, g, b); + } + + // kDifference_Mode + static inline int difference_byte(int sc, int dc, int sa, int da) { +- int tmp = SkMin32(sc * da, dc * sa); +- return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); ++ int tmp = dc * sa - sc * da; ++ if(tmp<0) ++ return - tmp; ++ ++ return tmp; + } + static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { + int sa = SkGetPackedA32(src); + int da = SkGetPackedA32(dst); + int a = srcover_byte(sa, da); +- int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); +- int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); +- int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, difference_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, difference_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, difference_byte); + return SkPackARGB32(a, r, g, b); + } + + // kExclusion_Mode + static inline int exclusion_byte(int sc, int dc, int sa, int da) { +- // this equations is wacky, wait for SVG to confirm it +- int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa); +- return clamp_div255round(r); ++ return sc * da + dc * sa - 2 * dc * sc; + } + static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { + int sa = SkGetPackedA32(src); + int da = SkGetPackedA32(dst); + int a = srcover_byte(sa, da); +- int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); +- int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); +- int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); ++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, exclusion_byte); ++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, exclusion_byte); ++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, exclusion_byte); ++ return SkPackARGB32(a, r, g, b); ++} ++ ++/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++struct BlendColor { ++ float r; ++ float g; ++ float b; ++ ++ BlendColor(): r(0), g(0), b(0) ++ {} ++}; ++ ++static inline float Lum(BlendColor C) ++{ ++ return C.r * 0.3 + C.g * 0.59 + C.b* 0.11; ++} ++ ++static inline float SkMinFloat(float a, float b) ++{ ++ if (a > b) ++ a = b; ++ return a; ++} ++ ++static inline float SkMaxFloat(float a, float b) ++{ ++ if (a < b) ++ a = b; ++ return a; ++} ++ ++#define minimum(C) SkMinFloat(SkMinFloat(C.r, C.g), C.b) ++#define maximum(C) SkMaxFloat(SkMaxFloat(C.r, C.g), C.b) ++ ++static inline float Sat(BlendColor c) { ++ return maximum(c) - minimum(c); ++} ++ ++static inline void setSaturationComponents(float& Cmin, float& Cmid, float& Cmax, float s) { ++ if(Cmax > Cmin) { ++ Cmid = (((Cmid - Cmin) * s ) / (Cmax - Cmin)); ++ Cmax = s; ++ } else { ++ Cmax = 0; ++ Cmid = 0; ++ } ++ Cmin = 0; ++} ++ ++static inline BlendColor SetSat(BlendColor C, float s) { ++ if(C.r <= C.g) { ++ if(C.g <= C.b) ++ setSaturationComponents(C.r, C.g, C.b, s); ++ else ++ if(C.r <= C.b) ++ setSaturationComponents(C.r, C.b, C.g, s); ++ else ++ setSaturationComponents(C.b, C.r, C.g, s); ++ } else if(C.r <= C.b) ++ setSaturationComponents(C.g, C.r, C.b, s); ++ else ++ if(C.g <= C.b) ++ setSaturationComponents(C.g, C.b, C.r, s); ++ else ++ setSaturationComponents(C.b, C.g, C.r, s); ++ ++ return C; ++} ++ ++static inline BlendColor clipColor(BlendColor C) { ++ float L = Lum(C); ++ float n = minimum(C); ++ float x = maximum(C); ++ if(n < 0) { ++ C.r = L + (((C.r - L) * L) / (L - n)); ++ C.g = L + (((C.g - L) * L) / (L - n)); ++ C.b = L + (((C.b - L) * L) / (L - n)); ++ } ++ ++ if(x > 1) { ++ C.r = L + (((C.r - L) * (1 - L)) / (x - L)); ++ C.g = L + (((C.g - L) * (1 - L)) / (x - L)); ++ C.b = L + (((C.b - L) * (1 - L)) / (x - L)); ++ } ++ return C; ++} ++ ++static inline BlendColor SetLum(BlendColor C, float l) { ++ float d = l - Lum(C); ++ C.r += d; ++ C.g += d; ++ C.b += d; ++ ++ return clipColor(C); ++} ++ ++#define blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \ ++ clamp_div255round(sc * (255 - da) + dc * (255 - sa) + (int)(sa * da * blendval)) ++ ++static SkPMColor hue_modeproc(SkPMColor src, SkPMColor dst) { ++ int sr = SkGetPackedR32(src); ++ int sg = SkGetPackedG32(src); ++ int sb = SkGetPackedB32(src); ++ int sa = SkGetPackedA32(src); ++ ++ int dr = SkGetPackedR32(dst); ++ int dg = SkGetPackedG32(dst); ++ int db = SkGetPackedB32(dst); ++ int da = SkGetPackedA32(dst); ++ ++ BlendColor Cs; ++ if(sa) { ++ Cs.r = (float)sr / sa; ++ Cs.g = (float)sg / sa; ++ Cs.b = (float)sb / sa; ++ BlendColor Cd; ++ if(da) { ++ Cd.r = (float)dr / da; ++ Cd.g = (float)dg / da; ++ Cd.b = (float)db / da; ++ Cs = SetLum(SetSat(Cs, Sat(Cd)), Lum(Cd)); ++ } ++ } ++ ++ int a = srcover_byte(sa, da); ++ int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r); ++ int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g); ++ int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b); ++ return SkPackARGB32(a, r, g, b); ++} ++ ++static SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) { ++ int sr = SkGetPackedR32(src); ++ int sg = SkGetPackedG32(src); ++ int sb = SkGetPackedB32(src); ++ int sa = SkGetPackedA32(src); ++ ++ int dr = SkGetPackedR32(dst); ++ int dg = SkGetPackedG32(dst); ++ int db = SkGetPackedB32(dst); ++ int da = SkGetPackedA32(dst); ++ ++ BlendColor Cs; ++ if(sa) { ++ Cs.r = (float)sr / sa; ++ Cs.g = (float)sg / sa; ++ Cs.b = (float)sb / sa; ++ BlendColor Cd; ++ if(da) { ++ Cd.r = (float)dr / da; ++ Cd.g = (float)dg / da; ++ Cd.b = (float)db / da; ++ Cs = SetLum(SetSat(Cd, Sat(Cs)), Lum(Cd)); ++ } ++ } ++ ++ int a = srcover_byte(sa, da); ++ int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r); ++ int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g); ++ int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b); ++ return SkPackARGB32(a, r, g, b); ++} ++ ++static SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) { ++ int sr = SkGetPackedR32(src); ++ int sg = SkGetPackedG32(src); ++ int sb = SkGetPackedB32(src); ++ int sa = SkGetPackedA32(src); ++ ++ int dr = SkGetPackedR32(dst); ++ int dg = SkGetPackedG32(dst); ++ int db = SkGetPackedB32(dst); ++ int da = SkGetPackedA32(dst); ++ ++ BlendColor Cs; ++ if(sa) { ++ Cs.r = (float)sr / sa; ++ Cs.g = (float)sg / sa; ++ Cs.b = (float)sb / sa; ++ BlendColor Cd; ++ if(da) { ++ Cd.r = (float)dr / da; ++ Cd.g = (float)dg / da; ++ Cd.b = (float)db / da; ++ Cs = SetLum(Cs, Lum(Cd)); ++ } ++ } ++ ++ int a = srcover_byte(sa, da); ++ int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r); ++ int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g); ++ int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b); ++ return SkPackARGB32(a, r, g, b); ++} ++ ++static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) { ++ int sr = SkGetPackedR32(src); ++ int sg = SkGetPackedG32(src); ++ int sb = SkGetPackedB32(src); ++ int sa = SkGetPackedA32(src); ++ ++ int dr = SkGetPackedR32(dst); ++ int dg = SkGetPackedG32(dst); ++ int db = SkGetPackedB32(dst); ++ int da = SkGetPackedA32(dst); ++ ++ BlendColor Cs; ++ if(sa) { ++ Cs.r = (float)sr / sa; ++ Cs.g = (float)sg / sa; ++ Cs.b = (float)sb / sa; ++ BlendColor Cd; ++ if(da) { ++ Cd.r = (float)dr / da; ++ Cd.g = (float)dg / da; ++ Cd.b = (float)db / da; ++ Cs = SetLum(Cd, Lum(Cs)); ++ } ++ } ++ ++ int a = srcover_byte(sa, da); ++ int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r); ++ int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g); ++ int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b); + return SkPackARGB32(a, r, g, b); + } + + struct ProcCoeff { + SkXfermodeProc fProc; + SkXfermode::Coeff fSC; + SkXfermode::Coeff fDC; + }; +@@ -430,27 +627,31 @@ static const ProcCoeff gProcCoeffs[] = { + { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, + { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, + { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, + { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, + { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, + { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, + + { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, +- { multiply_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, ++ { multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF}, + { screen_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, ++ { hue_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, ++ { saturation_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, ++ { color_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, ++ { luminosity_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + }; + + /////////////////////////////////////////////////////////////////////////////// + + bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) { + return false; + } + +@@ -1172,16 +1373,20 @@ static const Proc16Rec gModeProcs16[] = + { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken + { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten + { NULL, NULL, NULL }, // colordodge + { NULL, NULL, NULL }, // colorburn + { NULL, NULL, NULL }, // hardlight + { NULL, NULL, NULL }, // softlight + { NULL, NULL, NULL }, // difference + { NULL, NULL, NULL }, // exclusion ++ { NULL, NULL, NULL }, // hue ++ { NULL, NULL, NULL }, // saturation ++ { NULL, NULL, NULL }, // color ++ { NULL, NULL, NULL }, // luminosity + }; + + SkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) { + SkXfermodeProc16 proc16 = NULL; + if ((unsigned)mode < kModeCount) { + const Proc16Rec& rec = gModeProcs16[mode]; + unsigned a = SkColorGetA(srcColor); + diff --git a/gfx/skia/patches/archive/0010-Bug-848491-Re-apply-bug-817356-Patch-Skia-to-recogni.patch b/gfx/skia/patches/archive/0010-Bug-848491-Re-apply-bug-817356-Patch-Skia-to-recogni.patch new file mode 100644 index 0000000000..0d44b008d6 --- /dev/null +++ b/gfx/skia/patches/archive/0010-Bug-848491-Re-apply-bug-817356-Patch-Skia-to-recogni.patch @@ -0,0 +1,22 @@ +From: George Wright <gw@gwright.org.uk> +Date: Thu, 25 Apr 2013 20:55:02 -0400 +Subject: Bug 848491 - Re-apply bug 817356 - Patch Skia to recognize uppercase PPC/PPC64. + + +diff --git a/gfx/skia/include/core/SkPreConfig.h b/gfx/skia/include/core/SkPreConfig.h +index 11cb223..7e95b99 100644 +--- a/gfx/skia/include/core/SkPreConfig.h ++++ b/gfx/skia/include/core/SkPreConfig.h +@@ -99,7 +99,8 @@ + ////////////////////////////////////////////////////////////////////// + + #if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN) +- #if defined (__ppc__) || defined(__ppc64__) ++ #if defined (__ppc__) || defined(__PPC__) || defined(__ppc64__) \ ++ || defined(__PPC64__) + #define SK_CPU_BENDIAN + #else + #define SK_CPU_LENDIAN +-- +1.7.11.7 + diff --git a/gfx/skia/patches/archive/0011-Bug-719575-Fix-clang-build.patch b/gfx/skia/patches/archive/0011-Bug-719575-Fix-clang-build.patch new file mode 100644 index 0000000000..95cb08a36f --- /dev/null +++ b/gfx/skia/patches/archive/0011-Bug-719575-Fix-clang-build.patch @@ -0,0 +1,28 @@ +From cf855f31194ff071f2c787a7413d70a43f15f204 Mon Sep 17 00:00:00 2001 +From: Ehsan Akhgari <ehsan@mozilla.com> +Date: Tue, 29 May 2012 15:39:55 -0400 +Subject: [PATCH] Bug 755869 - Re-apply patch from bug 719575 to fix clang + builds for the new Skia r=gw280 + +--- + gfx/skia/src/ports/SkFontHost_mac_coretext.cpp | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp +index c43d1a6..ce5f409 100644 +--- a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp ++++ b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp +@@ -807,8 +807,8 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph& + void SkScalerContext_Mac::getVerticalOffset(CGGlyph glyphID, SkIPoint* offset) const { + CGSize vertOffset; + CTFontGetVerticalTranslationsForGlyphs(fCTVerticalFont, &glyphID, &vertOffset, 1); +- const SkPoint trans = {SkFloatToScalar(vertOffset.width), +- SkFloatToScalar(vertOffset.height)}; ++ const SkPoint trans = {SkScalar(SkFloatToScalar(vertOffset.width)), ++ SkScalar(SkFloatToScalar(vertOffset.height))}; + SkPoint floatOffset; + fVerticalMatrix.mapPoints(&floatOffset, &trans, 1); + if (!isSnowLeopard()) { +-- +1.7.5.4 + diff --git a/gfx/skia/patches/archive/0011-Bug-839347-no-anon-namespace-around-SkNO_RETURN_HINT.patch b/gfx/skia/patches/archive/0011-Bug-839347-no-anon-namespace-around-SkNO_RETURN_HINT.patch new file mode 100644 index 0000000000..854f0b1afe --- /dev/null +++ b/gfx/skia/patches/archive/0011-Bug-839347-no-anon-namespace-around-SkNO_RETURN_HINT.patch @@ -0,0 +1,31 @@ +# HG changeset patch +# Parent 2c6da9f02606f7a02f635d99ef8cf669d3bc5c4b +# User Daniel Holbert <dholbert@cs.stanford.edu> +Bug 839347: Move SkNO_RETURN_HINT out of anonymous namespace so that clang won't warn about it being unused. r=mattwoodrow + +diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h +--- a/gfx/skia/include/core/SkPostConfig.h ++++ b/gfx/skia/include/core/SkPostConfig.h +@@ -63,20 +63,18 @@ + * The clang static analyzer likes to know that when the program is not + * expected to continue (crash, assertion failure, etc). It will notice that + * some combination of parameters lead to a function call that does not return. + * It can then make appropriate assumptions about the parameters in code + * executed only if the non-returning function was *not* called. + */ + #if !defined(SkNO_RETURN_HINT) + #if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn) +- namespace { +- inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn)); +- inline void SkNO_RETURN_HINT() {} +- } ++ inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn)); ++ inline 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) diff --git a/gfx/skia/patches/archive/0012-Bug-751418-Add-our-own-GrUserConfig-r-mattwoodrow.patch b/gfx/skia/patches/archive/0012-Bug-751418-Add-our-own-GrUserConfig-r-mattwoodrow.patch new file mode 100644 index 0000000000..cde2940950 --- /dev/null +++ b/gfx/skia/patches/archive/0012-Bug-751418-Add-our-own-GrUserConfig-r-mattwoodrow.patch @@ -0,0 +1,29 @@ +From 4c25387e6e6cdb55f19e51631a78c3fa9b4a3c73 Mon Sep 17 00:00:00 2001 +From: George Wright <gw@gwright.org.uk> +Date: Thu, 1 Nov 2012 17:29:50 -0400 +Subject: [PATCH 2/8] Bug 751418 - Add our own GrUserConfig r=mattwoodrow + +--- + gfx/skia/include/gpu/GrUserConfig.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/gfx/skia/include/gpu/GrUserConfig.h b/gfx/skia/include/gpu/GrUserConfig.h +index d514486..b729ab3 100644 +--- a/gfx/skia/include/gpu/GrUserConfig.h ++++ b/gfx/skia/include/gpu/GrUserConfig.h +@@ -64,6 +64,12 @@ + #define GR_TEXT_SCALAR_IS_FIXED 0 + #define GR_TEXT_SCALAR_IS_FLOAT 1 + ++/* ++ * This allows us to set a callback to be called before each GL call to ensure ++ * that our context is set correctly ++ */ ++#define GR_GL_PER_GL_FUNC_CALLBACK 1 ++ + #endif + + +-- +1.7.11.7 + diff --git a/gfx/skia/patches/archive/0012-Bug-759683-make-ssse3-conditional.patch b/gfx/skia/patches/archive/0012-Bug-759683-make-ssse3-conditional.patch new file mode 100644 index 0000000000..dc780c5ec6 --- /dev/null +++ b/gfx/skia/patches/archive/0012-Bug-759683-make-ssse3-conditional.patch @@ -0,0 +1,22 @@ +diff --git a/gfx/skia/src/opts/opts_check_SSE2.cpp b/gfx/skia/src/opts/opts_check_SSE2.cpp +--- a/gfx/skia/src/opts/opts_check_SSE2.cpp ++++ b/gfx/skia/src/opts/opts_check_SSE2.cpp +@@ -91,17 +91,17 @@ static bool cachedHasSSE2() { + + static bool cachedHasSSSE3() { + static bool gHasSSSE3 = hasSSSE3(); + return gHasSSSE3; + } + + void SkBitmapProcState::platformProcs() { + if (cachedHasSSSE3()) { +-#if !defined(SK_BUILD_FOR_ANDROID) ++#if defined(SK_BUILD_SSSE3) + // Disable SSSE3 optimization for Android x86 + if (fSampleProc32 == S32_opaque_D32_filter_DX) { + fSampleProc32 = S32_opaque_D32_filter_DX_SSSE3; + } else if (fSampleProc32 == S32_alpha_D32_filter_DX) { + fSampleProc32 = S32_alpha_D32_filter_DX_SSSE3; + } + + if (fSampleProc32 == S32_opaque_D32_filter_DXDY) { diff --git a/gfx/skia/patches/archive/0013-Bug-751418-Fix-compile-error-on-gcc-in-Skia-GL-r-mat.patch b/gfx/skia/patches/archive/0013-Bug-751418-Fix-compile-error-on-gcc-in-Skia-GL-r-mat.patch new file mode 100644 index 0000000000..167e22184d --- /dev/null +++ b/gfx/skia/patches/archive/0013-Bug-751418-Fix-compile-error-on-gcc-in-Skia-GL-r-mat.patch @@ -0,0 +1,26 @@ +From 3d786b1f0c040205ad9ef6d4216ce06b41f7359f Mon Sep 17 00:00:00 2001 +From: George Wright <gw@gwright.org.uk> +Date: Mon, 5 Nov 2012 15:49:42 +0000 +Subject: [PATCH 3/8] Bug 751418 - Fix compile error on gcc in Skia/GL + r=mattwoodrow + +--- + gfx/skia/src/gpu/gl/GrGLProgram.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gfx/skia/src/gpu/gl/GrGLProgram.cpp b/gfx/skia/src/gpu/gl/GrGLProgram.cpp +index 2703110..40cadc3 100644 +--- a/gfx/skia/src/gpu/gl/GrGLProgram.cpp ++++ b/gfx/skia/src/gpu/gl/GrGLProgram.cpp +@@ -575,7 +575,7 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) { + POS_ATTR_NAME); + + builder.fVSCode.appendf("void main() {\n" +- "\tvec3 pos3 = %s * vec3("POS_ATTR_NAME", 1);\n" ++ "\tvec3 pos3 = %s * vec3(" POS_ATTR_NAME ", 1);\n" + "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", + viewMName); + +-- +1.7.11.7 + diff --git a/gfx/skia/patches/archive/0013-Bug-761890-fonts.patch b/gfx/skia/patches/archive/0013-Bug-761890-fonts.patch new file mode 100644 index 0000000000..f20293d4cc --- /dev/null +++ b/gfx/skia/patches/archive/0013-Bug-761890-fonts.patch @@ -0,0 +1,162 @@ +# HG changeset patch +# User Nicholas Cameron <ncameron@mozilla.com> +# Date 1337146927 -43200 +# Node ID 310209abef2c2667e5de41dd2a1f071e8cd42821 +# Parent 93f3ca4d5707b2aae9c6ae52d5d29c2c802e7ef8 +Bug 746883; changes to the Skia library. r=gw280 + +diff --git a/gfx/skia/include/core/SkDraw.h b/gfx/skia/include/core/SkDraw.h +--- a/gfx/skia/include/core/SkDraw.h ++++ b/gfx/skia/include/core/SkDraw.h +@@ -125,23 +125,24 @@ public: + #endif + }; + + class SkGlyphCache; + + class SkTextToPathIter { + public: + SkTextToPathIter(const char text[], size_t length, const SkPaint& paint, +- bool applyStrokeAndPathEffects); ++ bool applyStrokeAndPathEffects, bool useCanonicalTextSize = true); + ~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 ++ bool nextWithWhitespace(const SkPath** path, SkScalar* xpos); //!< returns false when there are no more paths + + private: + SkGlyphCache* fCache; + SkPaint fPaint; + SkScalar fScale; + SkFixed fPrevAdvance; + const char* fText; + const char* fStop; +diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp +--- a/gfx/skia/src/core/SkPaint.cpp ++++ b/gfx/skia/src/core/SkPaint.cpp +@@ -1359,30 +1359,32 @@ void SkPaint::getPosTextPath(const void* + const SkPoint pos[], SkPath* path) const { + SkASSERT(length == 0 || textData != NULL); + + const char* text = (const char*)textData; + if (text == NULL || length == 0 || path == NULL) { + return; + } + +- SkTextToPathIter iter(text, length, *this, false); ++ SkTextToPathIter iter(text, length, *this, false, false); + SkMatrix matrix; + SkPoint prevPos; + prevPos.set(0, 0); + + matrix.setScale(iter.getPathScale(), iter.getPathScale()); + path->reset(); + + unsigned int i = 0; + const SkPath* iterPath; +- while ((iterPath = iter.next(NULL)) != NULL) { +- matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); +- path->addPath(*iterPath, matrix); +- prevPos = pos[i]; ++ while (iter.nextWithWhitespace(&iterPath, NULL)) { ++ if (iterPath) { ++ matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); ++ path->addPath(*iterPath, matrix); ++ prevPos = pos[i]; ++ } + i++; + } + } + + static void add_flattenable(SkDescriptor* desc, uint32_t tag, + SkFlattenableWriteBuffer* buffer) { + buffer->flatten(desc->addEntry(tag, buffer->size(), NULL)); + } +@@ -2118,30 +2120,31 @@ const SkRect& SkPaint::doComputeFastBoun + + static bool has_thick_frame(const SkPaint& paint) { + return paint.getStrokeWidth() > 0 && + paint.getStyle() != SkPaint::kFill_Style; + } + + SkTextToPathIter::SkTextToPathIter( const char text[], size_t length, + const SkPaint& paint, +- bool applyStrokeAndPathEffects) ++ bool applyStrokeAndPathEffects, ++ bool useCanonicalTextSize) + : fPaint(paint) { + fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection, + true); + + fPaint.setLinearText(true); + fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup + + if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) { + applyStrokeAndPathEffects = false; + } + + // can't use our canonical size if we need to apply patheffects +- if (fPaint.getPathEffect() == NULL) { ++ if (useCanonicalTextSize && fPaint.getPathEffect() == NULL) { + fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); + fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; + if (has_thick_frame(fPaint)) { + fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale)); + } + } else { + fScale = SK_Scalar1; + } +@@ -2185,30 +2188,47 @@ SkTextToPathIter::SkTextToPathIter( cons + fXYIndex = paint.isVerticalText() ? 1 : 0; + } + + SkTextToPathIter::~SkTextToPathIter() { + SkGlyphCache::AttachCache(fCache); + } + + const SkPath* SkTextToPathIter::next(SkScalar* xpos) { +- while (fText < fStop) { ++ const SkPath* result; ++ while (nextWithWhitespace(&result, xpos)) { ++ if (result) { ++ if (xpos) { ++ *xpos = fXPos; ++ } ++ return result; ++ } ++ } ++ return NULL; ++} ++ ++bool SkTextToPathIter::nextWithWhitespace(const SkPath** path, SkScalar* xpos) { ++ if (fText < fStop) { + const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); + + fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale); + fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); + + if (glyph.fWidth) { + if (xpos) { + *xpos = fXPos; + } +- return fCache->findPath(glyph); ++ *path = fCache->findPath(glyph); ++ return true; ++ } else { ++ *path = NULL; ++ return true; + } + } +- return NULL; ++ return false; + } + + /////////////////////////////////////////////////////////////////////////////// + + bool SkPaint::nothingToDraw() const { + if (fLooper) { + return false; + } diff --git a/gfx/skia/patches/archive/0014-Bug-765038-Fix-clang-build.patch b/gfx/skia/patches/archive/0014-Bug-765038-Fix-clang-build.patch new file mode 100644 index 0000000000..6cc74914d2 --- /dev/null +++ b/gfx/skia/patches/archive/0014-Bug-765038-Fix-clang-build.patch @@ -0,0 +1,29 @@ +# HG changeset patch +# Parent 9ded7a9f94a863dfa1f3227d3013367f51b8b522 +# User Nicholas Cameron <ncameron@mozilla.com> +Bug 765038; fix a Clang compilation bug in Skia; r=jwatt + +diff --git a/gfx/skia/src/sfnt/SkOTTable_head.h b/gfx/skia/src/sfnt/SkOTTable_head.h +--- a/gfx/skia/src/sfnt/SkOTTable_head.h ++++ b/gfx/skia/src/sfnt/SkOTTable_head.h +@@ -109,18 +109,18 @@ struct SkOTTableHead { + } raw; + } macStyle; + SK_OT_USHORT lowestRecPPEM; + struct FontDirectionHint { + SK_TYPED_ENUM(Value, SK_OT_SHORT, + ((FullyMixedDirectionalGlyphs, SkTEndian_SwapBE16(0))) + ((OnlyStronglyLTR, SkTEndian_SwapBE16(1))) + ((StronglyLTR, SkTEndian_SwapBE16(2))) +- ((OnlyStronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(-1)))) +- ((StronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(-2)))) ++ ((OnlyStronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(static_cast<SK_OT_USHORT>(-1))))) ++ ((StronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(static_cast<SK_OT_USHORT>(-2))))) + SK_SEQ_END, + (value)SK_SEQ_END) + } fontDirectionHint; + struct IndexToLocFormat { + SK_TYPED_ENUM(Value, SK_OT_SHORT, + ((ShortOffsets, SkTEndian_SwapBE16(0))) + ((LongOffsets, SkTEndian_SwapBE16(1))) + SK_SEQ_END, diff --git a/gfx/skia/patches/archive/0015-Bug-766017-warnings.patch b/gfx/skia/patches/archive/0015-Bug-766017-warnings.patch new file mode 100644 index 0000000000..174dcb9bce --- /dev/null +++ b/gfx/skia/patches/archive/0015-Bug-766017-warnings.patch @@ -0,0 +1,865 @@ +From: David Zbarsky <dzbarsky@gmail.com> +Bug 766017 - Fix some skia warnings r=gw280 + +diff --git a/gfx/skia/include/utils/mac/SkCGUtils.h b/gfx/skia/include/utils/mac/SkCGUtils.h +--- a/gfx/skia/include/utils/mac/SkCGUtils.h ++++ b/gfx/skia/include/utils/mac/SkCGUtils.h +@@ -39,18 +39,16 @@ static inline CGImageRef SkCreateCGImage + /** + * Draw the bitmap into the specified CG context. The bitmap will be converted + * to a CGImage using the generic RGB colorspace. (x,y) specifies the position + * of the top-left corner of the bitmap. The bitmap is converted using the + * colorspace returned by CGColorSpaceCreateDeviceRGB() + */ + void SkCGDrawBitmap(CGContextRef, const SkBitmap&, float x, float y); + +-bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output); +- + /** + * Return a provider that wraps the specified stream. It will become an + * owner of the stream, so the caller must still manage its ownership. + * + * To hand-off ownership of the stream to the provider, the caller must do + * something like the following: + * + * SkStream* stream = new ...; +diff --git a/gfx/skia/src/core/SkAAClip.cpp b/gfx/skia/src/core/SkAAClip.cpp +--- a/gfx/skia/src/core/SkAAClip.cpp ++++ b/gfx/skia/src/core/SkAAClip.cpp +@@ -246,17 +246,17 @@ static void count_left_right_zeros(const + zeros = 0; + } + row += 2; + width -= n; + } + *riteZ = zeros; + } + +-#ifdef SK_DEBUG ++#if 0 + static void test_count_left_right_zeros() { + static bool gOnce; + if (gOnce) { + return; + } + gOnce = true; + + const uint8_t data0[] = { 0, 0, 10, 0xFF }; +@@ -1319,22 +1319,16 @@ bool SkAAClip::setPath(const SkPath& pat + } + + /////////////////////////////////////////////////////////////////////////////// + + typedef void (*RowProc)(SkAAClip::Builder&, int bottom, + const uint8_t* rowA, const SkIRect& rectA, + const uint8_t* rowB, const SkIRect& rectB); + +-static void sectRowProc(SkAAClip::Builder& builder, int bottom, +- const uint8_t* rowA, const SkIRect& rectA, +- const uint8_t* rowB, const SkIRect& rectB) { +- +-} +- + typedef U8CPU (*AlphaProc)(U8CPU alphaA, U8CPU alphaB); + + static U8CPU sectAlphaProc(U8CPU alphaA, U8CPU alphaB) { + // Multiply + return SkMulDiv255Round(alphaA, alphaB); + } + + static U8CPU unionAlphaProc(U8CPU alphaA, U8CPU alphaB) { +@@ -1429,31 +1423,16 @@ private: + static void adjust_row(RowIter& iter, int& leftA, int& riteA, int rite) { + if (rite == riteA) { + iter.next(); + leftA = iter.left(); + riteA = iter.right(); + } + } + +-static bool intersect(int& min, int& max, int boundsMin, int boundsMax) { +- SkASSERT(min < max); +- SkASSERT(boundsMin < boundsMax); +- if (min >= boundsMax || max <= boundsMin) { +- return false; +- } +- if (min < boundsMin) { +- min = boundsMin; +- } +- if (max > boundsMax) { +- max = boundsMax; +- } +- return true; +-} +- + static void operatorX(SkAAClip::Builder& builder, int lastY, + RowIter& iterA, RowIter& iterB, + AlphaProc proc, const SkIRect& bounds) { + int leftA = iterA.left(); + int riteA = iterA.right(); + int leftB = iterB.left(); + int riteB = iterB.right(); + +@@ -1970,34 +1949,33 @@ static void small_bzero(void* dst, size_ + static inline uint8_t mergeOne(uint8_t value, unsigned alpha) { + return SkMulDiv255Round(value, alpha); + } + static inline uint16_t mergeOne(uint16_t value, unsigned alpha) { + unsigned r = SkGetPackedR16(value); + unsigned g = SkGetPackedG16(value); + unsigned b = SkGetPackedB16(value); + return SkPackRGB16(SkMulDiv255Round(r, alpha), +- SkMulDiv255Round(r, alpha), +- SkMulDiv255Round(r, alpha)); ++ SkMulDiv255Round(g, alpha), ++ SkMulDiv255Round(b, alpha)); + } + static inline SkPMColor mergeOne(SkPMColor value, unsigned alpha) { + unsigned a = SkGetPackedA32(value); + unsigned r = SkGetPackedR32(value); + unsigned g = SkGetPackedG32(value); + unsigned b = SkGetPackedB32(value); + return SkPackARGB32(SkMulDiv255Round(a, alpha), + SkMulDiv255Round(r, alpha), + SkMulDiv255Round(g, alpha), + SkMulDiv255Round(b, alpha)); + } + + template <typename T> void mergeT(const T* SK_RESTRICT src, int srcN, + const uint8_t* SK_RESTRICT row, int rowN, + T* SK_RESTRICT dst) { +- SkDEBUGCODE(int accumulated = 0;) + for (;;) { + SkASSERT(rowN > 0); + SkASSERT(srcN > 0); + + int n = SkMin32(rowN, srcN); + unsigned rowA = row[1]; + if (0xFF == rowA) { + small_memcpy(dst, src, n * sizeof(T)); +diff --git a/gfx/skia/src/core/SkBlitMask_D32.cpp b/gfx/skia/src/core/SkBlitMask_D32.cpp +--- a/gfx/skia/src/core/SkBlitMask_D32.cpp ++++ b/gfx/skia/src/core/SkBlitMask_D32.cpp +@@ -268,107 +268,49 @@ bool SkBlitMask::BlitColor(const SkBitma + return true; + } + return false; + } + + /////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// + +-static void BW_RowProc_Blend(SkPMColor* SK_RESTRICT dst, +- const uint8_t* SK_RESTRICT mask, +- const SkPMColor* SK_RESTRICT src, int count) { +- int i, octuple = (count + 7) >> 3; +- for (i = 0; i < octuple; ++i) { +- int m = *mask++; +- if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); } +- if (m & 0x40) { dst[1] = SkPMSrcOver(src[1], dst[1]); } +- if (m & 0x20) { dst[2] = SkPMSrcOver(src[2], dst[2]); } +- if (m & 0x10) { dst[3] = SkPMSrcOver(src[3], dst[3]); } +- if (m & 0x08) { dst[4] = SkPMSrcOver(src[4], dst[4]); } +- if (m & 0x04) { dst[5] = SkPMSrcOver(src[5], dst[5]); } +- if (m & 0x02) { dst[6] = SkPMSrcOver(src[6], dst[6]); } +- if (m & 0x01) { dst[7] = SkPMSrcOver(src[7], dst[7]); } +- src += 8; +- dst += 8; +- } +- count &= 7; +- if (count > 0) { +- int m = *mask; +- do { +- if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); } +- m <<= 1; +- src += 1; +- dst += 1; +- } while (--count > 0); +- } +-} +- +-static void BW_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, +- const uint8_t* SK_RESTRICT mask, +- const SkPMColor* SK_RESTRICT src, int count) { +- int i, octuple = (count + 7) >> 3; +- for (i = 0; i < octuple; ++i) { +- int m = *mask++; +- if (m & 0x80) { dst[0] = src[0]; } +- if (m & 0x40) { dst[1] = src[1]; } +- if (m & 0x20) { dst[2] = src[2]; } +- if (m & 0x10) { dst[3] = src[3]; } +- if (m & 0x08) { dst[4] = src[4]; } +- if (m & 0x04) { dst[5] = src[5]; } +- if (m & 0x02) { dst[6] = src[6]; } +- if (m & 0x01) { dst[7] = src[7]; } +- src += 8; +- dst += 8; +- } +- count &= 7; +- if (count > 0) { +- int m = *mask; +- do { +- if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); } +- m <<= 1; +- src += 1; +- dst += 1; +- } while (--count > 0); +- } +-} +- + static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst, + const uint8_t* SK_RESTRICT mask, + const SkPMColor* SK_RESTRICT src, int count) { + for (int i = 0; i < count; ++i) { + if (mask[i]) { + dst[i] = SkBlendARGB32(src[i], dst[i], mask[i]); + } + } + } + + // expand the steps that SkAlphaMulQ performs, but this way we can +-// exand.. add.. combine ++// expand.. add.. combine + // instead of + // expand..combine add expand..combine + // + #define EXPAND0(v, m, s) ((v) & (m)) * (s) + #define EXPAND1(v, m, s) (((v) >> 8) & (m)) * (s) + #define COMBINE(e0, e1, m) ((((e0) >> 8) & (m)) | ((e1) & ~(m))) + + static void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, + const uint8_t* SK_RESTRICT mask, + const SkPMColor* SK_RESTRICT src, int count) { +- const uint32_t rbmask = gMask_00FF00FF; + for (int i = 0; i < count; ++i) { + int m = mask[i]; + if (m) { + m += (m >> 7); + #if 1 + // this is slightly slower than the expand/combine version, but it + // is much closer to the old results, so we use it for now to reduce + // rebaselining. + dst[i] = SkAlphaMulQ(src[i], m) + SkAlphaMulQ(dst[i], 256 - m); + #else ++ const uint32_t rbmask = gMask_00FF00FF; + uint32_t v = src[i]; + uint32_t s0 = EXPAND0(v, rbmask, m); + uint32_t s1 = EXPAND1(v, rbmask, m); + v = dst[i]; + uint32_t d0 = EXPAND0(v, rbmask, m); + uint32_t d1 = EXPAND1(v, rbmask, m); + dst[i] = COMBINE(s0 + d0, s1 + d1, rbmask); + #endif +@@ -559,17 +501,17 @@ SkBlitMask::RowProc SkBlitMask::RowFacto + // make this opt-in until chrome can rebaseline + RowProc proc = PlatformRowProcs(config, format, flags); + if (proc) { + return proc; + } + + static const RowProc gProcs[] = { + // need X coordinate to handle BW +- NULL, NULL, //(RowProc)BW_RowProc_Blend, (RowProc)BW_RowProc_Opaque, ++ NULL, NULL, + (RowProc)A8_RowProc_Blend, (RowProc)A8_RowProc_Opaque, + (RowProc)LCD16_RowProc_Blend, (RowProc)LCD16_RowProc_Opaque, + (RowProc)LCD32_RowProc_Blend, (RowProc)LCD32_RowProc_Opaque, + }; + + int index; + switch (config) { + case SkBitmap::kARGB_8888_Config: +diff --git a/gfx/skia/src/core/SkConcaveToTriangles.cpp b/gfx/skia/src/core/SkConcaveToTriangles.cpp +--- a/gfx/skia/src/core/SkConcaveToTriangles.cpp ++++ b/gfx/skia/src/core/SkConcaveToTriangles.cpp +@@ -37,17 +37,16 @@ + #include "SkTDArray.h" + #include "SkGeometry.h" + #include "SkTSort.h" + + // This is used to prevent runaway code bugs, and can probably be removed after + // the code has been proven robust. + #define kMaxCount 1000 + +-#define DEBUG + #ifdef DEBUG + //------------------------------------------------------------------------------ + // Debugging support + //------------------------------------------------------------------------------ + + #include <cstdio> + #include <stdarg.h> + +diff --git a/gfx/skia/src/core/SkPath.cpp b/gfx/skia/src/core/SkPath.cpp +--- a/gfx/skia/src/core/SkPath.cpp ++++ b/gfx/skia/src/core/SkPath.cpp +@@ -469,17 +469,16 @@ void SkPath::incReserve(U16CPU inc) { + fPts.setReserve(fPts.count() + inc); + + SkDEBUGCODE(this->validate();) + } + + void SkPath::moveTo(SkScalar x, SkScalar y) { + SkDEBUGCODE(this->validate();) + +- int vc = fVerbs.count(); + SkPoint* pt; + + // remember our index + fLastMoveToIndex = fPts.count(); + + pt = fPts.append(); + *fVerbs.append() = kMove_Verb; + pt->set(x, y); +@@ -1163,17 +1162,16 @@ void SkPath::reversePathTo(const SkPath& + } + pts -= gPtsInVerb[verbs[i]]; + } + } + + void SkPath::reverseAddPath(const SkPath& src) { + this->incReserve(src.fPts.count()); + +- const SkPoint* startPts = src.fPts.begin(); + const SkPoint* pts = src.fPts.end(); + const uint8_t* startVerbs = src.fVerbs.begin(); + const uint8_t* verbs = src.fVerbs.end(); + + fIsOval = false; + + bool needMove = true; + bool needClose = false; +diff --git a/gfx/skia/src/core/SkRegion.cpp b/gfx/skia/src/core/SkRegion.cpp +--- a/gfx/skia/src/core/SkRegion.cpp ++++ b/gfx/skia/src/core/SkRegion.cpp +@@ -920,20 +920,16 @@ static int operate(const SkRegion::RunTy + /* Given count RunTypes in a complex region, return the worst case number of + logical intervals that represents (i.e. number of rects that would be + returned from the iterator). + + We could just return count/2, since there must be at least 2 values per + interval, but we can first trim off the const overhead of the initial TOP + value, plus the final BOTTOM + 2 sentinels. + */ +-static int count_to_intervals(int count) { +- SkASSERT(count >= 6); // a single rect is 6 values +- return (count - 4) >> 1; +-} + + /* Given a number of intervals, what is the worst case representation of that + many intervals? + + Worst case (from a storage perspective), is a vertical stack of single + intervals: TOP + N * (BOTTOM INTERVALCOUNT LEFT RIGHT SENTINEL) + SENTINEL + */ + static int intervals_to_count(int intervals) { +diff --git a/gfx/skia/src/core/SkScalerContext.cpp b/gfx/skia/src/core/SkScalerContext.cpp +--- a/gfx/skia/src/core/SkScalerContext.cpp ++++ b/gfx/skia/src/core/SkScalerContext.cpp +@@ -336,44 +336,16 @@ SK_ERROR: + glyph->fTop = 0; + glyph->fWidth = 0; + glyph->fHeight = 0; + // put a valid value here, in case it was earlier set to + // MASK_FORMAT_JUST_ADVANCE + glyph->fMaskFormat = fRec.fMaskFormat; + } + +-static bool isLCD(const SkScalerContext::Rec& rec) { +- return SkMask::kLCD16_Format == rec.fMaskFormat || +- SkMask::kLCD32_Format == rec.fMaskFormat; +-} +- +-static uint16_t a8_to_rgb565(unsigned a8) { +- return SkPackRGB16(a8 >> 3, a8 >> 2, a8 >> 3); +-} +- +-static void copyToLCD16(const SkBitmap& src, const SkMask& dst) { +- SkASSERT(SkBitmap::kA8_Config == src.config()); +- SkASSERT(SkMask::kLCD16_Format == dst.fFormat); +- +- const int width = dst.fBounds.width(); +- const int height = dst.fBounds.height(); +- const uint8_t* srcP = src.getAddr8(0, 0); +- size_t srcRB = src.rowBytes(); +- uint16_t* dstP = (uint16_t*)dst.fImage; +- size_t dstRB = dst.fRowBytes; +- for (int y = 0; y < height; ++y) { +- for (int x = 0; x < width; ++x) { +- dstP[x] = a8_to_rgb565(srcP[x]); +- } +- srcP += srcRB; +- dstP = (uint16_t*)((char*)dstP + dstRB); +- } +-} +- + #define SK_FREETYPE_LCD_LERP 160 + + static int lerp(int start, int end) { + SkASSERT((unsigned)SK_FREETYPE_LCD_LERP <= 256); + return start + ((end - start) * (SK_FREETYPE_LCD_LERP) >> 8); + } + + static uint16_t packLCD16(unsigned r, unsigned g, unsigned b) { +diff --git a/gfx/skia/src/core/SkScan_AntiPath.cpp b/gfx/skia/src/core/SkScan_AntiPath.cpp +--- a/gfx/skia/src/core/SkScan_AntiPath.cpp ++++ b/gfx/skia/src/core/SkScan_AntiPath.cpp +@@ -230,52 +230,16 @@ void SuperBlitter::blitH(int x, int y, i + fOffsetX); + + #ifdef SK_DEBUG + fRuns.assertValid(y & MASK, (1 << (8 - SHIFT))); + fCurrX = x + width; + #endif + } + +-static void set_left_rite_runs(SkAlphaRuns& runs, int ileft, U8CPU leftA, +- int n, U8CPU riteA) { +- SkASSERT(leftA <= 0xFF); +- SkASSERT(riteA <= 0xFF); +- +- int16_t* run = runs.fRuns; +- uint8_t* aa = runs.fAlpha; +- +- if (ileft > 0) { +- run[0] = ileft; +- aa[0] = 0; +- run += ileft; +- aa += ileft; +- } +- +- SkASSERT(leftA < 0xFF); +- if (leftA > 0) { +- *run++ = 1; +- *aa++ = leftA; +- } +- +- if (n > 0) { +- run[0] = n; +- aa[0] = 0xFF; +- run += n; +- aa += n; +- } +- +- SkASSERT(riteA < 0xFF); +- if (riteA > 0) { +- *run++ = 1; +- *aa++ = riteA; +- } +- run[0] = 0; +-} +- + void SuperBlitter::blitRect(int x, int y, int width, int height) { + SkASSERT(width > 0); + SkASSERT(height > 0); + + // blit leading rows + while ((y & MASK)) { + this->blitH(x, y++, width); + if (--height <= 0) { +diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp +--- a/gfx/skia/src/effects/SkGradientShader.cpp ++++ b/gfx/skia/src/effects/SkGradientShader.cpp +@@ -865,45 +865,16 @@ bool Linear_Gradient::setContext(const S + } while (0) + + namespace { + + typedef void (*LinearShadeProc)(TileProc proc, SkFixed dx, SkFixed fx, + SkPMColor* dstC, const SkPMColor* cache, + int toggle, int count); + +-// This function is deprecated, and will be replaced by +-// shadeSpan_linear_vertical_lerp() once Chrome has been weaned off of it. +-void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx, +- SkPMColor* SK_RESTRICT dstC, +- const SkPMColor* SK_RESTRICT cache, +- int toggle, int count) { +- if (proc == clamp_tileproc) { +- // Read out clamp values from beginning/end of the cache. No need to lerp +- // or dither +- if (fx < 0) { +- sk_memset32(dstC, cache[-1], count); +- return; +- } else if (fx > 0xFFFF) { +- sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count); +- return; +- } +- } +- +- // We're a vertical gradient, so no change in a span. +- // If colors change sharply across the gradient, dithering is +- // insufficient (it subsamples the color space) and we need to lerp. +- unsigned fullIndex = proc(fx); +- unsigned fi = fullIndex >> (16 - Gradient_Shader::kCache32Bits); +- sk_memset32_dither(dstC, +- cache[toggle + fi], +- cache[(toggle ^ Gradient_Shader::kDitherStride32) + fi], +- count); +-} +- + // Linear interpolation (lerp) is unnecessary if there are no sharp + // discontinuities in the gradient - which must be true if there are + // only 2 colors - but it's cheap. + void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx, + SkPMColor* SK_RESTRICT dstC, + const SkPMColor* SK_RESTRICT cache, + int toggle, int count) { + if (proc == clamp_tileproc) { +@@ -2131,16 +2102,18 @@ protected: + buffer.writePoint(fCenter); + } + + private: + typedef Gradient_Shader INHERITED; + const SkPoint fCenter; + }; + ++#ifndef SK_SCALAR_IS_FLOAT ++ + #ifdef COMPUTE_SWEEP_TABLE + #define PI 3.14159265 + static bool gSweepTableReady; + static uint8_t gSweepTable[65]; + + /* Our table stores precomputed values for atan: [0...1] -> [0..PI/4] + We scale the results to [0..32] + */ +@@ -2168,20 +2141,23 @@ static const uint8_t gSweepTable[] = { + 10, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, + 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, + 26, 27, 27, 27, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, + 32 + }; + static const uint8_t* build_sweep_table() { return gSweepTable; } + #endif + ++#endif ++ + // divide numer/denom, with a bias of 6bits. Assumes numer <= denom + // and denom != 0. Since our table is 6bits big (+1), this is a nice fit. + // Same as (but faster than) SkFixedDiv(numer, denom) >> 10 + ++#ifndef SK_SCALAR_IS_FLOAT + //unsigned div_64(int numer, int denom); + static unsigned div_64(int numer, int denom) { + SkASSERT(numer <= denom); + SkASSERT(numer > 0); + SkASSERT(denom > 0); + + int nbits = SkCLZ(numer); + int dbits = SkCLZ(denom); +@@ -2294,16 +2270,17 @@ static unsigned atan_0_90(SkFixed y, SkF + result = 64 - result; + // pin to 63 + result -= result >> 6; + } + + SkASSERT(result <= 63); + return result; + } ++#endif + + // returns angle in a circle [0..2PI) -> [0..255] + #ifdef SK_SCALAR_IS_FLOAT + static unsigned SkATan2_255(float y, float x) { + // static const float g255Over2PI = 255 / (2 * SK_ScalarPI); + static const float g255Over2PI = 40.584510488433314f; + + float result = sk_float_atan2(y, x); +diff --git a/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp b/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp +--- a/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp ++++ b/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp +@@ -112,17 +112,17 @@ void BlitRect32_OpaqueWide_SSE2(SkPMColo + } + + void ColorRect32_SSE2(SkPMColor* destination, + int width, int height, + size_t rowBytes, uint32_t color) { + if (0 == height || 0 == width || 0 == color) { + return; + } +- unsigned colorA = SkGetPackedA32(color); ++ //unsigned colorA = SkGetPackedA32(color); + //if (255 == colorA) { + //if (width < 31) { + //BlitRect32_OpaqueNarrow_SSE2(destination, width, height, + //rowBytes, color); + //} else { + //BlitRect32_OpaqueWide_SSE2(destination, width, height, + //rowBytes, color); + //} +diff --git a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp +--- a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp ++++ b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp +@@ -75,20 +75,16 @@ static CGFloat CGRectGetMinY_inline(cons + static CGFloat CGRectGetMaxY_inline(const CGRect& rect) { + return rect.origin.y + rect.size.height; + } + + static CGFloat CGRectGetWidth_inline(const CGRect& rect) { + return rect.size.width; + } + +-static CGFloat CGRectGetHeight(const CGRect& rect) { +- return rect.size.height; +-} +- + /////////////////////////////////////////////////////////////////////////////// + + static void sk_memset_rect32(uint32_t* ptr, uint32_t value, size_t width, + size_t height, size_t rowBytes) { + SkASSERT(width); + SkASSERT(width * sizeof(uint32_t) <= rowBytes); + + if (width >= 32) { +@@ -125,28 +121,30 @@ static void sk_memset_rect32(uint32_t* p + *ptr++ = value; + } while (--w > 0); + ptr = (uint32_t*)((char*)ptr + rowBytes); + height -= 1; + } + } + } + ++#if 0 + // Potentially this should be made (1) public (2) optimized when width is small. + // Also might want 16 and 32 bit version + // + static void sk_memset_rect(void* ptr, U8CPU byte, size_t width, size_t height, + size_t rowBytes) { + uint8_t* dst = (uint8_t*)ptr; + while (height) { + memset(dst, byte, width); + dst += rowBytes; + height -= 1; + } + } ++#endif + + #include <sys/utsname.h> + + typedef uint32_t CGRGBPixel; + + static unsigned CGRGBPixel_getAlpha(CGRGBPixel pixel) { + return pixel & 0xFF; + } +@@ -250,23 +248,16 @@ static CGAffineTransform MatrixToCGAffin + return CGAffineTransformMake(ScalarToCG(matrix[SkMatrix::kMScaleX]) * sx, + -ScalarToCG(matrix[SkMatrix::kMSkewY]) * sy, + -ScalarToCG(matrix[SkMatrix::kMSkewX]) * sx, + ScalarToCG(matrix[SkMatrix::kMScaleY]) * sy, + ScalarToCG(matrix[SkMatrix::kMTransX]) * sx, + ScalarToCG(matrix[SkMatrix::kMTransY]) * sy); + } + +-static void CGAffineTransformToMatrix(const CGAffineTransform& xform, SkMatrix* matrix) { +- matrix->setAll( +- CGToScalar(xform.a), CGToScalar(xform.c), CGToScalar(xform.tx), +- CGToScalar(xform.b), CGToScalar(xform.d), CGToScalar(xform.ty), +- 0, 0, SK_Scalar1); +-} +- + static SkScalar getFontScale(CGFontRef cgFont) { + int unitsPerEm = CGFontGetUnitsPerEm(cgFont); + return SkScalarInvert(SkIntToScalar(unitsPerEm)); + } + + /////////////////////////////////////////////////////////////////////////////// + + #define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host) +@@ -1075,16 +1066,17 @@ static const uint8_t* getInverseTable(bo + if (!gInited) { + build_power_table(gWhiteTable, 1.5f); + build_power_table(gTable, 2.2f); + gInited = true; + } + return isWhite ? gWhiteTable : gTable; + } + ++#ifdef SK_USE_COLOR_LUMINANCE + static const uint8_t* getGammaTable(U8CPU luminance) { + static uint8_t gGammaTables[4][256]; + static bool gInited; + if (!gInited) { + #if 1 + float start = 1.1; + float stop = 2.1; + for (int i = 0; i < 4; ++i) { +@@ -1097,45 +1089,49 @@ static const uint8_t* getGammaTable(U8CP + build_power_table(gGammaTables[2], 1); + build_power_table(gGammaTables[3], 1); + #endif + gInited = true; + } + SkASSERT(0 == (luminance >> 8)); + return gGammaTables[luminance >> 6]; + } ++#endif + ++#ifndef SK_USE_COLOR_LUMINANCE + static void invertGammaMask(bool isWhite, CGRGBPixel rgb[], int width, + int height, size_t rb) { + const uint8_t* table = getInverseTable(isWhite); + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + uint32_t c = rgb[x]; + int r = (c >> 16) & 0xFF; + int g = (c >> 8) & 0xFF; + int b = (c >> 0) & 0xFF; + rgb[x] = (table[r] << 16) | (table[g] << 8) | table[b]; + } + rgb = (CGRGBPixel*)((char*)rgb + rb); + } + } ++#endif + + static void cgpixels_to_bits(uint8_t dst[], const CGRGBPixel src[], int count) { + while (count > 0) { + uint8_t mask = 0; + for (int i = 7; i >= 0; --i) { + mask |= (CGRGBPixel_getAlpha(*src++) >> 7) << i; + if (0 == --count) { + break; + } + } + *dst++ = mask; + } + } + ++#ifdef SK_USE_COLOR_LUMINANCE + static int lerpScale(int dst, int src, int scale) { + return dst + (scale * (src - dst) >> 23); + } + + static CGRGBPixel lerpPixel(CGRGBPixel dst, CGRGBPixel src, + int scaleR, int scaleG, int scaleB) { + int sr = (src >> 16) & 0xFF; + int sg = (src >> 8) & 0xFF; +@@ -1147,37 +1143,31 @@ static CGRGBPixel lerpPixel(CGRGBPixel d + int rr = lerpScale(dr, sr, scaleR); + int rg = lerpScale(dg, sg, scaleG); + int rb = lerpScale(db, sb, scaleB); + return (rr << 16) | (rg << 8) | rb; + } + + static void lerpPixels(CGRGBPixel dst[], const CGRGBPixel src[], int width, + int height, int rowBytes, int lumBits) { +-#ifdef SK_USE_COLOR_LUMINANCE + int scaleR = (1 << 23) * SkColorGetR(lumBits) / 0xFF; + int scaleG = (1 << 23) * SkColorGetG(lumBits) / 0xFF; + int scaleB = (1 << 23) * SkColorGetB(lumBits) / 0xFF; +-#else +- int scale = (1 << 23) * lumBits / SkScalerContext::kLuminance_Max; +- int scaleR = scale; +- int scaleG = scale; +- int scaleB = scale; +-#endif + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + // bit-not the src, since it was drawn from black, so we need the + // compliment of those bits + dst[x] = lerpPixel(dst[x], ~src[x], scaleR, scaleG, scaleB); + } + src = (CGRGBPixel*)((char*)src + rowBytes); + dst = (CGRGBPixel*)((char*)dst + rowBytes); + } + } ++#endif + + #if 1 + static inline int r32_to_16(int x) { return SkR32ToR16(x); } + static inline int g32_to_16(int x) { return SkG32ToG16(x); } + static inline int b32_to_16(int x) { return SkB32ToB16(x); } + #else + static inline int round8to5(int x) { + return (x + 3 - (x >> 5) + (x >> 7)) >> 3; +@@ -1212,22 +1202,21 @@ static inline uint32_t rgb_to_lcd32(CGRG + return SkPackARGB32(0xFF, r, g, b); + } + + #define BLACK_LUMINANCE_LIMIT 0x40 + #define WHITE_LUMINANCE_LIMIT 0xA0 + + void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) { + CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID(fBaseGlyphCount); +- + const bool isLCD = isLCDFormat(glyph.fMaskFormat); ++#ifdef SK_USE_COLOR_LUMINANCE + const bool isBW = SkMask::kBW_Format == glyph.fMaskFormat; + const bool isA8 = !isLCD && !isBW; +- +-#ifdef SK_USE_COLOR_LUMINANCE ++ + unsigned lumBits = fRec.getLuminanceColor(); + uint32_t xorMask = 0; + + if (isA8) { + // for A8, we just want a component (they're all the same) + lumBits = SkColorGetR(lumBits); + } + #else +diff --git a/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp b/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp +--- a/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp ++++ b/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp +@@ -163,59 +163,8 @@ private: + CGPDFDocumentRef fDoc; + }; + + static void CGDataProviderReleaseData_FromMalloc(void*, const void* data, + size_t size) { + sk_free((void*)data); + } + +-bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) { +- size_t size = stream->getLength(); +- void* ptr = sk_malloc_throw(size); +- stream->read(ptr, size); +- CGDataProviderRef data = CGDataProviderCreateWithData(NULL, ptr, size, +- CGDataProviderReleaseData_FromMalloc); +- if (NULL == data) { +- return false; +- } +- +- CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data); +- CGDataProviderRelease(data); +- if (NULL == pdf) { +- return false; +- } +- SkAutoPDFRelease releaseMe(pdf); +- +- CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1); +- if (NULL == page) { +- return false; +- } +- +- CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); +- +- int w = (int)CGRectGetWidth(bounds); +- int h = (int)CGRectGetHeight(bounds); +- +- SkBitmap bitmap; +- bitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h); +- bitmap.allocPixels(); +- bitmap.eraseColor(SK_ColorWHITE); +- +- size_t bitsPerComponent; +- CGBitmapInfo info; +- getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL); +- +- CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); +- CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h, +- bitsPerComponent, bitmap.rowBytes(), +- cs, info); +- CGColorSpaceRelease(cs); +- +- if (ctx) { +- CGContextDrawPDFPage(ctx, page); +- CGContextRelease(ctx); +- } +- +- output->swap(bitmap); +- return true; +-} +- diff --git a/gfx/skia/patches/archive/0016-Bug-718849-Radial-gradients.patch b/gfx/skia/patches/archive/0016-Bug-718849-Radial-gradients.patch new file mode 100644 index 0000000000..e00fd8602e --- /dev/null +++ b/gfx/skia/patches/archive/0016-Bug-718849-Radial-gradients.patch @@ -0,0 +1,400 @@ +# HG changeset patch +# User Matt Woodrow <mwoodrow@mozilla.com> +# Date 1339988782 -43200 +# Node ID 1e9dae659ee6c992f719fd4136efbcc5410ded37 +# Parent 946750f6d95febd199fb7b748e9d2c48fd01c8a6 +[mq]: skia-windows-gradients + +diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp +--- a/gfx/skia/src/effects/SkGradientShader.cpp ++++ b/gfx/skia/src/effects/SkGradientShader.cpp +@@ -847,16 +847,19 @@ bool Linear_Gradient::setContext(const S + fFlags |= SkShader::kConstInY32_Flag; + if ((fFlags & SkShader::kHasSpan16_Flag) && !paint.isDither()) { + // only claim this if we do have a 16bit mode (i.e. none of our + // colors have alpha), and if we are not dithering (which obviously + // is not const in Y). + fFlags |= SkShader::kConstInY16_Flag; + } + } ++ if (fStart == fEnd) { ++ fFlags &= ~kOpaqueAlpha_Flag; ++ } + return true; + } + + #define NO_CHECK_ITER \ + do { \ + unsigned fi = fx >> Gradient_Shader::kCache32Shift; \ + SkASSERT(fi <= 0xFF); \ + fx += dx; \ +@@ -976,16 +979,21 @@ void Linear_Gradient::shadeSpan(int x, i + TileProc proc = fTileProc; + const SkPMColor* SK_RESTRICT cache = this->getCache32(); + #ifdef USE_DITHER_32BIT_GRADIENT + int toggle = ((x ^ y) & 1) * kDitherStride32; + #else + int toggle = 0; + #endif + ++ if (fStart == fEnd) { ++ sk_bzero(dstC, count * sizeof(*dstC)); ++ return; ++ } ++ + if (fDstToIndexClass != kPerspective_MatrixClass) { + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); + SkFixed dx, fx = SkScalarToFixed(srcPt.fX); + + if (fDstToIndexClass == kFixedStepInX_MatrixClass) { + SkFixed dxStorage[1]; + (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL); +@@ -1169,16 +1177,21 @@ void Linear_Gradient::shadeSpan16(int x, + SkASSERT(count > 0); + + SkPoint srcPt; + SkMatrix::MapXYProc dstProc = fDstToIndexProc; + TileProc proc = fTileProc; + const uint16_t* SK_RESTRICT cache = this->getCache16(); + int toggle = ((x ^ y) & 1) * kDitherStride16; + ++ if (fStart == fEnd) { ++ sk_bzero(dstC, count * sizeof(*dstC)); ++ return; ++ } ++ + if (fDstToIndexClass != kPerspective_MatrixClass) { + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); + SkFixed dx, fx = SkScalarToFixed(srcPt.fX); + + if (fDstToIndexClass == kFixedStepInX_MatrixClass) { + SkFixed dxStorage[1]; + (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL); +@@ -1739,21 +1752,25 @@ void Radial_Gradient::shadeSpan(int x, i + possible circles on which the point may fall. Solving for t yields + the gradient value to use. + + If a<0, the start circle is entirely contained in the + end circle, and one of the roots will be <0 or >1 (off the line + segment). If a>0, the start circle falls at least partially + outside the end circle (or vice versa), and the gradient + defines a "tube" where a point may be on one circle (on the +- inside of the tube) or the other (outside of the tube). We choose +- one arbitrarily. ++ inside of the tube) or the other (outside of the tube). We choose ++ the one with the highest t value, as long as the radius that it ++ corresponds to is >=0. In the case where neither root has a positive ++ radius, we don't draw anything. + ++ XXXmattwoodrow: I've removed this for now since it breaks ++ down when Dr == 0. Is there something else we can do instead? + In order to keep the math to within the limits of fixed point, +- we divide the entire quadratic by Dr^2, and replace ++ we divide the entire quadratic by Dr, and replace + (x - Sx)/Dr with x' and (y - Sy)/Dr with y', giving + + [Dx^2 / Dr^2 + Dy^2 / Dr^2 - 1)] * t^2 + + 2 * [x' * Dx / Dr + y' * Dy / Dr - Sr / Dr] * t + + [x'^2 + y'^2 - Sr^2/Dr^2] = 0 + + (x' and y' are computed by appending the subtract and scale to the + fDstToIndex matrix in the constructor). +@@ -1763,99 +1780,122 @@ void Radial_Gradient::shadeSpan(int x, i + x' and y', if x and y are linear in the span, 'B' can be computed + incrementally with a simple delta (db below). If it is not (e.g., + a perspective projection), it must be computed in the loop. + + */ + + namespace { + +-inline SkFixed two_point_radial(SkScalar b, SkScalar fx, SkScalar fy, +- SkScalar sr2d2, SkScalar foura, +- SkScalar oneOverTwoA, bool posRoot) { ++inline bool two_point_radial(SkScalar b, SkScalar fx, SkScalar fy, ++ SkScalar sr2d2, SkScalar foura, ++ SkScalar oneOverTwoA, SkScalar diffRadius, ++ SkScalar startRadius, SkFixed& t) { + SkScalar c = SkScalarSquare(fx) + SkScalarSquare(fy) - sr2d2; + if (0 == foura) { +- return SkScalarToFixed(SkScalarDiv(-c, b)); ++ SkScalar result = SkScalarDiv(-c, b); ++ if (result * diffRadius + startRadius >= 0) { ++ t = SkScalarToFixed(result); ++ return true; ++ } ++ return false; + } + + SkScalar discrim = SkScalarSquare(b) - SkScalarMul(foura, c); + if (discrim < 0) { +- discrim = -discrim; ++ return false; + } + SkScalar rootDiscrim = SkScalarSqrt(discrim); +- SkScalar result; +- if (posRoot) { +- result = SkScalarMul(-b + rootDiscrim, oneOverTwoA); +- } else { +- result = SkScalarMul(-b - rootDiscrim, oneOverTwoA); ++ ++ // Make sure the results corresponds to a positive radius. ++ SkScalar result = SkScalarMul(-b + rootDiscrim, oneOverTwoA); ++ if (result * diffRadius + startRadius >= 0) { ++ t = SkScalarToFixed(result); ++ return true; + } +- return SkScalarToFixed(result); ++ result = SkScalarMul(-b - rootDiscrim, oneOverTwoA); ++ if (result * diffRadius + startRadius >= 0) { ++ t = SkScalarToFixed(result); ++ return true; ++ } ++ ++ return false; + } + + typedef void (* TwoPointRadialShadeProc)(SkScalar fx, SkScalar dx, + SkScalar fy, SkScalar dy, + SkScalar b, SkScalar db, +- SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot, ++ SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, ++ SkScalar fDiffRadius, SkScalar fRadius1, + SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, + int count); + + void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx, + SkScalar fy, SkScalar dy, + SkScalar b, SkScalar db, +- SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot, ++ SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, ++ SkScalar fDiffRadius, SkScalar fRadius1, + SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, + int count) { + for (; count > 0; --count) { +- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, +- fOneOverTwoA, posRoot); +- +- if (t < 0) { ++ SkFixed t; ++ if (!two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, fDiffRadius, fRadius1, t)) { ++ *(dstC++) = 0; ++ } else if (t < 0) { + *dstC++ = cache[-1]; + } else if (t > 0xFFFF) { + *dstC++ = cache[Gradient_Shader::kCache32Count * 2]; + } else { + SkASSERT(t <= 0xFFFF); + *dstC++ = cache[t >> Gradient_Shader::kCache32Shift]; + } + + fx += dx; + fy += dy; + b += db; + } + } + void shadeSpan_twopoint_mirror(SkScalar fx, SkScalar dx, + SkScalar fy, SkScalar dy, + SkScalar b, SkScalar db, +- SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot, ++ SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, ++ SkScalar fDiffRadius, SkScalar fRadius1, + SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, + int count) { + for (; count > 0; --count) { +- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, +- fOneOverTwoA, posRoot); +- SkFixed index = mirror_tileproc(t); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> Gradient_Shader::kCache32Shift]; ++ SkFixed t; ++ if (!two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, fDiffRadius, fRadius1, t)) { ++ *(dstC++) = 0; ++ } else { ++ SkFixed index = mirror_tileproc(t); ++ SkASSERT(index <= 0xFFFF); ++ *dstC++ = cache[index >> (16 - Gradient_Shader::kCache32Shift)]; ++ } + fx += dx; + fy += dy; + b += db; + } + } + + void shadeSpan_twopoint_repeat(SkScalar fx, SkScalar dx, + SkScalar fy, SkScalar dy, + SkScalar b, SkScalar db, +- SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot, ++ SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, ++ SkScalar fDiffRadius, SkScalar fRadius1, + SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, + int count) { + for (; count > 0; --count) { +- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, +- fOneOverTwoA, posRoot); +- SkFixed index = repeat_tileproc(t); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> Gradient_Shader::kCache32Shift]; ++ SkFixed t; ++ if (!two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, fDiffRadius, fRadius1, t)) { ++ *(dstC++) = 0; ++ } else { ++ SkFixed index = repeat_tileproc(t); ++ SkASSERT(index <= 0xFFFF); ++ *dstC++ = cache[index >> (16 - Gradient_Shader::kCache32Shift)]; ++ } + fx += dx; + fy += dy; + b += db; + } + } + + + +@@ -1935,17 +1975,16 @@ public: + sk_bzero(dstC, count * sizeof(*dstC)); + return; + } + SkMatrix::MapXYProc dstProc = fDstToIndexProc; + TileProc proc = fTileProc; + const SkPMColor* SK_RESTRICT cache = this->getCache32(); + + SkScalar foura = fA * 4; +- bool posRoot = fDiffRadius < 0; + if (fDstToIndexClass != kPerspective_MatrixClass) { + SkPoint srcPt; + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); + SkScalar dx, fx = srcPt.fX; + SkScalar dy, fy = srcPt.fY; + + if (fDstToIndexClass == kFixedStepInX_MatrixClass) { +@@ -1954,60 +1993,69 @@ public: + dx = SkFixedToScalar(fixedX); + dy = SkFixedToScalar(fixedY); + } else { + SkASSERT(fDstToIndexClass == kLinear_MatrixClass); + dx = fDstToIndex.getScaleX(); + dy = fDstToIndex.getSkewY(); + } + SkScalar b = (SkScalarMul(fDiff.fX, fx) + +- SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; ++ SkScalarMul(fDiff.fY, fy) - fStartRadius * fDiffRadius) * 2; + SkScalar db = (SkScalarMul(fDiff.fX, dx) + + SkScalarMul(fDiff.fY, dy)) * 2; + + TwoPointRadialShadeProc shadeProc = shadeSpan_twopoint_repeat; + if (proc == clamp_tileproc) { + shadeProc = shadeSpan_twopoint_clamp; + } else if (proc == mirror_tileproc) { + shadeProc = shadeSpan_twopoint_mirror; + } else { + SkASSERT(proc == repeat_tileproc); + } + (*shadeProc)(fx, dx, fy, dy, b, db, +- fSr2D2, foura, fOneOverTwoA, posRoot, ++ fSr2D2, foura, fOneOverTwoA, fDiffRadius, fRadius1, + dstC, cache, count); + } else { // perspective case + SkScalar dstX = SkIntToScalar(x); + SkScalar dstY = SkIntToScalar(y); + for (; count > 0; --count) { + SkPoint srcPt; + dstProc(fDstToIndex, dstX, dstY, &srcPt); + SkScalar fx = srcPt.fX; + SkScalar fy = srcPt.fY; + SkScalar b = (SkScalarMul(fDiff.fX, fx) + + SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; +- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, +- fOneOverTwoA, posRoot); +- SkFixed index = proc(t); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> Gradient_Shader::kCache32Shift]; ++ SkFixed t; ++ if (!two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, fDiffRadius, fRadius1, t)) { ++ *(dstC++) = 0; ++ } else { ++ SkFixed index = proc(t); ++ SkASSERT(index <= 0xFFFF); ++ *dstC++ = cache[index >> (16 - kCache32Bits)]; ++ } + dstX += SK_Scalar1; + } + } + } + + virtual bool setContext(const SkBitmap& device, + const SkPaint& paint, + const SkMatrix& matrix) SK_OVERRIDE { + if (!this->INHERITED::setContext(device, paint, matrix)) { + return false; + } + + // we don't have a span16 proc + fFlags &= ~kHasSpan16_Flag; ++ ++ // If we might end up wanting to draw nothing as part of the gradient ++ // then we should mark ourselves as not being opaque. ++ if (fA >= 0 || (fDiffRadius == 0 && fCenter1 == fCenter2)) { ++ fFlags &= ~kOpaqueAlpha_Flag; ++ } + return true; + } + + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Two_Point_Radial_Gradient) + + protected: + Two_Point_Radial_Gradient(SkFlattenableReadBuffer& buffer) + : INHERITED(buffer), +@@ -2033,26 +2081,22 @@ private: + const SkScalar fRadius1; + const SkScalar fRadius2; + SkPoint fDiff; + SkScalar fStartRadius, fDiffRadius, fSr2D2, fA, fOneOverTwoA; + + void init() { + fDiff = fCenter1 - fCenter2; + fDiffRadius = fRadius2 - fRadius1; +- SkScalar inv = SkScalarInvert(fDiffRadius); +- fDiff.fX = SkScalarMul(fDiff.fX, inv); +- fDiff.fY = SkScalarMul(fDiff.fY, inv); +- fStartRadius = SkScalarMul(fRadius1, inv); ++ fStartRadius = fRadius1; + fSr2D2 = SkScalarSquare(fStartRadius); +- fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1; ++ fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SkScalarSquare(fDiffRadius); + fOneOverTwoA = fA ? SkScalarInvert(fA * 2) : 0; + + fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY); +- fPtsToUnit.postScale(inv, inv); + } + }; + + /////////////////////////////////////////////////////////////////////////////// + + class Sweep_Gradient : public Gradient_Shader { + public: + Sweep_Gradient(SkScalar cx, SkScalar cy, const SkColor colors[], +@@ -2488,16 +2532,20 @@ SkShader* SkGradientShader::CreateTwoPoi + int colorCount, + SkShader::TileMode mode, + SkUnitMapper* mapper) { + if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) { + return NULL; + } + EXPAND_1_COLOR(colorCount); + ++ if (start == end && startRadius == 0) { ++ return CreateRadial(start, endRadius, colors, pos, colorCount, mode, mapper); ++ } ++ + return SkNEW_ARGS(Two_Point_Radial_Gradient, + (start, startRadius, end, endRadius, colors, pos, + colorCount, mode, mapper)); + } + + SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy, + const SkColor colors[], + const SkScalar pos[], diff --git a/gfx/skia/patches/archive/0017-Bug-740194-SkMemory-mozalloc.patch b/gfx/skia/patches/archive/0017-Bug-740194-SkMemory-mozalloc.patch new file mode 100644 index 0000000000..719fda1650 --- /dev/null +++ b/gfx/skia/patches/archive/0017-Bug-740194-SkMemory-mozalloc.patch @@ -0,0 +1,73 @@ +commit 5786f516119bcb677510f3c9256b870c3b5616c8 +Author: George Wright <gwright@mozilla.com> +Date: Wed Aug 15 23:51:34 2012 -0400 + + Bug 740194 - [Skia] Implement a version of SkMemory for Mozilla that uses the infallible mozalloc allocators r=cjones + +diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h +index f98ba85..17be191 100644 +--- a/gfx/skia/include/config/SkUserConfig.h ++++ b/gfx/skia/include/config/SkUserConfig.h +@@ -35,6 +35,16 @@ + commented out, so including it will have no effect. + */ + ++/* ++ Override new/delete with Mozilla's allocator, mozalloc ++ ++ Ideally we shouldn't need to do this here, but until ++ http://code.google.com/p/skia/issues/detail?id=598 is fixed ++ we need to include this here to override operator new and delete ++*/ ++ ++#include "mozilla/mozalloc.h" ++ + /////////////////////////////////////////////////////////////////////////////// + + /* Scalars (the fractional value type in skia) can be implemented either as +diff --git a/gfx/skia/src/ports/SkMemory_mozalloc.cpp b/gfx/skia/src/ports/SkMemory_mozalloc.cpp +new file mode 100644 +index 0000000..1f16ee5 +--- /dev/null ++++ b/gfx/skia/src/ports/SkMemory_mozalloc.cpp +@@ -0,0 +1,40 @@ ++/* ++ * Copyright 2011 Google Inc. ++ * Copyright 2012 Mozilla Foundation ++ * ++ * Use of this source code is governed by a BSD-style license that can be ++ * found in the LICENSE file. ++ */ ++ ++#include "SkTypes.h" ++ ++#include "mozilla/mozalloc.h" ++#include "mozilla/mozalloc_abort.h" ++#include "mozilla/mozalloc_oom.h" ++ ++void sk_throw() { ++ SkDEBUGFAIL("sk_throw"); ++ mozalloc_abort("Abort from sk_throw"); ++} ++ ++void sk_out_of_memory(void) { ++ SkDEBUGFAIL("sk_out_of_memory"); ++ mozalloc_handle_oom(0); ++} ++ ++void* sk_malloc_throw(size_t size) { ++ return sk_malloc_flags(size, SK_MALLOC_THROW); ++} ++ ++void* sk_realloc_throw(void* addr, size_t size) { ++ return moz_xrealloc(addr, size); ++} ++ ++void sk_free(void* p) { ++ free(p); ++} ++ ++void* sk_malloc_flags(size_t size, unsigned flags) { ++ return (flags & SK_MALLOC_THROW) ? moz_xmalloc(size) : malloc(size); ++} ++ diff --git a/gfx/skia/patches/archive/0018-Bug-817356-PPC-defines.patch b/gfx/skia/patches/archive/0018-Bug-817356-PPC-defines.patch new file mode 100644 index 0000000000..d16ec4b3b4 --- /dev/null +++ b/gfx/skia/patches/archive/0018-Bug-817356-PPC-defines.patch @@ -0,0 +1,14 @@ +Index: gfx/skia/include/core/SkPreConfig.h +=================================================================== +--- gfx/skia/include/core/SkPreConfig.h (revision 6724) ++++ gfx/skia/include/core/SkPreConfig.h (working copy) +@@ -94,7 +94,8 @@ + ////////////////////////////////////////////////////////////////////// + + #if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN) +- #if defined (__ppc__) || defined(__ppc64__) ++ #if defined (__ppc__) || defined(__PPC__) || defined(__ppc64__) \ ++ || defined(__PPC64__) + #define SK_CPU_BENDIAN + #else + #define SK_CPU_LENDIAN diff --git a/gfx/skia/patches/archive/0022-Bug-848491-Re-apply-bug-795538-Ensure-we-use-the-cor.patch b/gfx/skia/patches/archive/0022-Bug-848491-Re-apply-bug-795538-Ensure-we-use-the-cor.patch new file mode 100644 index 0000000000..97404c431b --- /dev/null +++ b/gfx/skia/patches/archive/0022-Bug-848491-Re-apply-bug-795538-Ensure-we-use-the-cor.patch @@ -0,0 +1,39 @@ +From: George Wright <gwright@mozilla.com> +Date: Thu, 20 Jun 2013 09:21:21 -0400 +Subject: Bug 848491 - Re-apply bug 795538 - Ensure we use the correct colour (and alpha) for the clamp values r=mattwoodrow + + +diff --git a/gfx/skia/src/effects/gradients/SkGradientShader.cpp b/gfx/skia/src/effects/gradients/SkGradientShader.cpp +index 27a9c46..ce077b5 100644 +--- a/gfx/skia/src/effects/gradients/SkGradientShader.cpp ++++ b/gfx/skia/src/effects/gradients/SkGradientShader.cpp +@@ -500,15 +500,17 @@ const SkPMColor* SkGradientShaderBase::getCache32() const { + } + + // Write the clamp colours into the first and last entries of fCache32 +- fCache32[kCache32ClampLower] = SkPackARGB32(fCacheAlpha, +- SkColorGetR(fOrigColors[0]), +- SkColorGetG(fOrigColors[0]), +- SkColorGetB(fOrigColors[0])); +- +- fCache32[kCache32ClampUpper] = SkPackARGB32(fCacheAlpha, +- SkColorGetR(fOrigColors[fColorCount - 1]), +- SkColorGetG(fOrigColors[fColorCount - 1]), +- SkColorGetB(fOrigColors[fColorCount - 1])); ++ fCache32[kCache32ClampLower] = SkPremultiplyARGBInline(SkMulDiv255Round(SkColorGetA(fOrigColors[0]), ++ fCacheAlpha), ++ SkColorGetR(fOrigColors[0]), ++ SkColorGetG(fOrigColors[0]), ++ SkColorGetB(fOrigColors[0])); ++ ++ fCache32[kCache32ClampUpper] = SkPremultiplyARGBInline(SkMulDiv255Round(SkColorGetA(fOrigColors[fColorCount - 1]), ++ fCacheAlpha), ++ SkColorGetR(fOrigColors[fColorCount - 1]), ++ SkColorGetG(fOrigColors[fColorCount - 1]), ++ SkColorGetB(fOrigColors[fColorCount - 1])); + + return fCache32; + } +-- +1.7.11.7 + diff --git a/gfx/skia/patches/archive/0023-Bug-890539-Fix-SK_COMPILE_ASSERT-build-warning.patch b/gfx/skia/patches/archive/0023-Bug-890539-Fix-SK_COMPILE_ASSERT-build-warning.patch new file mode 100644 index 0000000000..9bc7ddec46 --- /dev/null +++ b/gfx/skia/patches/archive/0023-Bug-890539-Fix-SK_COMPILE_ASSERT-build-warning.patch @@ -0,0 +1,39 @@ +# HG changeset patch +# Parent e378875000890099fffcdb4cbc4ab12828ac34ee +# User Daniel Holbert <dholbert@cs.stanford.edu> +Bug 890539: Annotate SK_COMPILE_ASSERT's typedef as permissibly unused, to fix GCC 4.8 build warning. r=gw280 + +diff --git a/gfx/skia/include/core/SkTypes.h b/gfx/skia/include/core/SkTypes.h +--- a/gfx/skia/include/core/SkTypes.h ++++ b/gfx/skia/include/core/SkTypes.h +@@ -121,18 +121,29 @@ inline void operator delete(void* p) { + #define SkDEVCODE(code) + #define SK_DEVELOPER_TO_STRING() + #endif + + template <bool> + struct SkCompileAssert { + }; + ++/* ++ * The SK_COMPILE_ASSERT definition creates an otherwise-unused typedef. This ++ * triggers compiler warnings with some versions of gcc, so mark the typedef ++ * as permissibly-unused to disable the warnings. ++ */ ++# if defined(__GNUC__) ++# define SK_COMPILE_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) ++# else ++# define SK_COMPILE_ASSERT_UNUSED_ATTRIBUTE /* nothing */ ++# endif ++ + #define SK_COMPILE_ASSERT(expr, msg) \ +- typedef SkCompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] ++ typedef SkCompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] SK_COMPILE_ASSERT_UNUSED_ATTRIBUTE + + /* + * Usage: SK_MACRO_CONCAT(a, b) to construct the symbol ab + * + * SK_MACRO_CONCAT_IMPL_PRIV just exists to make this work. Do not use directly + * + */ + #define SK_MACRO_CONCAT(X, Y) SK_MACRO_CONCAT_IMPL_PRIV(X, Y) diff --git a/gfx/skia/patches/archive/0024-Bug-887318-fix-bgra-readback.patch b/gfx/skia/patches/archive/0024-Bug-887318-fix-bgra-readback.patch new file mode 100644 index 0000000000..864a0af7a9 --- /dev/null +++ b/gfx/skia/patches/archive/0024-Bug-887318-fix-bgra-readback.patch @@ -0,0 +1,217 @@ +diff --git a/gfx/gl/GLContextSkia.cpp b/gfx/gl/GLContextSkia.cpp +--- a/gfx/gl/GLContextSkia.cpp ++++ b/gfx/gl/GLContextSkia.cpp +@@ -303,39 +303,47 @@ const GLubyte* glGetString_mozilla(GrGLe + if (name == LOCAL_GL_VERSION) { + if (sGLContext.get()->IsGLES2()) { + return reinterpret_cast<const GLubyte*>("OpenGL ES 2.0"); + } else { + return reinterpret_cast<const GLubyte*>("2.0"); + } + } else if (name == LOCAL_GL_EXTENSIONS) { + // Only expose the bare minimum extensions we want to support to ensure a functional Ganesh + // as GLContext only exposes certain extensions + static bool extensionsStringBuilt = false; +- static char extensionsString[120]; ++ static char extensionsString[256]; + + if (!extensionsStringBuilt) { + if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_texture_format_BGRA8888)) { + strcpy(extensionsString, "GL_EXT_texture_format_BGRA8888 "); + } + + if (sGLContext.get()->IsExtensionSupported(GLContext::OES_packed_depth_stencil)) { + strcat(extensionsString, "GL_OES_packed_depth_stencil "); + } + + if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_packed_depth_stencil)) { + strcat(extensionsString, "GL_EXT_packed_depth_stencil "); + } + + if (sGLContext.get()->IsExtensionSupported(GLContext::OES_rgb8_rgba8)) { + strcat(extensionsString, "GL_OES_rgb8_rgba8 "); + } + ++ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_bgra)) { ++ strcat(extensionsString, "GL_EXT_bgra "); ++ } ++ ++ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_read_format_bgra)) { ++ strcat(extensionsString, "GL_EXT_read_format_bgra "); ++ } ++ + extensionsStringBuilt = true; + } + + return reinterpret_cast<const GLubyte*>(extensionsString); + + } else if (name == LOCAL_GL_SHADING_LANGUAGE_VERSION) { + if (sGLContext.get()->IsGLES2()) { + return reinterpret_cast<const GLubyte*>("OpenGL ES GLSL ES 1.0"); + } else { + return reinterpret_cast<const GLubyte*>("1.10"); +diff --git a/gfx/skia/src/gpu/gl/GrGpuGL.cpp b/gfx/skia/src/gpu/gl/GrGpuGL.cpp +--- a/gfx/skia/src/gpu/gl/GrGpuGL.cpp ++++ b/gfx/skia/src/gpu/gl/GrGpuGL.cpp +@@ -1,18 +1,18 @@ + /* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +- ++#include <algorithm> + #include "GrGpuGL.h" + #include "GrGLStencilBuffer.h" + #include "GrGLPath.h" + #include "GrGLShaderBuilder.h" + #include "GrTemplates.h" + #include "GrTypes.h" + #include "SkTemplates.h" + + static const GrGLuint GR_MAX_GLUINT = ~0U; + static const GrGLint GR_INVAL_GLINT = ~0; +@@ -1381,29 +1381,67 @@ bool GrGpuGL::readPixelsWillPayForYFlip( + // Note the rowBytes might be tight to the passed in data, but if data + // gets clipped in x to the target the rowBytes will no longer be tight. + if (left >= 0 && (left + width) < renderTarget->width()) { + return 0 == rowBytes || + GrBytesPerPixel(config) * width == rowBytes; + } else { + return false; + } + } + ++static void swizzleRow(void* buffer, int byteLen) { ++ uint8_t* src = (uint8_t*)buffer; ++ uint8_t* end = src + byteLen; ++ ++ GrAssert((end - src) % 4 == 0); ++ ++ for (; src != end; src += 4) { ++ std::swap(src[0], src[2]); ++ } ++} ++ ++bool GrGpuGL::canReadBGRA() const ++{ ++ if (kDesktop_GrGLBinding == this->glBinding() || ++ this->hasExtension("GL_EXT_bgra")) ++ return true; ++ ++ if (this->hasExtension("GL_EXT_read_format_bgra")) { ++ GrGLint readFormat = 0; ++ GrGLint readType = 0; ++ ++ GL_CALL(GetIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat)); ++ GL_CALL(GetIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType)); ++ ++ return readFormat == GR_GL_BGRA && readType == GR_GL_UNSIGNED_BYTE; ++ } ++ ++ return false; ++} ++ + bool GrGpuGL::onReadPixels(GrRenderTarget* target, + int left, int top, + int width, int height, + GrPixelConfig config, + void* buffer, + size_t rowBytes) { + GrGLenum format; + GrGLenum type; + bool flipY = kBottomLeft_GrSurfaceOrigin == target->origin(); ++ bool needSwizzle = false; ++ ++ if (kBGRA_8888_GrPixelConfig == config && !this->canReadBGRA()) { ++ // Read RGBA and swizzle after ++ config = kRGBA_8888_GrPixelConfig; ++ needSwizzle = true; ++ } ++ + if (!this->configToGLFormats(config, false, NULL, &format, &type)) { + return false; + } + size_t bpp = GrBytesPerPixel(config); + if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, + &left, &top, &width, &height, + const_cast<const void**>(&buffer), + &rowBytes)) { + return false; + } +@@ -1478,35 +1516,46 @@ bool GrGpuGL::onReadPixels(GrRenderTarge + scratch.reset(tightRowBytes); + void* tmpRow = scratch.get(); + // flip y in-place by rows + const int halfY = height >> 1; + char* top = reinterpret_cast<char*>(buffer); + char* bottom = top + (height - 1) * rowBytes; + for (int y = 0; y < halfY; y++) { + memcpy(tmpRow, top, tightRowBytes); + memcpy(top, bottom, tightRowBytes); + memcpy(bottom, tmpRow, tightRowBytes); ++ ++ if (needSwizzle) { ++ swizzleRow(top, tightRowBytes); ++ swizzleRow(bottom, tightRowBytes); ++ } ++ + top += rowBytes; + bottom -= rowBytes; + } + } + } else { +- GrAssert(readDst != buffer); GrAssert(rowBytes != tightRowBytes); ++ GrAssert(readDst != buffer); ++ GrAssert(rowBytes != tightRowBytes); + // copy from readDst to buffer while flipping y + // const int halfY = height >> 1; + const char* src = reinterpret_cast<const char*>(readDst); + char* dst = reinterpret_cast<char*>(buffer); + if (flipY) { + dst += (height-1) * rowBytes; + } + for (int y = 0; y < height; y++) { + memcpy(dst, src, tightRowBytes); ++ if (needSwizzle) { ++ swizzleRow(dst, tightRowBytes); ++ } ++ + src += readDstRowBytes; + if (!flipY) { + dst += rowBytes; + } else { + dst -= rowBytes; + } + } + } + return true; + } +diff --git a/gfx/skia/src/gpu/gl/GrGpuGL.h b/gfx/skia/src/gpu/gl/GrGpuGL.h +--- a/gfx/skia/src/gpu/gl/GrGpuGL.h ++++ b/gfx/skia/src/gpu/gl/GrGpuGL.h +@@ -243,20 +243,22 @@ private: + GrPixelConfig dataConfig, + const void* data, + size_t rowBytes); + + bool createRenderTargetObjects(int width, int height, + GrGLuint texID, + GrGLRenderTarget::Desc* desc); + + void fillInConfigRenderableTable(); + ++ bool canReadBGRA() const; ++ + GrGLContext fGLContext; + + // GL program-related state + ProgramCache* fProgramCache; + SkAutoTUnref<GrGLProgram> fCurrentProgram; + + /////////////////////////////////////////////////////////////////////////// + ///@name Caching of GL State + ///@{ + int fHWActiveTextureUnitIdx; diff --git a/gfx/skia/patches/archive/0025-Bug-896049-Add-default-Value-SK_OVERRIDE.patch b/gfx/skia/patches/archive/0025-Bug-896049-Add-default-Value-SK_OVERRIDE.patch new file mode 100644 index 0000000000..aff99f75f1 --- /dev/null +++ b/gfx/skia/patches/archive/0025-Bug-896049-Add-default-Value-SK_OVERRIDE.patch @@ -0,0 +1,26 @@ +diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h +--- a/gfx/skia/include/core/SkPostConfig.h ++++ b/gfx/skia/include/core/SkPostConfig.h +@@ -325,19 +325,19 @@ + // 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 +- #else +- // Linux GCC ignores "__attribute__((override))" and rejects "override". +- #define SK_OVERRIDE ++ #endif ++ #ifndef SK_OVERRIDE ++ #define SK_OVERRIDE + #endif + #endif + + ////////////////////////////////////////////////////////////////////// + + #ifndef SK_PRINTF_LIKE + #if defined(__clang__) || defined(__GNUC__) + #define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B)))) diff --git a/gfx/skia/patches/archive/0026-Bug-901208-Fix-ARM-v4t.patch b/gfx/skia/patches/archive/0026-Bug-901208-Fix-ARM-v4t.patch new file mode 100644 index 0000000000..5c95b54014 --- /dev/null +++ b/gfx/skia/patches/archive/0026-Bug-901208-Fix-ARM-v4t.patch @@ -0,0 +1,83 @@ +diff --git a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp +--- a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp ++++ b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp +@@ -26,66 +26,78 @@ static void S32A_D565_Opaque(uint16_t* S + asm volatile ( + "1: \n\t" + "ldr r3, [%[src]], #4 \n\t" + "cmp r3, #0xff000000 \n\t" + "blo 2f \n\t" + "and r4, r3, #0x0000f8 \n\t" + "and r5, r3, #0x00fc00 \n\t" + "and r6, r3, #0xf80000 \n\t" ++#ifdef SK_ARM_HAS_EDSP + "pld [r1, #32] \n\t" ++#endif + "lsl r3, r4, #8 \n\t" + "orr r3, r3, r5, lsr #5 \n\t" + "orr r3, r3, r6, lsr #19 \n\t" + "subs %[count], %[count], #1 \n\t" + "strh r3, [%[dst]], #2 \n\t" + "bne 1b \n\t" + "b 4f \n\t" + "2: \n\t" + "lsrs r7, r3, #24 \n\t" + "beq 3f \n\t" + "ldrh r4, [%[dst]] \n\t" + "rsb r7, r7, #255 \n\t" + "and r6, r4, #0x001f \n\t" +-#if SK_ARM_ARCH == 6 ++#if SK_ARM_ARCH <= 6 + "lsl r5, r4, #21 \n\t" + "lsr r5, r5, #26 \n\t" + #else + "ubfx r5, r4, #5, #6 \n\t" + #endif ++#ifdef SK_ARM_HAS_EDSP + "pld [r0, #16] \n\t" ++#endif + "lsr r4, r4, #11 \n\t" + #ifdef SK_ARM_HAS_EDSP + "smulbb r6, r6, r7 \n\t" + "smulbb r5, r5, r7 \n\t" + "smulbb r4, r4, r7 \n\t" + #else + "mul r6, r6, r7 \n\t" + "mul r5, r5, r7 \n\t" + "mul r4, r4, r7 \n\t" + #endif ++#if SK_ARM_ARCH >= 6 + "uxtb r7, r3, ROR #16 \n\t" + "uxtb ip, r3, ROR #8 \n\t" ++#else ++ "mov ip, #0xff \n\t" ++ "and r7, ip, r3, ROR #16 \n\t" ++ "and ip, ip, r3, ROR #8 \n\t" ++#endif + "and r3, r3, #0xff \n\t" + "add r6, r6, #16 \n\t" + "add r5, r5, #32 \n\t" + "add r4, r4, #16 \n\t" + "add r6, r6, r6, lsr #5 \n\t" + "add r5, r5, r5, lsr #6 \n\t" + "add r4, r4, r4, lsr #5 \n\t" + "add r6, r7, r6, lsr #5 \n\t" + "add r5, ip, r5, lsr #6 \n\t" + "add r4, r3, r4, lsr #5 \n\t" + "lsr r6, r6, #3 \n\t" + "and r5, r5, #0xfc \n\t" + "and r4, r4, #0xf8 \n\t" + "orr r6, r6, r5, lsl #3 \n\t" + "orr r4, r6, r4, lsl #8 \n\t" + "strh r4, [%[dst]], #2 \n\t" ++#ifdef SK_ARM_HAS_EDSP + "pld [r1, #32] \n\t" ++#endif + "subs %[count], %[count], #1 \n\t" + "bne 1b \n\t" + "b 4f \n\t" + "3: \n\t" + "subs %[count], %[count], #1 \n\t" + "add %[dst], %[dst], #2 \n\t" + "bne 1b \n\t" + "4: \n\t" diff --git a/gfx/skia/patches/archive/0030-Bug-939629-Add-missing-include-guards.patch b/gfx/skia/patches/archive/0030-Bug-939629-Add-missing-include-guards.patch new file mode 100644 index 0000000000..c92bf2aaeb --- /dev/null +++ b/gfx/skia/patches/archive/0030-Bug-939629-Add-missing-include-guards.patch @@ -0,0 +1,94 @@ +# HG changeset patch +# Parent 979e60d9c09f22eb139643da6de7568b603e1aa1 + +diff --git a/gfx/skia/include/images/SkImages.h b/gfx/skia/include/images/SkImages.h +--- a/gfx/skia/include/images/SkImages.h ++++ b/gfx/skia/include/images/SkImages.h +@@ -1,14 +1,19 @@ + /* + * 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 SkImages_DEFINED ++#define SkImages_DEFINED ++ + class SkImages { + public: + /** + * Initializes flattenables in the images project. + */ + static void InitializeFlattenables(); + }; ++ ++#endif +diff --git a/gfx/skia/src/gpu/GrAAConvexPathRenderer.h b/gfx/skia/src/gpu/GrAAConvexPathRenderer.h +--- a/gfx/skia/src/gpu/GrAAConvexPathRenderer.h ++++ b/gfx/skia/src/gpu/GrAAConvexPathRenderer.h +@@ -1,16 +1,19 @@ + + /* + * 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 GrAAConvexPathRenderer_DEFINED ++#define GrAAConvexPathRenderer_DEFINED ++ + #include "GrPathRenderer.h" + + + class GrAAConvexPathRenderer : public GrPathRenderer { + public: + GrAAConvexPathRenderer(); + + virtual bool canDrawPath(const SkPath& path, +@@ -19,8 +22,10 @@ public: + bool antiAlias) const SK_OVERRIDE; + + protected: + virtual bool onDrawPath(const SkPath& path, + const SkStrokeRec& stroke, + GrDrawTarget* target, + bool antiAlias) SK_OVERRIDE; + }; ++ ++#endif +diff --git a/gfx/skia/src/gpu/GrReducedClip.h b/gfx/skia/src/gpu/GrReducedClip.h +--- a/gfx/skia/src/gpu/GrReducedClip.h ++++ b/gfx/skia/src/gpu/GrReducedClip.h +@@ -1,16 +1,19 @@ + + /* + * 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 GrReducedClip_DEFINED ++#define GrReducedClip_DEFINED ++ + #include "SkClipStack.h" + #include "SkTLList.h" + + namespace GrReducedClip { + + typedef SkTLList<SkClipStack::Element> ElementList; + + enum InitialState { +@@ -33,8 +36,10 @@ enum InitialState { + void ReduceClipStack(const SkClipStack& stack, + const SkIRect& queryBounds, + ElementList* result, + InitialState* initialState, + SkIRect* tighterBounds = NULL, + bool* requiresAA = NULL); + + } // namespace GrReducedClip ++ ++#endif diff --git a/gfx/skia/patches/archive/0031-Bug-945588-Add-include-guard.patch b/gfx/skia/patches/archive/0031-Bug-945588-Add-include-guard.patch new file mode 100644 index 0000000000..f58e7e1659 --- /dev/null +++ b/gfx/skia/patches/archive/0031-Bug-945588-Add-include-guard.patch @@ -0,0 +1,39 @@ +# HG changeset patch +# User Ehsan Akhgari <ehsan@mozilla.com> + +Bug 945588 - Add include guards to SkConfig8888.h + +diff --git a/gfx/skia/src/core/SkConfig8888.h b/gfx/skia/src/core/SkConfig8888.h +index 96eaef2..36bc9b4 100644 +--- a/gfx/skia/src/core/SkConfig8888.h ++++ b/gfx/skia/src/core/SkConfig8888.h +@@ -1,16 +1,18 @@ + + /* + * 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 SkConfig8888_DEFINED ++#define SkConfig8888_DEFINED + + #include "SkCanvas.h" + #include "SkColorPriv.h" + + /** + * Converts pixels from one Config8888 to another Config8888 + */ + void SkConvertConfig8888Pixels(uint32_t* dstPixels, +@@ -69,8 +71,10 @@ static inline void SkCopyConfig8888ToBitmap(const SkBitmap& dstBmp, + int h = dstBmp.height(); + size_t dstRowBytes = dstBmp.rowBytes(); + uint32_t* dstPixels = reinterpret_cast<uint32_t*>(dstBmp.getPixels()); + + SkConvertConfig8888Pixels(dstPixels, dstRowBytes, SkCanvas::kNative_Premul_Config8888, srcPixels, srcRowBytes, srcConfig8888, w, h); + } + + } ++ ++#endif diff --git a/gfx/skia/patches/archive/0032-Bug-974900-More-missing-include-guards.patch b/gfx/skia/patches/archive/0032-Bug-974900-More-missing-include-guards.patch new file mode 100644 index 0000000000..b6b8461213 --- /dev/null +++ b/gfx/skia/patches/archive/0032-Bug-974900-More-missing-include-guards.patch @@ -0,0 +1,148 @@ +# HG changeset patch +# Parent c8288d0c7a1544a590a0cac9c39397ac10c8a45b +Bug 974900 - Add missing include guards to Skia headers - r=gw280 + +diff --git a/gfx/skia/trunk/include/images/SkImages.h b/gfx/skia/trunk/include/images/SkImages.h +--- a/gfx/skia/trunk/include/images/SkImages.h ++++ b/gfx/skia/trunk/include/images/SkImages.h +@@ -1,14 +1,19 @@ + /* + * 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 SkImages_DEFINED ++#define SkImages_DEFINED ++ + class SkImages { + public: + /** + * Initializes flattenables in the images project. + */ + static void InitializeFlattenables(); + }; ++ ++#endif +diff --git a/gfx/skia/trunk/src/core/SkConvolver.h b/gfx/skia/trunk/src/core/SkConvolver.h +--- a/gfx/skia/trunk/src/core/SkConvolver.h ++++ b/gfx/skia/trunk/src/core/SkConvolver.h +@@ -8,16 +8,18 @@ + #include "SkSize.h" + #include "SkTypes.h" + #include "SkTArray.h" + + // avoid confusion with Mac OS X's math library (Carbon) + #if defined(__APPLE__) + #undef FloatToConvolutionFixed + #undef ConvolutionFixedToFloat ++#undef FloatToFixed ++#undef FixedToFloat + #endif + + // Represents a filter in one dimension. Each output pixel has one entry in this + // object for the filter values contributing to it. You build up the filter + // list by calling AddFilter for each output pixel (in order). + // + // We do 2-dimensional convolution by first convolving each row by one + // SkConvolutionFilter1D, then convolving each column by another one. +diff --git a/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h b/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h +--- a/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h ++++ b/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h +@@ -3,24 +3,28 @@ + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + #include "GrPathRenderer.h" + ++#ifndef GrAAConvexPathRenderer_DEFINED ++#define GrAAConvexPathRenderer_DEFINED + + class GrAAConvexPathRenderer : public GrPathRenderer { + public: + GrAAConvexPathRenderer(); + + virtual bool canDrawPath(const SkPath& path, + const SkStrokeRec& stroke, + const GrDrawTarget* target, + bool antiAlias) const SK_OVERRIDE; + + protected: + virtual bool onDrawPath(const SkPath& path, + const SkStrokeRec& stroke, + GrDrawTarget* target, + bool antiAlias) SK_OVERRIDE; + }; ++ ++#endif +diff --git a/gfx/skia/trunk/src/gpu/GrReducedClip.h b/gfx/skia/trunk/src/gpu/GrReducedClip.h +--- a/gfx/skia/trunk/src/gpu/GrReducedClip.h ++++ b/gfx/skia/trunk/src/gpu/GrReducedClip.h +@@ -1,16 +1,19 @@ + + /* + * 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 GrReducedClip_DEFINED ++#define GrReducedClip_DEFINED ++ + #include "SkClipStack.h" + #include "SkTLList.h" + + namespace GrReducedClip { + + typedef SkTLList<SkClipStack::Element> ElementList; + + enum InitialState { +@@ -36,8 +39,10 @@ SK_API void ReduceClipStack(const SkClip + const SkIRect& queryBounds, + ElementList* result, + int32_t* resultGenID, + InitialState* initialState, + SkIRect* tighterBounds = NULL, + bool* requiresAA = NULL); + + } // namespace GrReducedClip ++ ++#endif +diff --git a/gfx/skia/trunk/src/pathops/SkLineParameters.h b/gfx/skia/trunk/src/pathops/SkLineParameters.h +--- a/gfx/skia/trunk/src/pathops/SkLineParameters.h ++++ b/gfx/skia/trunk/src/pathops/SkLineParameters.h +@@ -1,14 +1,18 @@ + /* + * 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 SkLineParameters_DEFINED ++#define SkLineParameters_DEFINED ++ + #include "SkPathOpsCubic.h" + #include "SkPathOpsLine.h" + #include "SkPathOpsQuad.h" + + // Sources + // computer-aided design - volume 22 number 9 november 1990 pp 538 - 549 + // online at http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf + +@@ -164,8 +168,10 @@ public: + return -a; + } + + private: + double a; + double b; + double c; + }; ++ ++#endif diff --git a/gfx/skia/patches/archive/0033-Bug-974900-undef-interface-windows.patch b/gfx/skia/patches/archive/0033-Bug-974900-undef-interface-windows.patch new file mode 100644 index 0000000000..05f17000a0 --- /dev/null +++ b/gfx/skia/patches/archive/0033-Bug-974900-undef-interface-windows.patch @@ -0,0 +1,27 @@ +# HG changeset patch +# Parent b12f9a408740aa5fd93c296a7d41e1b5f54c1b20 +Bug 974900 - #undef interface defined by windows headers - r=gw280 + +diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h b/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h +--- a/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h ++++ b/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h +@@ -9,16 +9,19 @@ + #ifndef GrGLCaps_DEFINED + #define GrGLCaps_DEFINED + + #include "GrDrawTargetCaps.h" + #include "GrGLStencilBuffer.h" + #include "SkTArray.h" + #include "SkTDArray.h" + ++// defined in Windows headers ++#undef interface ++ + class GrGLContextInfo; + + /** + * Stores some capabilities of a GL context. Most are determined by the GL + * version and the extensions string. It also tracks formats that have passed + * the FBO completeness test. + */ + class GrGLCaps : public GrDrawTargetCaps { diff --git a/gfx/skia/patches/archive/SkPostConfig.patch b/gfx/skia/patches/archive/SkPostConfig.patch new file mode 100644 index 0000000000..d32341f4ea --- /dev/null +++ b/gfx/skia/patches/archive/SkPostConfig.patch @@ -0,0 +1,32 @@ +diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h +--- a/gfx/skia/include/core/SkPostConfig.h ++++ b/gfx/skia/include/core/SkPostConfig.h +@@ -277,19 +277,28 @@ + #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 + + ////////////////////////////////////////////////////////////////////// + diff --git a/gfx/skia/patches/archive/arm-fixes.patch b/gfx/skia/patches/archive/arm-fixes.patch new file mode 100644 index 0000000000..d9fa430df0 --- /dev/null +++ b/gfx/skia/patches/archive/arm-fixes.patch @@ -0,0 +1,191 @@ +diff --git a/gfx/skia/include/core/SkMath.h b/gfx/skia/include/core/SkMath.h +--- a/gfx/skia/include/core/SkMath.h ++++ b/gfx/skia/include/core/SkMath.h +@@ -148,20 +148,17 @@ 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. + */ +-#if defined(__arm__) \ +- && !defined(__thumb__) \ +- && !defined(__ARM_ARCH_4T__) \ +- && !defined(__ARM_ARCH_5T__) ++#ifdef SK_ARM_HAS_EDSP + 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) + ); +diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h +--- a/gfx/skia/include/core/SkPostConfig.h ++++ b/gfx/skia/include/core/SkPostConfig.h +@@ -300,8 +300,53 @@ + #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 +diff --git a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp +--- a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp ++++ b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp +@@ -6,17 +6,17 @@ + * found in the LICENSE file. + */ + + + #include "SkBitmapProcState.h" + #include "SkColorPriv.h" + #include "SkUtils.h" + +-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN) ++#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN) + void SI8_D16_nofilter_DX_arm( + const SkBitmapProcState& s, + const uint32_t* SK_RESTRICT xy, + int count, + uint16_t* SK_RESTRICT colors) __attribute__((optimize("O1"))); + + void SI8_D16_nofilter_DX_arm(const SkBitmapProcState& s, + const uint32_t* SK_RESTRICT xy, +@@ -177,17 +177,17 @@ void SI8_opaque_D32_nofilter_DX_arm(cons + : [xx] "+r" (xx), [count] "+r" (count), [colors] "+r" (colors) + : [table] "r" (table), [srcAddr] "r" (srcAddr) + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" + ); + } + + s.fBitmap->getColorTable()->unlockColors(false); + } +-#endif //__ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN) ++#endif // SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN) + + /////////////////////////////////////////////////////////////////////////////// + + /* If we replace a sampleproc, then we null-out the associated shaderproc, + otherwise the shader won't even look at the matrix/sampler + */ + void SkBitmapProcState::platformProcs() { + bool doFilter = fDoFilter; +@@ -195,17 +195,17 @@ void SkBitmapProcState::platformProcs() + bool justDx = false; + + if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { + justDx = true; + } + + switch (fBitmap->config()) { + case SkBitmap::kIndex8_Config: +-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN) ++#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN) + if (justDx && !doFilter) { + #if 0 /* crashing on android device */ + fSampleProc16 = SI8_D16_nofilter_DX_arm; + fShaderProc16 = NULL; + #endif + if (isOpaque) { + // this one is only very slighty faster than the C version + fSampleProc32 = SI8_opaque_D32_nofilter_DX_arm; +diff --git a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp +--- a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp ++++ b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp +@@ -669,18 +669,23 @@ static void __attribute((noinline,optimi + /* Double Loop */ + "1: \n\t" /* <double loop> */ + "ldm %[src]!, {r5, r6} \n\t" /* loading src pointers into r5 and r6 */ + "ldm %[dst], {r7, r8} \n\t" /* loading dst pointers into r7 and r8 */ + + /* dst1_scale and dst2_scale*/ + "lsr r9, r5, #24 \n\t" /* src >> 24 */ + "lsr r10, r6, #24 \n\t" /* src >> 24 */ ++#ifdef SK_ARM_HAS_EDSP + "smulbb r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */ + "smulbb r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */ ++#else ++ "mul r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */ ++ "mul r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */ ++#endif + "lsr r9, r9, #8 \n\t" /* r9 >> 8 */ + "lsr r10, r10, #8 \n\t" /* r10 >> 8 */ + "rsb r9, r9, #256 \n\t" /* dst1_scale = r9 = 255 - r9 + 1 */ + "rsb r10, r10, #256 \n\t" /* dst2_scale = r10 = 255 - r10 + 1 */ + + /* ---------------------- */ + + /* src1, src1_scale */ +@@ -739,17 +744,21 @@ static void __attribute((noinline,optimi + /* else get into the single loop */ + /* Single Loop */ + "2: \n\t" /* <single loop> */ + "ldr r5, [%[src]], #4 \n\t" /* loading src pointer into r5: r5=src */ + "ldr r7, [%[dst]] \n\t" /* loading dst pointer into r7: r7=dst */ + + "lsr r6, r5, #24 \n\t" /* src >> 24 */ + "and r8, r12, r5, lsr #8 \n\t" /* ag = r8 = r5 masked by r12 lsr by #8 */ ++#ifdef SK_ARM_HAS_EDSP + "smulbb r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */ ++#else ++ "mul r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */ ++#endif + "and r9, r12, r5 \n\t" /* rb = r9 = r5 masked by r12 */ + "lsr r6, r6, #8 \n\t" /* r6 >> 8 */ + "mul r8, r8, %[alpha] \n\t" /* ag = r8 times scale */ + "rsb r6, r6, #256 \n\t" /* r6 = 255 - r6 + 1 */ + + /* src, src_scale */ + "mul r9, r9, %[alpha] \n\t" /* rb = r9 times scale */ + "and r8, r8, r12, lsl #8 \n\t" /* ag masked by reverse mask (r12) */ diff --git a/gfx/skia/patches/archive/arm-opts.patch b/gfx/skia/patches/archive/arm-opts.patch new file mode 100644 index 0000000000..02ad85c9a7 --- /dev/null +++ b/gfx/skia/patches/archive/arm-opts.patch @@ -0,0 +1,41 @@ +diff --git a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp +--- a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp ++++ b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp +@@ -549,17 +549,17 @@ static void S32A_Opaque_BlitRow32_neon(S + #define S32A_Opaque_BlitRow32_PROC S32A_Opaque_BlitRow32_neon + + #else + + #ifdef TEST_SRC_ALPHA + #error The ARM asm version of S32A_Opaque_BlitRow32 does not support TEST_SRC_ALPHA + #endif + +-static void S32A_Opaque_BlitRow32_arm(SkPMColor* SK_RESTRICT dst, ++static void __attribute((noinline,optimize("-fomit-frame-pointer"))) S32A_Opaque_BlitRow32_arm(SkPMColor* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha) { + + SkASSERT(255 == alpha); + + /* Does not support the TEST_SRC_ALPHA case */ + asm volatile ( + "cmp %[count], #0 \n\t" /* comparing count with 0 */ +@@ -646,17 +646,17 @@ static void S32A_Opaque_BlitRow32_arm(Sk + ); + } + #define S32A_Opaque_BlitRow32_PROC S32A_Opaque_BlitRow32_arm + #endif + + /* + * ARM asm version of S32A_Blend_BlitRow32 + */ +-static void S32A_Blend_BlitRow32_arm(SkPMColor* SK_RESTRICT dst, ++static void __attribute((noinline,optimize("-fomit-frame-pointer"))) S32A_Blend_BlitRow32_arm(SkPMColor* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha) { + asm volatile ( + "cmp %[count], #0 \n\t" /* comparing count with 0 */ + "beq 3f \n\t" /* if zero exit */ + + "mov r12, #0xff \n\t" /* load the 0xff mask in r12 */ + "orr r12, r12, r12, lsl #16 \n\t" /* convert it to 0xff00ff in r12 */ diff --git a/gfx/skia/patches/archive/fix-comma-end-enum-list.patch b/gfx/skia/patches/archive/fix-comma-end-enum-list.patch new file mode 100644 index 0000000000..dea36377e8 --- /dev/null +++ b/gfx/skia/patches/archive/fix-comma-end-enum-list.patch @@ -0,0 +1,380 @@ +diff --git a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h +--- 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; + }; + +diff --git a/gfx/skia/include/core/SkBlitRow.h b/gfx/skia/include/core/SkBlitRow.h +--- a/gfx/skia/include/core/SkBlitRow.h ++++ b/gfx/skia/include/core/SkBlitRow.h +@@ -44,17 +44,17 @@ public: + + //! 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 + */ +diff --git a/gfx/skia/include/core/SkCanvas.h b/gfx/skia/include/core/SkCanvas.h +--- a/gfx/skia/include/core/SkCanvas.h ++++ b/gfx/skia/include/core/SkCanvas.h +@@ -132,17 +132,17 @@ 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 +diff --git a/gfx/skia/include/core/SkDevice.h b/gfx/skia/include/core/SkDevice.h +--- a/gfx/skia/include/core/SkDevice.h ++++ b/gfx/skia/include/core/SkDevice.h +@@ -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; + }; + + /** +diff --git a/gfx/skia/include/core/SkFlattenable.h b/gfx/skia/include/core/SkFlattenable.h +--- a/gfx/skia/include/core/SkFlattenable.h ++++ b/gfx/skia/include/core/SkFlattenable.h +@@ -216,17 +216,17 @@ public: + 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 { +diff --git a/gfx/skia/include/core/SkFontHost.h b/gfx/skia/include/core/SkFontHost.h +--- a/gfx/skia/include/core/SkFontHost.h ++++ b/gfx/skia/include/core/SkFontHost.h +@@ -245,17 +245,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 +264,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 + /////////////////////////////////////////////////////////////////////////// + +diff --git a/gfx/skia/include/core/SkMaskFilter.h b/gfx/skia/include/core/SkMaskFilter.h +--- a/gfx/skia/include/core/SkMaskFilter.h ++++ b/gfx/skia/include/core/SkMaskFilter.h +@@ -57,17 +57,17 @@ public: + + 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; + }; + +diff --git a/gfx/skia/include/core/SkPaint.h b/gfx/skia/include/core/SkPaint.h +--- a/gfx/skia/include/core/SkPaint.h ++++ b/gfx/skia/include/core/SkPaint.h +@@ -70,17 +70,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); + +@@ -282,17 +282,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; } +diff --git a/gfx/skia/include/core/SkScalerContext.h b/gfx/skia/include/core/SkScalerContext.h +--- a/gfx/skia/include/core/SkScalerContext.h ++++ b/gfx/skia/include/core/SkScalerContext.h +@@ -172,24 +172,24 @@ public: + 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 + + // 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_Bits = 3 // ensure Flags doesn't exceed 16bits + }; + + // computed values + enum { + kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag, + kLuminance_Max = (1 << kLuminance_Bits) - 1, +- kLuminance_Mask = kLuminance_Max << kLuminance_Shift, ++ kLuminance_Mask = kLuminance_Max << kLuminance_Shift + }; + + struct Rec { + uint32_t fOrigFontID; + uint32_t fFontID; + SkScalar fTextSize, fPreScaleX, fPreSkewX; + SkScalar fPost2x2[2][2]; + SkScalar fFrameWidth, fMiterLimit; +diff --git a/gfx/skia/include/core/SkTypes.h b/gfx/skia/include/core/SkTypes.h +--- a/gfx/skia/include/core/SkTypes.h ++++ b/gfx/skia/include/core/SkTypes.h +@@ -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; +diff --git a/gfx/skia/include/effects/SkLayerDrawLooper.h b/gfx/skia/include/effects/SkLayerDrawLooper.h +--- 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. +diff --git a/gfx/skia/src/core/SkBitmap.cpp b/gfx/skia/src/core/SkBitmap.cpp +--- a/gfx/skia/src/core/SkBitmap.cpp ++++ b/gfx/skia/src/core/SkBitmap.cpp +@@ -1357,17 +1357,17 @@ bool SkBitmap::extractAlpha(SkBitmap* ds + + /////////////////////////////////////////////////////////////////////////////// + + enum { + SERIALIZE_PIXELTYPE_NONE, + SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE, + SERIALIZE_PIXELTYPE_RAW_NO_CTABLE, + SERIALIZE_PIXELTYPE_REF_DATA, +- SERIALIZE_PIXELTYPE_REF_PTR, ++ SERIALIZE_PIXELTYPE_REF_PTR + }; + + static void writeString(SkFlattenableWriteBuffer& buffer, const char str[]) { + size_t len = strlen(str); + buffer.write32(len); + buffer.writePad(str, len); + } + +diff --git a/gfx/skia/src/core/SkMatrix.cpp b/gfx/skia/src/core/SkMatrix.cpp +--- a/gfx/skia/src/core/SkMatrix.cpp ++++ b/gfx/skia/src/core/SkMatrix.cpp +@@ -1715,17 +1715,17 @@ SkScalar SkMatrix::getMaxStretch() const + const SkMatrix& SkMatrix::I() { + static SkMatrix gIdentity; + static bool gOnce; + if (!gOnce) { + gIdentity.reset(); + gOnce = true; + } + return gIdentity; +-}; ++} + + const SkMatrix& SkMatrix::InvalidMatrix() { + static SkMatrix gInvalid; + static bool gOnce; + if (!gOnce) { + gInvalid.setAll(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, + SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, + SK_ScalarMax, SK_ScalarMax, SK_ScalarMax); diff --git a/gfx/skia/patches/archive/fix-gradient-clamp.patch b/gfx/skia/patches/archive/fix-gradient-clamp.patch new file mode 100644 index 0000000000..91481c2c12 --- /dev/null +++ b/gfx/skia/patches/archive/fix-gradient-clamp.patch @@ -0,0 +1,211 @@ +diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp +--- a/gfx/skia/src/effects/SkGradientShader.cpp ++++ b/gfx/skia/src/effects/SkGradientShader.cpp +@@ -167,16 +167,17 @@ private: + + mutable uint16_t* fCache16; // working ptr. If this is NULL, we need to recompute the cache values + mutable SkPMColor* fCache32; // working ptr. If this is NULL, we need to recompute the cache values + + mutable uint16_t* fCache16Storage; // storage for fCache16, allocated on demand + mutable SkMallocPixelRef* fCache32PixelRef; + mutable unsigned fCacheAlpha; // the alpha value we used when we computed the cache. larger than 8bits so we can store uninitialized value + ++ static SkPMColor PremultiplyColor(SkColor c0, U8CPU alpha); + static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count); + static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count, + U8CPU alpha); + void setCacheAlpha(U8CPU alpha) const; + void initCommon(); + + typedef SkShader INHERITED; + }; +@@ -512,16 +513,31 @@ static inline U8CPU dither_fixed_to_8(Sk + * For dithering with premultiply, we want to ceiling the alpha component, + * to ensure that it is always >= any color component. + */ + static inline U8CPU dither_ceil_fixed_to_8(SkFixed n) { + n >>= 8; + return ((n << 1) - (n | (n >> 8))) >> 8; + } + ++SkPMColor Gradient_Shader::PremultiplyColor(SkColor c0, U8CPU paintAlpha) ++{ ++ SkFixed a = SkMulDiv255Round(SkColorGetA(c0), paintAlpha); ++ SkFixed r = SkColorGetR(c0); ++ SkFixed g = SkColorGetG(c0); ++ SkFixed b = SkColorGetB(c0); ++ ++ a = SkIntToFixed(a) + 0x8000; ++ r = SkIntToFixed(r) + 0x8000; ++ g = SkIntToFixed(g) + 0x8000; ++ b = SkIntToFixed(b) + 0x8000; ++ ++ return SkPremultiplyARGBInline(a >> 16, r >> 16, g >> 16, b >> 16); ++} ++ + void Gradient_Shader::Build32bitCache(SkPMColor cache[], SkColor c0, SkColor c1, + int count, U8CPU paintAlpha) { + SkASSERT(count > 1); + + // need to apply paintAlpha to our two endpoints + SkFixed a = SkMulDiv255Round(SkColorGetA(c0), paintAlpha); + SkFixed da; + { +@@ -613,24 +629,24 @@ const uint16_t* Gradient_Shader::getCach + } + } + return fCache16; + } + + const SkPMColor* Gradient_Shader::getCache32() const { + if (fCache32 == NULL) { + // double the count for dither entries +- const int entryCount = kCache32Count * 2; ++ const int entryCount = kCache32Count * 2 + 2; + const size_t allocSize = sizeof(SkPMColor) * entryCount; + + if (NULL == fCache32PixelRef) { + fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef, + (NULL, allocSize, NULL)); + } +- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr(); ++ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1; + if (fColorCount == 2) { + Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1], + kCache32Count, fCacheAlpha); + } else { + Rec* rec = fRecs; + int prevIndex = 0; + for (int i = 1; i < fColorCount; i++) { + int nextIndex = SkFixedToFFFF(rec[i].fPos) >> (16 - kCache32Bits); +@@ -644,28 +660,31 @@ const SkPMColor* Gradient_Shader::getCac + } + SkASSERT(prevIndex == kCache32Count - 1); + } + + if (fMapper) { + SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef, + (NULL, allocSize, NULL)); + SkPMColor* linear = fCache32; // just computed linear data +- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data ++ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data + SkUnitMapper* map = fMapper; + for (int i = 0; i < kCache32Count; i++) { + int index = map->mapUnit16((i << 8) | i) >> 8; + mapped[i] = linear[index]; + mapped[i + kCache32Count] = linear[index + kCache32Count]; + } + fCache32PixelRef->unref(); + fCache32PixelRef = newPR; +- fCache32 = (SkPMColor*)newPR->getAddr(); ++ fCache32 = (SkPMColor*)newPR->getAddr() + 1; + } + } ++ //Write the clamp colours into the first and last entries of fCache32 ++ fCache32[-1] = PremultiplyColor(fOrigColors[0], fCacheAlpha); ++ fCache32[kCache32Count * 2] = PremultiplyColor(fOrigColors[fColorCount - 1], fCacheAlpha); + return fCache32; + } + + /* + * Because our caller might rebuild the same (logically the same) gradient + * over and over, we'd like to return exactly the same "bitmap" if possible, + * allowing the client to utilize a cache of our bitmap (e.g. with a GPU). + * To do that, we maintain a private cache of built-bitmaps, based on our +@@ -875,28 +894,38 @@ void Linear_Gradient::shadeSpan(int x, i + dx = dxStorage[0]; + } else { + SkASSERT(fDstToIndexClass == kLinear_MatrixClass); + dx = SkScalarToFixed(fDstToIndex.getScaleX()); + } + + if (SkFixedNearlyZero(dx)) { + // we're a vertical gradient, so no change in a span +- unsigned fi = proc(fx) >> (16 - kCache32Bits); +- sk_memset32_dither(dstC, cache[toggle + fi], +- cache[(toggle ^ TOGGLE_MASK) + fi], count); ++ if (proc == clamp_tileproc) { ++ if (fx < 0) { ++ sk_memset32(dstC, cache[-1], count); ++ } else if (fx > 0xFFFF) { ++ sk_memset32(dstC, cache[kCache32Count * 2], count); ++ } else { ++ unsigned fi = proc(fx) >> (16 - kCache32Bits); ++ sk_memset32_dither(dstC, cache[toggle + fi], ++ cache[(toggle ^ TOGGLE_MASK) + fi], count); ++ } ++ } else { ++ unsigned fi = proc(fx) >> (16 - kCache32Bits); ++ sk_memset32_dither(dstC, cache[toggle + fi], ++ cache[(toggle ^ TOGGLE_MASK) + fi], count); ++ } + } else if (proc == clamp_tileproc) { + SkClampRange range; +- range.init(fx, dx, count, 0, 0xFF); ++ range.init(fx, dx, count, cache[-1], cache[kCache32Count * 2]); + + if ((count = range.fCount0) > 0) { +- sk_memset32_dither(dstC, +- cache[toggle + range.fV0], +- cache[(toggle ^ TOGGLE_MASK) + range.fV0], +- count); ++ // Do we really want to dither the clamp values? ++ sk_memset32(dstC, range.fV0, count); + dstC += count; + } + if ((count = range.fCount1) > 0) { + int unroll = count >> 3; + fx = range.fFx1; + for (int i = 0; i < unroll; i++) { + NO_CHECK_ITER; NO_CHECK_ITER; + NO_CHECK_ITER; NO_CHECK_ITER; +@@ -905,20 +934,17 @@ void Linear_Gradient::shadeSpan(int x, i + } + if ((count &= 7) > 0) { + do { + NO_CHECK_ITER; + } while (--count != 0); + } + } + if ((count = range.fCount2) > 0) { +- sk_memset32_dither(dstC, +- cache[toggle + range.fV1], +- cache[(toggle ^ TOGGLE_MASK) + range.fV1], +- count); ++ sk_memset32(dstC, range.fV1, count); + } + } else if (proc == mirror_tileproc) { + do { + unsigned fi = mirror_8bits(fx >> 8); + SkASSERT(fi <= 0xFF); + fx += dx; + *dstC++ = cache[toggle + fi]; + toggle ^= TOGGLE_MASK; +@@ -1670,19 +1699,24 @@ public: + } + SkScalar b = (SkScalarMul(fDiff.fX, fx) + + SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; + SkScalar db = (SkScalarMul(fDiff.fX, dx) + + SkScalarMul(fDiff.fY, dy)) * 2; + if (proc == clamp_tileproc) { + for (; count > 0; --count) { + SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); +- SkFixed index = SkClampMax(t, 0xFFFF); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> (16 - kCache32Bits)]; ++ if (t < 0) { ++ *dstC++ = cache[-1]; ++ } else if (t > 0xFFFF) { ++ *dstC++ = cache[kCache32Count * 2]; ++ } else { ++ SkASSERT(t <= 0xFFFF); ++ *dstC++ = cache[t >> (16 - kCache32Bits)]; ++ } + fx += dx; + fy += dy; + b += db; + } + } else if (proc == mirror_tileproc) { + for (; count > 0; --count) { + SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); + SkFixed index = mirror_tileproc(t); diff --git a/gfx/skia/patches/archive/getpostextpath.patch b/gfx/skia/patches/archive/getpostextpath.patch new file mode 100644 index 0000000000..7181411ec8 --- /dev/null +++ b/gfx/skia/patches/archive/getpostextpath.patch @@ -0,0 +1,70 @@ +diff --git a/gfx/skia/include/core/SkPaint.h b/gfx/skia/include/core/SkPaint.h +--- a/gfx/skia/include/core/SkPaint.h ++++ b/gfx/skia/include/core/SkPaint.h +@@ -836,16 +836,19 @@ 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 void* findImage(const SkGlyph&); + + uint32_t getGenerationID() const; + #endif + + // returns true if the paint's settings (e.g. xfermode + alpha) resolve to +diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp +--- a/gfx/skia/src/core/SkPaint.cpp ++++ b/gfx/skia/src/core/SkPaint.cpp +@@ -1242,16 +1242,43 @@ void SkPaint::getTextPath(const void* te + const SkPath* iterPath; + while ((iterPath = iter.next(&xpos)) != NULL) { + matrix.postTranslate(xpos - prevXPos, 0); + path->addPath(*iterPath, matrix); + prevXPos = xpos; + } + } + ++void SkPaint::getPosTextPath(const void* textData, size_t length, ++ const SkPoint pos[], SkPath* path) const { ++ SkASSERT(length == 0 || textData != NULL); ++ ++ const char* text = (const char*)textData; ++ if (text == NULL || length == 0 || path == NULL) { ++ return; ++ } ++ ++ SkTextToPathIter iter(text, length, *this, false, true); ++ SkMatrix matrix; ++ SkPoint prevPos; ++ prevPos.set(0, 0); ++ ++ matrix.setScale(iter.getPathScale(), iter.getPathScale()); ++ path->reset(); ++ ++ unsigned int i = 0; ++ const SkPath* iterPath; ++ while ((iterPath = iter.next(NULL)) != NULL) { ++ matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); ++ path->addPath(*iterPath, matrix); ++ prevPos = pos[i]; ++ i++; ++ } ++} ++ + static void add_flattenable(SkDescriptor* desc, uint32_t tag, + SkFlattenableWriteBuffer* buffer) { + buffer->flatten(desc->addEntry(tag, buffer->size(), NULL)); + } + + // SkFontHost can override this choice in FilterRec() + static SkMask::Format computeMaskFormat(const SkPaint& paint) { + uint32_t flags = paint.getFlags(); diff --git a/gfx/skia/patches/archive/mingw-fix.patch b/gfx/skia/patches/archive/mingw-fix.patch new file mode 100644 index 0000000000..d91a16aa70 --- /dev/null +++ b/gfx/skia/patches/archive/mingw-fix.patch @@ -0,0 +1,57 @@ +diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h +index 0135b85..bb108f8 100644 +--- a/gfx/skia/include/core/SkPostConfig.h ++++ b/gfx/skia/include/core/SkPostConfig.h +@@ -253,7 +253,7 @@ + ////////////////////////////////////////////////////////////////////// + + #ifndef SK_OVERRIDE +-#if defined(SK_BUILD_FOR_WIN) ++#if defined(_MSC_VER) + #define SK_OVERRIDE override + #elif defined(__clang__) + // Some documentation suggests we should be using __attribute__((override)), +diff --git a/gfx/skia/src/ports/SkFontHost_win.cpp b/gfx/skia/src/ports/SkFontHost_win.cpp +index dd9c5dc..ca2c3dc 100644 +--- a/gfx/skia/src/ports/SkFontHost_win.cpp ++++ b/gfx/skia/src/ports/SkFontHost_win.cpp +@@ -22,7 +22,7 @@ + #ifdef WIN32 + #include "windows.h" + #include "tchar.h" +-#include "Usp10.h" ++#include "usp10.h" + + // always packed xxRRGGBB + typedef uint32_t SkGdiRGB; +@@ -1033,6 +1033,10 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( + HFONT savefont = (HFONT)SelectObject(hdc, font); + HFONT designFont = NULL; + ++ const char stem_chars[] = {'i', 'I', '!', '1'}; ++ int16_t min_width; ++ unsigned glyphCount; ++ + // To request design units, create a logical font whose height is specified + // as unitsPerEm. + OUTLINETEXTMETRIC otm; +@@ -1046,7 +1050,7 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( + if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) { + goto Error; + } +- const unsigned glyphCount = calculateGlyphCount(hdc); ++ glyphCount = calculateGlyphCount(hdc); + + info = new SkAdvancedTypefaceMetrics; + info->fEmSize = otm.otmEMSquare; +@@ -1115,9 +1119,8 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics( + + // Figure out a good guess for StemV - Min width of i, I, !, 1. + // This probably isn't very good with an italic font. +- int16_t min_width = SHRT_MAX; ++ min_width = SHRT_MAX; + info->fStemV = 0; +- char stem_chars[] = {'i', 'I', '!', '1'}; + for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) { + ABC abcWidths; + if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) { diff --git a/gfx/skia/patches/archive/new-aa.patch b/gfx/skia/patches/archive/new-aa.patch new file mode 100644 index 0000000000..d5e6fbf73d --- /dev/null +++ b/gfx/skia/patches/archive/new-aa.patch @@ -0,0 +1,22 @@ +diff --git a/gfx/skia/src/core/SkScan_AntiPath.cpp b/gfx/skia/src/core/SkScan_AntiPath.cpp +--- a/gfx/skia/src/core/SkScan_AntiPath.cpp ++++ b/gfx/skia/src/core/SkScan_AntiPath.cpp +@@ -31,17 +31,17 @@ + - supersampled coordinates, scale equal to the output * SCALE + + NEW_AA is a set of code-changes to try to make both paths produce identical + results. Its not quite there yet, though the remaining differences may be + in the subsequent blits, and not in the different masks/runs... + */ + //#define FORCE_SUPERMASK + //#define FORCE_RLE +-//#define SK_SUPPORT_NEW_AA ++#define SK_SUPPORT_NEW_AA + + /////////////////////////////////////////////////////////////////////////////// + + /// Base class for a single-pass supersampled blitter. + class BaseSuperBlitter : public SkBlitter { + public: + BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, + const SkRegion& clip); diff --git a/gfx/skia/patches/archive/old-android-fonthost.patch b/gfx/skia/patches/archive/old-android-fonthost.patch new file mode 100644 index 0000000000..1c64ace7dd --- /dev/null +++ b/gfx/skia/patches/archive/old-android-fonthost.patch @@ -0,0 +1,530 @@ +# HG changeset patch +# Parent 9ee29e4aace683ddf6cf8ddb2893cd34fcfc772c +# User James Willcox <jwillcox@mozilla.com> +diff --git a/gfx/skia/Makefile.in b/gfx/skia/Makefile.in +--- a/gfx/skia/Makefile.in ++++ b/gfx/skia/Makefile.in +@@ -305,21 +305,20 @@ CPPSRCS += \ + SkFontHost_mac_coretext.cpp \ + SkTime_Unix.cpp \ + $(NULL) + endif + + ifeq (android,$(MOZ_WIDGET_TOOLKIT)) + CPPSRCS += \ + SkFontHost_FreeType.cpp \ + SkFontHost_android.cpp \ + SkFontHost_gamma.cpp \ +- FontHostConfiguration_android.cpp \ + SkMMapStream.cpp \ + SkTime_Unix.cpp \ + $(NULL) + + DEFINES += -DSK_BUILD_FOR_ANDROID_NDK + OS_CXXFLAGS += $(CAIRO_FT_CFLAGS) + endif + + ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT)) + CPPSRCS += \ +diff --git a/gfx/skia/src/ports/SkFontHost_android.cpp b/gfx/skia/src/ports/SkFontHost_android.cpp +--- a/gfx/skia/src/ports/SkFontHost_android.cpp ++++ b/gfx/skia/src/ports/SkFontHost_android.cpp +@@ -1,38 +1,31 @@ ++ + /* +-** +-** Copyright 2006, The Android Open Source Project +-** +-** Licensed under the Apache License, Version 2.0 (the "License"); +-** you may not use this file except in compliance with the License. +-** You may obtain a copy of the License at +-** +-** http://www.apache.org/licenses/LICENSE-2.0 +-** +-** Unless required by applicable law or agreed to in writing, software +-** distributed under the License is distributed on an "AS IS" BASIS, +-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-** See the License for the specific language governing permissions and +-** limitations under the License. +-*/ ++ * 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. ++ */ ++ + + #include "SkFontHost.h" + #include "SkDescriptor.h" + #include "SkMMapStream.h" + #include "SkPaint.h" + #include "SkString.h" + #include "SkStream.h" + #include "SkThread.h" + #include "SkTSearch.h" +-#include "FontHostConfiguration_android.h" + #include <stdio.h> + ++#define FONT_CACHE_MEMORY_BUDGET (768 * 1024) ++ + #ifndef SK_FONT_FILE_PREFIX + #define SK_FONT_FILE_PREFIX "/fonts/" + #endif + + SkTypeface::Style find_name_and_attributes(SkStream* stream, SkString* name, + bool* isFixedWidth); + + static void GetFullPathForSysFonts(SkString* full, const char name[]) { + full->set(getenv("ANDROID_ROOT")); + full->append(SK_FONT_FILE_PREFIX); +@@ -99,21 +92,21 @@ static SkTypeface* find_best_face(const + if (faces[SkTypeface::kNormal] != NULL) { + return faces[SkTypeface::kNormal]; + } + // look for anything + for (int i = 0; i < 4; i++) { + if (faces[i] != NULL) { + return faces[i]; + } + } + // should never get here, since the faces list should not be empty +- SkDEBUGFAIL("faces list is empty"); ++ SkASSERT(!"faces list is empty"); + return NULL; + } + + static FamilyRec* find_family(const SkTypeface* member) { + FamilyRec* curr = gFamilyHead; + while (curr != NULL) { + for (int i = 0; i < 4; i++) { + if (curr->fFaces[i] == member) { + return curr; + } +@@ -138,31 +131,27 @@ static SkTypeface* find_from_uniqueID(ui + curr = curr->fNext; + } + return NULL; + } + + /* Remove reference to this face from its family. If the resulting family + is empty (has no faces), return that family, otherwise return NULL + */ + static FamilyRec* remove_from_family(const SkTypeface* face) { + FamilyRec* family = find_family(face); +- if (family) { +- SkASSERT(family->fFaces[face->style()] == face); +- family->fFaces[face->style()] = NULL; ++ SkASSERT(family->fFaces[face->style()] == face); ++ family->fFaces[face->style()] = NULL; + +- for (int i = 0; i < 4; i++) { +- if (family->fFaces[i] != NULL) { // family is non-empty +- return NULL; +- } ++ for (int i = 0; i < 4; i++) { ++ if (family->fFaces[i] != NULL) { // family is non-empty ++ return NULL; + } +- } else { +-// SkDebugf("remove_from_family(%p) face not found", face); + } + return family; // return the empty family + } + + // maybe we should make FamilyRec be doubly-linked + static void detach_and_delete_family(FamilyRec* family) { + FamilyRec* curr = gFamilyHead; + FamilyRec* prev = NULL; + + while (curr != NULL) { +@@ -172,21 +161,21 @@ static void detach_and_delete_family(Fam + gFamilyHead = next; + } else { + prev->fNext = next; + } + SkDELETE(family); + return; + } + prev = curr; + curr = next; + } +- SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete"); ++ SkASSERT(!"Yikes, couldn't find family in our list to remove/delete"); + } + + static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) { + NameFamilyPair* list = gNameList.begin(); + int count = gNameList.count(); + + int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); + + if (index >= 0) { + return find_best_face(list[index].fFamily, style); +@@ -387,111 +376,90 @@ static bool get_name_and_style(const cha + } + return false; + } + + // used to record our notion of the pre-existing fonts + struct FontInitRec { + const char* fFileName; + const char* const* fNames; // null-terminated list + }; + ++static const char* gSansNames[] = { ++ "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL ++}; ++ ++static const char* gSerifNames[] = { ++ "serif", "times", "times new roman", "palatino", "georgia", "baskerville", ++ "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL ++}; ++ ++static const char* gMonoNames[] = { ++ "monospace", "courier", "courier new", "monaco", NULL ++}; ++ + // deliberately empty, but we use the address to identify fallback fonts + static const char* gFBNames[] = { NULL }; + ++/* Fonts must be grouped by family, with the first font in a family having the ++ list of names (even if that list is empty), and the following members having ++ null for the list. The names list must be NULL-terminated ++*/ ++static const FontInitRec gSystemFonts[] = { ++ { "DroidSans.ttf", gSansNames }, ++ { "DroidSans-Bold.ttf", NULL }, ++ { "DroidSerif-Regular.ttf", gSerifNames }, ++ { "DroidSerif-Bold.ttf", NULL }, ++ { "DroidSerif-Italic.ttf", NULL }, ++ { "DroidSerif-BoldItalic.ttf", NULL }, ++ { "DroidSansMono.ttf", gMonoNames }, ++ /* These are optional, and can be ignored if not found in the file system. ++ These are appended to gFallbackFonts[] as they are seen, so we list ++ them in the order we want them to be accessed by NextLogicalFont(). ++ */ ++ { "DroidSansArabic.ttf", gFBNames }, ++ { "DroidSansHebrew.ttf", gFBNames }, ++ { "DroidSansThai.ttf", gFBNames }, ++ { "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font ++ { "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font ++ { "DroidSansJapanese.ttf", gFBNames }, ++ { "DroidSansFallback.ttf", gFBNames } ++}; + +-/* Fonts are grouped by family, with the first font in a family having the +- list of names (even if that list is empty), and the following members having +- null for the list. The names list must be NULL-terminated. +-*/ +-static FontInitRec *gSystemFonts; +-static size_t gNumSystemFonts = 0; +- +-#define SYSTEM_FONTS_FILE "/system/etc/system_fonts.cfg" ++#define DEFAULT_NAMES gSansNames + + // these globals are assigned (once) by load_system_fonts() + static FamilyRec* gDefaultFamily; + static SkTypeface* gDefaultNormal; +-static char** gDefaultNames = NULL; +-static uint32_t *gFallbackFonts; + +-/* Load info from a configuration file that populates the system/fallback font structures +-*/ +-static void load_font_info() { +-// load_font_info_xml("/system/etc/system_fonts.xml"); +- SkTDArray<FontFamily*> fontFamilies; +- getFontFamilies(fontFamilies); +- +- SkTDArray<FontInitRec> fontInfo; +- bool firstInFamily = false; +- for (int i = 0; i < fontFamilies.count(); ++i) { +- FontFamily *family = fontFamilies[i]; +- firstInFamily = true; +- for (int j = 0; j < family->fFileNames.count(); ++j) { +- FontInitRec fontInfoRecord; +- fontInfoRecord.fFileName = family->fFileNames[j]; +- if (j == 0) { +- if (family->fNames.count() == 0) { +- // Fallback font +- fontInfoRecord.fNames = (char **)gFBNames; +- } else { +- SkTDArray<const char*> names = family->fNames; +- const char **nameList = (const char**) +- malloc((names.count() + 1) * sizeof(char*)); +- if (nameList == NULL) { +- // shouldn't get here +- break; +- } +- if (gDefaultNames == NULL) { +- gDefaultNames = (char**) nameList; +- } +- for (int i = 0; i < names.count(); ++i) { +- nameList[i] = names[i]; +- } +- nameList[names.count()] = NULL; +- fontInfoRecord.fNames = nameList; +- } +- } else { +- fontInfoRecord.fNames = NULL; +- } +- *fontInfo.append() = fontInfoRecord; +- } +- } +- gNumSystemFonts = fontInfo.count(); +- gSystemFonts = (FontInitRec*) malloc(gNumSystemFonts * sizeof(FontInitRec)); +- gFallbackFonts = (uint32_t*) malloc((gNumSystemFonts + 1) * sizeof(uint32_t)); +- if (gSystemFonts == NULL) { +- // shouldn't get here +- gNumSystemFonts = 0; +- } +- for (size_t i = 0; i < gNumSystemFonts; ++i) { +- gSystemFonts[i].fFileName = fontInfo[i].fFileName; +- gSystemFonts[i].fNames = fontInfo[i].fNames; +- } +- fontFamilies.deleteAll(); +-} ++/* This is sized conservatively, assuming that it will never be a size issue. ++ It will be initialized in load_system_fonts(), and will be filled with the ++ fontIDs that can be used for fallback consideration, in sorted order (sorted ++ meaning element[0] should be used first, then element[1], etc. When we hit ++ a fontID==0 in the array, the list is done, hence our allocation size is ++ +1 the total number of possible system fonts. Also see NextLogicalFont(). ++ */ ++static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1]; + + /* Called once (ensured by the sentinel check at the beginning of our body). + Initializes all the globals, and register the system fonts. + */ + static void load_system_fonts() { + // check if we've already be called + if (NULL != gDefaultNormal) { + return; + } + +- load_font_info(); +- + const FontInitRec* rec = gSystemFonts; + SkTypeface* firstInFamily = NULL; + int fallbackCount = 0; + +- for (size_t i = 0; i < gNumSystemFonts; i++) { ++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { + // if we're the first in a new family, clear firstInFamily + if (rec[i].fNames != NULL) { + firstInFamily = NULL; + } + + bool isFixedWidth; + SkString name; + SkTypeface::Style style; + + // we expect all the fonts, except the "fallback" fonts +@@ -515,120 +483,75 @@ static void load_system_fonts() { + // SkDebugf("---- adding %s as fallback[%d] fontID %d\n", + // rec[i].fFileName, fallbackCount, tf->uniqueID()); + gFallbackFonts[fallbackCount++] = tf->uniqueID(); + } + + firstInFamily = tf; + FamilyRec* family = find_family(tf); + const char* const* names = rec[i].fNames; + + // record the default family if this is it +- if (names == gDefaultNames) { ++ if (names == DEFAULT_NAMES) { + gDefaultFamily = family; + } + // add the names to map to this family + while (*names) { + add_name(*names, family); + names += 1; + } + } + } + + // do this after all fonts are loaded. This is our default font, and it + // acts as a sentinel so we only execute load_system_fonts() once + gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal); + // now terminate our fallback list with the sentinel value + gFallbackFonts[fallbackCount] = 0; + } + + /////////////////////////////////////////////////////////////////////////////// + + void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { +- // lookup and record if the font is custom (i.e. not a system font) +- bool isCustomFont = !((FamilyTypeface*)face)->isSysFont(); +- stream->writeBool(isCustomFont); ++ const char* name = ((FamilyTypeface*)face)->getUniqueString(); + +- if (isCustomFont) { +- SkStream* fontStream = ((FamilyTypeface*)face)->openStream(); ++ stream->write8((uint8_t)face->style()); + +- // store the length of the custom font +- uint32_t len = fontStream->getLength(); +- stream->write32(len); +- +- // store the entire font in the serialized stream +- void* fontData = malloc(len); +- +- fontStream->read(fontData, len); +- stream->write(fontData, len); +- +- fontStream->unref(); +- free(fontData); +-// SkDebugf("--- fonthost custom serialize %d %d\n", face->style(), len); +- ++ if (NULL == name || 0 == *name) { ++ stream->writePackedUInt(0); ++// SkDebugf("--- fonthost serialize null\n"); + } else { +- const char* name = ((FamilyTypeface*)face)->getUniqueString(); +- +- stream->write8((uint8_t)face->style()); +- +- if (NULL == name || 0 == *name) { +- stream->writePackedUInt(0); +-// SkDebugf("--- fonthost serialize null\n"); +- } else { +- uint32_t len = strlen(name); +- stream->writePackedUInt(len); +- stream->write(name, len); +-// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style()); +- } ++ uint32_t len = strlen(name); ++ stream->writePackedUInt(len); ++ stream->write(name, len); ++// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style()); + } + } + + SkTypeface* SkFontHost::Deserialize(SkStream* stream) { + load_system_fonts(); + +- // check if the font is a custom or system font +- bool isCustomFont = stream->readBool(); ++ int style = stream->readU8(); + +- if (isCustomFont) { ++ int len = stream->readPackedUInt(); ++ if (len > 0) { ++ SkString str; ++ str.resize(len); ++ stream->read(str.writable_str(), len); + +- // read the length of the custom font from the stream +- uint32_t len = stream->readU32(); +- +- // generate a new stream to store the custom typeface +- SkMemoryStream* fontStream = new SkMemoryStream(len); +- stream->read((void*)fontStream->getMemoryBase(), len); +- +- SkTypeface* face = CreateTypefaceFromStream(fontStream); +- +- fontStream->unref(); +- +-// SkDebugf("--- fonthost custom deserialize %d %d\n", face->style(), len); +- return face; +- +- } else { +- int style = stream->readU8(); +- +- int len = stream->readPackedUInt(); +- if (len > 0) { +- SkString str; +- str.resize(len); +- stream->read(str.writable_str(), len); +- +- const FontInitRec* rec = gSystemFonts; +- for (size_t i = 0; i < gNumSystemFonts; i++) { +- if (strcmp(rec[i].fFileName, str.c_str()) == 0) { +- // backup until we hit the fNames +- for (int j = i; j >= 0; --j) { +- if (rec[j].fNames != NULL) { +- return SkFontHost::CreateTypeface(NULL, +- rec[j].fNames[0], NULL, 0, +- (SkTypeface::Style)style); +- } ++ const FontInitRec* rec = gSystemFonts; ++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { ++ if (strcmp(rec[i].fFileName, str.c_str()) == 0) { ++ // backup until we hit the fNames ++ for (int j = i; j >= 0; --j) { ++ if (rec[j].fNames != NULL) { ++ return SkFontHost::CreateTypeface(NULL, ++ rec[j].fNames[0], NULL, 0, (SkTypeface::Style)style); + } + } + } + } + } + return NULL; + } + + /////////////////////////////////////////////////////////////////////////////// + +@@ -697,49 +620,32 @@ size_t SkFontHost::GetFileName(SkFontID + } + return size; + } else { + return 0; + } + } + + SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) { + load_system_fonts(); + +- const SkTypeface* origTypeface = find_from_uniqueID(origFontID); +- const SkTypeface* currTypeface = find_from_uniqueID(currFontID); +- +- SkASSERT(origTypeface != 0); +- SkASSERT(currTypeface != 0); +- +- // Our fallback list always stores the id of the plain in each fallback +- // family, so we transform currFontID to its plain equivalent. +- currFontID = find_typeface(currTypeface, SkTypeface::kNormal)->uniqueID(); +- + /* First see if fontID is already one of our fallbacks. If so, return + its successor. If fontID is not in our list, then return the first one + in our list. Note: list is zero-terminated, and returning zero means + we have no more fonts to use for fallbacks. + */ + const uint32_t* list = gFallbackFonts; + for (int i = 0; list[i] != 0; i++) { + if (list[i] == currFontID) { +- if (list[i+1] == 0) +- return 0; +- const SkTypeface* nextTypeface = find_from_uniqueID(list[i+1]); +- return find_typeface(nextTypeface, origTypeface->style())->uniqueID(); ++ return list[i+1]; + } + } +- +- // If we get here, currFontID was not a fallback, so we start at the +- // beginning of our list. +- const SkTypeface* firstTypeface = find_from_uniqueID(list[0]); +- return find_typeface(firstTypeface, origTypeface->style())->uniqueID(); ++ return list[0]; + } + + /////////////////////////////////////////////////////////////////////////////// + + SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { + if (NULL == stream || stream->getLength() <= 0) { + return NULL; + } + + bool isFixedWidth; +@@ -754,10 +660,11 @@ SkTypeface* SkFontHost::CreateTypefaceFr + } + + SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { + SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path)); + SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream); + // since we created the stream, we let go of our ref() here + stream->unref(); + return face; + } + ++/////////////////////////////////////////////////////////////////////////////// diff --git a/gfx/skia/patches/archive/radial-gradients.patch b/gfx/skia/patches/archive/radial-gradients.patch new file mode 100644 index 0000000000..183923e83e --- /dev/null +++ b/gfx/skia/patches/archive/radial-gradients.patch @@ -0,0 +1,25 @@ +diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp +--- a/gfx/skia/src/effects/SkGradientShader.cpp ++++ b/gfx/skia/src/effects/SkGradientShader.cpp +@@ -1665,17 +1665,20 @@ public: + } + return kRadial2_GradientType; + } + + virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) SK_OVERRIDE { + SkASSERT(count > 0); + + // Zero difference between radii: fill with transparent black. +- if (fDiffRadius == 0) { ++ // TODO: Is removing this actually correct? Two circles with the ++ // same radius, but different centers doesn't sound like it ++ // should be cleared ++ if (fDiffRadius == 0 && fCenter1 == fCenter2) { + sk_bzero(dstC, count * sizeof(*dstC)); + return; + } + SkMatrix::MapXYProc dstProc = fDstToIndexProc; + TileProc proc = fTileProc; + const SkPMColor* SK_RESTRICT cache = this->getCache32(); + + SkScalar foura = fA * 4; diff --git a/gfx/skia/patches/archive/skia_restrict_problem.patch b/gfx/skia/patches/archive/skia_restrict_problem.patch new file mode 100644 index 0000000000..c7639ca2ce --- /dev/null +++ b/gfx/skia/patches/archive/skia_restrict_problem.patch @@ -0,0 +1,461 @@ +diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp +--- a/gfx/skia/src/effects/SkGradientShader.cpp ++++ b/gfx/skia/src/effects/SkGradientShader.cpp +@@ -1184,116 +1184,17 @@ public: + { + // make sure our table is insync with our current #define for kSQRT_TABLE_SIZE + SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE); + + rad_to_unit_matrix(center, radius, &fPtsToUnit); + } + + virtual void shadeSpan(int x, int y, SkPMColor* dstC, int count) SK_OVERRIDE; +- virtual void shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) SK_OVERRIDE { +- SkASSERT(count > 0); +- +- SkPoint srcPt; +- SkMatrix::MapXYProc dstProc = fDstToIndexProc; +- TileProc proc = fTileProc; +- const uint16_t* SK_RESTRICT cache = this->getCache16(); +- int toggle = ((x ^ y) & 1) << kCache16Bits; +- +- if (fDstToIndexClass != kPerspective_MatrixClass) { +- dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, +- SkIntToScalar(y) + SK_ScalarHalf, &srcPt); +- SkFixed dx, fx = SkScalarToFixed(srcPt.fX); +- SkFixed dy, fy = SkScalarToFixed(srcPt.fY); +- +- if (fDstToIndexClass == kFixedStepInX_MatrixClass) { +- SkFixed storage[2]; +- (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]); +- dx = storage[0]; +- dy = storage[1]; +- } else { +- SkASSERT(fDstToIndexClass == kLinear_MatrixClass); +- dx = SkScalarToFixed(fDstToIndex.getScaleX()); +- dy = SkScalarToFixed(fDstToIndex.getSkewY()); +- } +- +- if (proc == clamp_tileproc) { +- const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table; +- +- /* knock these down so we can pin against +- 0x7FFF, which is an immediate load, +- rather than 0xFFFF which is slower. This is a compromise, since it reduces our +- precision, but that appears to be visually OK. If we decide this is OK for +- all of our cases, we could (it seems) put this scale-down into fDstToIndex, +- to avoid having to do these extra shifts each time. +- */ +- fx >>= 1; +- dx >>= 1; +- fy >>= 1; +- dy >>= 1; +- if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total +- fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1); +- fy *= fy; +- do { +- unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1); +- unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS); +- fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS)); +- fx += dx; +- *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))]; +- toggle ^= (1 << kCache16Bits); +- } while (--count != 0); +- } else { +- do { +- unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1); +- unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1); +- fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS); +- fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS)); +- fx += dx; +- fy += dy; +- *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))]; +- toggle ^= (1 << kCache16Bits); +- } while (--count != 0); +- } +- } else if (proc == mirror_tileproc) { +- do { +- SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy)); +- unsigned fi = mirror_tileproc(dist); +- SkASSERT(fi <= 0xFFFF); +- fx += dx; +- fy += dy; +- *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))]; +- toggle ^= (1 << kCache16Bits); +- } while (--count != 0); +- } else { +- SkASSERT(proc == repeat_tileproc); +- do { +- SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy)); +- unsigned fi = repeat_tileproc(dist); +- SkASSERT(fi <= 0xFFFF); +- fx += dx; +- fy += dy; +- *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))]; +- toggle ^= (1 << kCache16Bits); +- } while (--count != 0); +- } +- } else { // perspective case +- SkScalar dstX = SkIntToScalar(x); +- SkScalar dstY = SkIntToScalar(y); +- do { +- dstProc(fDstToIndex, dstX, dstY, &srcPt); +- unsigned fi = proc(SkScalarToFixed(srcPt.length())); +- SkASSERT(fi <= 0xFFFF); +- +- int index = fi >> (16 - kCache16Bits); +- *dstC++ = cache[toggle + index]; +- toggle ^= (1 << kCache16Bits); +- +- dstX += SK_Scalar1; +- } while (--count != 0); +- } +- } ++ virtual void shadeSpan16(int x, int y, uint16_t* dstC, int count) SK_OVERRIDE; + + virtual BitmapType asABitmap(SkBitmap* bitmap, + SkMatrix* matrix, + TileMode* xy, + SkScalar* twoPointRadialParams) const SK_OVERRIDE { + if (bitmap) { + this->commonAsABitmap(bitmap); + } +@@ -1507,16 +1408,117 @@ void Radial_Gradient::shadeSpan(int x, i + unsigned fi = proc(SkScalarToFixed(srcPt.length())); + SkASSERT(fi <= 0xFFFF); + *dstC++ = cache[fi >> (16 - kCache32Bits)]; + dstX += SK_Scalar1; + } while (--count != 0); + } + } + ++void Radial_Gradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) { ++ SkASSERT(count > 0); ++ ++ SkPoint srcPt; ++ SkMatrix::MapXYProc dstProc = fDstToIndexProc; ++ TileProc proc = fTileProc; ++ const uint16_t* SK_RESTRICT cache = this->getCache16(); ++ int toggle = ((x ^ y) & 1) << kCache16Bits; ++ ++ if (fDstToIndexClass != kPerspective_MatrixClass) { ++ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, ++ SkIntToScalar(y) + SK_ScalarHalf, &srcPt); ++ SkFixed dx, fx = SkScalarToFixed(srcPt.fX); ++ SkFixed dy, fy = SkScalarToFixed(srcPt.fY); ++ ++ if (fDstToIndexClass == kFixedStepInX_MatrixClass) { ++ SkFixed storage[2]; ++ (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]); ++ dx = storage[0]; ++ dy = storage[1]; ++ } else { ++ SkASSERT(fDstToIndexClass == kLinear_MatrixClass); ++ dx = SkScalarToFixed(fDstToIndex.getScaleX()); ++ dy = SkScalarToFixed(fDstToIndex.getSkewY()); ++ } ++ ++ if (proc == clamp_tileproc) { ++ const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table; ++ ++ /* knock these down so we can pin against +- 0x7FFF, which is an immediate load, ++ rather than 0xFFFF which is slower. This is a compromise, since it reduces our ++ precision, but that appears to be visually OK. If we decide this is OK for ++ all of our cases, we could (it seems) put this scale-down into fDstToIndex, ++ to avoid having to do these extra shifts each time. ++ */ ++ fx >>= 1; ++ dx >>= 1; ++ fy >>= 1; ++ dy >>= 1; ++ if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total ++ fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1); ++ fy *= fy; ++ do { ++ unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1); ++ unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS); ++ fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS)); ++ fx += dx; ++ *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))]; ++ toggle ^= (1 << kCache16Bits); ++ } while (--count != 0); ++ } else { ++ do { ++ unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1); ++ unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1); ++ fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS); ++ fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS)); ++ fx += dx; ++ fy += dy; ++ *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))]; ++ toggle ^= (1 << kCache16Bits); ++ } while (--count != 0); ++ } ++ } else if (proc == mirror_tileproc) { ++ do { ++ SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy)); ++ unsigned fi = mirror_tileproc(dist); ++ SkASSERT(fi <= 0xFFFF); ++ fx += dx; ++ fy += dy; ++ *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))]; ++ toggle ^= (1 << kCache16Bits); ++ } while (--count != 0); ++ } else { ++ SkASSERT(proc == repeat_tileproc); ++ do { ++ SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy)); ++ unsigned fi = repeat_tileproc(dist); ++ SkASSERT(fi <= 0xFFFF); ++ fx += dx; ++ fy += dy; ++ *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))]; ++ toggle ^= (1 << kCache16Bits); ++ } while (--count != 0); ++ } ++ } else { // perspective case ++ SkScalar dstX = SkIntToScalar(x); ++ SkScalar dstY = SkIntToScalar(y); ++ do { ++ dstProc(fDstToIndex, dstX, dstY, &srcPt); ++ unsigned fi = proc(SkScalarToFixed(srcPt.length())); ++ SkASSERT(fi <= 0xFFFF); ++ ++ int index = fi >> (16 - kCache16Bits); ++ *dstC++ = cache[toggle + index]; ++ toggle ^= (1 << kCache16Bits); ++ ++ dstX += SK_Scalar1; ++ } while (--count != 0); ++ } ++} ++ + /* Two-point radial gradients are specified by two circles, each with a center + point and radius. The gradient can be considered to be a series of + concentric circles, with the color interpolated from the start circle + (at t=0) to the end circle (at t=1). + + For each point (x, y) in the span, we want to find the + interpolated circle that intersects that point. The center + of the desired circle (Cx, Cy) falls at some distance t +@@ -1661,109 +1663,17 @@ public: + info->fPoint[0] = fCenter1; + info->fPoint[1] = fCenter2; + info->fRadius[0] = fRadius1; + info->fRadius[1] = fRadius2; + } + return kRadial2_GradientType; + } + +- virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) SK_OVERRIDE { +- SkASSERT(count > 0); +- +- // Zero difference between radii: fill with transparent black. +- // TODO: Is removing this actually correct? Two circles with the +- // same radius, but different centers doesn't sound like it +- // should be cleared +- if (fDiffRadius == 0 && fCenter1 == fCenter2) { +- sk_bzero(dstC, count * sizeof(*dstC)); +- return; +- } +- SkMatrix::MapXYProc dstProc = fDstToIndexProc; +- TileProc proc = fTileProc; +- const SkPMColor* SK_RESTRICT cache = this->getCache32(); +- +- SkScalar foura = fA * 4; +- bool posRoot = fDiffRadius < 0; +- if (fDstToIndexClass != kPerspective_MatrixClass) { +- SkPoint srcPt; +- dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, +- SkIntToScalar(y) + SK_ScalarHalf, &srcPt); +- SkScalar dx, fx = srcPt.fX; +- SkScalar dy, fy = srcPt.fY; +- +- if (fDstToIndexClass == kFixedStepInX_MatrixClass) { +- SkFixed fixedX, fixedY; +- (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY); +- dx = SkFixedToScalar(fixedX); +- dy = SkFixedToScalar(fixedY); +- } else { +- SkASSERT(fDstToIndexClass == kLinear_MatrixClass); +- dx = fDstToIndex.getScaleX(); +- dy = fDstToIndex.getSkewY(); +- } +- SkScalar b = (SkScalarMul(fDiff.fX, fx) + +- SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; +- SkScalar db = (SkScalarMul(fDiff.fX, dx) + +- SkScalarMul(fDiff.fY, dy)) * 2; +- if (proc == clamp_tileproc) { +- for (; count > 0; --count) { +- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); +- if (t < 0) { +- *dstC++ = cache[-1]; +- } else if (t > 0xFFFF) { +- *dstC++ = cache[kCache32Count * 2]; +- } else { +- SkASSERT(t <= 0xFFFF); +- *dstC++ = cache[t >> (16 - kCache32Bits)]; +- } +- fx += dx; +- fy += dy; +- b += db; +- } +- } else if (proc == mirror_tileproc) { +- for (; count > 0; --count) { +- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); +- SkFixed index = mirror_tileproc(t); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> (16 - kCache32Bits)]; +- fx += dx; +- fy += dy; +- b += db; +- } +- } else { +- SkASSERT(proc == repeat_tileproc); +- for (; count > 0; --count) { +- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); +- SkFixed index = repeat_tileproc(t); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> (16 - kCache32Bits)]; +- fx += dx; +- fy += dy; +- b += db; +- } +- } +- } else { // perspective case +- SkScalar dstX = SkIntToScalar(x); +- SkScalar dstY = SkIntToScalar(y); +- for (; count > 0; --count) { +- SkPoint srcPt; +- dstProc(fDstToIndex, dstX, dstY, &srcPt); +- SkScalar fx = srcPt.fX; +- SkScalar fy = srcPt.fY; +- SkScalar b = (SkScalarMul(fDiff.fX, fx) + +- SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; +- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); +- SkFixed index = proc(t); +- SkASSERT(index <= 0xFFFF); +- *dstC++ = cache[index >> (16 - kCache32Bits)]; +- dstX += SK_Scalar1; +- } +- } +- } ++ virtual void shadeSpan(int x, int y, SkPMColor* dstC, int count) SK_OVERRIDE; + + virtual bool setContext(const SkBitmap& device, + const SkPaint& paint, + const SkMatrix& matrix) SK_OVERRIDE { + if (!this->INHERITED::setContext(device, paint, matrix)) { + return false; + } + +@@ -1817,16 +1727,110 @@ private: + fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1; + fOneOverTwoA = fA ? SkScalarInvert(fA * 2) : 0; + + fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY); + fPtsToUnit.postScale(inv, inv); + } + }; + ++void Two_Point_Radial_Gradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) { ++ SkASSERT(count > 0); ++ ++ // Zero difference between radii: fill with transparent black. ++ // TODO: Is removing this actually correct? Two circles with the ++ // same radius, but different centers doesn't sound like it ++ // should be cleared ++ if (fDiffRadius == 0 && fCenter1 == fCenter2) { ++ sk_bzero(dstC, count * sizeof(*dstC)); ++ return; ++ } ++ SkMatrix::MapXYProc dstProc = fDstToIndexProc; ++ TileProc proc = fTileProc; ++ const SkPMColor* SK_RESTRICT cache = this->getCache32(); ++ ++ SkScalar foura = fA * 4; ++ bool posRoot = fDiffRadius < 0; ++ if (fDstToIndexClass != kPerspective_MatrixClass) { ++ SkPoint srcPt; ++ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, ++ SkIntToScalar(y) + SK_ScalarHalf, &srcPt); ++ SkScalar dx, fx = srcPt.fX; ++ SkScalar dy, fy = srcPt.fY; ++ ++ if (fDstToIndexClass == kFixedStepInX_MatrixClass) { ++ SkFixed fixedX, fixedY; ++ (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY); ++ dx = SkFixedToScalar(fixedX); ++ dy = SkFixedToScalar(fixedY); ++ } else { ++ SkASSERT(fDstToIndexClass == kLinear_MatrixClass); ++ dx = fDstToIndex.getScaleX(); ++ dy = fDstToIndex.getSkewY(); ++ } ++ SkScalar b = (SkScalarMul(fDiff.fX, fx) + ++ SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; ++ SkScalar db = (SkScalarMul(fDiff.fX, dx) + ++ SkScalarMul(fDiff.fY, dy)) * 2; ++ if (proc == clamp_tileproc) { ++ for (; count > 0; --count) { ++ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); ++ if (t < 0) { ++ *dstC++ = cache[-1]; ++ } else if (t > 0xFFFF) { ++ *dstC++ = cache[kCache32Count * 2]; ++ } else { ++ SkASSERT(t <= 0xFFFF); ++ *dstC++ = cache[t >> (16 - kCache32Bits)]; ++ } ++ fx += dx; ++ fy += dy; ++ b += db; ++ } ++ } else if (proc == mirror_tileproc) { ++ for (; count > 0; --count) { ++ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); ++ SkFixed index = mirror_tileproc(t); ++ SkASSERT(index <= 0xFFFF); ++ *dstC++ = cache[index >> (16 - kCache32Bits)]; ++ fx += dx; ++ fy += dy; ++ b += db; ++ } ++ } else { ++ SkASSERT(proc == repeat_tileproc); ++ for (; count > 0; --count) { ++ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); ++ SkFixed index = repeat_tileproc(t); ++ SkASSERT(index <= 0xFFFF); ++ *dstC++ = cache[index >> (16 - kCache32Bits)]; ++ fx += dx; ++ fy += dy; ++ b += db; ++ } ++ } ++ } else { // perspective case ++ SkScalar dstX = SkIntToScalar(x); ++ SkScalar dstY = SkIntToScalar(y); ++ for (; count > 0; --count) { ++ SkPoint srcPt; ++ dstProc(fDstToIndex, dstX, dstY, &srcPt); ++ SkScalar fx = srcPt.fX; ++ SkScalar fy = srcPt.fY; ++ SkScalar b = (SkScalarMul(fDiff.fX, fx) + ++ SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2; ++ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot); ++ SkFixed index = proc(t); ++ SkASSERT(index <= 0xFFFF); ++ *dstC++ = cache[index >> (16 - kCache32Bits)]; ++ dstX += SK_Scalar1; ++ } ++ } ++} ++ + /////////////////////////////////////////////////////////////////////////////// + + class Sweep_Gradient : public Gradient_Shader { + public: + Sweep_Gradient(SkScalar cx, SkScalar cy, const SkColor colors[], + const SkScalar pos[], int count, SkUnitMapper* mapper) + : Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper), + fCenter(SkPoint::Make(cx, cy)) diff --git a/gfx/skia/patches/archive/uninitialized-margin.patch b/gfx/skia/patches/archive/uninitialized-margin.patch new file mode 100644 index 0000000000..b8ab213e7b --- /dev/null +++ b/gfx/skia/patches/archive/uninitialized-margin.patch @@ -0,0 +1,22 @@ +diff --git a/gfx/skia/src/core/SkDraw.cpp b/gfx/skia/src/core/SkDraw.cpp +--- a/gfx/skia/src/core/SkDraw.cpp ++++ b/gfx/skia/src/core/SkDraw.cpp +@@ -2529,17 +2529,17 @@ static bool compute_bounds(const SkPath& + + // init our bounds from the path + { + SkRect pathBounds = devPath.getBounds(); + pathBounds.inset(-SK_ScalarHalf, -SK_ScalarHalf); + pathBounds.roundOut(bounds); + } + +- SkIPoint margin; ++ SkIPoint margin = SkIPoint::Make(0, 0); + if (filter) { + SkASSERT(filterMatrix); + + SkMask srcM, dstM; + + srcM.fBounds = *bounds; + srcM.fFormat = SkMask::kA8_Format; + srcM.fImage = NULL; diff --git a/gfx/skia/patches/archive/user-config.patch b/gfx/skia/patches/archive/user-config.patch new file mode 100644 index 0000000000..11c6f1f638 --- /dev/null +++ b/gfx/skia/patches/archive/user-config.patch @@ -0,0 +1,40 @@ +diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h +--- a/gfx/skia/include/config/SkUserConfig.h ++++ b/gfx/skia/include/config/SkUserConfig.h +@@ -140,16 +140,20 @@ + /* 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, +@@ -161,9 +165,15 @@ + */ + #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 |