From f4f6304ed502b6a3635170fd24b1e612762938ce Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Wed, 7 Aug 2013 15:22:05 +0000 Subject: Remove operator== from SkPaint R=mtklein@google.com, reed@google.com Author: sglez@google.com Review URL: https://chromiumcodereview.appspot.com/21949007 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10603 2bbb7eff-a529-9590-31e7-b0007b416f81 --- core/SkPaint.cpp | 9 --------- views/animated/SkStaticTextView.cpp | 9 +++------ 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/core/SkPaint.cpp b/core/SkPaint.cpp index 372e6805..32883662 100644 --- a/core/SkPaint.cpp +++ b/core/SkPaint.cpp @@ -161,15 +161,6 @@ SkPaint& SkPaint::operator=(const SkPaint& src) { return *this; } -bool operator==(const SkPaint& a, const SkPaint& b) { -#ifdef SK_BUILD_FOR_ANDROID - //assumes that fGenerationID is the last field in the struct - return !memcmp(&a, &b, SK_OFFSETOF(SkPaint, fGenerationID)); -#else - return !memcmp(&a, &b, sizeof(a)); -#endif -} - void SkPaint::reset() { SkPaint init; diff --git a/views/animated/SkStaticTextView.cpp b/views/animated/SkStaticTextView.cpp index 0e4cad63..bbef63df 100644 --- a/views/animated/SkStaticTextView.cpp +++ b/views/animated/SkStaticTextView.cpp @@ -125,12 +125,9 @@ void SkStaticTextView::getPaint(SkPaint* paint) const void SkStaticTextView::setPaint(const SkPaint& paint) { - if (fPaint != paint) - { - fPaint = paint; - this->computeSize(); - this->inval(NULL); - } + fPaint = paint; + this->computeSize(); + this->inval(NULL); } void SkStaticTextView::onDraw(SkCanvas* canvas) -- cgit v1.2.3 From 381cbec9bfb4397f69086ebe4fab7ecc751ab55c Mon Sep 17 00:00:00 2001 From: "bungeman@google.com" Date: Wed, 7 Aug 2013 15:46:29 +0000 Subject: Add getFamilyNames to SkTypeface. Committed: https://code.google.com/p/skia/source/detail?r=10589 Committed: https://code.google.com/p/skia/source/detail?r=10592 Review URL: https://codereview.chromium.org/21716005 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10608 2bbb7eff-a529-9590-31e7-b0007b416f81 --- core/SkTypeface.cpp | 4 ++-- fonts/SkGScalerContext.cpp | 4 ++-- ports/SkFontHost_FreeType.cpp | 2 +- ports/SkFontHost_FreeType_common.h | 2 +- ports/SkFontHost_mac.cpp | 4 ++-- ports/SkFontHost_win.cpp | 4 ++-- ports/SkFontHost_win_dw.cpp | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/SkTypeface.cpp b/core/SkTypeface.cpp index 507c1bf2..dbe0f603 100644 --- a/core/SkTypeface.cpp +++ b/core/SkTypeface.cpp @@ -194,8 +194,8 @@ int SkTypeface::getUnitsPerEm() const { return this->onGetUPEM(); } -SkTypeface::LocalizedStrings* SkTypeface::getFamilyNames() const { - return this->onGetFamilyNames(); +SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const { + return this->onCreateFamilyNameIterator(); } void SkTypeface::getFamilyName(SkString* name) const { diff --git a/fonts/SkGScalerContext.cpp b/fonts/SkGScalerContext.cpp index 34a55e6d..2c4ebe50 100644 --- a/fonts/SkGScalerContext.cpp +++ b/fonts/SkGScalerContext.cpp @@ -202,8 +202,8 @@ int SkGTypeface::onGetUPEM() const { return fProxy->getUnitsPerEm(); } -SkTypeface::LocalizedStrings* SkGTypeface::onGetFamilyNames() const { - return fProxy->getFamilyNames(); +SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const { + return fProxy->createFamilyNameIterator(); } int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const { diff --git a/ports/SkFontHost_FreeType.cpp b/ports/SkFontHost_FreeType.cpp index c5542a9d..3a8a1ae2 100644 --- a/ports/SkFontHost_FreeType.cpp +++ b/ports/SkFontHost_FreeType.cpp @@ -1403,7 +1403,7 @@ int SkTypeface_FreeType::onCountGlyphs() const { return fGlyphCount; } -SkTypeface::LocalizedStrings* SkTypeface_FreeType::onGetFamilyNames() const { +SkTypeface::LocalizedStrings* SkTypeface_FreeType::onCreateFamilyNameIterator() const { SkTypeface::LocalizedStrings* nameIter = SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); if (NULL == nameIter) { diff --git a/ports/SkFontHost_FreeType_common.h b/ports/SkFontHost_FreeType_common.h index 5c069d04..c0f2dc75 100644 --- a/ports/SkFontHost_FreeType_common.h +++ b/ports/SkFontHost_FreeType_common.h @@ -64,7 +64,7 @@ protected: int glyphCount) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; - virtual LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; + virtual LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, diff --git a/ports/SkFontHost_mac.cpp b/ports/SkFontHost_mac.cpp index 9600730f..987f1851 100755 --- a/ports/SkFontHost_mac.cpp +++ b/ports/SkFontHost_mac.cpp @@ -454,7 +454,7 @@ protected: virtual int onGetUPEM() const SK_OVERRIDE; virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; - virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; + virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const SK_OVERRIDE; @@ -1750,7 +1750,7 @@ int SkTypeface_Mac::onGetUPEM() const { return CGFontGetUnitsPerEm(cgFont); } -SkTypeface::LocalizedStrings* SkTypeface_Mac::onGetFamilyNames() const { +SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const { SkTypeface::LocalizedStrings* nameIter = SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); if (NULL == nameIter) { diff --git a/ports/SkFontHost_win.cpp b/ports/SkFontHost_win.cpp index d52774ca..708c66fd 100755 --- a/ports/SkFontHost_win.cpp +++ b/ports/SkFontHost_win.cpp @@ -268,7 +268,7 @@ protected: virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; virtual int onGetUPEM() const SK_OVERRIDE; - virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; + virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const SK_OVERRIDE; @@ -2056,7 +2056,7 @@ int LogFontTypeface::onGetUPEM() const { return upem; } -SkTypeface::LocalizedStrings* LogFontTypeface::onGetFamilyNames() const { +SkTypeface::LocalizedStrings* LogFontTypeface::onCreateFamilyNameIterator() const { SkTypeface::LocalizedStrings* nameIter = SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); if (NULL == nameIter) { diff --git a/ports/SkFontHost_win_dw.cpp b/ports/SkFontHost_win_dw.cpp index cee8b362..5df90b47 100644 --- a/ports/SkFontHost_win_dw.cpp +++ b/ports/SkFontHost_win_dw.cpp @@ -495,7 +495,7 @@ protected: virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; virtual int onGetUPEM() const SK_OVERRIDE; - virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; + virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const SK_OVERRIDE; @@ -1130,7 +1130,7 @@ private: SkTScopedComPtr fStrings; }; -SkTypeface::LocalizedStrings* DWriteFontTypeface::onGetFamilyNames() const { +SkTypeface::LocalizedStrings* DWriteFontTypeface::onCreateFamilyNameIterator() const { SkTScopedComPtr familyNames; HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain family names."); -- cgit v1.2.3 From 3bdb8e323a07148ea95c62497dfcfed49c7c2a0a Mon Sep 17 00:00:00 2001 From: "robertphillips@google.com" Date: Wed, 7 Aug 2013 15:56:51 +0000 Subject: Reverting r10608 (Add getFamilyNames to SkTypeface) due to compilation failures git-svn-id: http://skia.googlecode.com/svn/trunk/src@10609 2bbb7eff-a529-9590-31e7-b0007b416f81 --- core/SkTypeface.cpp | 4 ++-- fonts/SkGScalerContext.cpp | 4 ++-- ports/SkFontHost_FreeType.cpp | 2 +- ports/SkFontHost_FreeType_common.h | 2 +- ports/SkFontHost_mac.cpp | 4 ++-- ports/SkFontHost_win.cpp | 4 ++-- ports/SkFontHost_win_dw.cpp | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/SkTypeface.cpp b/core/SkTypeface.cpp index dbe0f603..507c1bf2 100644 --- a/core/SkTypeface.cpp +++ b/core/SkTypeface.cpp @@ -194,8 +194,8 @@ int SkTypeface::getUnitsPerEm() const { return this->onGetUPEM(); } -SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const { - return this->onCreateFamilyNameIterator(); +SkTypeface::LocalizedStrings* SkTypeface::getFamilyNames() const { + return this->onGetFamilyNames(); } void SkTypeface::getFamilyName(SkString* name) const { diff --git a/fonts/SkGScalerContext.cpp b/fonts/SkGScalerContext.cpp index 2c4ebe50..34a55e6d 100644 --- a/fonts/SkGScalerContext.cpp +++ b/fonts/SkGScalerContext.cpp @@ -202,8 +202,8 @@ int SkGTypeface::onGetUPEM() const { return fProxy->getUnitsPerEm(); } -SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const { - return fProxy->createFamilyNameIterator(); +SkTypeface::LocalizedStrings* SkGTypeface::onGetFamilyNames() const { + return fProxy->getFamilyNames(); } int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const { diff --git a/ports/SkFontHost_FreeType.cpp b/ports/SkFontHost_FreeType.cpp index 3a8a1ae2..c5542a9d 100644 --- a/ports/SkFontHost_FreeType.cpp +++ b/ports/SkFontHost_FreeType.cpp @@ -1403,7 +1403,7 @@ int SkTypeface_FreeType::onCountGlyphs() const { return fGlyphCount; } -SkTypeface::LocalizedStrings* SkTypeface_FreeType::onCreateFamilyNameIterator() const { +SkTypeface::LocalizedStrings* SkTypeface_FreeType::onGetFamilyNames() const { SkTypeface::LocalizedStrings* nameIter = SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); if (NULL == nameIter) { diff --git a/ports/SkFontHost_FreeType_common.h b/ports/SkFontHost_FreeType_common.h index c0f2dc75..5c069d04 100644 --- a/ports/SkFontHost_FreeType_common.h +++ b/ports/SkFontHost_FreeType_common.h @@ -64,7 +64,7 @@ protected: int glyphCount) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; - virtual LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; + virtual LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, diff --git a/ports/SkFontHost_mac.cpp b/ports/SkFontHost_mac.cpp index 987f1851..9600730f 100755 --- a/ports/SkFontHost_mac.cpp +++ b/ports/SkFontHost_mac.cpp @@ -454,7 +454,7 @@ protected: virtual int onGetUPEM() const SK_OVERRIDE; virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; - virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; + virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const SK_OVERRIDE; @@ -1750,7 +1750,7 @@ int SkTypeface_Mac::onGetUPEM() const { return CGFontGetUnitsPerEm(cgFont); } -SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const { +SkTypeface::LocalizedStrings* SkTypeface_Mac::onGetFamilyNames() const { SkTypeface::LocalizedStrings* nameIter = SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); if (NULL == nameIter) { diff --git a/ports/SkFontHost_win.cpp b/ports/SkFontHost_win.cpp index 708c66fd..d52774ca 100755 --- a/ports/SkFontHost_win.cpp +++ b/ports/SkFontHost_win.cpp @@ -268,7 +268,7 @@ protected: virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; virtual int onGetUPEM() const SK_OVERRIDE; - virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; + virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const SK_OVERRIDE; @@ -2056,7 +2056,7 @@ int LogFontTypeface::onGetUPEM() const { return upem; } -SkTypeface::LocalizedStrings* LogFontTypeface::onCreateFamilyNameIterator() const { +SkTypeface::LocalizedStrings* LogFontTypeface::onGetFamilyNames() const { SkTypeface::LocalizedStrings* nameIter = SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); if (NULL == nameIter) { diff --git a/ports/SkFontHost_win_dw.cpp b/ports/SkFontHost_win_dw.cpp index 5df90b47..cee8b362 100644 --- a/ports/SkFontHost_win_dw.cpp +++ b/ports/SkFontHost_win_dw.cpp @@ -495,7 +495,7 @@ protected: virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; virtual int onGetUPEM() const SK_OVERRIDE; - virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; + virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const SK_OVERRIDE; @@ -1130,7 +1130,7 @@ private: SkTScopedComPtr fStrings; }; -SkTypeface::LocalizedStrings* DWriteFontTypeface::onCreateFamilyNameIterator() const { +SkTypeface::LocalizedStrings* DWriteFontTypeface::onGetFamilyNames() const { SkTScopedComPtr familyNames; HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain family names."); -- cgit v1.2.3 From 2d48d6a987023527eae7e12e5b7c21a41fb6ccaa Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Wed, 7 Aug 2013 16:22:47 +0000 Subject: Add SkCanvas::drawPosTextBounded. This allows subclasses which need bounding box information to get it from the caller if it has already been computed. BUG=chromium:269080 R=reed@google.com, tomhudson@chromium.org, tomhudson@google.com Author: jbroman@chromium.org Review URL: https://chromiumcodereview.appspot.com/22585002 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10612 2bbb7eff-a529-9590-31e7-b0007b416f81 --- core/SkBBoxRecord.cpp | 8 ++++++++ core/SkBBoxRecord.h | 3 +++ core/SkCanvas.cpp | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/core/SkBBoxRecord.cpp b/core/SkBBoxRecord.cpp index 52d599f5..666e4409 100644 --- a/core/SkBBoxRecord.cpp +++ b/core/SkBBoxRecord.cpp @@ -176,6 +176,14 @@ void SkBBoxRecord::drawPosText(const void* text, size_t byteLength, } } +void SkBBoxRecord::drawPosTextBounded(const void* text, size_t byteLength, + const SkPoint pos[], const SkRect& bbox, + const SkPaint& paint) { + if (this->transformBounds(bbox, &paint)) { + INHERITED::drawPosText(text, byteLength, pos, paint); + } +} + void SkBBoxRecord::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { SkRect bbox; diff --git a/core/SkBBoxRecord.h b/core/SkBBoxRecord.h index 9f796717..16dd8fff 100644 --- a/core/SkBBoxRecord.h +++ b/core/SkBBoxRecord.h @@ -49,6 +49,9 @@ public: const SkRect& dst, const SkPaint* paint) SK_OVERRIDE; virtual void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) SK_OVERRIDE; + virtual void drawPosTextBounded(const void* text, size_t byteLength, + const SkPoint pos[], const SkRect& bbox, + const SkPaint& paint) SK_OVERRIDE; virtual void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) SK_OVERRIDE; diff --git a/core/SkCanvas.cpp b/core/SkCanvas.cpp index 5a9a56b2..232bee33 100644 --- a/core/SkCanvas.cpp +++ b/core/SkCanvas.cpp @@ -1990,6 +1990,12 @@ void SkCanvas::drawPosText(const void* text, size_t byteLength, LOOPER_END } +void SkCanvas::drawPosTextBounded(const void* text, size_t byteLength, + const SkPoint pos[], const SkRect& bbox, + const SkPaint& paint) { + this->drawPosText(text, byteLength, pos, paint); +} + void SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { -- cgit v1.2.3 From ee2ecacf2de84506c14c6e516a5ed84da0920403 Mon Sep 17 00:00:00 2001 From: "bungeman@google.com" Date: Wed, 7 Aug 2013 17:09:22 +0000 Subject: Add getFamilyNames to SkTypeface. Committed: https://code.google.com/p/skia/source/detail?r=10589 Committed: https://code.google.com/p/skia/source/detail?r=10592 Committed: https://code.google.com/p/skia/source/detail?r=10608 Review URL: https://codereview.chromium.org/21716005 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10615 2bbb7eff-a529-9590-31e7-b0007b416f81 --- core/SkTypeface.cpp | 4 ++-- fonts/SkGScalerContext.cpp | 4 ++-- fonts/SkGScalerContext.h | 2 +- ports/SkFontHost_FreeType.cpp | 2 +- ports/SkFontHost_FreeType_common.h | 2 +- ports/SkFontHost_mac.cpp | 4 ++-- ports/SkFontHost_win.cpp | 4 ++-- ports/SkFontHost_win_dw.cpp | 4 ++-- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/SkTypeface.cpp b/core/SkTypeface.cpp index 507c1bf2..dbe0f603 100644 --- a/core/SkTypeface.cpp +++ b/core/SkTypeface.cpp @@ -194,8 +194,8 @@ int SkTypeface::getUnitsPerEm() const { return this->onGetUPEM(); } -SkTypeface::LocalizedStrings* SkTypeface::getFamilyNames() const { - return this->onGetFamilyNames(); +SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const { + return this->onCreateFamilyNameIterator(); } void SkTypeface::getFamilyName(SkString* name) const { diff --git a/fonts/SkGScalerContext.cpp b/fonts/SkGScalerContext.cpp index 34a55e6d..2c4ebe50 100644 --- a/fonts/SkGScalerContext.cpp +++ b/fonts/SkGScalerContext.cpp @@ -202,8 +202,8 @@ int SkGTypeface::onGetUPEM() const { return fProxy->getUnitsPerEm(); } -SkTypeface::LocalizedStrings* SkGTypeface::onGetFamilyNames() const { - return fProxy->getFamilyNames(); +SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const { + return fProxy->createFamilyNameIterator(); } int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const { diff --git a/fonts/SkGScalerContext.h b/fonts/SkGScalerContext.h index 0a06b7c1..5e73850a 100644 --- a/fonts/SkGScalerContext.h +++ b/fonts/SkGScalerContext.h @@ -32,7 +32,7 @@ protected: virtual int onCountGlyphs() const SK_OVERRIDE; virtual int onGetUPEM() const SK_OVERRIDE; - virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; + virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, diff --git a/ports/SkFontHost_FreeType.cpp b/ports/SkFontHost_FreeType.cpp index c5542a9d..3a8a1ae2 100644 --- a/ports/SkFontHost_FreeType.cpp +++ b/ports/SkFontHost_FreeType.cpp @@ -1403,7 +1403,7 @@ int SkTypeface_FreeType::onCountGlyphs() const { return fGlyphCount; } -SkTypeface::LocalizedStrings* SkTypeface_FreeType::onGetFamilyNames() const { +SkTypeface::LocalizedStrings* SkTypeface_FreeType::onCreateFamilyNameIterator() const { SkTypeface::LocalizedStrings* nameIter = SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); if (NULL == nameIter) { diff --git a/ports/SkFontHost_FreeType_common.h b/ports/SkFontHost_FreeType_common.h index 5c069d04..c0f2dc75 100644 --- a/ports/SkFontHost_FreeType_common.h +++ b/ports/SkFontHost_FreeType_common.h @@ -64,7 +64,7 @@ protected: int glyphCount) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; - virtual LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; + virtual LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, diff --git a/ports/SkFontHost_mac.cpp b/ports/SkFontHost_mac.cpp index 9600730f..987f1851 100755 --- a/ports/SkFontHost_mac.cpp +++ b/ports/SkFontHost_mac.cpp @@ -454,7 +454,7 @@ protected: virtual int onGetUPEM() const SK_OVERRIDE; virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; - virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; + virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const SK_OVERRIDE; @@ -1750,7 +1750,7 @@ int SkTypeface_Mac::onGetUPEM() const { return CGFontGetUnitsPerEm(cgFont); } -SkTypeface::LocalizedStrings* SkTypeface_Mac::onGetFamilyNames() const { +SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const { SkTypeface::LocalizedStrings* nameIter = SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); if (NULL == nameIter) { diff --git a/ports/SkFontHost_win.cpp b/ports/SkFontHost_win.cpp index d52774ca..708c66fd 100755 --- a/ports/SkFontHost_win.cpp +++ b/ports/SkFontHost_win.cpp @@ -268,7 +268,7 @@ protected: virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; virtual int onGetUPEM() const SK_OVERRIDE; - virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; + virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const SK_OVERRIDE; @@ -2056,7 +2056,7 @@ int LogFontTypeface::onGetUPEM() const { return upem; } -SkTypeface::LocalizedStrings* LogFontTypeface::onGetFamilyNames() const { +SkTypeface::LocalizedStrings* LogFontTypeface::onCreateFamilyNameIterator() const { SkTypeface::LocalizedStrings* nameIter = SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); if (NULL == nameIter) { diff --git a/ports/SkFontHost_win_dw.cpp b/ports/SkFontHost_win_dw.cpp index cee8b362..5df90b47 100644 --- a/ports/SkFontHost_win_dw.cpp +++ b/ports/SkFontHost_win_dw.cpp @@ -495,7 +495,7 @@ protected: virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; virtual int onGetUPEM() const SK_OVERRIDE; - virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE; + virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE; virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; virtual size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const SK_OVERRIDE; @@ -1130,7 +1130,7 @@ private: SkTScopedComPtr fStrings; }; -SkTypeface::LocalizedStrings* DWriteFontTypeface::onGetFamilyNames() const { +SkTypeface::LocalizedStrings* DWriteFontTypeface::onCreateFamilyNameIterator() const { SkTScopedComPtr familyNames; HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain family names."); -- cgit v1.2.3 From 2484f9bdddeef520f035d8da0e2c75626cb3224c Mon Sep 17 00:00:00 2001 From: "scroggo@google.com" Date: Wed, 7 Aug 2013 19:16:05 +0000 Subject: Add downsample from 8888 to 4444. Extend SkBitmap::copyTo to copy from a source with SkARGB_8888_Config to a destination bitmap with SkARGB_4444_Config. BUG=http://code.google.com/p/chromium/issues/detail?id=245774 R=reed@google.com Review URL: https://codereview.chromium.org/22350003 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10621 2bbb7eff-a529-9590-31e7-b0007b416f81 --- core/SkBitmap.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/core/SkBitmap.cpp b/core/SkBitmap.cpp index 9a116dfc..d3bbecd7 100644 --- a/core/SkBitmap.cpp +++ b/core/SkBitmap.cpp @@ -1017,11 +1017,12 @@ bool SkBitmap::canCopyTo(Config dstConfig) const { break; case kA1_Config: case kIndex8_Config: - case kARGB_4444_Config: if (!sameConfigs) { return false; } break; + case kARGB_4444_Config: + return sameConfigs || kARGB_8888_Config == this->config(); default: return false; } @@ -1109,6 +1110,19 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { dstP += tmpDst.rowBytes(); } } + } else if (SkBitmap::kARGB_4444_Config == dstConfig + && SkBitmap::kARGB_8888_Config == src->config()) { + SkASSERT(src->height() == tmpDst.height()); + SkASSERT(src->width() == tmpDst.width()); + for (int y = 0; y < src->height(); ++y) { + SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y); + SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y); + DITHER_4444_SCAN(y); + for (int x = 0; x < src->width(); ++x) { + dstRow[x] = SkDitherARGB32To4444(srcRow[x], + DITHER_VALUE(x)); + } + } } else { // if the src has alpha, we have to clear the dst first if (!src->isOpaque()) { -- cgit v1.2.3 From 26b0f38c98172733fb1b03662703b3f713121ceb Mon Sep 17 00:00:00 2001 From: "mtklein@google.com" Date: Wed, 7 Aug 2013 19:17:53 +0000 Subject: Restore SkPath(const SkPath&) to copy the generation ID on Android. BUG= R=bsalomon@google.com, bungeman@google.com, reed@google.com Review URL: https://codereview.chromium.org/22471002 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10622 2bbb7eff-a529-9590-31e7-b0007b416f81 --- core/SkPath.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/core/SkPath.cpp b/core/SkPath.cpp index 875be980..f5b8bd5e 100644 --- a/core/SkPath.cpp +++ b/core/SkPath.cpp @@ -185,12 +185,12 @@ void SkPath::resetFields() { } SkPath::SkPath(const SkPath& that) - : fPathRef(SkRef(that.fPathRef.get())) + : fPathRef(SkRef(that.fPathRef.get())) { + this->copyFields(that); #ifdef SK_BUILD_FOR_ANDROID - , fGenerationID(0) + fGenerationID = that.fGenerationID; + fSourcePath = NULL; // TODO(mtklein): follow up with Android: do we want to copy this too? #endif -{ - this->copyFields(that); SkDEBUGCODE(that.validate();) } @@ -204,6 +204,10 @@ SkPath& SkPath::operator=(const SkPath& that) { if (this != &that) { fPathRef.reset(SkRef(that.fPathRef.get())); this->copyFields(that); +#ifdef SK_BUILD_FOR_ANDROID + GEN_ID_INC; // Similar to swap, we can't just copy this or it could go back in time. + fSourcePath = NULL; // TODO(mtklein): follow up with Android: do we want to copy this too? +#endif } SkDEBUGCODE(this->validate();) return *this; @@ -220,10 +224,6 @@ void SkPath::copyFields(const SkPath& that) { fDirection = that.fDirection; fIsFinite = that.fIsFinite; fIsOval = that.fIsOval; -#ifdef SK_BUILD_FOR_ANDROID - GEN_ID_INC; - fSourcePath = NULL; -#endif } SK_API bool operator==(const SkPath& a, const SkPath& b) { @@ -253,8 +253,13 @@ void SkPath::swap(SkPath& that) { SkTSwap(fDirection, that.fDirection); SkTSwap(fIsFinite, that.fIsFinite); SkTSwap(fIsOval, that.fIsOval); +#ifdef SK_BUILD_FOR_ANDROID + // It doesn't really make sense to swap the generation IDs here, because they might go + // backwards. To be safe we increment both to mark them both as changed. GEN_ID_INC; GEN_ID_PTR_INC(&that); + SkTSwap(fSourcePath, that.fSourcePath); +#endif } } -- cgit v1.2.3 From 807d729d8f5b0048d3691ad3513a8adab5011998 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Wed, 7 Aug 2013 19:43:45 +0000 Subject: Fix BGRA readback on Android R=bsalomon@google.com, robertphillips@google.com Author: snorp@snorp.net Review URL: https://chromiumcodereview.appspot.com/22522002 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10624 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gpu/gl/GrGpuGL.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/gpu/gl/GrGpuGL.cpp b/gpu/gl/GrGpuGL.cpp index cc999438..5845d7a6 100644 --- a/gpu/gl/GrGpuGL.cpp +++ b/gpu/gl/GrGpuGL.cpp @@ -231,29 +231,32 @@ void GrGpuGL::fillInConfigRenderableTable() { } } -namespace { -GrPixelConfig preferred_pixel_ops_config(GrPixelConfig cpuConfig, GrPixelConfig surfaceConfig) { - if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == cpuConfig) { +GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig readConfig, + GrPixelConfig surfaceConfig) const { + if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig) { return kBGRA_8888_GrPixelConfig; - } else if (GrBytesPerPixel(cpuConfig) == 4 && - GrPixelConfigSwapRAndB(cpuConfig) == surfaceConfig) { + } else if (fGLContext.info().isMesa() && + GrBytesPerPixel(readConfig) == 4 && + GrPixelConfigSwapRAndB(readConfig) == surfaceConfig) { // Mesa 3D takes a slow path on when reading back BGRA from an RGBA surface and vice-versa. // Perhaps this should be guarded by some compiletime or runtime check. return surfaceConfig; + } else if (readConfig == kBGRA_8888_GrPixelConfig && + !this->glCaps().readPixelsSupported(this->glInterface(), + GR_GL_BGRA, GR_GL_UNSIGNED_BYTE)) { + return kRGBA_8888_GrPixelConfig; } else { - return cpuConfig; + return readConfig; } } -} - -GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig readConfig, - GrPixelConfig surfaceConfig) const { - return preferred_pixel_ops_config(readConfig, surfaceConfig); -} GrPixelConfig GrGpuGL::preferredWritePixelsConfig(GrPixelConfig writeConfig, GrPixelConfig surfaceConfig) const { - return preferred_pixel_ops_config(writeConfig, surfaceConfig); + if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == writeConfig) { + return kBGRA_8888_GrPixelConfig; + } else { + return writeConfig; + } } bool GrGpuGL::canWriteTexturePixels(const GrTexture* texture, GrPixelConfig srcConfig) const { -- cgit v1.2.3 From 47a939d1c3ccf83d6a64c225cb629650e128ecd6 Mon Sep 17 00:00:00 2001 From: "scroggo@google.com" Date: Wed, 7 Aug 2013 19:53:53 +0000 Subject: Support decoding subsets from JPG on Android. Previously we only supported it for the framework. Making this change allows us to test subset decoding in skimage, to make sure we don't break it. Will require rebaselining android skimage results. R=djsollen@google.com Review URL: https://codereview.chromium.org/21612003 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10625 2bbb7eff-a529-9590-31e7-b0007b416f81 --- images/SkImageDecoder_libjpeg.cpp | 19 ++++++------------- images/SkJpegUtility.cpp | 17 +++++------------ 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/images/SkImageDecoder_libjpeg.cpp b/images/SkImageDecoder_libjpeg.cpp index 81904ae5..d4047f19 100644 --- a/images/SkImageDecoder_libjpeg.cpp +++ b/images/SkImageDecoder_libjpeg.cpp @@ -1,4 +1,3 @@ - /* * Copyright 2007 The Android Open Source Project * @@ -26,12 +25,6 @@ extern "C" { #include "jerror.h" } -// Uncomment to enable the code path used by the Android framework with their -// custom image decoders. -//#if defined(SK_BUILD_FOR_ANDROID) && defined(SK_DEBUG) -// #define SK_BUILD_FOR_ANDROID_FRAMEWORK -//#endif - // These enable timing code that report milliseconds for an encoding/decoding //#define TIME_ENCODE //#define TIME_DECODE @@ -68,7 +61,7 @@ public: : fSrcMgr(stream, decoder) {} ~SkJPEGImageIndex() { -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID jpeg_destroy_huffman_index(&fHuffmanIndex); #endif jpeg_finish_decompress(&fCInfo); @@ -87,14 +80,14 @@ public: jpeg_decompress_struct* cinfo() { return &fCInfo; } -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID huffman_index* huffmanIndex() { return &fHuffmanIndex; } #endif private: skjpeg_source_mgr fSrcMgr; jpeg_decompress_struct fCInfo; -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID huffman_index fHuffmanIndex; #endif }; @@ -116,7 +109,7 @@ public: } protected: -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID virtual bool onBuildTileIndex(SkStream *stream, int *width, int *height) SK_OVERRIDE; virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRIDE; #endif @@ -180,7 +173,7 @@ static bool skip_src_rows(jpeg_decompress_struct* cinfo, void* buffer, int count return true; } -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID static bool skip_src_rows_tile(jpeg_decompress_struct* cinfo, huffman_index *index, void* buffer, int count) { for (int i = 0; i < count; i++) { @@ -479,7 +472,7 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { return true; } -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, int *width, int *height) { SkJPEGImageIndex* imageIndex = SkNEW_ARGS(SkJPEGImageIndex, (stream, this)); diff --git a/images/SkJpegUtility.cpp b/images/SkJpegUtility.cpp index 1f426f21..8d8f62f5 100644 --- a/images/SkJpegUtility.cpp +++ b/images/SkJpegUtility.cpp @@ -1,4 +1,3 @@ - /* * Copyright 2010 The Android Open Source Project * @@ -9,24 +8,18 @@ #include "SkJpegUtility.h" -// Uncomment to enable the code path used by the Android framework with their -// custom image decoders. -//#if defined(SK_BUILD_FOR_ANDROID) && defined(SK_DEBUG) -// #define SK_BUILD_FOR_ANDROID_FRAMEWORK -//#endif - ///////////////////////////////////////////////////////////////////// static void sk_init_source(j_decompress_ptr cinfo) { skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src; src->next_input_byte = (const JOCTET*)src->fBuffer; src->bytes_in_buffer = 0; -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID src->current_offset = 0; #endif src->fStream->rewind(); } -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID static boolean sk_seek_input_data(j_decompress_ptr cinfo, long byte_offset) { skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src; size_t bo = (size_t) byte_offset; @@ -57,7 +50,7 @@ static boolean sk_fill_input_buffer(j_decompress_ptr cinfo) { return FALSE; } -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID src->current_offset += bytes; #endif src->next_input_byte = (const JOCTET*)src->fBuffer; @@ -77,7 +70,7 @@ static void sk_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { cinfo->err->error_exit((j_common_ptr)cinfo); return; } -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID src->current_offset += bytes; #endif bytesToSkip -= bytes; @@ -119,7 +112,7 @@ skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder) skip_input_data = sk_skip_input_data; resync_to_restart = sk_resync_to_restart; term_source = sk_term_source; -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +#ifdef SK_BUILD_FOR_ANDROID seek_input_data = sk_seek_input_data; #endif // SkDebugf("**************** use memorybase %p %d\n", fMemoryBase, fMemoryBaseSize); -- cgit v1.2.3 From 70369e93981ba6a28fccc44c040b6b9a97fb4c08 Mon Sep 17 00:00:00 2001 From: "junov@chromium.org" Date: Wed, 7 Aug 2013 20:00:55 +0000 Subject: Upstreaming DropShadowImageFilter into skia, from Blink GM imagefiltersbase will need rebaselining after this change R=senorblanco@chromium.org Committed: https://code.google.com/p/skia/source/detail?r=10583 Review URL: https://codereview.chromium.org/22258005 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10626 2bbb7eff-a529-9590-31e7-b0007b416f81 --- effects/SkDropShadowImageFilter.cpp | 63 ++++++++++++++++++++++++++++++++ ports/SkGlobalInitialization_default.cpp | 2 + 2 files changed, 65 insertions(+) create mode 100644 effects/SkDropShadowImageFilter.cpp diff --git a/effects/SkDropShadowImageFilter.cpp b/effects/SkDropShadowImageFilter.cpp new file mode 100644 index 00000000..c9cfd602 --- /dev/null +++ b/effects/SkDropShadowImageFilter.cpp @@ -0,0 +1,63 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkDropShadowImageFilter.h" + +#include "SkBitmap.h" +#include "SkBlurImageFilter.h" +#include "SkCanvas.h" +#include "SkColorMatrixFilter.h" +#include "SkDevice.h" +#include "SkFlattenableBuffers.h" + +SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor color, SkImageFilter* input) + : SkImageFilter(input) + , fDx(dx) + , fDy(dy) + , fSigma(sigma) + , fColor(color) +{ +} + +SkDropShadowImageFilter::SkDropShadowImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) +{ + fDx = buffer.readScalar(); + fDy = buffer.readScalar(); + fSigma = buffer.readScalar(); + fColor = buffer.readColor(); +} + +void SkDropShadowImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const +{ + this->INHERITED::flatten(buffer); + buffer.writeScalar(fDx); + buffer.writeScalar(fDy); + buffer.writeScalar(fSigma); + buffer.writeColor(fColor); +} + +bool SkDropShadowImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, const SkMatrix& matrix, SkBitmap* result, SkIPoint* loc) +{ + SkBitmap src = source; + if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, loc)) + return false; + + SkAutoTUnref device(proxy->createDevice(src.width(), src.height())); + SkCanvas canvas(device.get()); + + SkAutoTUnref blurFilter(new SkBlurImageFilter(fSigma, fSigma)); + SkAutoTUnref colorFilter(SkColorFilter::CreateModeFilter(fColor, SkXfermode::kSrcIn_Mode)); + SkPaint paint; + paint.setImageFilter(blurFilter.get()); + paint.setColorFilter(colorFilter.get()); + paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); + canvas.drawBitmap(src, fDx, fDy, &paint); + canvas.drawBitmap(src, 0, 0); + *result = device->accessBitmap(false); + return true; +} + diff --git a/ports/SkGlobalInitialization_default.cpp b/ports/SkGlobalInitialization_default.cpp index a85fb6d1..24edd31e 100644 --- a/ports/SkGlobalInitialization_default.cpp +++ b/ports/SkGlobalInitialization_default.cpp @@ -36,6 +36,7 @@ #include "SkDataSet.h" #include "SkDiscretePathEffect.h" #include "SkDisplacementMapEffect.h" +#include "SkDropShadowImageFilter.h" #include "SkEmptyShader.h" #include "SkEmbossMaskFilter.h" #include "SkFlattenable.h" @@ -78,6 +79,7 @@ void SkFlattenable::InitializeFlattenables() { SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDilateImageFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiscretePathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDisplacementMapEffect) + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDropShadowImageFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmbossMaskFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmptyShader) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkErodeImageFilter) -- cgit v1.2.3 From ed850abd7cbac8c6e90fba694c10fd98330fa9ca Mon Sep 17 00:00:00 2001 From: "scroggo@google.com" Date: Wed, 7 Aug 2013 21:02:32 +0000 Subject: Fix failure exits from JPEG onBuildTileIndex. The setjmp exited without deleting the SkJPEGImageIndex, and another exit condition deleted the huffman index even though it had not been created yet. Create member functions on SkJPEGImageIndex to make the jpeg calls so it can keep track of what has been created, and avoid destroying anything else. Remove unnecessary lines to set values to their default values. Move all SkJPEGImageIndex code entirely inside #ifdef ANDROID blocks, since no piece of it is used except by ANDROID only code. BUG=skia:1471 R=djsollen@google.com, mtklein@google.com Review URL: https://codereview.chromium.org/21891007 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10628 2bbb7eff-a529-9590-31e7-b0007b416f81 --- images/SkImageDecoder_libjpeg.cpp | 130 ++++++++++++++++++++++++++++---------- 1 file changed, 95 insertions(+), 35 deletions(-) diff --git a/images/SkImageDecoder_libjpeg.cpp b/images/SkImageDecoder_libjpeg.cpp index d4047f19..914ceb7e 100644 --- a/images/SkImageDecoder_libjpeg.cpp +++ b/images/SkImageDecoder_libjpeg.cpp @@ -55,45 +55,115 @@ static void overwrite_mem_buffer_size(j_decompress_ptr cinfo) { ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +#ifdef SK_BUILD_FOR_ANDROID class SkJPEGImageIndex { public: SkJPEGImageIndex(SkStream* stream, SkImageDecoder* decoder) - : fSrcMgr(stream, decoder) {} + : fSrcMgr(stream, decoder) + , fInfoInitialized(false) + , fHuffmanCreated(false) + , fDecompressStarted(false) + { + SkDEBUGCODE(fReadHeaderSucceeded = false;) + } ~SkJPEGImageIndex() { -#ifdef SK_BUILD_FOR_ANDROID - jpeg_destroy_huffman_index(&fHuffmanIndex); -#endif - jpeg_finish_decompress(&fCInfo); + if (fHuffmanCreated) { + fHuffmanCreated = false; + jpeg_destroy_huffman_index(&fHuffmanIndex); + } + if (fDecompressStarted) { + fDecompressStarted = false; + jpeg_finish_decompress(&fCInfo); + } + if (fInfoInitialized) { + this->destroyInfo(); + } + } + + /** + * Destroy the cinfo struct. + * After this call, if a huffman index was already built, it + * can be used after calling initializeInfoAndReadHeader + * again. Must not be called after startTileDecompress except + * in the destructor. + */ + void destroyInfo() { + SkASSERT(fInfoInitialized); + SkASSERT(!fDecompressStarted); + fInfoInitialized = false; jpeg_destroy_decompress(&fCInfo); + SkDEBUGCODE(fReadHeaderSucceeded = false;) } /** - * Init the cinfo struct using libjpeg and apply any necessary - * customizations. + * Initialize the cinfo struct. + * Calls jpeg_create_decompress, makes customizations, and + * finally calls jpeg_read_header. Returns true if jpeg_read_header + * returns JPEG_HEADER_OK. + * If cinfo was already initialized, destroyInfo must be called to + * destroy the old one. Must not be called after startTileDecompress. */ - void initializeInfo() { + bool initializeInfoAndReadHeader() { + SkASSERT(!fInfoInitialized && !fDecompressStarted); jpeg_create_decompress(&fCInfo); overwrite_mem_buffer_size(&fCInfo); fCInfo.src = &fSrcMgr; + fInfoInitialized = true; + const bool success = (JPEG_HEADER_OK == jpeg_read_header(&fCInfo, true)); + SkDEBUGCODE(fReadHeaderSucceeded = success;) + return success; } jpeg_decompress_struct* cinfo() { return &fCInfo; } -#ifdef SK_BUILD_FOR_ANDROID huffman_index* huffmanIndex() { return &fHuffmanIndex; } -#endif + + /** + * Build the index to be used for tile based decoding. + * Must only be called after a successful call to + * initializeInfoAndReadHeader and must not be called more + * than once. + */ + bool buildHuffmanIndex() { + SkASSERT(fReadHeaderSucceeded); + SkASSERT(!fHuffmanCreated); + jpeg_create_huffman_index(&fCInfo, &fHuffmanIndex); + fHuffmanCreated = true; + SkASSERT(1 == fCInfo.scale_num && 1 == fCInfo.scale_denom); + return jpeg_build_huffman_index(&fCInfo, &fHuffmanIndex); + } + + /** + * Start tile based decoding. Must only be called after a + * successful call to buildHuffmanIndex, and must only be + * called once. + */ + bool startTileDecompress() { + SkASSERT(fHuffmanCreated); + SkASSERT(fReadHeaderSucceeded); + SkASSERT(!fDecompressStarted); + if (jpeg_start_tile_decompress(&fCInfo)) { + fDecompressStarted = true; + return true; + } + return false; + } private: skjpeg_source_mgr fSrcMgr; jpeg_decompress_struct fCInfo; -#ifdef SK_BUILD_FOR_ANDROID huffman_index fHuffmanIndex; -#endif + bool fInfoInitialized; + bool fHuffmanCreated; + bool fDecompressStarted; + SkDEBUGCODE(bool fReadHeaderSucceeded;) }; +#endif class SkJPEGImageDecoder : public SkImageDecoder { public: +#ifdef SK_BUILD_FOR_ANDROID SkJPEGImageDecoder() { fImageIndex = NULL; fImageWidth = 0; @@ -103,6 +173,7 @@ public: virtual ~SkJPEGImageDecoder() { SkDELETE(fImageIndex); } +#endif virtual Format getFormat() const { return kJPEG_Format; @@ -116,9 +187,11 @@ protected: virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; private: +#ifdef SK_BUILD_FOR_ANDROID SkJPEGImageIndex* fImageIndex; int fImageWidth; int fImageHeight; +#endif typedef SkImageDecoder INHERITED; }; @@ -475,9 +548,8 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { #ifdef SK_BUILD_FOR_ANDROID bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, int *width, int *height) { - SkJPEGImageIndex* imageIndex = SkNEW_ARGS(SkJPEGImageIndex, (stream, this)); + SkAutoTDelete imageIndex(SkNEW_ARGS(SkJPEGImageIndex, (stream, this))); jpeg_decompress_struct* cinfo = imageIndex->cinfo(); - huffman_index* huffmanIndex = imageIndex->huffmanIndex(); skjpeg_error_mgr sk_err; cinfo->err = jpeg_std_error(&sk_err); @@ -490,33 +562,19 @@ bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, int *width, int *hei } // create the cinfo used to create/build the huffmanIndex - imageIndex->initializeInfo(); - cinfo->do_fancy_upsampling = 0; - cinfo->do_block_smoothing = 0; - - int status = jpeg_read_header(cinfo, true); - if (JPEG_HEADER_OK != status) { - SkDELETE(imageIndex); + if (!imageIndex->initializeInfoAndReadHeader()) { return false; } - jpeg_create_huffman_index(cinfo, huffmanIndex); - cinfo->scale_num = 1; - cinfo->scale_denom = 1; - if (!jpeg_build_huffman_index(cinfo, huffmanIndex)) { - SkDELETE(imageIndex); + if (!imageIndex->buildHuffmanIndex()) { return false; } // destroy the cinfo used to create/build the huffman index - jpeg_destroy_decompress(cinfo); + imageIndex->destroyInfo(); // Init decoder to image decode mode - imageIndex->initializeInfo(); - - status = jpeg_read_header(cinfo, true); - if (JPEG_HEADER_OK != status) { - SkDELETE(imageIndex); + if (!imageIndex->initializeInfoAndReadHeader()) { return false; } @@ -525,16 +583,18 @@ bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, int *width, int *hei cinfo->do_block_smoothing = 0; // instead of jpeg_start_decompress() we start a tiled decompress - jpeg_start_tile_decompress(cinfo); + if (!imageIndex->startTileDecompress()) { + return false; + } - cinfo->scale_num = 1; + SkASSERT(1 == cinfo->scale_num); *height = cinfo->output_height; *width = cinfo->output_width; fImageWidth = *width; fImageHeight = *height; SkDELETE(fImageIndex); - fImageIndex = imageIndex; + fImageIndex = imageIndex.detach(); return true; } -- cgit v1.2.3 From 223831f023a7ed8f20b18bd81aa167412dff0122 Mon Sep 17 00:00:00 2001 From: "scroggo@google.com" Date: Wed, 7 Aug 2013 21:09:13 +0000 Subject: Beginning work to refactor jpeg tile decoding. Keep common code together, so we can fix bugs in tile and normal decode simultaneously. Convert if-then chains to switch statements for readability. Add getBitmapConfig, common to both normal and tile decode, which ensures that they behave the same. getBitmapConfig uses the code originally in onDecode, so subsetting grayscale into A8 now works. In getBitmapConfig, handle JCS_YCCK properly. Fix a bug where requesting A8 from a JCS_CMYK image would result in a total failure to decode, since we would change out_color_space to an invalid choice. Factor common code for applying dither and changing the out_color_space into apply_dither_mode (final name TBD). Skips CMYK like normal decoding did before. BUG=skia:1472 BUG=https://b.corp.google.com/issue?id=9466275 BUG=https://b.corp.google.com/issue?id=9189955 R=mtklein@google.com Review URL: https://codereview.chromium.org/22290002 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10629 2bbb7eff-a529-9590-31e7-b0007b416f81 --- images/SkImageDecoder_libjpeg.cpp | 286 ++++++++++++++++++++++++-------------- 1 file changed, 182 insertions(+), 104 deletions(-) diff --git a/images/SkImageDecoder_libjpeg.cpp b/images/SkImageDecoder_libjpeg.cpp index 914ceb7e..788e3526 100644 --- a/images/SkImageDecoder_libjpeg.cpp +++ b/images/SkImageDecoder_libjpeg.cpp @@ -30,7 +30,6 @@ extern "C" { //#define TIME_DECODE // this enables our rgb->yuv code, which is faster than libjpeg on ARM -// disable for the moment, as we have some glitches when width != multiple of 4 #define WE_CONVERT_TO_YUV // If ANDROID_RGB is defined by in the jpeg headers it indicates that jpeg offers @@ -39,7 +38,7 @@ extern "C" { ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -static void overwrite_mem_buffer_size(j_decompress_ptr cinfo) { +static void overwrite_mem_buffer_size(jpeg_decompress_struct* cinfo) { #ifdef SK_BUILD_FOR_ANDROID /* Check if the device indicates that it has a large amount of system memory * if so, increase the memory allocation to 30MB instead of the default 5MB. @@ -55,6 +54,14 @@ static void overwrite_mem_buffer_size(j_decompress_ptr cinfo) { ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +static void initialize_info(jpeg_decompress_struct* cinfo, skjpeg_source_mgr* src_mgr) { + SkASSERT(cinfo != NULL); + SkASSERT(src_mgr != NULL); + jpeg_create_decompress(cinfo); + overwrite_mem_buffer_size(cinfo); + cinfo->src = src_mgr; +} + #ifdef SK_BUILD_FOR_ANDROID class SkJPEGImageIndex { public: @@ -69,10 +76,17 @@ public: ~SkJPEGImageIndex() { if (fHuffmanCreated) { + // Set to false before calling the libjpeg function, in case + // the libjpeg function calls longjmp. Our setjmp handler may + // attempt to delete this SkJPEGImageIndex, thus entering this + // destructor again. Setting fHuffmanCreated to false first + // prevents an infinite loop. fHuffmanCreated = false; jpeg_destroy_huffman_index(&fHuffmanIndex); } if (fDecompressStarted) { + // Like fHuffmanCreated, set to false before calling libjpeg + // function to prevent potential infinite loop. fDecompressStarted = false; jpeg_finish_decompress(&fCInfo); } @@ -91,6 +105,8 @@ public: void destroyInfo() { SkASSERT(fInfoInitialized); SkASSERT(!fDecompressStarted); + // Like fHuffmanCreated, set to false before calling libjpeg + // function to prevent potential infinite loop. fInfoInitialized = false; jpeg_destroy_decompress(&fCInfo); SkDEBUGCODE(fReadHeaderSucceeded = false;) @@ -106,9 +122,7 @@ public: */ bool initializeInfoAndReadHeader() { SkASSERT(!fInfoInitialized && !fDecompressStarted); - jpeg_create_decompress(&fCInfo); - overwrite_mem_buffer_size(&fCInfo); - fCInfo.src = &fSrcMgr; + initialize_info(&fCInfo, &fSrcMgr); fInfoInitialized = true; const bool success = (JPEG_HEADER_OK == jpeg_read_header(&fCInfo, true)); SkDEBUGCODE(fReadHeaderSucceeded = success;) @@ -193,6 +207,14 @@ private: int fImageHeight; #endif + /** + * Determine the appropriate bitmap config and out_color_space based on + * both the preference of the caller and the jpeg_color_space on the + * jpeg_decompress_struct passed in. + * Must be called after jpeg_read_header. + */ + SkBitmap::Config getBitmapConfig(jpeg_decompress_struct*); + typedef SkImageDecoder INHERITED; }; @@ -295,6 +317,131 @@ static void convert_CMYK_to_RGB(uint8_t* scanline, unsigned int width) { } } +/** + * Common code for setting the error manager. + */ +static void set_error_mgr(jpeg_decompress_struct* cinfo, skjpeg_error_mgr* errorManager) { + SkASSERT(cinfo != NULL); + SkASSERT(errorManager != NULL); + cinfo->err = jpeg_std_error(errorManager); + errorManager->error_exit = skjpeg_error_exit; +} + +/** + * Common code for turning off upsampling and smoothing. Turning these + * off helps performance without showing noticable differences in the + * resulting bitmap. + */ +static void turn_off_visual_optimizations(jpeg_decompress_struct* cinfo) { + SkASSERT(cinfo != NULL); + /* this gives about 30% performance improvement. In theory it may + reduce the visual quality, in practice I'm not seeing a difference + */ + cinfo->do_fancy_upsampling = 0; + + /* this gives another few percents */ + cinfo->do_block_smoothing = 0; +} + +/** + * Common code for setting the dct method. + */ +static void set_dct_method(const SkImageDecoder& decoder, jpeg_decompress_struct* cinfo) { + SkASSERT(cinfo != NULL); +#ifdef DCT_IFAST_SUPPORTED + if (decoder.getPreferQualityOverSpeed()) { + cinfo->dct_method = JDCT_ISLOW; + } else { + cinfo->dct_method = JDCT_IFAST; + } +#else + cinfo->dct_method = JDCT_ISLOW; +#endif +} + +SkBitmap::Config SkJPEGImageDecoder::getBitmapConfig(jpeg_decompress_struct* cinfo) { + SkASSERT(cinfo != NULL); + + SrcDepth srcDepth = k32Bit_SrcDepth; + if (JCS_GRAYSCALE == cinfo->jpeg_color_space) { + srcDepth = k8BitGray_SrcDepth; + } + + SkBitmap::Config config = this->getPrefConfig(srcDepth, /*hasAlpha*/ false); + switch (config) { + case SkBitmap::kA8_Config: + // Only respect A8 config if the original is grayscale, + // in which case we will treat the grayscale as alpha + // values. + if (cinfo->jpeg_color_space != JCS_GRAYSCALE) { + config = SkBitmap::kARGB_8888_Config; + } + break; + case SkBitmap::kARGB_8888_Config: + // Fall through. + case SkBitmap::kARGB_4444_Config: + // Fall through. + case SkBitmap::kRGB_565_Config: + // These are acceptable destination configs. + break; + default: + // Force all other configs to 8888. + config = SkBitmap::kARGB_8888_Config; + break; + } + + switch (cinfo->jpeg_color_space) { + case JCS_CMYK: + // Fall through. + case JCS_YCCK: + // libjpeg cannot convert from CMYK or YCCK to RGB - here we set up + // so libjpeg will give us CMYK samples back and we will later + // manually convert them to RGB + cinfo->out_color_space = JCS_CMYK; + break; + case JCS_GRAYSCALE: + if (SkBitmap::kA8_Config == config) { + cinfo->out_color_space = JCS_GRAYSCALE; + break; + } + // The data is JCS_GRAYSCALE, but the caller wants some sort of RGB + // config. Fall through to set to the default. + default: + cinfo->out_color_space = JCS_RGB; + break; + } + return config; +} + +#ifdef ANDROID_RGB +/** + * Based on the config and dither mode, adjust out_color_space and + * dither_mode of cinfo. + */ +static void adjust_out_color_space_and_dither(jpeg_decompress_struct* cinfo, + SkBitmap::Config config, + const SkImageDecoder& decoder) { + SkASSERT(cinfo != NULL); + cinfo->dither_mode = JDITHER_NONE; + if (JCS_CMYK == cinfo->out_color_space) { + return; + } + switch(config) { + case SkBitmap::kARGB_8888_Config: + cinfo->out_color_space = JCS_RGBA_8888; + break; + case SkBitmap::kRGB_565_Config: + cinfo->out_color_space = JCS_RGB_565; + if (decoder.getDitherImage()) { + cinfo->dither_mode = JDITHER_ORDERED; + } + break; + default: + break; + } +} +#endif + bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { #ifdef TIME_DECODE SkAutoTime atm("JPEG Decode"); @@ -303,11 +450,10 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { JPEGAutoClean autoClean; jpeg_decompress_struct cinfo; - skjpeg_error_mgr errorManager; skjpeg_source_mgr srcManager(stream, this); - cinfo.err = jpeg_std_error(&errorManager); - errorManager.error_exit = skjpeg_error_exit; + skjpeg_error_mgr errorManager; + set_error_mgr(&cinfo, &errorManager); // All objects need to be instantiated before this setjmp call so that // they will be cleaned up properly if an error occurs. @@ -315,14 +461,9 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { return return_false(cinfo, *bm, "setjmp"); } - jpeg_create_decompress(&cinfo); + initialize_info(&cinfo, &srcManager); autoClean.set(&cinfo); - overwrite_mem_buffer_size(&cinfo); - - //jpeg_stdio_src(&cinfo, file); - cinfo.src = &srcManager; - int status = jpeg_read_header(&cinfo, true); if (status != JPEG_HEADER_OK) { return return_false(cinfo, *bm, "read_header"); @@ -334,67 +475,17 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { */ int sampleSize = this->getSampleSize(); -#ifdef DCT_IFAST_SUPPORTED - if (this->getPreferQualityOverSpeed()) { - cinfo.dct_method = JDCT_ISLOW; - } else { - cinfo.dct_method = JDCT_IFAST; - } -#else - cinfo.dct_method = JDCT_ISLOW; -#endif + set_dct_method(*this, &cinfo); - cinfo.scale_num = 1; + SkASSERT(1 == cinfo.scale_num); cinfo.scale_denom = sampleSize; - /* this gives about 30% performance improvement. In theory it may - reduce the visual quality, in practice I'm not seeing a difference - */ - cinfo.do_fancy_upsampling = 0; - - /* this gives another few percents */ - cinfo.do_block_smoothing = 0; - - SrcDepth srcDepth = k32Bit_SrcDepth; - /* default format is RGB */ - if (cinfo.jpeg_color_space == JCS_CMYK) { - // libjpeg cannot convert from CMYK to RGB - here we set up - // so libjpeg will give us CMYK samples back and we will - // later manually convert them to RGB - cinfo.out_color_space = JCS_CMYK; - } else if (cinfo.jpeg_color_space == JCS_GRAYSCALE) { - cinfo.out_color_space = JCS_GRAYSCALE; - srcDepth = k8BitGray_SrcDepth; - } else { - cinfo.out_color_space = JCS_RGB; - } + turn_off_visual_optimizations(&cinfo); - SkBitmap::Config config = this->getPrefConfig(srcDepth, false); - // only these make sense for jpegs - if (SkBitmap::kA8_Config == config) { - if (cinfo.jpeg_color_space != JCS_GRAYSCALE) { - // Converting from a non grayscale image to A8 is - // not currently supported. - config = SkBitmap::kARGB_8888_Config; - // Change the output from jpeg back to RGB. - cinfo.out_color_space = JCS_RGB; - } - } else if (config != SkBitmap::kARGB_8888_Config && - config != SkBitmap::kARGB_4444_Config && - config != SkBitmap::kRGB_565_Config) { - config = SkBitmap::kARGB_8888_Config; - } + const SkBitmap::Config config = this->getBitmapConfig(&cinfo); #ifdef ANDROID_RGB - cinfo.dither_mode = JDITHER_NONE; - if (SkBitmap::kARGB_8888_Config == config && JCS_CMYK != cinfo.out_color_space) { - cinfo.out_color_space = JCS_RGBA_8888; - } else if (SkBitmap::kRGB_565_Config == config && JCS_CMYK != cinfo.out_color_space) { - cinfo.out_color_space = JCS_RGB_565; - if (this->getDitherImage()) { - cinfo.dither_mode = JDITHER_ORDERED; - } - } + adjust_out_color_space_and_dither(&cinfo, config, *this); #endif if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { @@ -552,8 +643,7 @@ bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, int *width, int *hei jpeg_decompress_struct* cinfo = imageIndex->cinfo(); skjpeg_error_mgr sk_err; - cinfo->err = jpeg_std_error(&sk_err); - sk_err.error_exit = skjpeg_error_exit; + set_error_mgr(cinfo, &sk_err); // All objects need to be instantiated before this setjmp call so that // they will be cleaned up properly if an error occurs. @@ -578,9 +668,13 @@ bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, int *width, int *hei return false; } - cinfo->out_color_space = JCS_RGBA_8888; - cinfo->do_fancy_upsampling = 0; - cinfo->do_block_smoothing = 0; + // FIXME: This sets cinfo->out_color_space, which we may change later + // based on the config in onDecodeSubset. This should be fine, since + // jpeg_init_read_tile_scanline will check out_color_space again after + // that change (when it calls jinit_color_deconverter). + (void) this->getBitmapConfig(cinfo); + + turn_off_visual_optimizations(cinfo); // instead of jpeg_start_decompress() we start a tiled decompress if (!imageIndex->startTileDecompress()) { @@ -588,10 +682,15 @@ bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, int *width, int *hei } SkASSERT(1 == cinfo->scale_num); - *height = cinfo->output_height; - *width = cinfo->output_width; - fImageWidth = *width; - fImageHeight = *height; + fImageWidth = cinfo->output_width; + fImageHeight = cinfo->output_height; + + if (width) { + *width = fImageWidth; + } + if (height) { + *height = fImageHeight; + } SkDELETE(fImageIndex); fImageIndex = imageIndex.detach(); @@ -613,8 +712,8 @@ bool SkJPEGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { skjpeg_error_mgr errorManager; - cinfo->err = jpeg_std_error(&errorManager); - errorManager.error_exit = skjpeg_error_exit; + set_error_mgr(cinfo, &errorManager); + if (setjmp(errorManager.fJmpBuf)) { return false; } @@ -622,32 +721,11 @@ bool SkJPEGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { int requestedSampleSize = this->getSampleSize(); cinfo->scale_denom = requestedSampleSize; - if (this->getPreferQualityOverSpeed()) { - cinfo->dct_method = JDCT_ISLOW; - } else { - cinfo->dct_method = JDCT_IFAST; - } - - SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, false); - if (config != SkBitmap::kARGB_8888_Config && - config != SkBitmap::kARGB_4444_Config && - config != SkBitmap::kRGB_565_Config) { - config = SkBitmap::kARGB_8888_Config; - } - - /* default format is RGB */ - cinfo->out_color_space = JCS_RGB; + set_dct_method(*this, cinfo); + const SkBitmap::Config config = this->getBitmapConfig(cinfo); #ifdef ANDROID_RGB - cinfo->dither_mode = JDITHER_NONE; - if (SkBitmap::kARGB_8888_Config == config) { - cinfo->out_color_space = JCS_RGBA_8888; - } else if (SkBitmap::kRGB_565_Config == config) { - cinfo->out_color_space = JCS_RGB_565; - if (this->getDitherImage()) { - cinfo->dither_mode = JDITHER_ORDERED; - } - } + adjust_out_color_space_and_dither(cinfo, config, *this); #endif int startX = rect.fLeft; -- cgit v1.2.3 From 0f7d37e323e0b18c1f9802301f6da4d11ddd7641 Mon Sep 17 00:00:00 2001 From: "robertphillips@google.com" Date: Wed, 7 Aug 2013 22:36:29 +0000 Subject: Revert r10603 (Remove operator== from SkPaint) due to Chrome failures git-svn-id: http://skia.googlecode.com/svn/trunk/src@10632 2bbb7eff-a529-9590-31e7-b0007b416f81 --- core/SkPaint.cpp | 9 +++++++++ views/animated/SkStaticTextView.cpp | 9 ++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/core/SkPaint.cpp b/core/SkPaint.cpp index 32883662..372e6805 100644 --- a/core/SkPaint.cpp +++ b/core/SkPaint.cpp @@ -161,6 +161,15 @@ SkPaint& SkPaint::operator=(const SkPaint& src) { return *this; } +bool operator==(const SkPaint& a, const SkPaint& b) { +#ifdef SK_BUILD_FOR_ANDROID + //assumes that fGenerationID is the last field in the struct + return !memcmp(&a, &b, SK_OFFSETOF(SkPaint, fGenerationID)); +#else + return !memcmp(&a, &b, sizeof(a)); +#endif +} + void SkPaint::reset() { SkPaint init; diff --git a/views/animated/SkStaticTextView.cpp b/views/animated/SkStaticTextView.cpp index bbef63df..0e4cad63 100644 --- a/views/animated/SkStaticTextView.cpp +++ b/views/animated/SkStaticTextView.cpp @@ -125,9 +125,12 @@ void SkStaticTextView::getPaint(SkPaint* paint) const void SkStaticTextView::setPaint(const SkPaint& paint) { - fPaint = paint; - this->computeSize(); - this->inval(NULL); + if (fPaint != paint) + { + fPaint = paint; + this->computeSize(); + this->inval(NULL); + } } void SkStaticTextView::onDraw(SkCanvas* canvas) -- cgit v1.2.3 From cd634d7d19724b55a269f714dbc51cd37dbbb83b Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Thu, 8 Aug 2013 02:52:05 +0000 Subject: Use Path Ops to generate PDF clips R=vandebo@chromium.org, edisonn@google.com, caryclark@google.com Author: richardlin@chromium.org Review URL: https://chromiumcodereview.appspot.com/21161003 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10633 2bbb7eff-a529-9590-31e7-b0007b416f81 --- pdf/SkPDFDevice.cpp | 122 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 105 insertions(+), 17 deletions(-) diff --git a/pdf/SkPDFDevice.cpp b/pdf/SkPDFDevice.cpp index eda3616a..410b0499 100644 --- a/pdf/SkPDFDevice.cpp +++ b/pdf/SkPDFDevice.cpp @@ -327,6 +327,96 @@ static void emit_clip(SkPath* clipPath, SkRect* clipRect, } } +#ifdef SK_PDF_USE_PATHOPS +/* Calculate an inverted path's equivalent non-inverted path, given the + * canvas bounds. + * outPath may alias with invPath (since this is supported by PathOps). + */ +static bool calculate_inverse_path(const SkRect& bounds, const SkPath& invPath, + SkPath* outPath) { + SkASSERT(invPath.isInverseFillType()); + + SkPath clipPath; + clipPath.addRect(bounds); + + return Op(clipPath, invPath, kIntersect_PathOp, outPath); +} + +// Sanity check the numerical values of the SkRegion ops and PathOps ops +// enums so region_op_to_pathops_op can do a straight passthrough cast. +// If these are failing, it may be necessary to make region_op_to_pathops_op +// do more. +SK_COMPILE_ASSERT(SkRegion::kDifference_Op == (int)kDifference_PathOp, + region_pathop_mismatch); +SK_COMPILE_ASSERT(SkRegion::kIntersect_Op == (int)kIntersect_PathOp, + region_pathop_mismatch); +SK_COMPILE_ASSERT(SkRegion::kUnion_Op == (int)kUnion_PathOp, + region_pathop_mismatch); +SK_COMPILE_ASSERT(SkRegion::kXOR_Op == (int)kXOR_PathOp, + region_pathop_mismatch); +SK_COMPILE_ASSERT(SkRegion::kReverseDifference_Op == + (int)kReverseDifference_PathOp, + region_pathop_mismatch); + +static SkPathOp region_op_to_pathops_op(SkRegion::Op op) { + SkASSERT(op >= 0); + SkASSERT(op <= SkRegion::kReverseDifference_Op); + return (SkPathOp)op; +} + +/* Uses Path Ops to calculate a vector SkPath clip from a clip stack. + * Returns true if successful, or false if not successful. + * If successful, the resulting clip is stored in outClipPath. + * If not successful, outClipPath is undefined, and a fallback method + * should be used. + */ +static bool get_clip_stack_path(const SkMatrix& transform, + const SkClipStack& clipStack, + const SkRegion& clipRegion, + SkPath* outClipPath) { + outClipPath->reset(); + outClipPath->setFillType(SkPath::kInverseWinding_FillType); + + const SkClipStack::Element* clipEntry; + SkClipStack::Iter iter; + iter.reset(clipStack, SkClipStack::Iter::kBottom_IterStart); + for (clipEntry = iter.next(); clipEntry; clipEntry = iter.next()) { + SkPath entryPath; + if (SkClipStack::Element::kEmpty_Type == clipEntry->getType()) { + outClipPath->reset(); + outClipPath->setFillType(SkPath::kInverseWinding_FillType); + continue; + } else if (SkClipStack::Element::kRect_Type == clipEntry->getType()) { + entryPath.addRect(clipEntry->getRect()); + } else if (SkClipStack::Element::kPath_Type == clipEntry->getType()) { + entryPath = clipEntry->getPath(); + } + entryPath.transform(transform); + + if (SkRegion::kReplace_Op == clipEntry->getOp()) { + *outClipPath = entryPath; + } else { + SkPathOp op = region_op_to_pathops_op(clipEntry->getOp()); + if (!Op(*outClipPath, entryPath, op, outClipPath)) { + return false; + } + } + } + + if (outClipPath->isInverseFillType()) { + // The bounds are slightly outset to ensure this is correct in the + // face of floating-point accuracy and possible SkRegion bitmap + // approximations. + SkRect clipBounds = SkRect::Make(clipRegion.getBounds()); + clipBounds.outset(SK_Scalar1, SK_Scalar1); + if (!calculate_inverse_path(clipBounds, *outClipPath, outClipPath)) { + return false; + } + } + return true; +} +#endif + // TODO(vandebo): Take advantage of SkClipStack::getSaveCount(), the PDF // graphic state stack, and the fact that we can know all the clips used // on the page to optimize this. @@ -345,6 +435,19 @@ void GraphicStackState::updateClip(const SkClipStack& clipStack, } push(); + currentEntry()->fClipStack = clipStack; + currentEntry()->fClipRegion = clipRegion; + + SkMatrix transform; + transform.setTranslate(translation.fX, translation.fY); + +#ifdef SK_PDF_USE_PATHOPS + SkPath clipPath; + if (get_clip_stack_path(transform, clipStack, clipRegion, &clipPath)) { + emit_clip(&clipPath, NULL, fContentStream); + return; + } +#endif // gsState->initialEntry()->fClipStack/Region specifies the clip that has // already been applied. (If this is a top level device, then it specifies // a clip to the content area. If this is a layer, then it specifies @@ -373,8 +476,6 @@ void GraphicStackState::updateClip(const SkClipStack& clipStack, emit_clip(&clipPath, NULL, fContentStream); } else { skip_clip_stack_prefix(fEntries[0].fClipStack, clipStack, &iter); - SkMatrix transform; - transform.setTranslate(translation.fX, translation.fY); const SkClipStack::Element* clipEntry; for (clipEntry = iter.next(); clipEntry; clipEntry = iter.next()) { SkASSERT(clipEntry->getOp() == SkRegion::kIntersect_Op); @@ -396,8 +497,6 @@ void GraphicStackState::updateClip(const SkClipStack& clipStack, } } } - currentEntry()->fClipStack = clipStack; - currentEntry()->fClipRegion = clipRegion; } void GraphicStackState::updateMatrix(const SkMatrix& matrix) { @@ -1239,19 +1338,7 @@ SkData* SkPDFDevice::copyContentToData() const { return data.copyToData(); } -/* Calculate an inverted path's equivalent non-inverted path, given the - * canvas bounds. - */ -static bool calculate_inverse_path(const SkRect& bounds, const SkPath& invPath, - SkPath* outPath) { - SkASSERT(invPath.isInverseFillType()); - - SkPath clipPath; - clipPath.addRect(bounds); - - return Op(clipPath, invPath, kIntersect_PathOp, outPath); -} - +#ifdef SK_PDF_USE_PATHOPS /* Draws an inverse filled path by using Path Ops to compute the positive * inverse using the current clip as the inverse bounds. * Return true if this was an inverse path and was properly handled, @@ -1312,6 +1399,7 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath, drawPath(d, modifiedPath, noInversePaint, NULL, true); return true; } +#endif bool SkPDFDevice::handleRectAnnotation(const SkRect& r, const SkMatrix& matrix, const SkPaint& p) { -- cgit v1.2.3 From dc8a93e06c9e4d97ad5a2369bc4fde767d4a897e Mon Sep 17 00:00:00 2001 From: "skia.committer@gmail.com" Date: Thu, 8 Aug 2013 07:01:20 +0000 Subject: Sanitizing source files in Housekeeper-Nightly git-svn-id: http://skia.googlecode.com/svn/trunk/src@10634 2bbb7eff-a529-9590-31e7-b0007b416f81 --- effects/SkDropShadowImageFilter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/effects/SkDropShadowImageFilter.cpp b/effects/SkDropShadowImageFilter.cpp index c9cfd602..b8bbfd6f 100644 --- a/effects/SkDropShadowImageFilter.cpp +++ b/effects/SkDropShadowImageFilter.cpp @@ -60,4 +60,3 @@ bool SkDropShadowImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source *result = device->accessBitmap(false); return true; } - -- cgit v1.2.3 From fa08a97d448f44c3eea8f4710bc9e54f6efe32a3 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Thu, 8 Aug 2013 10:51:45 +0000 Subject: ARM Skia NEON patches - 11 - Blitter_RGB16 Blitter_RGB16: fixes and improvements - fix alpha calculation: it was still using the old version of SkAlpha255To256. 11 more tests pass in gm. - clean a lot the code: the existing code was "a bit" messy with a lot of duplicated hardcoded constants, got rid of all this. - improve speed a little: part of it as a side-effect of the change in the way alpha is calculated but also by grouping loads and stores. One "issue" was present and still remains: the NEON code doesn't give the same result as the black blitter on black. It accounts for dozens of mismatches in gm. Is this considered "not too bad"? Would you be interested in a NEON version of the black blitter? The current comments seem to indicate that the black blitter is here only to give a performance boost when NEON is not presents so I didn't write a NEON version. BUG= R=djsollen@google.com, tomhudson@google.com, reed@google.com Author: kevin.petit.arm@gmail.com Review URL: https://chromiumcodereview.appspot.com/18666005 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10635 2bbb7eff-a529-9590-31e7-b0007b416f81 --- core/SkBlitter_RGB16.cpp | 100 +++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 55 deletions(-) diff --git a/core/SkBlitter_RGB16.cpp b/core/SkBlitter_RGB16.cpp index cb572325..256cbc69 100644 --- a/core/SkBlitter_RGB16.cpp +++ b/core/SkBlitter_RGB16.cpp @@ -390,63 +390,53 @@ void SkRGB16_Opaque_Blitter::blitMask(const SkMask& mask, do { int w = width; if (w >= UNROLL) { - uint32x4_t color; /* can use same one */ - uint32x4_t dev_lo, dev_hi; - uint32x4_t t1; - uint32x4_t wn1, wn2; - uint16x4_t odev_lo, odev_hi; - uint16x4_t alpha_lo, alpha_hi; - uint16x8_t alpha_full; - + uint32x4_t color, dev_lo, dev_hi; + uint32x4_t wn1, wn2, tmp; + uint32x4_t vmask_g16, vmask_ng16; + uint16x8_t valpha, vdev; + uint16x4_t odev_lo, odev_hi, valpha_lo, valpha_hi; + + // prepare constants + vmask_g16 = vdupq_n_u32(SK_G16_MASK_IN_PLACE); + vmask_ng16 = vdupq_n_u32(~SK_G16_MASK_IN_PLACE); color = vdupq_n_u32(expanded32); do { - /* alpha is 8x8, widen and split to get pair of 16x4's */ - alpha_full = vmovl_u8(vld1_u8(alpha)); - alpha_full = vaddq_u16(alpha_full, vshrq_n_u16(alpha_full,7)); - alpha_full = vshrq_n_u16(alpha_full, 3); - alpha_lo = vget_low_u16(alpha_full); - alpha_hi = vget_high_u16(alpha_full); - - dev_lo = vmovl_u16(vld1_u16(device)); - dev_hi = vmovl_u16(vld1_u16(device+4)); - - /* unpack in 32 bits */ - dev_lo = vorrq_u32( - vandq_u32(dev_lo, vdupq_n_u32(0x0000F81F)), - vshlq_n_u32(vandq_u32(dev_lo, - vdupq_n_u32(0x000007E0)), - 16) - ); - dev_hi = vorrq_u32( - vandq_u32(dev_hi, vdupq_n_u32(0x0000F81F)), - vshlq_n_u32(vandq_u32(dev_hi, - vdupq_n_u32(0x000007E0)), - 16) - ); - - /* blend the two */ - t1 = vmulq_u32(vsubq_u32(color, dev_lo), vmovl_u16(alpha_lo)); - t1 = vshrq_n_u32(t1, 5); - dev_lo = vaddq_u32(dev_lo, t1); - - t1 = vmulq_u32(vsubq_u32(color, dev_hi), vmovl_u16(alpha_hi)); - t1 = vshrq_n_u32(t1, 5); - dev_hi = vaddq_u32(dev_hi, t1); - - /* re-compact and store */ - wn1 = vandq_u32(dev_lo, vdupq_n_u32(0x0000F81F)), - wn2 = vshrq_n_u32(dev_lo, 16); - wn2 = vandq_u32(wn2, vdupq_n_u32(0x000007E0)); - odev_lo = vmovn_u32(vorrq_u32(wn1, wn2)); - - wn1 = vandq_u32(dev_hi, vdupq_n_u32(0x0000F81F)), - wn2 = vshrq_n_u32(dev_hi, 16); - wn2 = vandq_u32(wn2, vdupq_n_u32(0x000007E0)); - odev_hi = vmovn_u32(vorrq_u32(wn1, wn2)); - - vst1_u16(device, odev_lo); - vst1_u16(device+4, odev_hi); + // alpha is 8x8, widen and split to get a pair of 16x4 + valpha = vaddw_u8(vdupq_n_u16(1), vld1_u8(alpha)); + valpha = vshrq_n_u16(valpha, 3); + valpha_lo = vget_low_u16(valpha); + valpha_hi = vget_high_u16(valpha); + + // load pixels + vdev = vld1q_u16(device); + dev_lo = vmovl_u16(vget_low_u16(vdev)); + dev_hi = vmovl_u16(vget_high_u16(vdev)); + + // unpack them in 32 bits + dev_lo = (dev_lo & vmask_ng16) | vshlq_n_u32(dev_lo & vmask_g16, 16); + dev_hi = (dev_hi & vmask_ng16) | vshlq_n_u32(dev_hi & vmask_g16, 16); + + // blend with color + tmp = (color - dev_lo) * vmovl_u16(valpha_lo); + tmp = vshrq_n_u32(tmp, 5); + dev_lo += tmp; + + tmp = vmulq_u32(color - dev_hi, vmovl_u16(valpha_hi)); + tmp = vshrq_n_u32(tmp, 5); + dev_hi += tmp; + + // re-compact + wn1 = dev_lo & vmask_ng16; + wn2 = vshrq_n_u32(dev_lo, 16) & vmask_g16; + odev_lo = vmovn_u32(wn1 | wn2); + + wn1 = dev_hi & vmask_ng16; + wn2 = vshrq_n_u32(dev_hi, 16) & vmask_g16; + odev_hi = vmovn_u32(wn1 | wn2); + + // store + vst1q_u16(device, vcombine_u16(odev_lo, odev_hi)); device += UNROLL; alpha += UNROLL; @@ -454,7 +444,7 @@ void SkRGB16_Opaque_Blitter::blitMask(const SkMask& mask, } while (w >= UNROLL); } - /* residuals (which is everything if we have no neon) */ + // residuals while (w > 0) { *device = blend_compact(expanded32, SkExpand_rgb_16(*device), SkAlpha255To256(*alpha++) >> 3); -- cgit v1.2.3 From 28bfaf06601e98cd656b9a6954fbaa5576e07fb2 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Thu, 8 Aug 2013 18:22:07 +0000 Subject: Fix hairline pathrenderer for Nexus-10. Switches to using additional geometry and passing in the coverage value instead. BUG= R=robertphillips@google.com, bsalomon@google.com Author: jvanverth@google.com Review URL: https://chromiumcodereview.appspot.com/22486003 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10640 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gpu/GrAAHairLinePathRenderer.cpp | 101 +++++++++++++++++++++++++++++---------- 1 file changed, 75 insertions(+), 26 deletions(-) diff --git a/gpu/GrAAHairLinePathRenderer.cpp b/gpu/GrAAHairLinePathRenderer.cpp index c1f951ab..33c2ac38 100644 --- a/gpu/GrAAHairLinePathRenderer.cpp +++ b/gpu/GrAAHairLinePathRenderer.cpp @@ -29,15 +29,20 @@ namespace { static const int kVertsPerQuad = 5; static const int kIdxsPerQuad = 9; -static const int kVertsPerLineSeg = 4; -static const int kIdxsPerLineSeg = 6; +static const int kVertsPerLineSeg = 6; +static const int kIdxsPerLineSeg = 12; static const int kNumQuadsInIdxBuffer = 256; static const size_t kQuadIdxSBufize = kIdxsPerQuad * sizeof(uint16_t) * kNumQuadsInIdxBuffer; -bool push_quad_index_data(GrIndexBuffer* qIdxBuffer) { +static const int kNumLineSegsInIdxBuffer = 256; +static const size_t kLineSegIdxSBufize = kIdxsPerLineSeg * + sizeof(uint16_t) * + kNumLineSegsInIdxBuffer; + +static bool push_quad_index_data(GrIndexBuffer* qIdxBuffer) { uint16_t* data = (uint16_t*) qIdxBuffer->lock(); bool tempData = NULL == data; if (tempData) { @@ -78,22 +83,66 @@ bool push_quad_index_data(GrIndexBuffer* qIdxBuffer) { return true; } } + +static bool push_line_index_data(GrIndexBuffer* lIdxBuffer) { + uint16_t* data = (uint16_t*) lIdxBuffer->lock(); + bool tempData = NULL == data; + if (tempData) { + data = SkNEW_ARRAY(uint16_t, kNumLineSegsInIdxBuffer * kIdxsPerLineSeg); + } + for (int i = 0; i < kNumLineSegsInIdxBuffer; ++i) { + // Each line segment is rendered as two quads, with alpha = 1 along the + // spine of the segment, and alpha = 0 along the outer edges, represented + // horizontally (i.e., the line equation is t*(p1-p0) + p0) + // + // p4 p5 + // p0 p1 + // p2 p3 + // + // Each is drawn as four triangles specified by these 12 indices: + int baseIdx = i * kIdxsPerLineSeg; + uint16_t baseVert = (uint16_t)(i * kVertsPerLineSeg); + data[0 + baseIdx] = baseVert + 0; // p0 + data[1 + baseIdx] = baseVert + 1; // p1 + data[2 + baseIdx] = baseVert + 2; // p2 + + data[3 + baseIdx] = baseVert + 2; // p2 + data[4 + baseIdx] = baseVert + 1; // p1 + data[5 + baseIdx] = baseVert + 3; // p3 + + data[6 + baseIdx] = baseVert + 0; // p0 + data[7 + baseIdx] = baseVert + 5; // p5 + data[8 + baseIdx] = baseVert + 1; // p1 + + data[9 + baseIdx] = baseVert + 0; // p0 + data[10+ baseIdx] = baseVert + 4; // p4 + data[11+ baseIdx] = baseVert + 5; // p5 + } + if (tempData) { + bool ret = lIdxBuffer->updateData(data, kLineSegIdxSBufize); + delete[] data; + return ret; + } else { + lIdxBuffer->unlock(); + return true; + } +} } GrPathRenderer* GrAAHairLinePathRenderer::Create(GrContext* context) { - const GrIndexBuffer* lIdxBuffer = context->getQuadIndexBuffer(); - if (NULL == lIdxBuffer) { - return NULL; - } GrGpu* gpu = context->getGpu(); GrIndexBuffer* qIdxBuf = gpu->createIndexBuffer(kQuadIdxSBufize, false); SkAutoTUnref qIdxBuffer(qIdxBuf); - if (NULL == qIdxBuf || - !push_quad_index_data(qIdxBuf)) { + if (NULL == qIdxBuf || !push_quad_index_data(qIdxBuf)) { + return NULL; + } + GrIndexBuffer* lIdxBuf = gpu->createIndexBuffer(kLineSegIdxSBufize, false); + SkAutoTUnref lIdxBuffer(lIdxBuf); + if (NULL == lIdxBuf || !push_line_index_data(lIdxBuf)) { return NULL; } return SkNEW_ARGS(GrAAHairLinePathRenderer, - (context, lIdxBuffer, qIdxBuf)); + (context, lIdxBuf, qIdxBuf)); } GrAAHairLinePathRenderer::GrAAHairLinePathRenderer( @@ -436,9 +485,7 @@ struct Vertex { GrPoint fPos; union { struct { - SkScalar fA; - SkScalar fB; - SkScalar fC; + SkScalar fCoverage; } fLine; struct { SkScalar fK; @@ -661,17 +708,17 @@ void add_line(const SkPoint p[2], if (orthVec.setLength(SK_Scalar1)) { orthVec.setOrthog(orthVec); - SkScalar lineC = -(a.dot(orthVec)); for (int i = 0; i < kVertsPerLineSeg; ++i) { - (*vert)[i].fPos = (i < 2) ? a : b; - if (0 == i || 3 == i) { + (*vert)[i].fPos = (i & 0x1) ? b : a; + if (i & 0x2) { + (*vert)[i].fPos += orthVec; + (*vert)[i].fLine.fCoverage = 0; + } else if (i & 0x4) { (*vert)[i].fPos -= orthVec; + (*vert)[i].fLine.fCoverage = 0; } else { - (*vert)[i].fPos += orthVec; + (*vert)[i].fLine.fCoverage = SK_Scalar1; } - (*vert)[i].fLine.fA = orthVec.fX; - (*vert)[i].fLine.fB = orthVec.fY; - (*vert)[i].fLine.fC = lineC; } if (NULL != toSrc) { toSrc->mapPointsWithStride(&(*vert)->fPos, @@ -684,6 +731,8 @@ void add_line(const SkPoint p[2], (*vert)[1].fPos.set(SK_ScalarMax, SK_ScalarMax); (*vert)[2].fPos.set(SK_ScalarMax, SK_ScalarMax); (*vert)[3].fPos.set(SK_ScalarMax, SK_ScalarMax); + (*vert)[4].fPos.set(SK_ScalarMax, SK_ScalarMax); + (*vert)[5].fPos.set(SK_ScalarMax, SK_ScalarMax); } *vert += kVertsPerLineSeg; @@ -936,7 +985,7 @@ GrEffectRef* HairQuadEdgeEffect::TestCreate(SkMWCRandom* random, /** * The output of this effect is a 1-pixel wide line. - * Input is 2D implicit device coord line eq (a*x + b*y +c = 0). 4th component unused. + * Input is coverage relative to the line. */ class HairLineEdgeEffect : public GrEffect { public: @@ -978,9 +1027,7 @@ public: builder->addVarying(kVec4f_GrSLType, "HairLineEdge", &vsName, &fsName); - builder->fsCodeAppendf("\t\tedgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n", - builder->fragmentPosition(), fsName); - builder->fsCodeAppendf("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); + builder->fsCodeAppendf("\t\tedgeAlpha = %s.x;\n", fsName); SkString modulate; GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha"); @@ -1191,13 +1238,15 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path, #endif { + // the fact we're using an effect to pass per-vertex coverage is kind of dumb, + // but necessary due to the shared vertex buffer + // TODO: refactor so that we render lines with a separate vertex buffer GrDrawState::AutoRestoreEffects are(drawState); target->setIndexSourceToBuffer(fLinesIndexBuffer); int lines = 0; - int nBufLines = fLinesIndexBuffer->maxQuads(); drawState->addCoverageEffect(hairLineEffect, kEdgeAttrIndex)->unref(); while (lines < lineCnt) { - int n = GrMin(lineCnt - lines, nBufLines); + int n = GrMin(lineCnt - lines, kNumLineSegsInIdxBuffer); target->drawIndexed(kTriangles_GrPrimitiveType, kVertsPerLineSeg*lines, // startV 0, // startI -- cgit v1.2.3 From 0557dc6ef8020de593ebc426d32668fc75296ee1 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Thu, 8 Aug 2013 19:20:05 +0000 Subject: Adding 2 functions to the Skia API I need wrappers for both SkOrderedReadBuffer and SkOrderedWriteBuffer inside Chromium in order to do the IPC serialization of Skia SkImageFilter objects. See https://codereview.chromium.org/21271002/ BUG= R=djsollen@google.com, scroggo@google.com, reed@google.com Author: sugoi@chromium.org Review URL: https://chromiumcodereview.appspot.com/22591002 git-svn-id: http://skia.googlecode.com/svn/trunk/src@10642 2bbb7eff-a529-9590-31e7-b0007b416f81 --- core/SkFlattenableSerialization.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 core/SkFlattenableSerialization.cpp diff --git a/core/SkFlattenableSerialization.cpp b/core/SkFlattenableSerialization.cpp new file mode 100644 index 00000000..b74c82f0 --- /dev/null +++ b/core/SkFlattenableSerialization.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkFlattenableSerialization.h" + +#include "SkData.h" +#include "SkFlattenable.h" +#include "SkOrderedReadBuffer.h" +#include "SkOrderedWriteBuffer.h" + +SkData* SkSerializeFlattenable(SkFlattenable* flattenable) { + SkOrderedWriteBuffer writer(1024); + writer.setFlags(SkOrderedWriteBuffer::kCrossProcess_Flag); + writer.writeFlattenable(flattenable); + uint32_t size = writer.bytesWritten(); + void* data = sk_malloc_throw(size); + writer.writeToMemory(data); + return SkData::NewFromMalloc(data, size); +} + +SkFlattenable* SkDeserializeFlattenable(const void* data, size_t size) { + SkOrderedReadBuffer buffer(data, size); + return buffer.readFlattenable(); +} -- cgit v1.2.3 From 06e8b2aa9249ff96559f7c08adffa83f4e855258 Mon Sep 17 00:00:00 2001 From: "jvanverth@google.com" Date: Thu, 8 Aug 2013 22:42:37 +0000 Subject: Revert r10640: Fix hairline pathrenderer for Nexus-10. git-svn-id: http://skia.googlecode.com/svn/trunk/src@10647 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gpu/GrAAHairLinePathRenderer.cpp | 101 ++++++++++----------------------------- 1 file changed, 26 insertions(+), 75 deletions(-) diff --git a/gpu/GrAAHairLinePathRenderer.cpp b/gpu/GrAAHairLinePathRenderer.cpp index 33c2ac38..c1f951ab 100644 --- a/gpu/GrAAHairLinePathRenderer.cpp +++ b/gpu/GrAAHairLinePathRenderer.cpp @@ -29,20 +29,15 @@ namespace { static const int kVertsPerQuad = 5; static const int kIdxsPerQuad = 9; -static const int kVertsPerLineSeg = 6; -static const int kIdxsPerLineSeg = 12; +static const int kVertsPerLineSeg = 4; +static const int kIdxsPerLineSeg = 6; static const int kNumQuadsInIdxBuffer = 256; static const size_t kQuadIdxSBufize = kIdxsPerQuad * sizeof(uint16_t) * kNumQuadsInIdxBuffer; -static const int kNumLineSegsInIdxBuffer = 256; -static const size_t kLineSegIdxSBufize = kIdxsPerLineSeg * - sizeof(uint16_t) * - kNumLineSegsInIdxBuffer; - -static bool push_quad_index_data(GrIndexBuffer* qIdxBuffer) { +bool push_quad_index_data(GrIndexBuffer* qIdxBuffer) { uint16_t* data = (uint16_t*) qIdxBuffer->lock(); bool tempData = NULL == data; if (tempData) { @@ -83,66 +78,22 @@ static bool push_quad_index_data(GrIndexBuffer* qIdxBuffer) { return true; } } - -static bool push_line_index_data(GrIndexBuffer* lIdxBuffer) { - uint16_t* data = (uint16_t*) lIdxBuffer->lock(); - bool tempData = NULL == data; - if (tempData) { - data = SkNEW_ARRAY(uint16_t, kNumLineSegsInIdxBuffer * kIdxsPerLineSeg); - } - for (int i = 0; i < kNumLineSegsInIdxBuffer; ++i) { - // Each line segment is rendered as two quads, with alpha = 1 along the - // spine of the segment, and alpha = 0 along the outer edges, represented - // horizontally (i.e., the line equation is t*(p1-p0) + p0) - // - // p4 p5 - // p0 p1 - // p2 p3 - // - // Each is drawn as four triangles specified by these 12 indices: - int baseIdx = i * kIdxsPerLineSeg; - uint16_t baseVert = (uint16_t)(i * kVertsPerLineSeg); - data[0 + baseIdx] = baseVert + 0; // p0 - data[1 + baseIdx] = baseVert + 1; // p1 - data[2 + baseIdx] = baseVert + 2; // p2 - - data[3 + baseIdx] = baseVert + 2; // p2 - data[4 + baseIdx] = baseVert + 1; // p1 - data[5 + baseIdx] = baseVert + 3; // p3 - - data[6 + baseIdx] = baseVert + 0; // p0 - data[7 + baseIdx] = baseVert + 5; // p5 - data[8 + baseIdx] = baseVert + 1; // p1 - - data[9 + baseIdx] = baseVert + 0; // p0 - data[10+ baseIdx] = baseVert + 4; // p4 - data[11+ baseIdx] = baseVert + 5; // p5 - } - if (tempData) { - bool ret = lIdxBuffer->updateData(data, kLineSegIdxSBufize); - delete[] data; - return ret; - } else { - lIdxBuffer->unlock(); - return true; - } -} } GrPathRenderer* GrAAHairLinePathRenderer::Create(GrContext* context) { + const GrIndexBuffer* lIdxBuffer = context->getQuadIndexBuffer(); + if (NULL == lIdxBuffer) { + return NULL; + } GrGpu* gpu = context->getGpu(); GrIndexBuffer* qIdxBuf = gpu->createIndexBuffer(kQuadIdxSBufize, false); SkAutoTUnref qIdxBuffer(qIdxBuf); - if (NULL == qIdxBuf || !push_quad_index_data(qIdxBuf)) { - return NULL; - } - GrIndexBuffer* lIdxBuf = gpu->createIndexBuffer(kLineSegIdxSBufize, false); - SkAutoTUnref lIdxBuffer(lIdxBuf); - if (NULL == lIdxBuf || !push_line_index_data(lIdxBuf)) { + if (NULL == qIdxBuf || + !push_quad_index_data(qIdxBuf)) { return NULL; } return SkNEW_ARGS(GrAAHairLinePathRenderer, - (context, lIdxBuf, qIdxBuf)); + (context, lIdxBuffer, qIdxBuf)); } GrAAHairLinePathRenderer::GrAAHairLinePathRenderer( @@ -485,7 +436,9 @@ struct Vertex { GrPoint fPos; union { struct { - SkScalar fCoverage; + SkScalar fA; + SkScalar fB; + SkScalar fC; } fLine; struct { SkScalar fK; @@ -708,17 +661,17 @@ void add_line(const SkPoint p[2], if (orthVec.setLength(SK_Scalar1)) { orthVec.setOrthog(orthVec); + SkScalar lineC = -(a.dot(orthVec)); for (int i = 0; i < kVertsPerLineSeg; ++i) { - (*vert)[i].fPos = (i & 0x1) ? b : a; - if (i & 0x2) { - (*vert)[i].fPos += orthVec; - (*vert)[i].fLine.fCoverage = 0; - } else if (i & 0x4) { + (*vert)[i].fPos = (i < 2) ? a : b; + if (0 == i || 3 == i) { (*vert)[i].fPos -= orthVec; - (*vert)[i].fLine.fCoverage = 0; } else { - (*vert)[i].fLine.fCoverage = SK_Scalar1; + (*vert)[i].fPos += orthVec; } + (*vert)[i].fLine.fA = orthVec.fX; + (*vert)[i].fLine.fB = orthVec.fY; + (*vert)[i].fLine.fC = lineC; } if (NULL != toSrc) { toSrc->mapPointsWithStride(&(*vert)->fPos, @@ -731,8 +684,6 @@ void add_line(const SkPoint p[2], (*vert)[1].fPos.set(SK_ScalarMax, SK_ScalarMax); (*vert)[2].fPos.set(SK_ScalarMax, SK_ScalarMax); (*vert)[3].fPos.set(SK_ScalarMax, SK_ScalarMax); - (*vert)[4].fPos.set(SK_ScalarMax, SK_ScalarMax); - (*vert)[5].fPos.set(SK_ScalarMax, SK_ScalarMax); } *vert += kVertsPerLineSeg; @@ -985,7 +936,7 @@ GrEffectRef* HairQuadEdgeEffect::TestCreate(SkMWCRandom* random, /** * The output of this effect is a 1-pixel wide line. - * Input is coverage relative to the line. + * Input is 2D implicit device coord line eq (a*x + b*y +c = 0). 4th component unused. */ class HairLineEdgeEffect : public GrEffect { public: @@ -1027,7 +978,9 @@ public: builder->addVarying(kVec4f_GrSLType, "HairLineEdge", &vsName, &fsName); - builder->fsCodeAppendf("\t\tedgeAlpha = %s.x;\n", fsName); + builder->fsCodeAppendf("\t\tedgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n", + builder->fragmentPosition(), fsName); + builder->fsCodeAppendf("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); SkString modulate; GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha"); @@ -1238,15 +1191,13 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path, #endif { - // the fact we're using an effect to pass per-vertex coverage is kind of dumb, - // but necessary due to the shared vertex buffer - // TODO: refactor so that we render lines with a separate vertex buffer GrDrawState::AutoRestoreEffects are(drawState); target->setIndexSourceToBuffer(fLinesIndexBuffer); int lines = 0; + int nBufLines = fLinesIndexBuffer->maxQuads(); drawState->addCoverageEffect(hairLineEffect, kEdgeAttrIndex)->unref(); while (lines < lineCnt) { - int n = GrMin(lineCnt - lines, kNumLineSegsInIdxBuffer); + int n = GrMin(lineCnt - lines, nBufLines); target->drawIndexed(kTriangles_GrPrimitiveType, kVertsPerLineSeg*lines, // startV 0, // startI -- cgit v1.2.3