diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-05-09 18:35:53 +0100 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-05-13 13:57:14 +0100 |
commit | c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d (patch) | |
tree | 1dbdbb0624cc869ab25ee7f46971984c6fee3e7a /skia | |
parent | 2d519ce2457219605d4f472da8d2ffd469796035 (diff) | |
download | chromium_org-c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d.tar.gz |
Merge from Chromium at DEPS revision r198571
This commit was generated by merge_to_master.py.
Change-Id: I951118a03836157090561764dd2627f0add8118f
Diffstat (limited to 'skia')
-rw-r--r-- | skia/ext/SkThread_chrome.cc | 2 | ||||
-rw-r--r-- | skia/ext/analysis_canvas.cc | 209 | ||||
-rw-r--r-- | skia/ext/analysis_canvas.h | 35 | ||||
-rw-r--r-- | skia/ext/analysis_canvas_unittest.cc | 330 | ||||
-rw-r--r-- | skia/ext/convolver.cc | 788 | ||||
-rw-r--r-- | skia/ext/convolver.h | 73 | ||||
-rw-r--r-- | skia/ext/convolver_SSE2.cc | 456 | ||||
-rw-r--r-- | skia/ext/convolver_SSE2.h | 26 | ||||
-rw-r--r-- | skia/ext/convolver_unittest.cc | 158 | ||||
-rw-r--r-- | skia/ext/image_operations.cc | 24 | ||||
-rw-r--r-- | skia/ext/image_operations_unittest.cc | 86 | ||||
-rw-r--r-- | skia/ext/platform_device.h | 4 | ||||
-rw-r--r-- | skia/ext/vector_canvas_unittest.cc | 5 | ||||
-rw-r--r-- | skia/skia.gyp | 45 | ||||
-rw-r--r-- | skia/skia.target.darwin-arm.mk | 546 | ||||
-rw-r--r-- | skia/skia.target.darwin-x86.mk | 546 | ||||
-rw-r--r-- | skia/skia.target.linux-arm.mk | 49 | ||||
-rw-r--r-- | skia/skia.target.linux-x86.mk | 50 | ||||
-rw-r--r-- | skia/skia_opts.target.darwin-arm.mk | 160 | ||||
-rw-r--r-- | skia/skia_opts.target.darwin-x86.mk | 162 | ||||
-rw-r--r-- | skia/skia_opts.target.linux-arm.mk | 8 | ||||
-rw-r--r-- | skia/skia_opts.target.linux-x86.mk | 17 | ||||
-rw-r--r-- | skia/skia_test_expectations.txt | 5 |
23 files changed, 2800 insertions, 984 deletions
diff --git a/skia/ext/SkThread_chrome.cc b/skia/ext/SkThread_chrome.cc index 4904f2da47..f379bebee7 100644 --- a/skia/ext/SkThread_chrome.cc +++ b/skia/ext/SkThread_chrome.cc @@ -51,7 +51,7 @@ int32_t sk_atomic_conditional_inc(int32_t* addr) { } int32_t before; - before = base::subtle::Aquire_CompareAndSwap(addr, value, value + 1); + before = base::subtle::Acquire_CompareAndSwap(addr, value, value + 1); if (before == value) { return value; diff --git a/skia/ext/analysis_canvas.cc b/skia/ext/analysis_canvas.cc index 93580b0132..467f62c421 100644 --- a/skia/ext/analysis_canvas.cc +++ b/skia/ext/analysis_canvas.cc @@ -13,23 +13,6 @@ namespace { -// FIXME: Arbitrary numbers. Requires tuning & experimentation. -// Probably requires per-platform tuning; N10 average draw call takes -// 25x as long as Z620. -const int gPictureCostThreshold = 1000; -const int kUnknownExpensiveCost = 500; -const int kUnknownBitmapCost = 1000; - -// URI label for a lazily decoded SkPixelRef. -const char kLabelLazyDecoded[] = "lazy"; -const int kLabelLazyDecodedLength = 4; - -// Estimate of rasterization performance on mid-low-range hardware, -// drawing rectangles with simple paints. -const int kSimpleRectPixelsPerUS = 1000; -const int kComplexRectPixelsPerUS = 100; -const int kSimpleTextCharPerUS = 2; - bool isSolidColorPaint(const SkPaint& paint) { SkXfermode::Mode xferMode; @@ -80,42 +63,37 @@ bool isFullQuad(const SkDraw& draw, drawBitmapRect.contains(canvasRect); } -bool hasBitmap(const SkPaint& paint) { - SkShader* shader = paint.getShader(); - return shader && - (SkShader::kNone_BitmapType != shader->asABitmap(NULL, NULL, NULL)); -} - } // namespace namespace skia { AnalysisDevice::AnalysisDevice(const SkBitmap& bm) : INHERITED(bm) - , estimatedCost_(0) , isForcedNotSolid_(false) , isForcedNotTransparent_(false) , isSolidColor_(false) - , isTransparent_(false) { - + , isTransparent_(false) + , hasText_(false) { } AnalysisDevice::~AnalysisDevice() { } -int AnalysisDevice::getEstimatedCost() const { - return estimatedCost_; -} - bool AnalysisDevice::getColorIfSolid(SkColor* color) const { - if (isSolidColor_) + if (isTransparent_) { + *color = SK_ColorTRANSPARENT; + return true; + } + if (isSolidColor_) { *color = color_; - return isSolidColor_; + return true; + } + return false; } -bool AnalysisDevice::isTransparent() const { - return isTransparent_; +bool AnalysisDevice::hasText() const { + return hasText_; } void AnalysisDevice::setForceNotSolid(bool flag) { @@ -130,57 +108,9 @@ void AnalysisDevice::setForceNotTransparent(bool flag) { isTransparent_ = false; } -void AnalysisDevice::addPixelRefIfLazy(SkPixelRef* pixelRef) { - if (!pixelRef) - return; - - uint32_t genID = pixelRef->getGenerationID(); - - // If this ID exists (whether it is lazy pixel ref or not), - // we can return early. - std::pair<IdSet::iterator, bool> insertionResult = - existingPixelRefIDs_.insert(genID); - if (!insertionResult.second) - return; - - if (pixelRef->getURI() && - !strncmp(pixelRef->getURI(), - kLabelLazyDecoded, - kLabelLazyDecodedLength)) { - lazyPixelRefs_.push_back(static_cast<skia::LazyPixelRef*>(pixelRef)); - } -} - -void AnalysisDevice::addBitmap(const SkBitmap& bitmap) { - addPixelRefIfLazy(bitmap.pixelRef()); -} - -void AnalysisDevice::addBitmapFromPaint(const SkPaint& paint) { - SkShader* shader = paint.getShader(); - if (shader) { - SkBitmap bitmap; - // Check whether the shader is a gradient in order to short-circuit - // call to asABitmap to prevent generation of bitmaps from - // gradient shaders, which implement asABitmap. - if (SkShader::kNone_GradientType == shader->asAGradient(NULL) && - SkShader::kNone_BitmapType != shader->asABitmap(&bitmap, NULL, NULL)) { - addPixelRefIfLazy(bitmap.pixelRef()); - } - } -} - -void AnalysisDevice::consumeLazyPixelRefs(LazyPixelRefList* pixelRefs) { - DCHECK(pixelRefs); - DCHECK(pixelRefs->empty()); - lazyPixelRefs_.swap(*pixelRefs); - existingPixelRefIDs_.clear(); -} - void AnalysisDevice::clear(SkColor color) { - // FIXME: cost here should be simple rect of device size - estimatedCost_ += kUnknownExpensiveCost; - isTransparent_ = (!isForcedNotTransparent_ && SkColorGetA(color) == 0); + hasText_ = false; if (!isForcedNotSolid_ && SkColorGetA(color) == 255) { isSolidColor_ = true; @@ -192,40 +122,20 @@ void AnalysisDevice::clear(SkColor color) { } void AnalysisDevice::drawPaint(const SkDraw&, const SkPaint& paint) { - estimatedCost_ += kUnknownExpensiveCost; - if (hasBitmap(paint)) { - estimatedCost_ += kUnknownBitmapCost; - addBitmapFromPaint(paint); - } - isSolidColor_ = false; + isSolidColor_ = + (isSolidColor_ && isSolidColorPaint(paint) && paint.getColor() == color_); isTransparent_ = false; } void AnalysisDevice::drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, const SkPoint[], const SkPaint& paint) { - estimatedCost_ += kUnknownExpensiveCost; - if (hasBitmap(paint)) { - estimatedCost_ += kUnknownBitmapCost; - addBitmapFromPaint(paint); - } isSolidColor_ = false; isTransparent_ = false; } void AnalysisDevice::drawRect(const SkDraw& draw, const SkRect& rect, const SkPaint& paint) { - - // FIXME: if there's a pending image decode & resize, more expensive - estimatedCost_ += 1 + rect.width() * rect.height() / kSimpleRectPixelsPerUS; - if (paint.getMaskFilter()) { - estimatedCost_ += kUnknownExpensiveCost; - } - if (hasBitmap(paint)) { - estimatedCost_ += kUnknownBitmapCost; - addBitmapFromPaint(paint); - } - bool doesCoverCanvas = isFullQuad(draw, SkRect::MakeWH(width(), height()), rect); @@ -246,6 +156,7 @@ void AnalysisDevice::drawRect(const SkDraw& draw, const SkRect& rect, !isForcedNotTransparent_ && xferMode == SkXfermode::kClear_Mode) { isTransparent_ = true; + hasText_ = false; } else if (paint.getAlpha() != 0 || xferMode != SkXfermode::kSrc_Mode) { @@ -257,11 +168,15 @@ void AnalysisDevice::drawRect(const SkDraw& draw, const SkRect& rect, // - We're not in "forced not solid" mode // - Paint is solid color // - The quad is a full tile quad + // - The exception is if the tile is already solid tile, + // and we're drawing the same solid color paint then + // the tile remains solid. if (!isForcedNotSolid_ && isSolidColorPaint(paint) && - doesCoverCanvas) { + (doesCoverCanvas || (isSolidColor_ && paint.getColor() == color_))) { isSolidColor_ = true; color_ = paint.getColor(); + hasText_ = false; } else { isSolidColor_ = false; @@ -270,11 +185,6 @@ void AnalysisDevice::drawRect(const SkDraw& draw, const SkRect& rect, void AnalysisDevice::drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) { - estimatedCost_ += kUnknownExpensiveCost; - if (hasBitmap(paint)) { - estimatedCost_ += kUnknownBitmapCost; - addBitmapFromPaint(paint); - } isSolidColor_ = false; isTransparent_ = false; } @@ -283,19 +193,6 @@ void AnalysisDevice::drawPath(const SkDraw&, const SkPath& path, const SkPaint& paint, const SkMatrix* prePathMatrix, bool pathIsMutable ) { - // On Z620, every antialiased path costs us about 300us. - // We've only seen this in practice on filled paths, but - // we expect it to apply to all path stroking modes. - if (paint.getMaskFilter()) { - estimatedCost_ += 300; - } - // FIXME: horrible overestimate if the path is stroked instead of filled - estimatedCost_ += 1 + path.getBounds().width() * - path.getBounds().height() / kSimpleRectPixelsPerUS; - if (hasBitmap(paint)) { - estimatedCost_ += kUnknownBitmapCost; - addBitmapFromPaint(paint); - } isSolidColor_ = false; isTransparent_ = false; } @@ -303,77 +200,49 @@ void AnalysisDevice::drawPath(const SkDraw&, const SkPath& path, void AnalysisDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap, const SkIRect* srcRectOrNull, const SkMatrix& matrix, const SkPaint& paint) { - estimatedCost_ += kUnknownExpensiveCost; - //DCHECK(hasBitmap(paint)); - estimatedCost_ += kUnknownBitmapCost; isSolidColor_ = false; isTransparent_ = false; - addBitmap(bitmap); } void AnalysisDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y, const SkPaint& paint) { - estimatedCost_ += kUnknownExpensiveCost; - //DCHECK(hasBitmap(paint)); - estimatedCost_ += kUnknownBitmapCost; isSolidColor_ = false; isTransparent_ = false; - addBitmap(bitmap); } void AnalysisDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, const SkRect* srcOrNull, const SkRect& dst, const SkPaint& paint) { - // FIXME: we also accumulate cost from drawRect() - estimatedCost_ += 1 + dst.width() * dst.height() / kComplexRectPixelsPerUS; - //DCHECK(hasBitmap(paint)); - estimatedCost_ += kUnknownBitmapCost; - // Call drawRect to determine transparency, // but reset solid color to false. drawRect(draw, dst, paint); isSolidColor_ = false; - addBitmap(bitmap); } void AnalysisDevice::drawText(const SkDraw&, const void* text, size_t len, SkScalar x, SkScalar y, const SkPaint& paint) { - estimatedCost_ += 1 + len / kSimpleTextCharPerUS; - if (hasBitmap(paint)) { - estimatedCost_ += kUnknownBitmapCost; - addBitmapFromPaint(paint); - } isSolidColor_ = false; isTransparent_ = false; + hasText_ = true; } void AnalysisDevice::drawPosText(const SkDraw& draw, const void* text, size_t len, const SkScalar pos[], SkScalar constY, int scalarsPerPos, const SkPaint& paint) { - // FIXME: On Z620, every glyph cache miss costs us about 10us. - // We don't have a good mechanism for predicting glyph cache misses. - estimatedCost_ += 1 + len / kSimpleTextCharPerUS; - if (hasBitmap(paint)) { - estimatedCost_ += kUnknownBitmapCost; - addBitmapFromPaint(paint); - } isSolidColor_ = false; isTransparent_ = false; + hasText_ = true; } void AnalysisDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) { - estimatedCost_ += 1 + len / kSimpleTextCharPerUS; - if (hasBitmap(paint)) { - estimatedCost_ += kUnknownBitmapCost; - addBitmapFromPaint(paint); - } isSolidColor_ = false; isTransparent_ = false; + hasText_ = true; } #ifdef SK_BUILD_FOR_ANDROID @@ -381,13 +250,9 @@ void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len, const SkPoint pos[], const SkPaint& paint, const SkPath& path, const SkMatrix* matrix) { - estimatedCost_ += 1 + len / kSimpleTextCharPerUS; - if (hasBitmap(paint)) { - estimatedCost_ += kUnknownBitmapCost; - addBitmapFromPaint(paint); - } isSolidColor_ = false; isTransparent_ = false; + hasText_ = true; } #endif @@ -397,20 +262,12 @@ void AnalysisDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, const SkPaint& paint) { - estimatedCost_ += kUnknownExpensiveCost; - if (hasBitmap(paint)) { - estimatedCost_ += kUnknownBitmapCost; - addBitmapFromPaint(paint); - } isSolidColor_ = false; isTransparent_ = false; } void AnalysisDevice::drawDevice(const SkDraw&, SkDevice*, int x, int y, const SkPaint& paint) { - estimatedCost_ += kUnknownExpensiveCost; - if (hasBitmap(paint)) - estimatedCost_ += kUnknownBitmapCost; isSolidColor_ = false; isTransparent_ = false; } @@ -429,24 +286,12 @@ AnalysisCanvas::~AnalysisCanvas() { } -bool AnalysisCanvas::isCheap() const { - return getEstimatedCost() < gPictureCostThreshold; -} - bool AnalysisCanvas::getColorIfSolid(SkColor* color) const { return (static_cast<AnalysisDevice*>(getDevice()))->getColorIfSolid(color); } -bool AnalysisCanvas::isTransparent() const { - return (static_cast<AnalysisDevice*>(getDevice()))->isTransparent(); -} - -int AnalysisCanvas::getEstimatedCost() const { - return (static_cast<AnalysisDevice*>(getDevice()))->getEstimatedCost(); -} - -void AnalysisCanvas::consumeLazyPixelRefs(LazyPixelRefList* pixelRefs) { - static_cast<AnalysisDevice*>(getDevice())->consumeLazyPixelRefs(pixelRefs); +bool AnalysisCanvas::hasText() const { + return (static_cast<AnalysisDevice*>(getDevice()))->hasText(); } bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, diff --git a/skia/ext/analysis_canvas.h b/skia/ext/analysis_canvas.h index 3c2daafebd..67151d36e5 100644 --- a/skia/ext/analysis_canvas.h +++ b/skia/ext/analysis_canvas.h @@ -5,11 +5,6 @@ #ifndef SKIA_EXT_ANALYSIS_CANVAS_H_ #define SKIA_EXT_ANALYSIS_CANVAS_H_ -#include <list> -#include <set> - -#include "base/hash_tables.h" -#include "skia/ext/lazy_pixel_ref.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkDevice.h" @@ -22,23 +17,15 @@ class AnalysisDevice; // played back through it. // To use: create a SkBitmap with kNo_Config, create an AnalysisDevice // using that bitmap, and create an AnalysisCanvas using the device. -// Play a picture into the canvas, and then check isCheap(). +// Play a picture into the canvas, and then check result. class SK_API AnalysisCanvas : public SkCanvas { public: - typedef std::list<skia::LazyPixelRef*> LazyPixelRefList; - AnalysisCanvas(AnalysisDevice*); virtual ~AnalysisCanvas(); - // Returns true if the estimated cost of drawing is below an - // arbitrary threshold. - bool isCheap() const; + // Returns true when a SkColor can be used to represent result. bool getColorIfSolid(SkColor* color) const; - bool isTransparent() const; - void consumeLazyPixelRefs(LazyPixelRefList* pixelRefs); - - // Returns the estimated cost of drawing, in arbitrary units. - int getEstimatedCost() const; + bool hasText() const; virtual bool clipRect(const SkRect& rect, SkRegion::Op op = SkRegion::kIntersect_Op, @@ -67,16 +54,11 @@ class SK_API AnalysisCanvas : public SkCanvas { class SK_API AnalysisDevice : public SkDevice { public: - typedef std::list<skia::LazyPixelRef*> LazyPixelRefList; - typedef base::hash_set<uint32_t> IdSet; - AnalysisDevice(const SkBitmap& bm); virtual ~AnalysisDevice(); - int getEstimatedCost() const; bool getColorIfSolid(SkColor* color) const; - bool isTransparent() const; - void consumeLazyPixelRefs(LazyPixelRefList* pixelRefs); + bool hasText() const; void setForceNotSolid(bool flag); void setForceNotTransparent(bool flag); @@ -129,23 +111,16 @@ class SK_API AnalysisDevice : public SkDevice { virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y, const SkPaint&) OVERRIDE; - int estimatedCost_; - private: typedef SkDevice INHERITED; - void addPixelRefIfLazy(SkPixelRef* pixelRef); - void addBitmap(const SkBitmap& bitmap); - void addBitmapFromPaint(const SkPaint& paint); - bool isForcedNotSolid_; bool isForcedNotTransparent_; bool isSolidColor_; SkColor color_; bool isTransparent_; - IdSet existingPixelRefIDs_; - LazyPixelRefList lazyPixelRefs_; + bool hasText_; }; } // namespace skia diff --git a/skia/ext/analysis_canvas_unittest.cc b/skia/ext/analysis_canvas_unittest.cc index f403a596d8..4c54dd5b39 100644 --- a/skia/ext/analysis_canvas_unittest.cc +++ b/skia/ext/analysis_canvas_unittest.cc @@ -20,46 +20,6 @@ void transparentFill(skia::AnalysisCanvas& canvas) { } // namespace namespace skia { -class TestPixelRef : public SkPixelRef { - public: - // Pure virtual implementation. - SkFlattenable::Factory getFactory() { return NULL; } - void* onLockPixels(SkColorTable**) { return NULL; } - void onUnlockPixels() {} -}; - -class TestLazyPixelRef : public LazyPixelRef { - public: - // Pure virtual implementation. - SkFlattenable::Factory getFactory() { return NULL; } - void* onLockPixels(SkColorTable**) { return NULL; } - void onUnlockPixels() {} - bool PrepareToDecode(const PrepareParams& params) { return true; } - void Decode() {} -}; - -class TestShader : public SkShader { - public: - TestShader(SkBitmap* bitmap) - : bitmap_(bitmap) { - } - - SkShader::BitmapType asABitmap(SkBitmap* bitmap, - SkMatrix*, TileMode xy[2]) const { - if (bitmap) - *bitmap = *bitmap_; - return SkShader::kDefault_BitmapType; - } - - // Pure virtual implementation. - void shadeSpan(int x, int y, SkPMColor[], int count) {} - SkFlattenable::Factory getFactory() { return NULL; } - - private: - - SkBitmap* bitmap_; -}; - TEST(AnalysisCanvasTest, EmptyCanvas) { SkBitmap emptyBitmap; emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255); @@ -68,8 +28,6 @@ TEST(AnalysisCanvasTest, EmptyCanvas) { SkColor color; EXPECT_FALSE(canvas.getColorIfSolid(&color)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); } TEST(AnalysisCanvasTest, ClearCanvas) { @@ -83,17 +41,15 @@ TEST(AnalysisCanvasTest, ClearCanvas) { canvas.clear(color); SkColor outputColor; - EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_TRUE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); + EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); + EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); // Solid color color = SkColorSetARGB(255, 65, 43, 21); canvas.clear(color); EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_FALSE(canvas.isCheap()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); EXPECT_EQ(outputColor, color); // Translucent color @@ -101,17 +57,15 @@ TEST(AnalysisCanvasTest, ClearCanvas) { canvas.clear(color); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_FALSE(canvas.isCheap()); // Test helper methods solidColorFill(canvas); EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); transparentFill(canvas); - EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_TRUE(canvas.isTransparent()); + EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); + EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); } TEST(AnalysisCanvasTest, ComplexActions) { @@ -130,8 +84,6 @@ TEST(AnalysisCanvasTest, ComplexActions) { SkColor outputColor; //TODO(vmpstr): This should return true. (crbug.com/180597) EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); // Draw points test. SkPoint points[4] = { @@ -145,16 +97,12 @@ TEST(AnalysisCanvasTest, ComplexActions) { canvas.drawPoints(SkCanvas::kLines_PointMode, 4, points, paint); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_FALSE(canvas.isCheap()); // Draw oval test. solidColorFill(canvas); canvas.drawOval(SkRect::MakeWH(255, 255), paint); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_FALSE(canvas.isCheap()); // Draw bitmap test. solidColorFill(canvas); @@ -163,8 +111,6 @@ TEST(AnalysisCanvasTest, ComplexActions) { canvas.drawBitmap(secondBitmap, 0, 0); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_FALSE(canvas.isCheap()); } TEST(AnalysisCanvasTest, SimpleDrawRect) { @@ -181,8 +127,7 @@ TEST(AnalysisCanvasTest, SimpleDrawRect) { SkColor outputColor; EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); EXPECT_EQ(color, outputColor); color = SkColorSetARGB(255, 22, 33, 44); @@ -191,16 +136,13 @@ TEST(AnalysisCanvasTest, SimpleDrawRect) { canvas.drawRect(SkRect::MakeWH(382, 382), paint); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); color = SkColorSetARGB(255, 33, 44, 55); paint.setColor(color); canvas.drawRect(SkRect::MakeWH(383, 383), paint); EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); EXPECT_EQ(color, outputColor); color = SkColorSetARGB(0, 0, 0, 0); @@ -208,8 +150,7 @@ TEST(AnalysisCanvasTest, SimpleDrawRect) { canvas.drawRect(SkRect::MakeWH(383, 383), paint); EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); EXPECT_EQ(outputColor, SkColorSetARGB(255, 33, 44, 55)); color = SkColorSetARGB(128, 128, 128, 128); @@ -217,21 +158,16 @@ TEST(AnalysisCanvasTest, SimpleDrawRect) { canvas.drawRect(SkRect::MakeWH(383, 383), paint); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); paint.setXfermodeMode(SkXfermode::kClear_Mode); canvas.drawRect(SkRect::MakeWH(382, 382), paint); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); canvas.drawRect(SkRect::MakeWH(383, 383), paint); - EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_TRUE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); + EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); + EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); canvas.translate(128, 128); color = SkColorSetARGB(255, 11, 22, 33); @@ -240,16 +176,21 @@ TEST(AnalysisCanvasTest, SimpleDrawRect) { canvas.drawRect(SkRect::MakeWH(255, 255), paint); EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); EXPECT_EQ(color, outputColor); + // Paint with the same color, tile should remain solid. canvas.rotate(50); canvas.drawRect(SkRect::MakeWH(255, 255), paint); + EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); + EXPECT_EQ(color, outputColor); + + color = SkColorSetARGB(255, 12, 23, 34); + paint.setColor(color); + paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); + canvas.drawRect(SkRect::MakeWH(255, 255), paint); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); - EXPECT_TRUE(canvas.isCheap()); } TEST(AnalysisCanvasTest, ClipPath) { @@ -300,153 +241,172 @@ TEST(AnalysisCanvasTest, SaveLayerRestore) { // This should force non-transparency canvas.saveLayer(&bounds, &paint, SkCanvas::kMatrix_SaveFlag); EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); transparentFill(canvas); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); solidColorFill(canvas); EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); paint.setXfermodeMode(SkXfermode::kDst_Mode); // This should force non-solid color canvas.saveLayer(&bounds, &paint, SkCanvas::kMatrix_SaveFlag); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); transparentFill(canvas); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); solidColorFill(canvas); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); canvas.restore(); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); transparentFill(canvas); EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); solidColorFill(canvas); EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); canvas.restore(); EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); transparentFill(canvas); - EXPECT_FALSE(canvas.getColorIfSolid(&outputColor)); - EXPECT_TRUE(canvas.isTransparent()); + EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); + EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); solidColorFill(canvas); EXPECT_TRUE(canvas.getColorIfSolid(&outputColor)); - EXPECT_FALSE(canvas.isTransparent()); + EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); } -TEST(AnalysisCanvasTest, LazyPixelRefs) { - // Set up two lazy and two non-lazy pixel refs and the corresponding bitmaps. - TestLazyPixelRef firstLazyPixelRef; - firstLazyPixelRef.setURI("lazy"); - TestLazyPixelRef secondLazyPixelRef; - secondLazyPixelRef.setURI("lazy"); - - TestPixelRef firstNonLazyPixelRef; - TestPixelRef secondNonLazyPixelRef; - secondNonLazyPixelRef.setURI("notsolazy"); - - SkBitmap firstLazyBitmap; - firstLazyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255); - firstLazyBitmap.setPixelRef(&firstLazyPixelRef); - SkBitmap secondLazyBitmap; - secondLazyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255); - secondLazyBitmap.setPixelRef(&secondLazyPixelRef); - - SkBitmap firstNonLazyBitmap; - firstNonLazyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255); - SkBitmap secondNonLazyBitmap; - secondNonLazyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255); - secondNonLazyBitmap.setPixelRef(&secondNonLazyPixelRef); - - // The testcase starts here. - SkBitmap emptyBitmap; - emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255); - skia::AnalysisDevice device(emptyBitmap); - skia::AnalysisCanvas canvas(&device); - - // This should be the first ref. - canvas.drawBitmap(firstLazyBitmap, 0, 0); - // The following will be ignored (non-lazy). - canvas.drawBitmap(firstNonLazyBitmap, 0, 0); - canvas.drawBitmap(firstNonLazyBitmap, 0, 0); - canvas.drawBitmap(secondNonLazyBitmap, 0, 0); - canvas.drawBitmap(secondNonLazyBitmap, 0, 0); - // This one will be ignored (already exists). - canvas.drawBitmap(firstLazyBitmap, 0, 0); - // This should be the second ref. - canvas.drawBitmap(secondLazyBitmap, 0, 0); - - std::list<skia::LazyPixelRef*> pixelRefs; - canvas.consumeLazyPixelRefs(&pixelRefs); - - // We expect to get only lazy pixel refs and only unique results. - EXPECT_EQ(pixelRefs.size(), 2u); - if (!pixelRefs.empty()) { - EXPECT_EQ(pixelRefs.front(), - static_cast<LazyPixelRef*>(&firstLazyPixelRef)); - EXPECT_EQ(pixelRefs.back(), - static_cast<LazyPixelRef*>(&secondLazyPixelRef)); - } -} - -TEST(AnalysisCanvasTest, PixelRefsFromPaint) { - TestLazyPixelRef lazyPixelRef; - lazyPixelRef.setURI("lazy"); - - TestPixelRef nonLazyPixelRef; - nonLazyPixelRef.setURI("notsolazy"); +TEST(AnalysisCanvasTest, HasText) { + int width = 200; + int height = 100; - SkBitmap lazyBitmap; - lazyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255); - lazyBitmap.setPixelRef(&lazyPixelRef); + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kNo_Config, width, height); - SkBitmap nonLazyBitmap; - nonLazyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255); - nonLazyBitmap.setPixelRef(&nonLazyPixelRef); + const char* text = "A"; + size_t byteLength = 1; - TestShader lazyShader(&lazyBitmap); - TestShader nonLazyShader(&nonLazyBitmap); - - SkPaint lazyPaint; - lazyPaint.setShader(&lazyShader); - SkPaint nonLazyPaint; - nonLazyPaint.setShader(&nonLazyShader); - - SkBitmap emptyBitmap; - emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255); - skia::AnalysisDevice device(emptyBitmap); - skia::AnalysisCanvas canvas(&device); - - canvas.drawRect(SkRect::MakeWH(255, 255), lazyPaint); - canvas.drawRect(SkRect::MakeWH(255, 255), lazyPaint); - canvas.drawRect(SkRect::MakeWH(255, 255), lazyPaint); - canvas.drawRect(SkRect::MakeWH(255, 255), nonLazyPaint); - canvas.drawRect(SkRect::MakeWH(255, 255), nonLazyPaint); - canvas.drawRect(SkRect::MakeWH(255, 255), nonLazyPaint); - - std::list<skia::LazyPixelRef*> pixelRefs; - canvas.consumeLazyPixelRefs(&pixelRefs); + SkPoint point = SkPoint::Make(SkIntToScalar(25), SkIntToScalar(25)); + SkPath path; + path.moveTo(point); + path.lineTo(SkIntToScalar(75), SkIntToScalar(75)); - // We expect to get only lazy pixel refs and only unique results. - EXPECT_EQ(pixelRefs.size(), 1u); - if (!pixelRefs.empty()) { - EXPECT_EQ(pixelRefs.front(), static_cast<LazyPixelRef*>(&lazyPixelRef)); + SkPaint paint; + paint.setColor(SK_ColorGRAY); + paint.setTextSize(SkIntToScalar(10)); + + { + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + // Test after initialization. + EXPECT_FALSE(canvas.hasText()); + // Test drawing anything other than text. + canvas.drawRect(SkRect::MakeWH(width/2, height), paint); + EXPECT_FALSE(canvas.hasText()); + } + { + // Test SkCanvas::drawText. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.drawText(text, byteLength, point.fX, point.fY, paint); + EXPECT_TRUE(canvas.hasText()); + } + { + // Test SkCanvas::drawPosText. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.drawPosText(text, byteLength, &point, paint); + EXPECT_TRUE(canvas.hasText()); + } + { + // Test SkCanvas::drawPosTextH. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.drawPosTextH(text, byteLength, &point.fX, point.fY, paint); + EXPECT_TRUE(canvas.hasText()); + } + { + // Test SkCanvas::drawTextOnPathHV. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.drawTextOnPathHV(text, byteLength, path, point.fX, point.fY, paint); + EXPECT_TRUE(canvas.hasText()); + } + { + // Test SkCanvas::drawTextOnPath. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.drawTextOnPath(text, byteLength, path, NULL, paint); + EXPECT_TRUE(canvas.hasText()); + } + { + // Text under opaque rect. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.drawText(text, byteLength, point.fX, point.fY, paint); + EXPECT_TRUE(canvas.hasText()); + canvas.drawRect(SkRect::MakeWH(width, height), paint); + EXPECT_FALSE(canvas.hasText()); + } + { + // Text under translucent rect. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.drawText(text, byteLength, point.fX, point.fY, paint); + EXPECT_TRUE(canvas.hasText()); + SkPaint translucentPaint; + translucentPaint.setColor(0x88FFFFFF); + canvas.drawRect(SkRect::MakeWH(width, height), translucentPaint); + EXPECT_TRUE(canvas.hasText()); + } + { + // Text under rect in clear mode. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.drawText(text, byteLength, point.fX, point.fY, paint); + EXPECT_TRUE(canvas.hasText()); + SkPaint clearModePaint; + clearModePaint.setXfermodeMode(SkXfermode::kClear_Mode); + canvas.drawRect(SkRect::MakeWH(width, height), clearModePaint); + EXPECT_FALSE(canvas.hasText()); + } + { + // Clear. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.drawText(text, byteLength, point.fX, point.fY, paint); + EXPECT_TRUE(canvas.hasText()); + canvas.clear(SK_ColorGRAY); + EXPECT_FALSE(canvas.hasText()); + } + { + // Text inside clip region. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.clipRect(SkRect::MakeWH(100, 100)); + canvas.drawText(text, byteLength, point.fX, point.fY, paint); + EXPECT_TRUE(canvas.hasText()); + } + { + // Text outside clip region. + skia::AnalysisDevice device(bitmap); + skia::AnalysisCanvas canvas(&device); + canvas.clipRect(SkRect::MakeXYWH(100, 0, 100, 100)); + canvas.drawText(text, byteLength, point.fX, point.fY, paint); + // Analysis device does not do any clipping. + // So even when text is outside the clip region, + // it is marked as having the text. + // TODO(alokp): We may be able to do some trivial rejection. + EXPECT_TRUE(canvas.hasText()); } } diff --git a/skia/ext/convolver.cc b/skia/ext/convolver.cc index 47e3711fac..2057b2219a 100644 --- a/skia/ext/convolver.cc +++ b/skia/ext/convolver.cc @@ -4,13 +4,12 @@ #include <algorithm> +#include "base/logging.h" #include "skia/ext/convolver.h" +#include "skia/ext/convolver_SSE2.h" +#include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkTypes.h" -#if defined(SIMD_SSE2) -#include <emmintrin.h> // ARCH_CPU_X86_FAMILY was defined in build/config.h -#endif - namespace skia { namespace { @@ -25,6 +24,17 @@ inline unsigned char ClampTo8(int a) { return 255; } +// Takes the value produced by accumulating element-wise product of image with +// a kernel and brings it back into range. +// All of the filter scaling factors are in fixed point with kShiftBits bits of +// fractional part. +inline unsigned char BringBackTo8(int a, bool take_absolute) { + a >>= ConvolutionFilter1D::kShiftBits; + if (take_absolute) + a = std::abs(a); + return ClampTo8(a); +} + // Stores a list of rows in a circular buffer. The usage is you write into it // by calling AdvanceRow. It will keep track of which row in the buffer it // should use next, and the total number of rows added. @@ -223,431 +233,23 @@ void ConvolveVertically(const ConvolutionFilter1D::Fixed* filter_values, } } - -// Convolves horizontally along a single row. The row data is given in -// |src_data| and continues for the num_values() of the filter. -void ConvolveHorizontally_SSE2(const unsigned char* src_data, - const ConvolutionFilter1D& filter, - unsigned char* out_row) { -#if defined(SIMD_SSE2) - int num_values = filter.num_values(); - - int filter_offset, filter_length; - __m128i zero = _mm_setzero_si128(); - __m128i mask[4]; - // |mask| will be used to decimate all extra filter coefficients that are - // loaded by SIMD when |filter_length| is not divisible by 4. - // mask[0] is not used in following algorithm. - mask[1] = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, -1); - mask[2] = _mm_set_epi16(0, 0, 0, 0, 0, 0, -1, -1); - mask[3] = _mm_set_epi16(0, 0, 0, 0, 0, -1, -1, -1); - - // Output one pixel each iteration, calculating all channels (RGBA) together. - for (int out_x = 0; out_x < num_values; out_x++) { - const ConvolutionFilter1D::Fixed* filter_values = - filter.FilterForValue(out_x, &filter_offset, &filter_length); - - __m128i accum = _mm_setzero_si128(); - - // Compute the first pixel in this row that the filter affects. It will - // touch |filter_length| pixels (4 bytes each) after this. - const __m128i* row_to_filter = - reinterpret_cast<const __m128i*>(&src_data[filter_offset << 2]); - - // We will load and accumulate with four coefficients per iteration. - for (int filter_x = 0; filter_x < filter_length >> 2; filter_x++) { - - // Load 4 coefficients => duplicate 1st and 2nd of them for all channels. - __m128i coeff, coeff16; - // [16] xx xx xx xx c3 c2 c1 c0 - coeff = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(filter_values)); - // [16] xx xx xx xx c1 c1 c0 c0 - coeff16 = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(1, 1, 0, 0)); - // [16] c1 c1 c1 c1 c0 c0 c0 c0 - coeff16 = _mm_unpacklo_epi16(coeff16, coeff16); - - // Load four pixels => unpack the first two pixels to 16 bits => - // multiply with coefficients => accumulate the convolution result. - // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 - __m128i src8 = _mm_loadu_si128(row_to_filter); - // [16] a1 b1 g1 r1 a0 b0 g0 r0 - __m128i src16 = _mm_unpacklo_epi8(src8, zero); - __m128i mul_hi = _mm_mulhi_epi16(src16, coeff16); - __m128i mul_lo = _mm_mullo_epi16(src16, coeff16); - // [32] a0*c0 b0*c0 g0*c0 r0*c0 - __m128i t = _mm_unpacklo_epi16(mul_lo, mul_hi); - accum = _mm_add_epi32(accum, t); - // [32] a1*c1 b1*c1 g1*c1 r1*c1 - t = _mm_unpackhi_epi16(mul_lo, mul_hi); - accum = _mm_add_epi32(accum, t); - - // Duplicate 3rd and 4th coefficients for all channels => - // unpack the 3rd and 4th pixels to 16 bits => multiply with coefficients - // => accumulate the convolution results. - // [16] xx xx xx xx c3 c3 c2 c2 - coeff16 = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(3, 3, 2, 2)); - // [16] c3 c3 c3 c3 c2 c2 c2 c2 - coeff16 = _mm_unpacklo_epi16(coeff16, coeff16); - // [16] a3 g3 b3 r3 a2 g2 b2 r2 - src16 = _mm_unpackhi_epi8(src8, zero); - mul_hi = _mm_mulhi_epi16(src16, coeff16); - mul_lo = _mm_mullo_epi16(src16, coeff16); - // [32] a2*c2 b2*c2 g2*c2 r2*c2 - t = _mm_unpacklo_epi16(mul_lo, mul_hi); - accum = _mm_add_epi32(accum, t); - // [32] a3*c3 b3*c3 g3*c3 r3*c3 - t = _mm_unpackhi_epi16(mul_lo, mul_hi); - accum = _mm_add_epi32(accum, t); - - // Advance the pixel and coefficients pointers. - row_to_filter += 1; - filter_values += 4; - } - - // When |filter_length| is not divisible by 4, we need to decimate some of - // the filter coefficient that was loaded incorrectly to zero; Other than - // that the algorithm is same with above, exceot that the 4th pixel will be - // always absent. - int r = filter_length&3; - if (r) { - // Note: filter_values must be padded to align_up(filter_offset, 8). - __m128i coeff, coeff16; - coeff = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(filter_values)); - // Mask out extra filter taps. - coeff = _mm_and_si128(coeff, mask[r]); - coeff16 = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(1, 1, 0, 0)); - coeff16 = _mm_unpacklo_epi16(coeff16, coeff16); - - // Note: line buffer must be padded to align_up(filter_offset, 16). - // We resolve this by use C-version for the last horizontal line. - __m128i src8 = _mm_loadu_si128(row_to_filter); - __m128i src16 = _mm_unpacklo_epi8(src8, zero); - __m128i mul_hi = _mm_mulhi_epi16(src16, coeff16); - __m128i mul_lo = _mm_mullo_epi16(src16, coeff16); - __m128i t = _mm_unpacklo_epi16(mul_lo, mul_hi); - accum = _mm_add_epi32(accum, t); - t = _mm_unpackhi_epi16(mul_lo, mul_hi); - accum = _mm_add_epi32(accum, t); - - src16 = _mm_unpackhi_epi8(src8, zero); - coeff16 = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(3, 3, 2, 2)); - coeff16 = _mm_unpacklo_epi16(coeff16, coeff16); - mul_hi = _mm_mulhi_epi16(src16, coeff16); - mul_lo = _mm_mullo_epi16(src16, coeff16); - t = _mm_unpacklo_epi16(mul_lo, mul_hi); - accum = _mm_add_epi32(accum, t); - } - - // Shift right for fixed point implementation. - accum = _mm_srai_epi32(accum, ConvolutionFilter1D::kShiftBits); - - // Packing 32 bits |accum| to 16 bits per channel (signed saturation). - accum = _mm_packs_epi32(accum, zero); - // Packing 16 bits |accum| to 8 bits per channel (unsigned saturation). - accum = _mm_packus_epi16(accum, zero); - - // Store the pixel value of 32 bits. - *(reinterpret_cast<int*>(out_row)) = _mm_cvtsi128_si32(accum); - out_row += 4; - } -#endif -} - -// Convolves horizontally along four rows. The row data is given in -// |src_data| and continues for the num_values() of the filter. -// The algorithm is almost same as |ConvolveHorizontally_SSE2|. Please -// refer to that function for detailed comments. -void ConvolveHorizontally4_SSE2(const unsigned char* src_data[4], - const ConvolutionFilter1D& filter, - unsigned char* out_row[4]) { -#if defined(SIMD_SSE2) - int num_values = filter.num_values(); - - int filter_offset, filter_length; - __m128i zero = _mm_setzero_si128(); - __m128i mask[4]; - // |mask| will be used to decimate all extra filter coefficients that are - // loaded by SIMD when |filter_length| is not divisible by 4. - // mask[0] is not used in following algorithm. - mask[1] = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, -1); - mask[2] = _mm_set_epi16(0, 0, 0, 0, 0, 0, -1, -1); - mask[3] = _mm_set_epi16(0, 0, 0, 0, 0, -1, -1, -1); - - // Output one pixel each iteration, calculating all channels (RGBA) together. - for (int out_x = 0; out_x < num_values; out_x++) { - const ConvolutionFilter1D::Fixed* filter_values = - filter.FilterForValue(out_x, &filter_offset, &filter_length); - - // four pixels in a column per iteration. - __m128i accum0 = _mm_setzero_si128(); - __m128i accum1 = _mm_setzero_si128(); - __m128i accum2 = _mm_setzero_si128(); - __m128i accum3 = _mm_setzero_si128(); - int start = (filter_offset<<2); - // We will load and accumulate with four coefficients per iteration. - for (int filter_x = 0; filter_x < (filter_length >> 2); filter_x++) { - __m128i coeff, coeff16lo, coeff16hi; - // [16] xx xx xx xx c3 c2 c1 c0 - coeff = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(filter_values)); - // [16] xx xx xx xx c1 c1 c0 c0 - coeff16lo = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(1, 1, 0, 0)); - // [16] c1 c1 c1 c1 c0 c0 c0 c0 - coeff16lo = _mm_unpacklo_epi16(coeff16lo, coeff16lo); - // [16] xx xx xx xx c3 c3 c2 c2 - coeff16hi = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(3, 3, 2, 2)); - // [16] c3 c3 c3 c3 c2 c2 c2 c2 - coeff16hi = _mm_unpacklo_epi16(coeff16hi, coeff16hi); - - __m128i src8, src16, mul_hi, mul_lo, t; - -#define ITERATION(src, accum) \ - src8 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src)); \ - src16 = _mm_unpacklo_epi8(src8, zero); \ - mul_hi = _mm_mulhi_epi16(src16, coeff16lo); \ - mul_lo = _mm_mullo_epi16(src16, coeff16lo); \ - t = _mm_unpacklo_epi16(mul_lo, mul_hi); \ - accum = _mm_add_epi32(accum, t); \ - t = _mm_unpackhi_epi16(mul_lo, mul_hi); \ - accum = _mm_add_epi32(accum, t); \ - src16 = _mm_unpackhi_epi8(src8, zero); \ - mul_hi = _mm_mulhi_epi16(src16, coeff16hi); \ - mul_lo = _mm_mullo_epi16(src16, coeff16hi); \ - t = _mm_unpacklo_epi16(mul_lo, mul_hi); \ - accum = _mm_add_epi32(accum, t); \ - t = _mm_unpackhi_epi16(mul_lo, mul_hi); \ - accum = _mm_add_epi32(accum, t) - - ITERATION(src_data[0] + start, accum0); - ITERATION(src_data[1] + start, accum1); - ITERATION(src_data[2] + start, accum2); - ITERATION(src_data[3] + start, accum3); - - start += 16; - filter_values += 4; - } - - int r = filter_length & 3; - if (r) { - // Note: filter_values must be padded to align_up(filter_offset, 8); - __m128i coeff; - coeff = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(filter_values)); - // Mask out extra filter taps. - coeff = _mm_and_si128(coeff, mask[r]); - - __m128i coeff16lo = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(1, 1, 0, 0)); - /* c1 c1 c1 c1 c0 c0 c0 c0 */ - coeff16lo = _mm_unpacklo_epi16(coeff16lo, coeff16lo); - __m128i coeff16hi = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(3, 3, 2, 2)); - coeff16hi = _mm_unpacklo_epi16(coeff16hi, coeff16hi); - - __m128i src8, src16, mul_hi, mul_lo, t; - - ITERATION(src_data[0] + start, accum0); - ITERATION(src_data[1] + start, accum1); - ITERATION(src_data[2] + start, accum2); - ITERATION(src_data[3] + start, accum3); - } - - accum0 = _mm_srai_epi32(accum0, ConvolutionFilter1D::kShiftBits); - accum0 = _mm_packs_epi32(accum0, zero); - accum0 = _mm_packus_epi16(accum0, zero); - accum1 = _mm_srai_epi32(accum1, ConvolutionFilter1D::kShiftBits); - accum1 = _mm_packs_epi32(accum1, zero); - accum1 = _mm_packus_epi16(accum1, zero); - accum2 = _mm_srai_epi32(accum2, ConvolutionFilter1D::kShiftBits); - accum2 = _mm_packs_epi32(accum2, zero); - accum2 = _mm_packus_epi16(accum2, zero); - accum3 = _mm_srai_epi32(accum3, ConvolutionFilter1D::kShiftBits); - accum3 = _mm_packs_epi32(accum3, zero); - accum3 = _mm_packus_epi16(accum3, zero); - - *(reinterpret_cast<int*>(out_row[0])) = _mm_cvtsi128_si32(accum0); - *(reinterpret_cast<int*>(out_row[1])) = _mm_cvtsi128_si32(accum1); - *(reinterpret_cast<int*>(out_row[2])) = _mm_cvtsi128_si32(accum2); - *(reinterpret_cast<int*>(out_row[3])) = _mm_cvtsi128_si32(accum3); - - out_row[0] += 4; - out_row[1] += 4; - out_row[2] += 4; - out_row[3] += 4; +void ConvolveVertically(const ConvolutionFilter1D::Fixed* filter_values, + int filter_length, + unsigned char* const* source_data_rows, + int pixel_width, + unsigned char* out_row, + bool source_has_alpha) { + if (source_has_alpha) { + ConvolveVertically<true>(filter_values, filter_length, + source_data_rows, + pixel_width, + out_row); + } else { + ConvolveVertically<false>(filter_values, filter_length, + source_data_rows, + pixel_width, + out_row); } -#endif -} - -// Does vertical convolution to produce one output row. The filter values and -// length are given in the first two parameters. These are applied to each -// of the rows pointed to in the |source_data_rows| array, with each row -// being |pixel_width| wide. -// -// The output must have room for |pixel_width * 4| bytes. -template<bool has_alpha> -void ConvolveVertically_SSE2(const ConvolutionFilter1D::Fixed* filter_values, - int filter_length, - unsigned char* const* source_data_rows, - int pixel_width, - unsigned char* out_row) { -#if defined(SIMD_SSE2) - int width = pixel_width & ~3; - - __m128i zero = _mm_setzero_si128(); - __m128i accum0, accum1, accum2, accum3, coeff16; - const __m128i* src; - // Output four pixels per iteration (16 bytes). - for (int out_x = 0; out_x < width; out_x += 4) { - - // Accumulated result for each pixel. 32 bits per RGBA channel. - accum0 = _mm_setzero_si128(); - accum1 = _mm_setzero_si128(); - accum2 = _mm_setzero_si128(); - accum3 = _mm_setzero_si128(); - - // Convolve with one filter coefficient per iteration. - for (int filter_y = 0; filter_y < filter_length; filter_y++) { - - // Duplicate the filter coefficient 8 times. - // [16] cj cj cj cj cj cj cj cj - coeff16 = _mm_set1_epi16(filter_values[filter_y]); - - // Load four pixels (16 bytes) together. - // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 - src = reinterpret_cast<const __m128i*>( - &source_data_rows[filter_y][out_x << 2]); - __m128i src8 = _mm_loadu_si128(src); - - // Unpack 1st and 2nd pixels from 8 bits to 16 bits for each channels => - // multiply with current coefficient => accumulate the result. - // [16] a1 b1 g1 r1 a0 b0 g0 r0 - __m128i src16 = _mm_unpacklo_epi8(src8, zero); - __m128i mul_hi = _mm_mulhi_epi16(src16, coeff16); - __m128i mul_lo = _mm_mullo_epi16(src16, coeff16); - // [32] a0 b0 g0 r0 - __m128i t = _mm_unpacklo_epi16(mul_lo, mul_hi); - accum0 = _mm_add_epi32(accum0, t); - // [32] a1 b1 g1 r1 - t = _mm_unpackhi_epi16(mul_lo, mul_hi); - accum1 = _mm_add_epi32(accum1, t); - - // Unpack 3rd and 4th pixels from 8 bits to 16 bits for each channels => - // multiply with current coefficient => accumulate the result. - // [16] a3 b3 g3 r3 a2 b2 g2 r2 - src16 = _mm_unpackhi_epi8(src8, zero); - mul_hi = _mm_mulhi_epi16(src16, coeff16); - mul_lo = _mm_mullo_epi16(src16, coeff16); - // [32] a2 b2 g2 r2 - t = _mm_unpacklo_epi16(mul_lo, mul_hi); - accum2 = _mm_add_epi32(accum2, t); - // [32] a3 b3 g3 r3 - t = _mm_unpackhi_epi16(mul_lo, mul_hi); - accum3 = _mm_add_epi32(accum3, t); - } - - // Shift right for fixed point implementation. - accum0 = _mm_srai_epi32(accum0, ConvolutionFilter1D::kShiftBits); - accum1 = _mm_srai_epi32(accum1, ConvolutionFilter1D::kShiftBits); - accum2 = _mm_srai_epi32(accum2, ConvolutionFilter1D::kShiftBits); - accum3 = _mm_srai_epi32(accum3, ConvolutionFilter1D::kShiftBits); - - // Packing 32 bits |accum| to 16 bits per channel (signed saturation). - // [16] a1 b1 g1 r1 a0 b0 g0 r0 - accum0 = _mm_packs_epi32(accum0, accum1); - // [16] a3 b3 g3 r3 a2 b2 g2 r2 - accum2 = _mm_packs_epi32(accum2, accum3); - - // Packing 16 bits |accum| to 8 bits per channel (unsigned saturation). - // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 - accum0 = _mm_packus_epi16(accum0, accum2); - - if (has_alpha) { - // Compute the max(ri, gi, bi) for each pixel. - // [8] xx a3 b3 g3 xx a2 b2 g2 xx a1 b1 g1 xx a0 b0 g0 - __m128i a = _mm_srli_epi32(accum0, 8); - // [8] xx xx xx max3 xx xx xx max2 xx xx xx max1 xx xx xx max0 - __m128i b = _mm_max_epu8(a, accum0); // Max of r and g. - // [8] xx xx a3 b3 xx xx a2 b2 xx xx a1 b1 xx xx a0 b0 - a = _mm_srli_epi32(accum0, 16); - // [8] xx xx xx max3 xx xx xx max2 xx xx xx max1 xx xx xx max0 - b = _mm_max_epu8(a, b); // Max of r and g and b. - // [8] max3 00 00 00 max2 00 00 00 max1 00 00 00 max0 00 00 00 - b = _mm_slli_epi32(b, 24); - - // Make sure the value of alpha channel is always larger than maximum - // value of color channels. - accum0 = _mm_max_epu8(b, accum0); - } else { - // Set value of alpha channels to 0xFF. - __m128i mask = _mm_set1_epi32(0xff000000); - accum0 = _mm_or_si128(accum0, mask); - } - - // Store the convolution result (16 bytes) and advance the pixel pointers. - _mm_storeu_si128(reinterpret_cast<__m128i*>(out_row), accum0); - out_row += 16; - } - - // When the width of the output is not divisible by 4, We need to save one - // pixel (4 bytes) each time. And also the fourth pixel is always absent. - if (pixel_width & 3) { - accum0 = _mm_setzero_si128(); - accum1 = _mm_setzero_si128(); - accum2 = _mm_setzero_si128(); - for (int filter_y = 0; filter_y < filter_length; ++filter_y) { - coeff16 = _mm_set1_epi16(filter_values[filter_y]); - // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 - src = reinterpret_cast<const __m128i*>( - &source_data_rows[filter_y][width<<2]); - __m128i src8 = _mm_loadu_si128(src); - // [16] a1 b1 g1 r1 a0 b0 g0 r0 - __m128i src16 = _mm_unpacklo_epi8(src8, zero); - __m128i mul_hi = _mm_mulhi_epi16(src16, coeff16); - __m128i mul_lo = _mm_mullo_epi16(src16, coeff16); - // [32] a0 b0 g0 r0 - __m128i t = _mm_unpacklo_epi16(mul_lo, mul_hi); - accum0 = _mm_add_epi32(accum0, t); - // [32] a1 b1 g1 r1 - t = _mm_unpackhi_epi16(mul_lo, mul_hi); - accum1 = _mm_add_epi32(accum1, t); - // [16] a3 b3 g3 r3 a2 b2 g2 r2 - src16 = _mm_unpackhi_epi8(src8, zero); - mul_hi = _mm_mulhi_epi16(src16, coeff16); - mul_lo = _mm_mullo_epi16(src16, coeff16); - // [32] a2 b2 g2 r2 - t = _mm_unpacklo_epi16(mul_lo, mul_hi); - accum2 = _mm_add_epi32(accum2, t); - } - - accum0 = _mm_srai_epi32(accum0, ConvolutionFilter1D::kShiftBits); - accum1 = _mm_srai_epi32(accum1, ConvolutionFilter1D::kShiftBits); - accum2 = _mm_srai_epi32(accum2, ConvolutionFilter1D::kShiftBits); - // [16] a1 b1 g1 r1 a0 b0 g0 r0 - accum0 = _mm_packs_epi32(accum0, accum1); - // [16] a3 b3 g3 r3 a2 b2 g2 r2 - accum2 = _mm_packs_epi32(accum2, zero); - // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 - accum0 = _mm_packus_epi16(accum0, accum2); - if (has_alpha) { - // [8] xx a3 b3 g3 xx a2 b2 g2 xx a1 b1 g1 xx a0 b0 g0 - __m128i a = _mm_srli_epi32(accum0, 8); - // [8] xx xx xx max3 xx xx xx max2 xx xx xx max1 xx xx xx max0 - __m128i b = _mm_max_epu8(a, accum0); // Max of r and g. - // [8] xx xx a3 b3 xx xx a2 b2 xx xx a1 b1 xx xx a0 b0 - a = _mm_srli_epi32(accum0, 16); - // [8] xx xx xx max3 xx xx xx max2 xx xx xx max1 xx xx xx max0 - b = _mm_max_epu8(a, b); // Max of r and g and b. - // [8] max3 00 00 00 max2 00 00 00 max1 00 00 00 max0 00 00 00 - b = _mm_slli_epi32(b, 24); - accum0 = _mm_max_epu8(b, accum0); - } else { - __m128i mask = _mm_set1_epi32(0xff000000); - accum0 = _mm_or_si128(accum0, mask); - } - - for (int out_x = width; out_x < pixel_width; out_x++) { - *(reinterpret_cast<int*>(out_row)) = _mm_cvtsi128_si32(accum0); - accum0 = _mm_srli_si128(accum0, 4); - out_row += 4; - } - } -#endif } } // namespace @@ -682,6 +284,7 @@ void ConvolutionFilter1D::AddFilter(int filter_offset, // cases it is beneficial to only store the central factors. // For a scaling to 1/4th in each dimension using a Lanczos-2 filter on // a 1080p image this optimization gives a ~10% speed improvement. + int filter_size = filter_length; int first_non_zero = 0; while (first_non_zero < filter_length && filter_values[first_non_zero] == 0) first_non_zero++; @@ -709,12 +312,64 @@ void ConvolutionFilter1D::AddFilter(int filter_offset, instance.data_location = (static_cast<int>(filter_values_.size()) - filter_length); instance.offset = filter_offset; - instance.length = filter_length; + instance.trimmed_length = filter_length; + instance.length = filter_size; filters_.push_back(instance); max_filter_ = std::max(max_filter_, filter_length); } +const ConvolutionFilter1D::Fixed* ConvolutionFilter1D::GetSingleFilter( + int* specified_filter_length, + int* filter_offset, + int* filter_length) const { + const FilterInstance& filter = filters_[0]; + *filter_offset = filter.offset; + *filter_length = filter.trimmed_length; + *specified_filter_length = filter.length; + if (filter.trimmed_length == 0) + return NULL; + + return &filter_values_[filter.data_location]; +} + +typedef void (*ConvolveVertically_pointer)( + const ConvolutionFilter1D::Fixed* filter_values, + int filter_length, + unsigned char* const* source_data_rows, + int pixel_width, + unsigned char* out_row, + bool has_alpha); +typedef void (*Convolve4RowsHorizontally_pointer)( + const unsigned char* src_data[4], + const ConvolutionFilter1D& filter, + unsigned char* out_row[4]); +typedef void (*ConvolveHorizontally_pointer)( + const unsigned char* src_data, + const ConvolutionFilter1D& filter, + unsigned char* out_row); + +struct ConvolveProcs { + // This is how many extra pixels may be read by the + // conolve*horizontally functions. + int extra_horizontal_reads; + ConvolveVertically_pointer convolve_vertically; + Convolve4RowsHorizontally_pointer convolve_4rows_horizontally; + ConvolveHorizontally_pointer convolve_horizontally; +}; + +void SetupSIMD(ConvolveProcs *procs) { +#ifdef SIMD_SSE2 + base::CPU cpu; + if (cpu.has_sse2()) { + procs->extra_horizontal_reads = 3; + procs->convolve_vertically = &ConvolveVertically_SSE2; + procs->convolve_4rows_horizontally = &Convolve4RowsHorizontally_SSE2; + procs->convolve_horizontally = &ConvolveHorizontally_SSE2; + } +#endif +} + void BGRAConvolve2D(const unsigned char* source_data, int source_byte_row_stride, bool source_has_alpha, @@ -722,12 +377,15 @@ void BGRAConvolve2D(const unsigned char* source_data, const ConvolutionFilter1D& filter_y, int output_byte_row_stride, unsigned char* output, - bool use_sse2) { -#if !defined(SIMD_SSE2) - // Even we have runtime support for SSE2 instructions, since the binary - // was not built with SSE2 support, we had to fallback to C version. - use_sse2 = false; -#endif + bool use_simd_if_possible) { + ConvolveProcs simd; + simd.extra_horizontal_reads = 0; + simd.convolve_vertically = NULL; + simd.convolve_4rows_horizontally = NULL; + simd.convolve_horizontally = NULL; + if (use_simd_if_possible) { + SetupSIMD(&simd); + } int max_y_filter_size = filter_y.max_filter(); @@ -752,7 +410,8 @@ void BGRAConvolve2D(const unsigned char* source_data, // TODO(jiesun): We do not use aligned load from row buffer in vertical // convolution pass yet. Somehow Windows does not like it. int row_buffer_width = (filter_x.num_values() + 15) & ~0xF; - int row_buffer_height = max_y_filter_size + (use_sse2 ? 4 : 0); + int row_buffer_height = max_y_filter_size + + (simd.convolve_4rows_horizontally ? 4 : 0); CircularRowBuffer row_buffer(row_buffer_width, row_buffer_height, filter_offset); @@ -775,7 +434,8 @@ void BGRAConvolve2D(const unsigned char* source_data, // rows we need to avoid the SSE implementation for here. filter_x.FilterForValue(filter_x.num_values() - 1, &last_filter_offset, &last_filter_length); - int avoid_sse_rows = 1 + 3/(last_filter_offset + last_filter_length); + int avoid_simd_rows = 1 + simd.extra_horizontal_reads / + (last_filter_offset + last_filter_length); filter_y.FilterForValue(num_output_rows - 1, &last_filter_offset, &last_filter_length); @@ -785,49 +445,36 @@ void BGRAConvolve2D(const unsigned char* source_data, &filter_offset, &filter_length); // Generate output rows until we have enough to run the current filter. - if (use_sse2) { - while (next_x_row < filter_offset + filter_length) { - if (next_x_row + 3 < last_filter_offset + last_filter_length - - avoid_sse_rows) { - const unsigned char* src[4]; - unsigned char* out_row[4]; - for (int i = 0; i < 4; ++i) { - src[i] = &source_data[(next_x_row + i) * source_byte_row_stride]; - out_row[i] = row_buffer.AdvanceRow(); - } - ConvolveHorizontally4_SSE2(src, filter_x, out_row); - next_x_row += 4; + while (next_x_row < filter_offset + filter_length) { + if (simd.convolve_4rows_horizontally && + next_x_row + 3 < last_filter_offset + last_filter_length - + avoid_simd_rows) { + const unsigned char* src[4]; + unsigned char* out_row[4]; + for (int i = 0; i < 4; ++i) { + src[i] = &source_data[(next_x_row + i) * source_byte_row_stride]; + out_row[i] = row_buffer.AdvanceRow(); + } + simd.convolve_4rows_horizontally(src, filter_x, out_row); + next_x_row += 4; + } else { + // Check if we need to avoid SSE2 for this row. + if (simd.convolve_horizontally && + next_x_row < last_filter_offset + last_filter_length - + avoid_simd_rows) { + simd.convolve_horizontally( + &source_data[next_x_row * source_byte_row_stride], + filter_x, row_buffer.AdvanceRow()); } else { - // Check if we need to avoid SSE2 for this row. - if (next_x_row >= last_filter_offset + last_filter_length - - avoid_sse_rows) { - if (source_has_alpha) { - ConvolveHorizontally<true>( - &source_data[next_x_row * source_byte_row_stride], - filter_x, row_buffer.AdvanceRow()); - } else { - ConvolveHorizontally<false>( - &source_data[next_x_row * source_byte_row_stride], - filter_x, row_buffer.AdvanceRow()); - } + if (source_has_alpha) { + ConvolveHorizontally<true>( + &source_data[next_x_row * source_byte_row_stride], + filter_x, row_buffer.AdvanceRow()); } else { - ConvolveHorizontally_SSE2( + ConvolveHorizontally<false>( &source_data[next_x_row * source_byte_row_stride], filter_x, row_buffer.AdvanceRow()); } - next_x_row++; - } - } - } else { - while (next_x_row < filter_offset + filter_length) { - if (source_has_alpha) { - ConvolveHorizontally<true>( - &source_data[next_x_row * source_byte_row_stride], - filter_x, row_buffer.AdvanceRow()); - } else { - ConvolveHorizontally<false>( - &source_data[next_x_row * source_byte_row_stride], - filter_x, row_buffer.AdvanceRow()); } next_x_row++; } @@ -846,26 +493,181 @@ void BGRAConvolve2D(const unsigned char* source_data, unsigned char* const* first_row_for_filter = &rows_to_convolve[filter_offset - first_row_in_circular_buffer]; - if (source_has_alpha) { - if (use_sse2) { - ConvolveVertically_SSE2<true>(filter_values, filter_length, - first_row_for_filter, - filter_x.num_values(), cur_output_row); - } else { - ConvolveVertically<true>(filter_values, filter_length, - first_row_for_filter, - filter_x.num_values(), cur_output_row); - } + if (simd.convolve_vertically) { + simd.convolve_vertically(filter_values, filter_length, + first_row_for_filter, + filter_x.num_values(), cur_output_row, + source_has_alpha); } else { - if (use_sse2) { - ConvolveVertically_SSE2<false>(filter_values, filter_length, - first_row_for_filter, - filter_x.num_values(), cur_output_row); - } else { - ConvolveVertically<false>(filter_values, filter_length, - first_row_for_filter, - filter_x.num_values(), cur_output_row); + ConvolveVertically(filter_values, filter_length, + first_row_for_filter, + filter_x.num_values(), cur_output_row, + source_has_alpha); + } + } +} + +void SingleChannelConvolveX1D(const unsigned char* source_data, + int source_byte_row_stride, + int input_channel_index, + int input_channel_count, + const ConvolutionFilter1D& filter, + const SkISize& image_size, + unsigned char* output, + int output_byte_row_stride, + int output_channel_index, + int output_channel_count, + bool absolute_values) { + int filter_offset, filter_length, filter_size; + // Very much unlike BGRAConvolve2D, here we expect to have the same filter + // for all pixels. + const ConvolutionFilter1D::Fixed* filter_values = + filter.GetSingleFilter(&filter_size, &filter_offset, &filter_length); + + if (filter_values == NULL || image_size.width() < filter_size) { + NOTREACHED(); + return; + } + + int centrepoint = filter_length / 2; + if (filter_size - filter_offset != 2 * filter_offset) { + // This means the original filter was not symmetrical AND + // got clipped from one side more than from the other. + centrepoint = filter_size / 2 - filter_offset; + } + + const unsigned char* source_data_row = source_data; + unsigned char* output_row = output; + + for (int r = 0; r < image_size.height(); ++r) { + unsigned char* target_byte = output_row + output_channel_index; + // Process the lead part, padding image to the left with the first pixel. + int c = 0; + for (; c < centrepoint; ++c, target_byte += output_channel_count) { + int accval = 0; + int i = 0; + int pixel_byte_index = input_channel_index; + for (; i < centrepoint - c; ++i) // Padding part. + accval += filter_values[i] * source_data_row[pixel_byte_index]; + + for (; i < filter_length; ++i, pixel_byte_index += input_channel_count) + accval += filter_values[i] * source_data_row[pixel_byte_index]; + + *target_byte = BringBackTo8(accval, absolute_values); + } + + // Now for the main event. + for (; c < image_size.width() - centrepoint; + ++c, target_byte += output_channel_count) { + int accval = 0; + int pixel_byte_index = (c - centrepoint) * input_channel_count + + input_channel_index; + + for (int i = 0; i < filter_length; + ++i, pixel_byte_index += input_channel_count) { + accval += filter_values[i] * source_data_row[pixel_byte_index]; } + + *target_byte = BringBackTo8(accval, absolute_values); + } + + for (; c < image_size.width(); ++c, target_byte += output_channel_count) { + int accval = 0; + int overlap_taps = image_size.width() - c + centrepoint; + int pixel_byte_index = (c - centrepoint) * input_channel_count + + input_channel_index; + int i = 0; + for (; i < overlap_taps - 1; ++i, pixel_byte_index += input_channel_count) + accval += filter_values[i] * source_data_row[pixel_byte_index]; + + for (; i < filter_length; ++i) + accval += filter_values[i] * source_data_row[pixel_byte_index]; + + *target_byte = BringBackTo8(accval, absolute_values); + } + + source_data_row += source_byte_row_stride; + output_row += output_byte_row_stride; + } +} + +void SingleChannelConvolveY1D(const unsigned char* source_data, + int source_byte_row_stride, + int input_channel_index, + int input_channel_count, + const ConvolutionFilter1D& filter, + const SkISize& image_size, + unsigned char* output, + int output_byte_row_stride, + int output_channel_index, + int output_channel_count, + bool absolute_values) { + int filter_offset, filter_length, filter_size; + // Very much unlike BGRAConvolve2D, here we expect to have the same filter + // for all pixels. + const ConvolutionFilter1D::Fixed* filter_values = + filter.GetSingleFilter(&filter_size, &filter_offset, &filter_length); + + if (filter_values == NULL || image_size.height() < filter_size) { + NOTREACHED(); + return; + } + + int centrepoint = filter_length / 2; + if (filter_size - filter_offset != 2 * filter_offset) { + // This means the original filter was not symmetrical AND + // got clipped from one side more than from the other. + centrepoint = filter_size / 2 - filter_offset; + } + + for (int c = 0; c < image_size.width(); ++c) { + unsigned char* target_byte = output + c * output_channel_count + + output_channel_index; + int r = 0; + + for (; r < centrepoint; ++r, target_byte += output_byte_row_stride) { + int accval = 0; + int i = 0; + int pixel_byte_index = c * input_channel_count + input_channel_index; + + for (; i < centrepoint - r; ++i) // Padding part. + accval += filter_values[i] * source_data[pixel_byte_index]; + + for (; i < filter_length; ++i, pixel_byte_index += source_byte_row_stride) + accval += filter_values[i] * source_data[pixel_byte_index]; + + *target_byte = BringBackTo8(accval, absolute_values); + } + + for (; r < image_size.height() - centrepoint; + ++r, target_byte += output_byte_row_stride) { + int accval = 0; + int pixel_byte_index = (r - centrepoint) * source_byte_row_stride + + c * input_channel_count + input_channel_index; + for (int i = 0; i < filter_length; + ++i, pixel_byte_index += source_byte_row_stride) { + accval += filter_values[i] * source_data[pixel_byte_index]; + } + + *target_byte = BringBackTo8(accval, absolute_values); + } + + for (; r < image_size.height(); + ++r, target_byte += output_byte_row_stride) { + int accval = 0; + int overlap_taps = image_size.height() - r + centrepoint; + int pixel_byte_index = (r - centrepoint) * source_byte_row_stride + + c * input_channel_count + input_channel_index; + int i = 0; + for (; i < overlap_taps - 1; + ++i, pixel_byte_index += source_byte_row_stride) { + accval += filter_values[i] * source_data[pixel_byte_index]; + } + + for (; i < filter_length; ++i) + accval += filter_values[i] * source_data[pixel_byte_index]; + + *target_byte = BringBackTo8(accval, absolute_values); } } } diff --git a/skia/ext/convolver.h b/skia/ext/convolver.h index ea62a46e72..6da703c7ed 100644 --- a/skia/ext/convolver.h +++ b/skia/ext/convolver.h @@ -10,14 +10,14 @@ #include "base/basictypes.h" #include "base/cpu.h" +#include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkTypes.h" -#if defined(ARCH_CPU_X86_FAMILY) -// TODO(hclam): SSE2 is disabled on Linux 32-bits because GCC requires -msse2. -// We should refactor the code in .cc and enable this. -#if defined(ARCH_CPU_X86_64) || defined(OS_MACOSX) || defined(COMPILER_MSVC) +// We can build SSE2 optimized versions for all x86 CPUs +// except when building for the IOS emulator. +#if defined(ARCH_CPU_X86_FAMILY) && !defined(OS_IOS) #define SIMD_SSE2 1 -#endif +#define SIMD_PADDING 8 // 8 * int16 #endif // avoid confusion with Mac OS X's math library (Carbon) @@ -100,22 +100,35 @@ class ConvolutionFilter1D { int* filter_length) const { const FilterInstance& filter = filters_[value_offset]; *filter_offset = filter.offset; - *filter_length = filter.length; - if (filter.length == 0) { + *filter_length = filter.trimmed_length; + if (filter.trimmed_length == 0) { return NULL; } return &filter_values_[filter.data_location]; } - - inline void PaddingForSIMD(int padding_count) { + // Retrieves the filter for the offset 0, presumed to be the one and only. + // The offset and length of the filter values are put into the corresponding + // out arguments (see AddFilter). Note that |filter_legth| and + // |specified_filter_length| may be different if leading/trailing zeros of the + // original floating point form were clipped. + // There will be |filter_length| values in the return array. + // Returns NULL if the filter is 0-length (for instance when all floating + // point values passed to AddFilter were clipped to 0). + const Fixed* GetSingleFilter(int* specified_filter_length, + int* filter_offset, + int* filter_length) const; + + inline void PaddingForSIMD() { // Padding |padding_count| of more dummy coefficients after the coefficients // of last filter to prevent SIMD instructions which load 8 or 16 bytes // together to access invalid memory areas. We are not trying to align the // coefficients right now due to the opaqueness of <vector> implementation. // This has to be done after all |AddFilter| calls. - for (int i = 0; i < padding_count; ++i) +#ifdef SIMD_PADDING + for (int i = 0; i < SIMD_PADDING; ++i) filter_values_.push_back(static_cast<Fixed>(0)); +#endif } private: @@ -127,6 +140,11 @@ class ConvolutionFilter1D { int offset; // Number of values in this filter instance. + int trimmed_length; + + // Filter length as specified. Note that this may be different from + // 'trimmed_length' if leading/trailing zeros of the original floating + // point form were clipped differently on each tail. int length; }; @@ -167,7 +185,40 @@ SK_API void BGRAConvolve2D(const unsigned char* source_data, const ConvolutionFilter1D& yfilter, int output_byte_row_stride, unsigned char* output, - bool use_sse2); + bool use_simd_if_possible); + +// Does a 1D convolution of the given source image along the X dimension on +// a single channel of the bitmap. +// +// The function uses the same convolution kernel for each pixel. That kernel +// must be added to |filter| at offset 0. This is a most straightforward +// implementation of convolution, intended chiefly for development purposes. +SK_API void SingleChannelConvolveX1D(const unsigned char* source_data, + int source_byte_row_stride, + int input_channel_index, + int input_channel_count, + const ConvolutionFilter1D& filter, + const SkISize& image_size, + unsigned char* output, + int output_byte_row_stride, + int output_channel_index, + int output_channel_count, + bool absolute_values); + +// Does a 1D convolution of the given source image along the Y dimension on +// a single channel of the bitmap. +SK_API void SingleChannelConvolveY1D(const unsigned char* source_data, + int source_byte_row_stride, + int input_channel_index, + int input_channel_count, + const ConvolutionFilter1D& filter, + const SkISize& image_size, + unsigned char* output, + int output_byte_row_stride, + int output_channel_index, + int output_channel_count, + bool absolute_values); + } // namespace skia #endif // SKIA_EXT_CONVOLVER_H_ diff --git a/skia/ext/convolver_SSE2.cc b/skia/ext/convolver_SSE2.cc new file mode 100644 index 0000000000..a823edcb51 --- /dev/null +++ b/skia/ext/convolver_SSE2.cc @@ -0,0 +1,456 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <algorithm> + +#include "skia/ext/convolver.h" +#include "skia/ext/convolver_SSE2.h" +#include "third_party/skia/include/core/SkTypes.h" + +#include <emmintrin.h> // ARCH_CPU_X86_FAMILY was defined in build/config.h + +namespace skia { + +// Convolves horizontally along a single row. The row data is given in +// |src_data| and continues for the num_values() of the filter. +void ConvolveHorizontally_SSE2(const unsigned char* src_data, + const ConvolutionFilter1D& filter, + unsigned char* out_row) { + int num_values = filter.num_values(); + + int filter_offset, filter_length; + __m128i zero = _mm_setzero_si128(); + __m128i mask[4]; + // |mask| will be used to decimate all extra filter coefficients that are + // loaded by SIMD when |filter_length| is not divisible by 4. + // mask[0] is not used in following algorithm. + mask[1] = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, -1); + mask[2] = _mm_set_epi16(0, 0, 0, 0, 0, 0, -1, -1); + mask[3] = _mm_set_epi16(0, 0, 0, 0, 0, -1, -1, -1); + + // Output one pixel each iteration, calculating all channels (RGBA) together. + for (int out_x = 0; out_x < num_values; out_x++) { + const ConvolutionFilter1D::Fixed* filter_values = + filter.FilterForValue(out_x, &filter_offset, &filter_length); + + __m128i accum = _mm_setzero_si128(); + + // Compute the first pixel in this row that the filter affects. It will + // touch |filter_length| pixels (4 bytes each) after this. + const __m128i* row_to_filter = + reinterpret_cast<const __m128i*>(&src_data[filter_offset << 2]); + + // We will load and accumulate with four coefficients per iteration. + for (int filter_x = 0; filter_x < filter_length >> 2; filter_x++) { + + // Load 4 coefficients => duplicate 1st and 2nd of them for all channels. + __m128i coeff, coeff16; + // [16] xx xx xx xx c3 c2 c1 c0 + coeff = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(filter_values)); + // [16] xx xx xx xx c1 c1 c0 c0 + coeff16 = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(1, 1, 0, 0)); + // [16] c1 c1 c1 c1 c0 c0 c0 c0 + coeff16 = _mm_unpacklo_epi16(coeff16, coeff16); + + // Load four pixels => unpack the first two pixels to 16 bits => + // multiply with coefficients => accumulate the convolution result. + // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 + __m128i src8 = _mm_loadu_si128(row_to_filter); + // [16] a1 b1 g1 r1 a0 b0 g0 r0 + __m128i src16 = _mm_unpacklo_epi8(src8, zero); + __m128i mul_hi = _mm_mulhi_epi16(src16, coeff16); + __m128i mul_lo = _mm_mullo_epi16(src16, coeff16); + // [32] a0*c0 b0*c0 g0*c0 r0*c0 + __m128i t = _mm_unpacklo_epi16(mul_lo, mul_hi); + accum = _mm_add_epi32(accum, t); + // [32] a1*c1 b1*c1 g1*c1 r1*c1 + t = _mm_unpackhi_epi16(mul_lo, mul_hi); + accum = _mm_add_epi32(accum, t); + + // Duplicate 3rd and 4th coefficients for all channels => + // unpack the 3rd and 4th pixels to 16 bits => multiply with coefficients + // => accumulate the convolution results. + // [16] xx xx xx xx c3 c3 c2 c2 + coeff16 = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(3, 3, 2, 2)); + // [16] c3 c3 c3 c3 c2 c2 c2 c2 + coeff16 = _mm_unpacklo_epi16(coeff16, coeff16); + // [16] a3 g3 b3 r3 a2 g2 b2 r2 + src16 = _mm_unpackhi_epi8(src8, zero); + mul_hi = _mm_mulhi_epi16(src16, coeff16); + mul_lo = _mm_mullo_epi16(src16, coeff16); + // [32] a2*c2 b2*c2 g2*c2 r2*c2 + t = _mm_unpacklo_epi16(mul_lo, mul_hi); + accum = _mm_add_epi32(accum, t); + // [32] a3*c3 b3*c3 g3*c3 r3*c3 + t = _mm_unpackhi_epi16(mul_lo, mul_hi); + accum = _mm_add_epi32(accum, t); + + // Advance the pixel and coefficients pointers. + row_to_filter += 1; + filter_values += 4; + } + + // When |filter_length| is not divisible by 4, we need to decimate some of + // the filter coefficient that was loaded incorrectly to zero; Other than + // that the algorithm is same with above, exceot that the 4th pixel will be + // always absent. + int r = filter_length&3; + if (r) { + // Note: filter_values must be padded to align_up(filter_offset, 8). + __m128i coeff, coeff16; + coeff = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(filter_values)); + // Mask out extra filter taps. + coeff = _mm_and_si128(coeff, mask[r]); + coeff16 = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(1, 1, 0, 0)); + coeff16 = _mm_unpacklo_epi16(coeff16, coeff16); + + // Note: line buffer must be padded to align_up(filter_offset, 16). + // We resolve this by use C-version for the last horizontal line. + __m128i src8 = _mm_loadu_si128(row_to_filter); + __m128i src16 = _mm_unpacklo_epi8(src8, zero); + __m128i mul_hi = _mm_mulhi_epi16(src16, coeff16); + __m128i mul_lo = _mm_mullo_epi16(src16, coeff16); + __m128i t = _mm_unpacklo_epi16(mul_lo, mul_hi); + accum = _mm_add_epi32(accum, t); + t = _mm_unpackhi_epi16(mul_lo, mul_hi); + accum = _mm_add_epi32(accum, t); + + src16 = _mm_unpackhi_epi8(src8, zero); + coeff16 = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(3, 3, 2, 2)); + coeff16 = _mm_unpacklo_epi16(coeff16, coeff16); + mul_hi = _mm_mulhi_epi16(src16, coeff16); + mul_lo = _mm_mullo_epi16(src16, coeff16); + t = _mm_unpacklo_epi16(mul_lo, mul_hi); + accum = _mm_add_epi32(accum, t); + } + + // Shift right for fixed point implementation. + accum = _mm_srai_epi32(accum, ConvolutionFilter1D::kShiftBits); + + // Packing 32 bits |accum| to 16 bits per channel (signed saturation). + accum = _mm_packs_epi32(accum, zero); + // Packing 16 bits |accum| to 8 bits per channel (unsigned saturation). + accum = _mm_packus_epi16(accum, zero); + + // Store the pixel value of 32 bits. + *(reinterpret_cast<int*>(out_row)) = _mm_cvtsi128_si32(accum); + out_row += 4; + } +} + +// Convolves horizontally along four rows. The row data is given in +// |src_data| and continues for the num_values() of the filter. +// The algorithm is almost same as |ConvolveHorizontally_SSE2|. Please +// refer to that function for detailed comments. +void Convolve4RowsHorizontally_SSE2(const unsigned char* src_data[4], + const ConvolutionFilter1D& filter, + unsigned char* out_row[4]) { + int num_values = filter.num_values(); + + int filter_offset, filter_length; + __m128i zero = _mm_setzero_si128(); + __m128i mask[4]; + // |mask| will be used to decimate all extra filter coefficients that are + // loaded by SIMD when |filter_length| is not divisible by 4. + // mask[0] is not used in following algorithm. + mask[1] = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, -1); + mask[2] = _mm_set_epi16(0, 0, 0, 0, 0, 0, -1, -1); + mask[3] = _mm_set_epi16(0, 0, 0, 0, 0, -1, -1, -1); + + // Output one pixel each iteration, calculating all channels (RGBA) together. + for (int out_x = 0; out_x < num_values; out_x++) { + const ConvolutionFilter1D::Fixed* filter_values = + filter.FilterForValue(out_x, &filter_offset, &filter_length); + + // four pixels in a column per iteration. + __m128i accum0 = _mm_setzero_si128(); + __m128i accum1 = _mm_setzero_si128(); + __m128i accum2 = _mm_setzero_si128(); + __m128i accum3 = _mm_setzero_si128(); + int start = (filter_offset<<2); + // We will load and accumulate with four coefficients per iteration. + for (int filter_x = 0; filter_x < (filter_length >> 2); filter_x++) { + __m128i coeff, coeff16lo, coeff16hi; + // [16] xx xx xx xx c3 c2 c1 c0 + coeff = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(filter_values)); + // [16] xx xx xx xx c1 c1 c0 c0 + coeff16lo = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(1, 1, 0, 0)); + // [16] c1 c1 c1 c1 c0 c0 c0 c0 + coeff16lo = _mm_unpacklo_epi16(coeff16lo, coeff16lo); + // [16] xx xx xx xx c3 c3 c2 c2 + coeff16hi = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(3, 3, 2, 2)); + // [16] c3 c3 c3 c3 c2 c2 c2 c2 + coeff16hi = _mm_unpacklo_epi16(coeff16hi, coeff16hi); + + __m128i src8, src16, mul_hi, mul_lo, t; + +#define ITERATION(src, accum) \ + src8 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src)); \ + src16 = _mm_unpacklo_epi8(src8, zero); \ + mul_hi = _mm_mulhi_epi16(src16, coeff16lo); \ + mul_lo = _mm_mullo_epi16(src16, coeff16lo); \ + t = _mm_unpacklo_epi16(mul_lo, mul_hi); \ + accum = _mm_add_epi32(accum, t); \ + t = _mm_unpackhi_epi16(mul_lo, mul_hi); \ + accum = _mm_add_epi32(accum, t); \ + src16 = _mm_unpackhi_epi8(src8, zero); \ + mul_hi = _mm_mulhi_epi16(src16, coeff16hi); \ + mul_lo = _mm_mullo_epi16(src16, coeff16hi); \ + t = _mm_unpacklo_epi16(mul_lo, mul_hi); \ + accum = _mm_add_epi32(accum, t); \ + t = _mm_unpackhi_epi16(mul_lo, mul_hi); \ + accum = _mm_add_epi32(accum, t) + + ITERATION(src_data[0] + start, accum0); + ITERATION(src_data[1] + start, accum1); + ITERATION(src_data[2] + start, accum2); + ITERATION(src_data[3] + start, accum3); + + start += 16; + filter_values += 4; + } + + int r = filter_length & 3; + if (r) { + // Note: filter_values must be padded to align_up(filter_offset, 8); + __m128i coeff; + coeff = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(filter_values)); + // Mask out extra filter taps. + coeff = _mm_and_si128(coeff, mask[r]); + + __m128i coeff16lo = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(1, 1, 0, 0)); + /* c1 c1 c1 c1 c0 c0 c0 c0 */ + coeff16lo = _mm_unpacklo_epi16(coeff16lo, coeff16lo); + __m128i coeff16hi = _mm_shufflelo_epi16(coeff, _MM_SHUFFLE(3, 3, 2, 2)); + coeff16hi = _mm_unpacklo_epi16(coeff16hi, coeff16hi); + + __m128i src8, src16, mul_hi, mul_lo, t; + + ITERATION(src_data[0] + start, accum0); + ITERATION(src_data[1] + start, accum1); + ITERATION(src_data[2] + start, accum2); + ITERATION(src_data[3] + start, accum3); + } + + accum0 = _mm_srai_epi32(accum0, ConvolutionFilter1D::kShiftBits); + accum0 = _mm_packs_epi32(accum0, zero); + accum0 = _mm_packus_epi16(accum0, zero); + accum1 = _mm_srai_epi32(accum1, ConvolutionFilter1D::kShiftBits); + accum1 = _mm_packs_epi32(accum1, zero); + accum1 = _mm_packus_epi16(accum1, zero); + accum2 = _mm_srai_epi32(accum2, ConvolutionFilter1D::kShiftBits); + accum2 = _mm_packs_epi32(accum2, zero); + accum2 = _mm_packus_epi16(accum2, zero); + accum3 = _mm_srai_epi32(accum3, ConvolutionFilter1D::kShiftBits); + accum3 = _mm_packs_epi32(accum3, zero); + accum3 = _mm_packus_epi16(accum3, zero); + + *(reinterpret_cast<int*>(out_row[0])) = _mm_cvtsi128_si32(accum0); + *(reinterpret_cast<int*>(out_row[1])) = _mm_cvtsi128_si32(accum1); + *(reinterpret_cast<int*>(out_row[2])) = _mm_cvtsi128_si32(accum2); + *(reinterpret_cast<int*>(out_row[3])) = _mm_cvtsi128_si32(accum3); + + out_row[0] += 4; + out_row[1] += 4; + out_row[2] += 4; + out_row[3] += 4; + } +} + +// Does vertical convolution to produce one output row. The filter values and +// length are given in the first two parameters. These are applied to each +// of the rows pointed to in the |source_data_rows| array, with each row +// being |pixel_width| wide. +// +// The output must have room for |pixel_width * 4| bytes. +template<bool has_alpha> +void ConvolveVertically_SSE2(const ConvolutionFilter1D::Fixed* filter_values, + int filter_length, + unsigned char* const* source_data_rows, + int pixel_width, + unsigned char* out_row) { + int width = pixel_width & ~3; + + __m128i zero = _mm_setzero_si128(); + __m128i accum0, accum1, accum2, accum3, coeff16; + const __m128i* src; + // Output four pixels per iteration (16 bytes). + for (int out_x = 0; out_x < width; out_x += 4) { + + // Accumulated result for each pixel. 32 bits per RGBA channel. + accum0 = _mm_setzero_si128(); + accum1 = _mm_setzero_si128(); + accum2 = _mm_setzero_si128(); + accum3 = _mm_setzero_si128(); + + // Convolve with one filter coefficient per iteration. + for (int filter_y = 0; filter_y < filter_length; filter_y++) { + + // Duplicate the filter coefficient 8 times. + // [16] cj cj cj cj cj cj cj cj + coeff16 = _mm_set1_epi16(filter_values[filter_y]); + + // Load four pixels (16 bytes) together. + // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 + src = reinterpret_cast<const __m128i*>( + &source_data_rows[filter_y][out_x << 2]); + __m128i src8 = _mm_loadu_si128(src); + + // Unpack 1st and 2nd pixels from 8 bits to 16 bits for each channels => + // multiply with current coefficient => accumulate the result. + // [16] a1 b1 g1 r1 a0 b0 g0 r0 + __m128i src16 = _mm_unpacklo_epi8(src8, zero); + __m128i mul_hi = _mm_mulhi_epi16(src16, coeff16); + __m128i mul_lo = _mm_mullo_epi16(src16, coeff16); + // [32] a0 b0 g0 r0 + __m128i t = _mm_unpacklo_epi16(mul_lo, mul_hi); + accum0 = _mm_add_epi32(accum0, t); + // [32] a1 b1 g1 r1 + t = _mm_unpackhi_epi16(mul_lo, mul_hi); + accum1 = _mm_add_epi32(accum1, t); + + // Unpack 3rd and 4th pixels from 8 bits to 16 bits for each channels => + // multiply with current coefficient => accumulate the result. + // [16] a3 b3 g3 r3 a2 b2 g2 r2 + src16 = _mm_unpackhi_epi8(src8, zero); + mul_hi = _mm_mulhi_epi16(src16, coeff16); + mul_lo = _mm_mullo_epi16(src16, coeff16); + // [32] a2 b2 g2 r2 + t = _mm_unpacklo_epi16(mul_lo, mul_hi); + accum2 = _mm_add_epi32(accum2, t); + // [32] a3 b3 g3 r3 + t = _mm_unpackhi_epi16(mul_lo, mul_hi); + accum3 = _mm_add_epi32(accum3, t); + } + + // Shift right for fixed point implementation. + accum0 = _mm_srai_epi32(accum0, ConvolutionFilter1D::kShiftBits); + accum1 = _mm_srai_epi32(accum1, ConvolutionFilter1D::kShiftBits); + accum2 = _mm_srai_epi32(accum2, ConvolutionFilter1D::kShiftBits); + accum3 = _mm_srai_epi32(accum3, ConvolutionFilter1D::kShiftBits); + + // Packing 32 bits |accum| to 16 bits per channel (signed saturation). + // [16] a1 b1 g1 r1 a0 b0 g0 r0 + accum0 = _mm_packs_epi32(accum0, accum1); + // [16] a3 b3 g3 r3 a2 b2 g2 r2 + accum2 = _mm_packs_epi32(accum2, accum3); + + // Packing 16 bits |accum| to 8 bits per channel (unsigned saturation). + // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 + accum0 = _mm_packus_epi16(accum0, accum2); + + if (has_alpha) { + // Compute the max(ri, gi, bi) for each pixel. + // [8] xx a3 b3 g3 xx a2 b2 g2 xx a1 b1 g1 xx a0 b0 g0 + __m128i a = _mm_srli_epi32(accum0, 8); + // [8] xx xx xx max3 xx xx xx max2 xx xx xx max1 xx xx xx max0 + __m128i b = _mm_max_epu8(a, accum0); // Max of r and g. + // [8] xx xx a3 b3 xx xx a2 b2 xx xx a1 b1 xx xx a0 b0 + a = _mm_srli_epi32(accum0, 16); + // [8] xx xx xx max3 xx xx xx max2 xx xx xx max1 xx xx xx max0 + b = _mm_max_epu8(a, b); // Max of r and g and b. + // [8] max3 00 00 00 max2 00 00 00 max1 00 00 00 max0 00 00 00 + b = _mm_slli_epi32(b, 24); + + // Make sure the value of alpha channel is always larger than maximum + // value of color channels. + accum0 = _mm_max_epu8(b, accum0); + } else { + // Set value of alpha channels to 0xFF. + __m128i mask = _mm_set1_epi32(0xff000000); + accum0 = _mm_or_si128(accum0, mask); + } + + // Store the convolution result (16 bytes) and advance the pixel pointers. + _mm_storeu_si128(reinterpret_cast<__m128i*>(out_row), accum0); + out_row += 16; + } + + // When the width of the output is not divisible by 4, We need to save one + // pixel (4 bytes) each time. And also the fourth pixel is always absent. + if (pixel_width & 3) { + accum0 = _mm_setzero_si128(); + accum1 = _mm_setzero_si128(); + accum2 = _mm_setzero_si128(); + for (int filter_y = 0; filter_y < filter_length; ++filter_y) { + coeff16 = _mm_set1_epi16(filter_values[filter_y]); + // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 + src = reinterpret_cast<const __m128i*>( + &source_data_rows[filter_y][width<<2]); + __m128i src8 = _mm_loadu_si128(src); + // [16] a1 b1 g1 r1 a0 b0 g0 r0 + __m128i src16 = _mm_unpacklo_epi8(src8, zero); + __m128i mul_hi = _mm_mulhi_epi16(src16, coeff16); + __m128i mul_lo = _mm_mullo_epi16(src16, coeff16); + // [32] a0 b0 g0 r0 + __m128i t = _mm_unpacklo_epi16(mul_lo, mul_hi); + accum0 = _mm_add_epi32(accum0, t); + // [32] a1 b1 g1 r1 + t = _mm_unpackhi_epi16(mul_lo, mul_hi); + accum1 = _mm_add_epi32(accum1, t); + // [16] a3 b3 g3 r3 a2 b2 g2 r2 + src16 = _mm_unpackhi_epi8(src8, zero); + mul_hi = _mm_mulhi_epi16(src16, coeff16); + mul_lo = _mm_mullo_epi16(src16, coeff16); + // [32] a2 b2 g2 r2 + t = _mm_unpacklo_epi16(mul_lo, mul_hi); + accum2 = _mm_add_epi32(accum2, t); + } + + accum0 = _mm_srai_epi32(accum0, ConvolutionFilter1D::kShiftBits); + accum1 = _mm_srai_epi32(accum1, ConvolutionFilter1D::kShiftBits); + accum2 = _mm_srai_epi32(accum2, ConvolutionFilter1D::kShiftBits); + // [16] a1 b1 g1 r1 a0 b0 g0 r0 + accum0 = _mm_packs_epi32(accum0, accum1); + // [16] a3 b3 g3 r3 a2 b2 g2 r2 + accum2 = _mm_packs_epi32(accum2, zero); + // [8] a3 b3 g3 r3 a2 b2 g2 r2 a1 b1 g1 r1 a0 b0 g0 r0 + accum0 = _mm_packus_epi16(accum0, accum2); + if (has_alpha) { + // [8] xx a3 b3 g3 xx a2 b2 g2 xx a1 b1 g1 xx a0 b0 g0 + __m128i a = _mm_srli_epi32(accum0, 8); + // [8] xx xx xx max3 xx xx xx max2 xx xx xx max1 xx xx xx max0 + __m128i b = _mm_max_epu8(a, accum0); // Max of r and g. + // [8] xx xx a3 b3 xx xx a2 b2 xx xx a1 b1 xx xx a0 b0 + a = _mm_srli_epi32(accum0, 16); + // [8] xx xx xx max3 xx xx xx max2 xx xx xx max1 xx xx xx max0 + b = _mm_max_epu8(a, b); // Max of r and g and b. + // [8] max3 00 00 00 max2 00 00 00 max1 00 00 00 max0 00 00 00 + b = _mm_slli_epi32(b, 24); + accum0 = _mm_max_epu8(b, accum0); + } else { + __m128i mask = _mm_set1_epi32(0xff000000); + accum0 = _mm_or_si128(accum0, mask); + } + + for (int out_x = width; out_x < pixel_width; out_x++) { + *(reinterpret_cast<int*>(out_row)) = _mm_cvtsi128_si32(accum0); + accum0 = _mm_srli_si128(accum0, 4); + out_row += 4; + } + } +} + +void ConvolveVertically_SSE2(const ConvolutionFilter1D::Fixed* filter_values, + int filter_length, + unsigned char* const* source_data_rows, + int pixel_width, + unsigned char* out_row, + bool has_alpha) { + if (has_alpha) { + ConvolveVertically_SSE2<true>(filter_values, + filter_length, + source_data_rows, + pixel_width, + out_row); + } else { + ConvolveVertically_SSE2<false>(filter_values, + filter_length, + source_data_rows, + pixel_width, + out_row); + } +} + +} // namespace skia diff --git a/skia/ext/convolver_SSE2.h b/skia/ext/convolver_SSE2.h new file mode 100644 index 0000000000..6b79daee8c --- /dev/null +++ b/skia/ext/convolver_SSE2.h @@ -0,0 +1,26 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SKIA_EXT_CONVOLVER_SSE2_H_ +#define SKIA_EXT_CONVOLVER_SSE2_H_ + +#include "skia/ext/convolver.h" + +namespace skia { + +void ConvolveVertically_SSE2(const ConvolutionFilter1D::Fixed* filter_values, + int filter_length, + unsigned char* const* source_data_rows, + int pixel_width, + unsigned char* out_row, + bool has_alpha); +void Convolve4RowsHorizontally_SSE2(const unsigned char* src_data[4], + const ConvolutionFilter1D& filter, + unsigned char* out_row[4]); +void ConvolveHorizontally_SSE2(const unsigned char* src_data, + const ConvolutionFilter1D& filter, + unsigned char* out_row); +} // namespace skia + +#endif // SKIA_EXT_CONVOLVER_SSE2_H_ diff --git a/skia/ext/convolver_unittest.cc b/skia/ext/convolver_unittest.cc index 6bf09ee6d4..2ab61e3a47 100644 --- a/skia/ext/convolver_unittest.cc +++ b/skia/ext/convolver_unittest.cc @@ -211,10 +211,6 @@ TEST(Convolver, AddFilter) { } TEST(Convolver, SIMDVerification) { -#if defined(SIMD_SSE2) - base::CPU cpu; - if (!cpu.has_sse2()) return; - int source_sizes[][2] = { {1,1}, {1,2}, {1,3}, {1,4}, {1,5}, {2,1}, {2,2}, {2,3}, {2,4}, {2,5}, @@ -246,14 +242,14 @@ TEST(Convolver, SIMDVerification) { std::min<int>(arraysize(filter), source_width - offset)); } - x_filter.PaddingForSIMD(8); + x_filter.PaddingForSIMD(); for (unsigned int p = 0; p < dest_height; ++p) { unsigned int offset = source_height * p / dest_height; y_filter.AddFilter(offset, filter, std::min<int>(arraysize(filter), source_height - offset)); } - y_filter.PaddingForSIMD(8); + y_filter.PaddingForSIMD(); // Allocate input and output skia bitmap. SkBitmap source, result_c, result_sse; @@ -326,7 +322,155 @@ TEST(Convolver, SIMDVerification) { } } } -#endif +} + +TEST(Convolver, SeparableSingleConvolution) { + static const int kImgWidth = 1024; + static const int kImgHeight = 1024; + static const int kChannelCount = 3; + static const int kStrideSlack = 22; + ConvolutionFilter1D filter; + const float box[5] = { 0.2f, 0.2f, 0.2f, 0.2f, 0.2f }; + filter.AddFilter(0, box, 5); + + // Allocate a source image and set to 0. + const int src_row_stride = kImgWidth * kChannelCount + kStrideSlack; + int src_byte_count = src_row_stride * kImgHeight; + std::vector<unsigned char> input; + const int signal_x = kImgWidth / 2; + const int signal_y = kImgHeight / 2; + input.resize(src_byte_count, 0); + // The image has a single impulse pixel in channel 1, smack in the middle. + const int non_zero_pixel_index = + signal_y * src_row_stride + signal_x * kChannelCount + 1; + input[non_zero_pixel_index] = 255; + + // Destination will be a single channel image with stide matching width. + const int dest_row_stride = kImgWidth; + const int dest_byte_count = dest_row_stride * kImgHeight; + std::vector<unsigned char> output; + output.resize(dest_byte_count); + + // Apply convolution in X. + SingleChannelConvolveX1D(&input[0], src_row_stride, 1, kChannelCount, + filter, SkISize::Make(kImgWidth, kImgHeight), + &output[0], dest_row_stride, 0, 1, false); + for (int x = signal_x - 2; x <= signal_x + 2; ++x) + EXPECT_GT(output[signal_y * dest_row_stride + x], 0); + + EXPECT_EQ(output[signal_y * dest_row_stride + signal_x - 3], 0); + EXPECT_EQ(output[signal_y * dest_row_stride + signal_x + 3], 0); + + // Apply convolution in Y. + SingleChannelConvolveY1D(&input[0], src_row_stride, 1, kChannelCount, + filter, SkISize::Make(kImgWidth, kImgHeight), + &output[0], dest_row_stride, 0, 1, false); + for (int y = signal_y - 2; y <= signal_y + 2; ++y) + EXPECT_GT(output[y * dest_row_stride + signal_x], 0); + + EXPECT_EQ(output[(signal_y - 3) * dest_row_stride + signal_x], 0); + EXPECT_EQ(output[(signal_y + 3) * dest_row_stride + signal_x], 0); + + EXPECT_EQ(output[signal_y * dest_row_stride + signal_x - 1], 0); + EXPECT_EQ(output[signal_y * dest_row_stride + signal_x + 1], 0); + + // The main point of calling this is to invoke the routine on input without + // padding. + std::vector<unsigned char> output2; + output2.resize(dest_byte_count); + SingleChannelConvolveX1D(&output[0], dest_row_stride, 0, 1, + filter, SkISize::Make(kImgWidth, kImgHeight), + &output2[0], dest_row_stride, 0, 1, false); + // This should be a result of 2D convolution. + for (int x = signal_x - 2; x <= signal_x + 2; ++x) { + for (int y = signal_y - 2; y <= signal_y + 2; ++y) + EXPECT_GT(output2[y * dest_row_stride + x], 0); + } + EXPECT_EQ(output2[0], 0); + EXPECT_EQ(output2[dest_row_stride - 1], 0); + EXPECT_EQ(output2[dest_byte_count - 1], 0); +} + +TEST(Convolver, SeparableSingleConvolutionEdges) { + // The purpose of this test is to check if the implementation treats correctly + // edges of the image. + static const int kImgWidth = 600; + static const int kImgHeight = 800; + static const int kChannelCount = 3; + static const int kStrideSlack = 22; + static const int kChannel = 1; + ConvolutionFilter1D filter; + const float box[5] = { 0.2f, 0.2f, 0.2f, 0.2f, 0.2f }; + filter.AddFilter(0, box, 5); + + // Allocate a source image and set to 0. + int src_row_stride = kImgWidth * kChannelCount + kStrideSlack; + int src_byte_count = src_row_stride * kImgHeight; + std::vector<unsigned char> input(src_byte_count); + + // Draw a frame around the image. + for (int i = 0; i < src_byte_count; ++i) { + int row = i / src_row_stride; + int col = i % src_row_stride / kChannelCount; + int channel = i % src_row_stride % kChannelCount; + if (channel != kChannel || col > kImgWidth) { + input[i] = 255; + } else if (row == 0 || col == 0 || + col == kImgWidth - 1 || row == kImgHeight - 1) { + input[i] = 100; + } else if (row == 1 || col == 1 || + col == kImgWidth - 2 || row == kImgHeight - 2) { + input[i] = 200; + } else { + input[i] = 0; + } + } + + // Destination will be a single channel image with stide matching width. + int dest_row_stride = kImgWidth; + int dest_byte_count = dest_row_stride * kImgHeight; + std::vector<unsigned char> output; + output.resize(dest_byte_count); + + // Apply convolution in X. + SingleChannelConvolveX1D(&input[0], src_row_stride, 1, kChannelCount, + filter, SkISize::Make(kImgWidth, kImgHeight), + &output[0], dest_row_stride, 0, 1, false); + + // Sadly, comparison is not as simple as retaining all values. + int invalid_values = 0; + const unsigned char first_value = output[0]; + EXPECT_NEAR(first_value, 100, 1); + for (int i = 0; i < dest_row_stride; ++i) { + if (output[i] != first_value) + ++invalid_values; + } + EXPECT_EQ(0, invalid_values); + + int test_row = 22; + EXPECT_NEAR(output[test_row * dest_row_stride], 100, 1); + EXPECT_NEAR(output[test_row * dest_row_stride + 1], 80, 1); + EXPECT_NEAR(output[test_row * dest_row_stride + 2], 60, 1); + EXPECT_NEAR(output[test_row * dest_row_stride + 3], 40, 1); + EXPECT_NEAR(output[(test_row + 1) * dest_row_stride - 1], 100, 1); + EXPECT_NEAR(output[(test_row + 1) * dest_row_stride - 2], 80, 1); + EXPECT_NEAR(output[(test_row + 1) * dest_row_stride - 3], 60, 1); + EXPECT_NEAR(output[(test_row + 1) * dest_row_stride - 4], 40, 1); + + SingleChannelConvolveY1D(&input[0], src_row_stride, 1, kChannelCount, + filter, SkISize::Make(kImgWidth, kImgHeight), + &output[0], dest_row_stride, 0, 1, false); + + int test_column = 42; + EXPECT_NEAR(output[test_column], 100, 1); + EXPECT_NEAR(output[test_column + dest_row_stride], 80, 1); + EXPECT_NEAR(output[test_column + dest_row_stride * 2], 60, 1); + EXPECT_NEAR(output[test_column + dest_row_stride * 3], 40, 1); + + EXPECT_NEAR(output[test_column + dest_row_stride * (kImgHeight - 1)], 100, 1); + EXPECT_NEAR(output[test_column + dest_row_stride * (kImgHeight - 2)], 80, 1); + EXPECT_NEAR(output[test_column + dest_row_stride * (kImgHeight - 3)], 60, 1); + EXPECT_NEAR(output[test_column + dest_row_stride * (kImgHeight - 4)], 40, 1); } } // namespace skia diff --git a/skia/ext/image_operations.cc b/skia/ext/image_operations.cc index 70ba7d693a..b1cdade0ad 100644 --- a/skia/ext/image_operations.cc +++ b/skia/ext/image_operations.cc @@ -140,7 +140,7 @@ class ResizeFilter { // for the transform is also specified. void ComputeFilters(int src_size, int dest_subset_lo, int dest_subset_size, - float scale, float src_support, + float scale, ConvolutionFilter1D* output); // Computes the filter value given the coordinate in filter space. @@ -191,17 +191,10 @@ ResizeFilter::ResizeFilter(ImageOperations::ResizeMethod method, float scale_y = static_cast<float>(dest_height) / static_cast<float>(src_full_height); - x_filter_support_ = GetFilterSupport(scale_x); - y_filter_support_ = GetFilterSupport(scale_y); - - // Support of the filter in source space. - float src_x_support = x_filter_support_ / scale_x; - float src_y_support = y_filter_support_ / scale_y; - ComputeFilters(src_full_width, dest_subset.fLeft, dest_subset.width(), - scale_x, src_x_support, &x_filter_); + scale_x, &x_filter_); ComputeFilters(src_full_height, dest_subset.fTop, dest_subset.height(), - scale_y, src_y_support, &y_filter_); + scale_y, &y_filter_); } // TODO(egouriou): Take advantage of periods in the convolution. @@ -217,7 +210,7 @@ ResizeFilter::ResizeFilter(ImageOperations::ResizeMethod method, // loading the factors only once outside the borders. void ResizeFilter::ComputeFilters(int src_size, int dest_subset_lo, int dest_subset_size, - float scale, float src_support, + float scale, ConvolutionFilter1D* output) { int dest_subset_hi = dest_subset_lo + dest_subset_size; // [lo, hi) @@ -228,6 +221,10 @@ void ResizeFilter::ComputeFilters(int src_size, // some computations. float clamped_scale = std::min(1.0f, scale); + // This is how many source pixels from the center we need to count + // to support the filtering function. + float src_support = GetFilterSupport(clamped_scale) / clamped_scale; + // Speed up the divisions below by turning them into multiplies. float inv_scale = 1.0f / scale; @@ -303,7 +300,7 @@ void ResizeFilter::ComputeFilters(int src_size, static_cast<int>(fixed_filter_values->size())); } - output->PaddingForSIMD(8); + output->PaddingForSIMD(); } ImageOperations::ResizeMethod ResizeMethodToAlgorithmMethod( @@ -512,7 +509,6 @@ SkBitmap ImageOperations::ResizeBasic(const SkBitmap& source, reinterpret_cast<const uint8*>(source.getPixels()); // Convolve into the result. - base::CPU cpu; SkBitmap result; result.setConfig(SkBitmap::kARGB_8888_Config, dest_subset.width(), dest_subset.height()); @@ -524,7 +520,7 @@ SkBitmap ImageOperations::ResizeBasic(const SkBitmap& source, !source.isOpaque(), filter.x_filter(), filter.y_filter(), static_cast<int>(result.rowBytes()), static_cast<unsigned char*>(result.getPixels()), - cpu.has_sse2()); + true); // Preserve the "opaque" flag for use as an optimization later. result.setIsOpaque(source.isOpaque()); diff --git a/skia/ext/image_operations_unittest.cc b/skia/ext/image_operations_unittest.cc index a0897ad9af..fead994736 100644 --- a/skia/ext/image_operations_unittest.cc +++ b/skia/ext/image_operations_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include <algorithm> +#include <cmath> #include <iomanip> #include <vector> @@ -632,3 +633,88 @@ TEST(ImageOperations, CompareLanczosMethods) { #endif // #if DEBUG_BITMAP_GENERATION } } + +#ifndef M_PI +// No M_PI in math.h on windows? No problem. +#define M_PI 3.14159265358979323846 +#endif + +static double sinc(double x) { + if (x == 0.0) return 1.0; + x *= M_PI; + return sin(x) / x; +} + +static double lanczos3(double offset) { + if (fabs(offset) >= 3) return 0.0; + return sinc(offset) * sinc(offset / 3.0); +} + +TEST(ImageOperations, ScaleUp) { + const int src_w = 3; + const int src_h = 3; + const int dst_w = 9; + const int dst_h = 9; + SkBitmap src; + src.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); + src.allocPixels(); + + for (int src_y = 0; src_y < src_h; ++src_y) { + for (int src_x = 0; src_x < src_w; ++src_x) { + *src.getAddr32(src_x, src_y) = SkColorSetARGBInline(255, + 10 + src_x * 100, + 10 + src_y * 100, + 0); + } + } + + SkBitmap dst = skia::ImageOperations::Resize( + src, + skia::ImageOperations::RESIZE_LANCZOS3, + dst_w, dst_h); + SkAutoLockPixels dst_lock(dst); + for (int dst_y = 0; dst_y < dst_h; ++dst_y) { + for (int dst_x = 0; dst_x < dst_w; ++dst_x) { + float dst_x_in_src = (dst_x + 0.5) * src_w / dst_w; + float dst_y_in_src = (dst_y + 0.5) * src_h / dst_h; + float a = 0.0f; + float r = 0.0f; + float g = 0.0f; + float b = 0.0f; + float sum = 0.0f; + for (int src_y = 0; src_y < src_h; ++src_y) { + for (int src_x = 0; src_x < src_w; ++src_x) { + double coeff = + lanczos3(src_x + 0.5 - dst_x_in_src) * + lanczos3(src_y + 0.5 - dst_y_in_src); + sum += coeff; + SkColor tmp = *src.getAddr32(src_x, src_y); + a += coeff * SkColorGetA(tmp); + r += coeff * SkColorGetR(tmp); + g += coeff * SkColorGetG(tmp); + b += coeff * SkColorGetB(tmp); + } + } + a /= sum; + r /= sum; + g /= sum; + b /= sum; + if (a < 0.0f) a = 0.0f; + if (r < 0.0f) r = 0.0f; + if (g < 0.0f) g = 0.0f; + if (b < 0.0f) b = 0.0f; + if (a > 255.0f) a = 255.0f; + if (r > 255.0f) r = 255.0f; + if (g > 255.0f) g = 255.0f; + if (b > 255.0f) b = 255.0f; + SkColor dst_color = *dst.getAddr32(dst_x, dst_y); + EXPECT_LE(fabs(SkColorGetA(dst_color) - a), 1.5f); + EXPECT_LE(fabs(SkColorGetR(dst_color) - r), 1.5f); + EXPECT_LE(fabs(SkColorGetG(dst_color) - g), 1.5f); + EXPECT_LE(fabs(SkColorGetB(dst_color) - b), 1.5f); + if (HasFailure()) { + return; + } + } + } +} diff --git a/skia/ext/platform_device.h b/skia/ext/platform_device.h index 69efb3f723..4ac3aee565 100644 --- a/skia/ext/platform_device.h +++ b/skia/ext/platform_device.h @@ -22,7 +22,7 @@ class SkPath; class SkRegion; #if defined(OS_LINUX) || defined(OS_OPENBSD) || defined(OS_FREEBSD) \ - || defined(OS_SUN) + || defined(OS_SOLARIS) typedef struct _cairo cairo_t; typedef struct _cairo_rectangle cairo_rectangle_t; #elif defined(OS_MACOSX) @@ -41,7 +41,7 @@ typedef RECT PlatformRect; typedef void* PlatformSurface; typedef SkIRect* PlatformRect; #elif defined(OS_LINUX) || defined(OS_OPENBSD) || defined(OS_FREEBSD) \ - || defined(OS_SUN) + || defined(OS_SOLARIS) typedef cairo_t* PlatformSurface; typedef cairo_rectangle_t PlatformRect; #elif defined(OS_MACOSX) diff --git a/skia/ext/vector_canvas_unittest.cc b/skia/ext/vector_canvas_unittest.cc index 8d3fc46445..59f70e6225 100644 --- a/skia/ext/vector_canvas_unittest.cc +++ b/skia/ext/vector_canvas_unittest.cc @@ -334,10 +334,9 @@ void Premultiply(SkBitmap bitmap) { void LoadPngFileToSkBitmap(const base::FilePath& filename, SkBitmap* bitmap, bool is_opaque) { - base::FilePath absolute_path(filename); - file_util::AbsolutePath(&absolute_path); std::string compressed; - file_util::ReadFileToString(absolute_path, &compressed); + file_util::ReadFileToString(base::MakeAbsoluteFilePath(filename), + &compressed); ASSERT_TRUE(compressed.size()); ASSERT_TRUE(gfx::PNGCodec::Decode( diff --git a/skia/skia.gyp b/skia/skia.gyp index 3db86fcc9d..63ab0699bc 100644 --- a/skia/skia.gyp +++ b/skia/skia.gyp @@ -38,11 +38,12 @@ # this should likely be moved into src/utils in skia '../third_party/skia/src/core/SkFlate.cpp', - '../third_party/skia/src/images/bmpdecoderhelper.cpp', - '../third_party/skia/src/images/bmpdecoderhelper.h', + #'../third_party/skia/src/images/bmpdecoderhelper.cpp', + #'../third_party/skia/src/images/bmpdecoderhelper.h', #'../third_party/skia/src/images/SkFDStream.cpp', - '../third_party/skia/src/images/SkImageDecoder.cpp', - '../third_party/skia/src/images/SkImageDecoder_Factory.cpp', + #'../third_party/skia/src/images/SkImageDecoder.cpp', + #'../third_party/skia/src/images/SkImageDecoder_FactoryDefault.cpp', + #'../third_party/skia/src/images/SkImageDecoder_FactoryRegistrar.cpp', #'../third_party/skia/src/images/SkImageDecoder_fpdfemb.cpp', #'../third_party/skia/src/images/SkImageDecoder_libbmp.cpp', #'../third_party/skia/src/images/SkImageDecoder_libgif.cpp', @@ -76,6 +77,8 @@ '../third_party/skia/src/pdf/SkPDFGraphicState.h', '../third_party/skia/src/pdf/SkPDFImage.cpp', '../third_party/skia/src/pdf/SkPDFImage.h', + '../third_party/skia/src/pdf/SkPDFImageStream.cpp', + '../third_party/skia/src/pdf/SkPDFImageStream.h', '../third_party/skia/src/pdf/SkPDFPage.cpp', '../third_party/skia/src/pdf/SkPDFPage.h', '../third_party/skia/src/pdf/SkPDFShader.cpp', @@ -143,8 +146,8 @@ '../third_party/skia/include/ports/SkTypeface_win.h', - '../third_party/skia/include/images/SkImageDecoder.h', - '../third_party/skia/include/images/SkImageEncoder.h', + #'../third_party/skia/include/images/SkImageDecoder.h', + #'../third_party/skia/include/images/SkImageEncoder.h', '../third_party/skia/include/images/SkImageRef.h', '../third_party/skia/include/images/SkImageRef_GlobalPool.h', '../third_party/skia/include/images/SkMovie.h', @@ -207,6 +210,7 @@ '../third_party/skia/include/effects', '../third_party/skia/include/images', '../third_party/skia/include/lazy', + '../third_party/skia/include/pathops', '../third_party/skia/include/pdf', '../third_party/skia/include/pipe', '../third_party/skia/include/ports', @@ -240,6 +244,8 @@ # Disable this check because it is too strict for some Chromium-specific # subclasses of SkPixelRef. See bug: crbug.com/171776. 'SK_DISABLE_PIXELREF_LOCKCOUNT_BALANCE_CHECK', + + 'IGNORE_ROT_AA_RECT_OPT', ], 'sources!': [ '../third_party/skia/include/core/SkTypes.h', @@ -340,12 +346,7 @@ [ 'OS != "win"', { 'sources/': [ ['exclude', '_win\\.(cc|cpp)$'] ], }], - [ 'armv7 == 1', { - 'defines': [ - '__ARM_ARCH__=7', - ], - }], - [ 'armv7 == 1 and arm_neon == 1', { + [ 'target_arch == "arm" and arm_version >= 7 and arm_neon == 1', { 'defines': [ '__ARM_HAVE_NEON', ], @@ -555,6 +556,7 @@ '../third_party/skia/include/pdf', '../third_party/skia/include/gpu', '../third_party/skia/include/gpu/gl', + '../third_party/skia/include/pathops', '../third_party/skia/include/pipe', '../third_party/skia/include/ports', '../third_party/skia/include/utils', @@ -637,6 +639,7 @@ '../third_party/skia/include/effects', '../third_party/skia/include/images', '../third_party/skia/include/lazy', + '../third_party/skia/include/pathops', '../third_party/skia/include/utils', '../third_party/skia/src/core', ], @@ -658,6 +661,7 @@ '../third_party/skia/src/opts/SkBlitRect_opts_SSE2.cpp', '../third_party/skia/src/opts/SkBlitRow_opts_SSE2.cpp', '../third_party/skia/src/opts/SkUtils_opts_SSE2.cpp', + 'ext/convolver_SSE2.cc', ], 'conditions': [ # x86 Android doesn't support SSSE3 instructions. @@ -670,12 +674,7 @@ }], [ 'target_arch == "arm"', { 'conditions': [ - [ 'armv7 == 1', { - 'defines': [ - '__ARM_ARCH__=7', - ], - }], - [ 'armv7 == 1 and arm_neon == 1', { + [ 'arm_version >= 7 and arm_neon == 1', { 'defines': [ '__ARM_HAVE_NEON', ], @@ -704,12 +703,12 @@ '../third_party/skia/src/opts/SkBitmapProcState_opts_arm.cpp', ], }], - [ 'armv7 == 1 and arm_neon == 0', { + [ 'target_arch == "arm" and (arm_version < 7 or arm_neon == 0)', { 'sources': [ '../third_party/skia/src/opts/memset.arm.S', ], }], - [ 'armv7 == 1 and arm_neon == 1', { + [ 'target_arch == "arm" and arm_version >= 7 and arm_neon == 1', { 'sources': [ '../third_party/skia/src/opts/memset16_neon.S', '../third_party/skia/src/opts/memset32_neon.S', @@ -720,13 +719,13 @@ '../third_party/skia/src/opts/SkBlitRow_opts_arm_neon.cpp', ], }], - [ 'target_arch == "arm" and armv7 == 0', { + [ 'target_arch == "arm" and arm_version < 6', { 'sources': [ '../third_party/skia/src/opts/SkBlitRow_opts_none.cpp', '../third_party/skia/src/opts/SkUtils_opts_none.cpp', ], }], - [ 'target_arch == "arm" and armv7 == 1', { + [ 'target_arch == "arm" and arm_version >= 6', { 'sources': [ '../third_party/skia/src/opts/SkBlitRow_opts_arm.cpp', '../third_party/skia/src/opts/SkBlitRow_opts_arm.h', @@ -760,6 +759,7 @@ 'config', '../third_party/skia/include/config', '../third_party/skia/include/core', + '../third_party/skia/include/pathops', '../third_party/skia/src/core', ], 'conditions': [ @@ -824,6 +824,7 @@ '../third_party/skia/include/effects', '../third_party/skia/include/images', '../third_party/skia/include/lazy', + '../third_party/skia/include/pathops', '../third_party/skia/include/utils', '../third_party/skia/src/core', ], diff --git a/skia/skia.target.darwin-arm.mk b/skia/skia.target.darwin-arm.mk new file mode 100644 index 0000000000..a2607a14ed --- /dev/null +++ b/skia/skia.target.darwin-arm.mk @@ -0,0 +1,546 @@ +# This file is generated by gyp; do not edit. + +include $(CLEAR_VARS) + +LOCAL_MODULE_CLASS := STATIC_LIBRARIES +LOCAL_MODULE := skia_skia_gyp +LOCAL_MODULE_SUFFIX := .a +LOCAL_MODULE_TAGS := optional +gyp_intermediate_dir := $(call local-intermediates-dir) +gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared) + +# Make sure our deps are built first. +GYP_TARGET_DEPENDENCIES := \ + $(call intermediates-dir-for,GYP,third_party_WebKit_Source_WebKit_chromium_skia_webkit_gyp)/skia_webkit.stamp \ + $(call intermediates-dir-for,GYP,third_party_expat_expat_gyp)/expat.stamp + +GYP_GENERATED_OUTPUTS := + +# Make sure our deps and generated files are built first. +LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS) + +$(gyp_intermediate_dir)/analysis_canvas.cpp: $(LOCAL_PATH)/skia/ext/analysis_canvas.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/bitmap_platform_device_android.cpp: $(LOCAL_PATH)/skia/ext/bitmap_platform_device_android.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/convolver.cpp: $(LOCAL_PATH)/skia/ext/convolver.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/google_logging.cpp: $(LOCAL_PATH)/skia/ext/google_logging.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/image_operations.cpp: $(LOCAL_PATH)/skia/ext/image_operations.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/lazy_pixel_ref.cpp: $(LOCAL_PATH)/skia/ext/lazy_pixel_ref.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/paint_simplifier.cpp: $(LOCAL_PATH)/skia/ext/paint_simplifier.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/platform_canvas.cpp: $(LOCAL_PATH)/skia/ext/platform_canvas.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/platform_device.cpp: $(LOCAL_PATH)/skia/ext/platform_device.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/platform_device_linux.cpp: $(LOCAL_PATH)/skia/ext/platform_device_linux.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/skia_utils_base.cpp: $(LOCAL_PATH)/skia/ext/skia_utils_base.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/vector_canvas.cpp: $(LOCAL_PATH)/skia/ext/vector_canvas.cc + mkdir -p $(@D); cp $< $@ +LOCAL_GENERATED_SOURCES := \ + $(gyp_intermediate_dir)/analysis_canvas.cpp \ + $(gyp_intermediate_dir)/bitmap_platform_device_android.cpp \ + $(gyp_intermediate_dir)/convolver.cpp \ + $(gyp_intermediate_dir)/google_logging.cpp \ + $(gyp_intermediate_dir)/image_operations.cpp \ + $(gyp_intermediate_dir)/lazy_pixel_ref.cpp \ + $(gyp_intermediate_dir)/paint_simplifier.cpp \ + $(gyp_intermediate_dir)/platform_canvas.cpp \ + $(gyp_intermediate_dir)/platform_device.cpp \ + $(gyp_intermediate_dir)/platform_device_linux.cpp \ + $(gyp_intermediate_dir)/skia_utils_base.cpp \ + $(gyp_intermediate_dir)/vector_canvas.cpp + +GYP_COPIED_SOURCE_ORIGIN_DIRS := \ + $(LOCAL_PATH)/skia/ext + +LOCAL_SRC_FILES := \ + third_party/skia/src/core/SkFlate.cpp \ + third_party/skia/src/images/SkScaledBitmapSampler.cpp \ + third_party/skia/src/ports/SkPurgeableMemoryBlock_none.cpp \ + third_party/skia/src/ports/FontHostConfiguration_android.cpp \ + third_party/skia/src/ports/SkFontHost_FreeType.cpp \ + third_party/skia/src/ports/SkFontHost_FreeType_common.cpp \ + third_party/skia/src/ports/SkFontHost_android.cpp \ + third_party/skia/src/ports/SkGlobalInitialization_chromium.cpp \ + third_party/skia/src/ports/SkOSFile_stdio.cpp \ + third_party/skia/src/ports/SkThread_pthread.cpp \ + third_party/skia/src/ports/SkTime_Unix.cpp \ + third_party/skia/src/sfnt/SkOTUtils.cpp \ + third_party/skia/src/utils/SkBase64.cpp \ + third_party/skia/src/utils/SkBitSet.cpp \ + third_party/skia/src/utils/SkDeferredCanvas.cpp \ + third_party/skia/src/utils/SkMatrix44.cpp \ + third_party/skia/src/utils/SkNullCanvas.cpp \ + third_party/skia/src/utils/SkNWayCanvas.cpp \ + third_party/skia/src/utils/SkPictureUtils.cpp \ + third_party/skia/src/utils/SkRTConf.cpp \ + skia/ext/SkMemory_new_handler.cpp \ + third_party/skia/src/core/Sk64.cpp \ + third_party/skia/src/core/SkAAClip.cpp \ + third_party/skia/src/core/SkAnnotation.cpp \ + third_party/skia/src/core/SkAdvancedTypefaceMetrics.cpp \ + third_party/skia/src/core/SkAlphaRuns.cpp \ + third_party/skia/src/core/SkBBoxHierarchy.cpp \ + third_party/skia/src/core/SkBBoxRecord.cpp \ + third_party/skia/src/core/SkBBoxHierarchyRecord.cpp \ + third_party/skia/src/core/SkBitmap.cpp \ + third_party/skia/src/core/SkBitmapHeap.cpp \ + third_party/skia/src/core/SkBitmapProcShader.cpp \ + third_party/skia/src/core/SkBitmapProcState.cpp \ + third_party/skia/src/core/SkBitmapProcState_matrixProcs.cpp \ + third_party/skia/src/core/SkBitmapSampler.cpp \ + third_party/skia/src/core/SkBitmap_scroll.cpp \ + third_party/skia/src/core/SkBlitMask_D32.cpp \ + third_party/skia/src/core/SkBlitRow_D16.cpp \ + third_party/skia/src/core/SkBlitRow_D32.cpp \ + third_party/skia/src/core/SkBlitRow_D4444.cpp \ + third_party/skia/src/core/SkBlitter.cpp \ + third_party/skia/src/core/SkBlitter_4444.cpp \ + third_party/skia/src/core/SkBlitter_A1.cpp \ + third_party/skia/src/core/SkBlitter_A8.cpp \ + third_party/skia/src/core/SkBlitter_ARGB32.cpp \ + third_party/skia/src/core/SkBlitter_RGB16.cpp \ + third_party/skia/src/core/SkBlitter_Sprite.cpp \ + third_party/skia/src/core/SkBuffer.cpp \ + third_party/skia/src/core/SkCanvas.cpp \ + third_party/skia/src/core/SkChunkAlloc.cpp \ + third_party/skia/src/core/SkClipStack.cpp \ + third_party/skia/src/core/SkColor.cpp \ + third_party/skia/src/core/SkColorFilter.cpp \ + third_party/skia/src/core/SkColorTable.cpp \ + third_party/skia/src/core/SkComposeShader.cpp \ + third_party/skia/src/core/SkConfig8888.cpp \ + third_party/skia/src/core/SkCordic.cpp \ + third_party/skia/src/core/SkCubicClipper.cpp \ + third_party/skia/src/core/SkData.cpp \ + third_party/skia/src/core/SkDataTable.cpp \ + third_party/skia/src/core/SkDebug.cpp \ + third_party/skia/src/core/SkDeque.cpp \ + third_party/skia/src/core/SkDevice.cpp \ + third_party/skia/src/core/SkDeviceProfile.cpp \ + third_party/skia/src/core/SkDither.cpp \ + third_party/skia/src/core/SkDraw.cpp \ + third_party/skia/src/core/SkEdgeBuilder.cpp \ + third_party/skia/src/core/SkEdgeClipper.cpp \ + third_party/skia/src/core/SkEdge.cpp \ + third_party/skia/src/core/SkError.cpp \ + third_party/skia/src/core/SkFDStream.cpp \ + third_party/skia/src/core/SkFilterProc.cpp \ + third_party/skia/src/core/SkFlattenable.cpp \ + third_party/skia/src/core/SkFlattenableBuffers.cpp \ + third_party/skia/src/core/SkFloat.cpp \ + third_party/skia/src/core/SkFloatBits.cpp \ + third_party/skia/src/core/SkFontHost.cpp \ + third_party/skia/src/core/SkFontDescriptor.cpp \ + third_party/skia/src/core/SkFontStream.cpp \ + third_party/skia/src/core/SkGeometry.cpp \ + third_party/skia/src/core/SkGlyphCache.cpp \ + third_party/skia/src/core/SkGraphics.cpp \ + third_party/skia/src/core/SkInstCnt.cpp \ + third_party/skia/src/core/SkImageFilter.cpp \ + third_party/skia/src/core/SkImageFilterUtils.cpp \ + third_party/skia/src/core/SkLineClipper.cpp \ + third_party/skia/src/core/SkMallocPixelRef.cpp \ + third_party/skia/src/core/SkMask.cpp \ + third_party/skia/src/core/SkMaskFilter.cpp \ + third_party/skia/src/core/SkMaskGamma.cpp \ + third_party/skia/src/core/SkMath.cpp \ + third_party/skia/src/core/SkMatrix.cpp \ + third_party/skia/src/core/SkMetaData.cpp \ + third_party/skia/src/core/SkOrderedReadBuffer.cpp \ + third_party/skia/src/core/SkOrderedWriteBuffer.cpp \ + third_party/skia/src/core/SkPackBits.cpp \ + third_party/skia/src/core/SkPaint.cpp \ + third_party/skia/src/core/SkPaintPriv.cpp \ + third_party/skia/src/core/SkPath.cpp \ + third_party/skia/src/core/SkPathEffect.cpp \ + third_party/skia/src/core/SkPathHeap.cpp \ + third_party/skia/src/core/SkPathMeasure.cpp \ + third_party/skia/src/core/SkPicture.cpp \ + third_party/skia/src/core/SkPictureFlat.cpp \ + third_party/skia/src/core/SkPicturePlayback.cpp \ + third_party/skia/src/core/SkPictureRecord.cpp \ + third_party/skia/src/core/SkPictureStateTree.cpp \ + third_party/skia/src/core/SkPixelRef.cpp \ + third_party/skia/src/core/SkPoint.cpp \ + third_party/skia/src/core/SkProcSpriteBlitter.cpp \ + third_party/skia/src/core/SkPtrRecorder.cpp \ + third_party/skia/src/core/SkQuadClipper.cpp \ + third_party/skia/src/core/SkRasterClip.cpp \ + third_party/skia/src/core/SkRasterizer.cpp \ + third_party/skia/src/core/SkRect.cpp \ + third_party/skia/src/core/SkRefCnt.cpp \ + third_party/skia/src/core/SkRefDict.cpp \ + third_party/skia/src/core/SkRegion.cpp \ + third_party/skia/src/core/SkRegion_path.cpp \ + third_party/skia/src/core/SkRRect.cpp \ + third_party/skia/src/core/SkRTree.cpp \ + third_party/skia/src/core/SkScalar.cpp \ + third_party/skia/src/core/SkScalerContext.cpp \ + third_party/skia/src/core/SkScan.cpp \ + third_party/skia/src/core/SkScan_AntiPath.cpp \ + third_party/skia/src/core/SkScan_Antihair.cpp \ + third_party/skia/src/core/SkScan_Hairline.cpp \ + third_party/skia/src/core/SkScan_Path.cpp \ + third_party/skia/src/core/SkShader.cpp \ + third_party/skia/src/core/SkSpriteBlitter_ARGB32.cpp \ + third_party/skia/src/core/SkSpriteBlitter_RGB16.cpp \ + third_party/skia/src/core/SkStream.cpp \ + third_party/skia/src/core/SkString.cpp \ + third_party/skia/src/core/SkStringUtils.cpp \ + third_party/skia/src/core/SkStroke.cpp \ + third_party/skia/src/core/SkStrokeRec.cpp \ + third_party/skia/src/core/SkStrokerPriv.cpp \ + third_party/skia/src/core/SkTileGrid.cpp \ + third_party/skia/src/core/SkTileGridPicture.cpp \ + third_party/skia/src/core/SkTLS.cpp \ + third_party/skia/src/core/SkTSearch.cpp \ + third_party/skia/src/core/SkTypeface.cpp \ + third_party/skia/src/core/SkTypefaceCache.cpp \ + third_party/skia/src/core/SkUnPreMultiply.cpp \ + third_party/skia/src/core/SkUtils.cpp \ + third_party/skia/src/core/SkWriter32.cpp \ + third_party/skia/src/core/SkXfermode.cpp \ + third_party/skia/src/image/SkDataPixelRef.cpp \ + third_party/skia/src/image/SkImage.cpp \ + third_party/skia/src/image/SkImagePriv.cpp \ + third_party/skia/src/image/SkImage_Picture.cpp \ + third_party/skia/src/image/SkImage_Raster.cpp \ + third_party/skia/src/image/SkSurface.cpp \ + third_party/skia/src/image/SkSurface_Picture.cpp \ + third_party/skia/src/image/SkSurface_Raster.cpp \ + third_party/skia/src/pipe/SkGPipeRead.cpp \ + third_party/skia/src/pipe/SkGPipeWrite.cpp \ + third_party/skia/src/lazy/SkBitmapFactory.cpp \ + third_party/skia/src/lazy/SkLazyPixelRef.cpp \ + third_party/skia/src/lazy/SkLruImageCache.cpp \ + third_party/skia/src/lazy/SkPurgeableMemoryBlock_common.cpp \ + third_party/skia/src/lazy/SkPurgeableImageCache.cpp \ + third_party/skia/src/pathops/SkAddIntersections.cpp \ + third_party/skia/src/pathops/SkDCubicIntersection.cpp \ + third_party/skia/src/pathops/SkDCubicLineIntersection.cpp \ + third_party/skia/src/pathops/SkDCubicToQuads.cpp \ + third_party/skia/src/pathops/SkDLineIntersection.cpp \ + third_party/skia/src/pathops/SkDQuadImplicit.cpp \ + third_party/skia/src/pathops/SkDQuadIntersection.cpp \ + third_party/skia/src/pathops/SkDQuadLineIntersection.cpp \ + third_party/skia/src/pathops/SkIntersections.cpp \ + third_party/skia/src/pathops/SkOpAngle.cpp \ + third_party/skia/src/pathops/SkOpContour.cpp \ + third_party/skia/src/pathops/SkOpEdgeBuilder.cpp \ + third_party/skia/src/pathops/SkOpSegment.cpp \ + third_party/skia/src/pathops/SkPathOpsBounds.cpp \ + third_party/skia/src/pathops/SkPathOpsCommon.cpp \ + third_party/skia/src/pathops/SkPathOpsCubic.cpp \ + third_party/skia/src/pathops/SkPathOpsDebug.cpp \ + third_party/skia/src/pathops/SkPathOpsLine.cpp \ + third_party/skia/src/pathops/SkPathOpsOp.cpp \ + third_party/skia/src/pathops/SkPathOpsPoint.cpp \ + third_party/skia/src/pathops/SkPathOpsQuad.cpp \ + third_party/skia/src/pathops/SkPathOpsRect.cpp \ + third_party/skia/src/pathops/SkPathOpsSimplify.cpp \ + third_party/skia/src/pathops/SkPathOpsTriangle.cpp \ + third_party/skia/src/pathops/SkPathOpsTypes.cpp \ + third_party/skia/src/pathops/SkPathWriter.cpp \ + third_party/skia/src/pathops/SkQuarticRoot.cpp \ + third_party/skia/src/pathops/SkReduceOrder.cpp \ + third_party/skia/src/effects/Sk1DPathEffect.cpp \ + third_party/skia/src/effects/Sk2DPathEffect.cpp \ + third_party/skia/src/effects/SkAvoidXfermode.cpp \ + third_party/skia/src/effects/SkArithmeticMode.cpp \ + third_party/skia/src/effects/SkBicubicImageFilter.cpp \ + third_party/skia/src/effects/SkBitmapSource.cpp \ + third_party/skia/src/effects/SkBlendImageFilter.cpp \ + third_party/skia/src/effects/SkBlurDrawLooper.cpp \ + third_party/skia/src/effects/SkBlurMask.cpp \ + third_party/skia/src/effects/SkBlurImageFilter.cpp \ + third_party/skia/src/effects/SkBlurMaskFilter.cpp \ + third_party/skia/src/effects/SkColorFilters.cpp \ + third_party/skia/src/effects/SkColorFilterImageFilter.cpp \ + third_party/skia/src/effects/SkColorMatrix.cpp \ + third_party/skia/src/effects/SkColorMatrixFilter.cpp \ + third_party/skia/src/effects/SkCornerPathEffect.cpp \ + third_party/skia/src/effects/SkDashPathEffect.cpp \ + third_party/skia/src/effects/SkDiscretePathEffect.cpp \ + third_party/skia/src/effects/SkDisplacementMapEffect.cpp \ + third_party/skia/src/effects/SkEmbossMask.cpp \ + third_party/skia/src/effects/SkEmbossMaskFilter.cpp \ + third_party/skia/src/effects/SkKernel33MaskFilter.cpp \ + third_party/skia/src/effects/SkLayerDrawLooper.cpp \ + third_party/skia/src/effects/SkLayerRasterizer.cpp \ + third_party/skia/src/effects/SkLightingImageFilter.cpp \ + third_party/skia/src/effects/SkMatrixConvolutionImageFilter.cpp \ + third_party/skia/src/effects/SkMergeImageFilter.cpp \ + third_party/skia/src/effects/SkMorphologyImageFilter.cpp \ + third_party/skia/src/effects/SkOffsetImageFilter.cpp \ + third_party/skia/src/effects/SkPaintFlagsDrawFilter.cpp \ + third_party/skia/src/effects/SkPerlinNoiseShader.cpp \ + third_party/skia/src/effects/SkPixelXorXfermode.cpp \ + third_party/skia/src/effects/SkPorterDuff.cpp \ + third_party/skia/src/effects/SkRectShaderImageFilter.cpp \ + third_party/skia/src/effects/SkStippleMaskFilter.cpp \ + third_party/skia/src/effects/SkTableColorFilter.cpp \ + third_party/skia/src/effects/SkTableMaskFilter.cpp \ + third_party/skia/src/effects/SkTestImageFilters.cpp \ + third_party/skia/src/effects/SkTransparentShader.cpp \ + third_party/skia/src/effects/SkMagnifierImageFilter.cpp \ + third_party/skia/src/effects/gradients/SkBitmapCache.cpp \ + third_party/skia/src/effects/gradients/SkClampRange.cpp \ + third_party/skia/src/effects/gradients/SkGradientShader.cpp \ + third_party/skia/src/effects/gradients/SkLinearGradient.cpp \ + third_party/skia/src/effects/gradients/SkRadialGradient.cpp \ + third_party/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp \ + third_party/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp \ + third_party/skia/src/effects/gradients/SkSweepGradient.cpp \ + third_party/skia/src/gpu/GrAAHairLinePathRenderer.cpp \ + third_party/skia/src/gpu/GrAAConvexPathRenderer.cpp \ + third_party/skia/src/gpu/GrAARectRenderer.cpp \ + third_party/skia/src/gpu/GrAddPathRenderers_default.cpp \ + third_party/skia/src/gpu/GrAllocPool.cpp \ + third_party/skia/src/gpu/GrAtlas.cpp \ + third_party/skia/src/gpu/GrBufferAllocPool.cpp \ + third_party/skia/src/gpu/GrCacheID.cpp \ + third_party/skia/src/gpu/GrClipData.cpp \ + third_party/skia/src/gpu/GrContext.cpp \ + third_party/skia/src/gpu/GrDefaultPathRenderer.cpp \ + third_party/skia/src/gpu/GrDrawState.cpp \ + third_party/skia/src/gpu/GrDrawTarget.cpp \ + third_party/skia/src/gpu/GrEffect.cpp \ + third_party/skia/src/gpu/GrGeometryBuffer.cpp \ + third_party/skia/src/gpu/GrClipMaskCache.cpp \ + third_party/skia/src/gpu/GrClipMaskManager.cpp \ + third_party/skia/src/gpu/GrGpu.cpp \ + third_party/skia/src/gpu/GrGpuFactory.cpp \ + third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \ + third_party/skia/src/gpu/GrMemory.cpp \ + third_party/skia/src/gpu/GrMemoryPool.cpp \ + third_party/skia/src/gpu/GrOvalRenderer.cpp \ + third_party/skia/src/gpu/GrPath.cpp \ + third_party/skia/src/gpu/GrPathRendererChain.cpp \ + third_party/skia/src/gpu/GrPathRenderer.cpp \ + third_party/skia/src/gpu/GrPathUtils.cpp \ + third_party/skia/src/gpu/GrRectanizer.cpp \ + third_party/skia/src/gpu/GrRenderTarget.cpp \ + third_party/skia/src/gpu/GrReducedClip.cpp \ + third_party/skia/src/gpu/GrResource.cpp \ + third_party/skia/src/gpu/GrResourceCache.cpp \ + third_party/skia/src/gpu/GrStencil.cpp \ + third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \ + third_party/skia/src/gpu/GrStencilBuffer.cpp \ + third_party/skia/src/gpu/GrSWMaskHelper.cpp \ + third_party/skia/src/gpu/GrSoftwarePathRenderer.cpp \ + third_party/skia/src/gpu/GrSurface.cpp \ + third_party/skia/src/gpu/GrTextContext.cpp \ + third_party/skia/src/gpu/GrTextStrike.cpp \ + third_party/skia/src/gpu/GrTexture.cpp \ + third_party/skia/src/gpu/GrTextureAccess.cpp \ + third_party/skia/src/gpu/gr_unittests.cpp \ + third_party/skia/src/gpu/effects/GrConfigConversionEffect.cpp \ + third_party/skia/src/gpu/effects/GrConvolutionEffect.cpp \ + third_party/skia/src/gpu/effects/GrSimpleTextureEffect.cpp \ + third_party/skia/src/gpu/effects/GrSingleTextureEffect.cpp \ + third_party/skia/src/gpu/effects/GrTextureDomainEffect.cpp \ + third_party/skia/src/gpu/effects/GrTextureStripAtlas.cpp \ + third_party/skia/src/gpu/gl/GrGLBufferImpl.cpp \ + third_party/skia/src/gpu/gl/GrGLCaps.cpp \ + third_party/skia/src/gpu/gl/GrGLContext.cpp \ + third_party/skia/src/gpu/gl/GrGLCreateNativeInterface_none.cpp \ + third_party/skia/src/gpu/gl/GrGLDefaultInterface_none.cpp \ + third_party/skia/src/gpu/gl/GrGLEffect.cpp \ + third_party/skia/src/gpu/gl/GrGLExtensions.cpp \ + third_party/skia/src/gpu/gl/GrGLEffectMatrix.cpp \ + third_party/skia/src/gpu/gl/GrGLIndexBuffer.cpp \ + third_party/skia/src/gpu/gl/GrGLInterface.cpp \ + third_party/skia/src/gpu/gl/GrGLNoOpInterface.cpp \ + third_party/skia/src/gpu/gl/GrGLPath.cpp \ + third_party/skia/src/gpu/gl/GrGLProgram.cpp \ + third_party/skia/src/gpu/gl/GrGLProgramDesc.cpp \ + third_party/skia/src/gpu/gl/GrGLRenderTarget.cpp \ + third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp \ + third_party/skia/src/gpu/gl/GrGLSL.cpp \ + third_party/skia/src/gpu/gl/GrGLStencilBuffer.cpp \ + third_party/skia/src/gpu/gl/GrGLTexture.cpp \ + third_party/skia/src/gpu/gl/GrGLUtil.cpp \ + third_party/skia/src/gpu/gl/GrGLUniformManager.cpp \ + third_party/skia/src/gpu/gl/GrGLVertexArray.cpp \ + third_party/skia/src/gpu/gl/GrGLVertexBuffer.cpp \ + third_party/skia/src/gpu/gl/GrGpuGL.cpp \ + third_party/skia/src/gpu/gl/GrGpuGL_program.cpp \ + third_party/skia/src/gpu/SkGpuDevice.cpp \ + third_party/skia/src/gpu/SkGr.cpp \ + third_party/skia/src/gpu/SkGrFontScaler.cpp \ + third_party/skia/src/gpu/SkGrPixelRef.cpp \ + third_party/skia/src/gpu/SkGrTexturePixelRef.cpp \ + third_party/skia/src/image/SkImage_Gpu.cpp \ + third_party/skia/src/image/SkSurface_Gpu.cpp \ + third_party/skia/src/gpu/gl/SkGLContextHelper.cpp + + +# Flags passed to both C and C++ files. +MY_CFLAGS := \ + -fstack-protector \ + --param=ssp-buffer-size=4 \ + -fno-exceptions \ + -fno-strict-aliasing \ + -Wno-unused-parameter \ + -Wno-missing-field-initializers \ + -fvisibility=hidden \ + -pipe \ + -fPIC \ + -Wno-format \ + -fno-tree-sra \ + -fuse-ld=gold \ + -Wno-psabi \ + -ffunction-sections \ + -funwind-tables \ + -g \ + -fstack-protector \ + -fno-short-enums \ + -finline-limit=64 \ + -Wa,--noexecstack \ + -U_FORTIFY_SOURCE \ + -Wno-extra \ + -Wno-ignored-qualifiers \ + -Wno-type-limits \ + -Wno-address \ + -Wno-format-security \ + -Wno-return-type \ + -Wno-sequence-point \ + -Os \ + -g \ + -fomit-frame-pointer \ + -fdata-sections \ + -ffunction-sections + +MY_CFLAGS_C := + +MY_DEFS := \ + '-D_FILE_OFFSET_BITS=64' \ + '-DUSE_LINUX_BREAKPAD' \ + '-DNO_TCMALLOC' \ + '-DDISABLE_NACL' \ + '-DCHROMIUM_BUILD' \ + '-DUSE_LIBJPEG_TURBO=1' \ + '-DUSE_PROPRIETARY_CODECS' \ + '-DENABLE_GPU=1' \ + '-DUSE_OPENSSL=1' \ + '-DENABLE_EGLIMAGE=1' \ + '-DENABLE_LANGUAGE_DETECTION=1' \ + '-DSK_USE_POSIX_THREADS' \ + '-DSK_BUILD_NO_IMAGE_ENCODE' \ + '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \ + '-DGR_STATIC_RECT_VB=1' \ + '-DGR_AGGRESSIVE_SHADER_OPTS=1' \ + '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \ + '-DSK_ENABLE_INST_COUNT=0' \ + '-DSK_ALLOW_OVER_32K_BITMAPS' \ + '-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=0' \ + '-DSK_DISABLE_PIXELREF_LOCKCOUNT_BALANCE_CHECK' \ + '-DIGNORE_ROT_AA_RECT_OPT' \ + '-DSK_GAMMA_APPLY_TO_A8' \ + '-DSK_GAMMA_EXPONENT=1.4' \ + '-DSK_GAMMA_CONTRAST=0.0' \ + '-DHAVE_PTHREADS' \ + '-DOS_ANDROID' \ + '-DSK_BUILD_FOR_ANDROID_NDK' \ + '-DSK_DEFAULT_FONT_CACHE_LIMIT=(8*1024*1024)' \ + '-DUSE_CHROMIUM_SKIA' \ + '-DANDROID' \ + '-D__GNU_SOURCE=1' \ + '-DUSE_STLPORT=1' \ + '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \ + '-DCHROME_BUILD_ID=""' \ + '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \ + '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \ + '-D_DEBUG' + +LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS) + +# Include paths placed before CFLAGS/CPPFLAGS +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/skia/config \ + $(LOCAL_PATH)/third_party/skia/include/config \ + $(LOCAL_PATH)/third_party/skia/include/core \ + $(LOCAL_PATH)/third_party/skia/include/effects \ + $(LOCAL_PATH)/third_party/skia/include/images \ + $(LOCAL_PATH)/third_party/skia/include/lazy \ + $(LOCAL_PATH)/third_party/skia/include/pathops \ + $(LOCAL_PATH)/third_party/skia/include/pdf \ + $(LOCAL_PATH)/third_party/skia/include/pipe \ + $(LOCAL_PATH)/third_party/skia/include/ports \ + $(LOCAL_PATH)/third_party/skia/include/utils \ + $(LOCAL_PATH)/third_party/skia/src/core \ + $(LOCAL_PATH)/third_party/skia/src/image \ + $(LOCAL_PATH)/third_party/skia/src/sfnt \ + $(LOCAL_PATH)/third_party/skia/src/utils \ + $(LOCAL_PATH)/third_party/skia/src/lazy \ + $(LOCAL_PATH)/third_party/skia/include/gpu \ + $(LOCAL_PATH)/third_party/skia/include/gpu/gl \ + $(LOCAL_PATH)/third_party/skia/src/gpu \ + $(LOCAL_PATH)/third_party/expat/files/lib \ + $(LOCAL_PATH)/third_party/zlib \ + $(GYP_ABS_ANDROID_TOP_DIR)/external/expat/lib \ + $(LOCAL_PATH)/third_party/freetype/include \ + $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \ + $(GYP_ABS_ANDROID_TOP_DIR)/bionic \ + $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport + +LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES) + +# Flags passed to only C++ (and not C) files. +LOCAL_CPPFLAGS := \ + -fno-rtti \ + -fno-threadsafe-statics \ + -fvisibility-inlines-hidden \ + -Wno-deprecated \ + -Wno-abi \ + -Wno-error=c++0x-compat \ + -Wno-non-virtual-dtor \ + -Wno-sign-promo \ + -Wno-non-virtual-dtor + +### Rules for final target. + +LOCAL_LDFLAGS := \ + -Wl,-z,now \ + -Wl,-z,relro \ + -Wl,-z,noexecstack \ + -fPIC \ + -Wl,-z,relro \ + -Wl,-z,now \ + -fuse-ld=gold \ + -nostdlib \ + -Wl,--no-undefined \ + -Wl,--exclude-libs=ALL \ + -Wl,--icf=safe \ + -Wl,--gc-sections \ + -Wl,-O1 \ + -Wl,--as-needed + + +LOCAL_STATIC_LIBRARIES := + +# Enable grouping to fix circular references +LOCAL_GROUP_STATIC_LIBRARIES := true + +LOCAL_SHARED_LIBRARIES := \ + libstlport \ + libdl + +# Add target alias to "gyp_all_modules" target. +.PHONY: gyp_all_modules +gyp_all_modules: skia_skia_gyp + +# Alias gyp target name. +.PHONY: skia +skia: skia_skia_gyp + +include $(BUILD_STATIC_LIBRARY) diff --git a/skia/skia.target.darwin-x86.mk b/skia/skia.target.darwin-x86.mk new file mode 100644 index 0000000000..cc6959af74 --- /dev/null +++ b/skia/skia.target.darwin-x86.mk @@ -0,0 +1,546 @@ +# This file is generated by gyp; do not edit. + +include $(CLEAR_VARS) + +LOCAL_MODULE_CLASS := STATIC_LIBRARIES +LOCAL_MODULE := skia_skia_gyp +LOCAL_MODULE_SUFFIX := .a +LOCAL_MODULE_TAGS := optional +gyp_intermediate_dir := $(call local-intermediates-dir) +gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared) + +# Make sure our deps are built first. +GYP_TARGET_DEPENDENCIES := \ + $(call intermediates-dir-for,GYP,third_party_WebKit_Source_WebKit_chromium_skia_webkit_gyp)/skia_webkit.stamp \ + $(call intermediates-dir-for,GYP,third_party_expat_expat_gyp)/expat.stamp + +GYP_GENERATED_OUTPUTS := + +# Make sure our deps and generated files are built first. +LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS) + +$(gyp_intermediate_dir)/analysis_canvas.cpp: $(LOCAL_PATH)/skia/ext/analysis_canvas.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/bitmap_platform_device_android.cpp: $(LOCAL_PATH)/skia/ext/bitmap_platform_device_android.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/convolver.cpp: $(LOCAL_PATH)/skia/ext/convolver.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/google_logging.cpp: $(LOCAL_PATH)/skia/ext/google_logging.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/image_operations.cpp: $(LOCAL_PATH)/skia/ext/image_operations.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/lazy_pixel_ref.cpp: $(LOCAL_PATH)/skia/ext/lazy_pixel_ref.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/paint_simplifier.cpp: $(LOCAL_PATH)/skia/ext/paint_simplifier.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/platform_canvas.cpp: $(LOCAL_PATH)/skia/ext/platform_canvas.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/platform_device.cpp: $(LOCAL_PATH)/skia/ext/platform_device.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/platform_device_linux.cpp: $(LOCAL_PATH)/skia/ext/platform_device_linux.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/skia_utils_base.cpp: $(LOCAL_PATH)/skia/ext/skia_utils_base.cc + mkdir -p $(@D); cp $< $@ +$(gyp_intermediate_dir)/vector_canvas.cpp: $(LOCAL_PATH)/skia/ext/vector_canvas.cc + mkdir -p $(@D); cp $< $@ +LOCAL_GENERATED_SOURCES := \ + $(gyp_intermediate_dir)/analysis_canvas.cpp \ + $(gyp_intermediate_dir)/bitmap_platform_device_android.cpp \ + $(gyp_intermediate_dir)/convolver.cpp \ + $(gyp_intermediate_dir)/google_logging.cpp \ + $(gyp_intermediate_dir)/image_operations.cpp \ + $(gyp_intermediate_dir)/lazy_pixel_ref.cpp \ + $(gyp_intermediate_dir)/paint_simplifier.cpp \ + $(gyp_intermediate_dir)/platform_canvas.cpp \ + $(gyp_intermediate_dir)/platform_device.cpp \ + $(gyp_intermediate_dir)/platform_device_linux.cpp \ + $(gyp_intermediate_dir)/skia_utils_base.cpp \ + $(gyp_intermediate_dir)/vector_canvas.cpp + +GYP_COPIED_SOURCE_ORIGIN_DIRS := \ + $(LOCAL_PATH)/skia/ext + +LOCAL_SRC_FILES := \ + third_party/skia/src/core/SkFlate.cpp \ + third_party/skia/src/images/SkScaledBitmapSampler.cpp \ + third_party/skia/src/opts/opts_check_SSE2.cpp \ + third_party/skia/src/ports/SkPurgeableMemoryBlock_none.cpp \ + third_party/skia/src/ports/FontHostConfiguration_android.cpp \ + third_party/skia/src/ports/SkFontHost_FreeType.cpp \ + third_party/skia/src/ports/SkFontHost_FreeType_common.cpp \ + third_party/skia/src/ports/SkFontHost_android.cpp \ + third_party/skia/src/ports/SkGlobalInitialization_chromium.cpp \ + third_party/skia/src/ports/SkOSFile_stdio.cpp \ + third_party/skia/src/ports/SkThread_pthread.cpp \ + third_party/skia/src/ports/SkTime_Unix.cpp \ + third_party/skia/src/sfnt/SkOTUtils.cpp \ + third_party/skia/src/utils/SkBase64.cpp \ + third_party/skia/src/utils/SkBitSet.cpp \ + third_party/skia/src/utils/SkDeferredCanvas.cpp \ + third_party/skia/src/utils/SkMatrix44.cpp \ + third_party/skia/src/utils/SkNullCanvas.cpp \ + third_party/skia/src/utils/SkNWayCanvas.cpp \ + third_party/skia/src/utils/SkPictureUtils.cpp \ + third_party/skia/src/utils/SkRTConf.cpp \ + skia/ext/SkMemory_new_handler.cpp \ + third_party/skia/src/core/Sk64.cpp \ + third_party/skia/src/core/SkAAClip.cpp \ + third_party/skia/src/core/SkAnnotation.cpp \ + third_party/skia/src/core/SkAdvancedTypefaceMetrics.cpp \ + third_party/skia/src/core/SkAlphaRuns.cpp \ + third_party/skia/src/core/SkBBoxHierarchy.cpp \ + third_party/skia/src/core/SkBBoxRecord.cpp \ + third_party/skia/src/core/SkBBoxHierarchyRecord.cpp \ + third_party/skia/src/core/SkBitmap.cpp \ + third_party/skia/src/core/SkBitmapHeap.cpp \ + third_party/skia/src/core/SkBitmapProcShader.cpp \ + third_party/skia/src/core/SkBitmapProcState.cpp \ + third_party/skia/src/core/SkBitmapProcState_matrixProcs.cpp \ + third_party/skia/src/core/SkBitmapSampler.cpp \ + third_party/skia/src/core/SkBitmap_scroll.cpp \ + third_party/skia/src/core/SkBlitMask_D32.cpp \ + third_party/skia/src/core/SkBlitRow_D16.cpp \ + third_party/skia/src/core/SkBlitRow_D32.cpp \ + third_party/skia/src/core/SkBlitRow_D4444.cpp \ + third_party/skia/src/core/SkBlitter.cpp \ + third_party/skia/src/core/SkBlitter_4444.cpp \ + third_party/skia/src/core/SkBlitter_A1.cpp \ + third_party/skia/src/core/SkBlitter_A8.cpp \ + third_party/skia/src/core/SkBlitter_ARGB32.cpp \ + third_party/skia/src/core/SkBlitter_RGB16.cpp \ + third_party/skia/src/core/SkBlitter_Sprite.cpp \ + third_party/skia/src/core/SkBuffer.cpp \ + third_party/skia/src/core/SkCanvas.cpp \ + third_party/skia/src/core/SkChunkAlloc.cpp \ + third_party/skia/src/core/SkClipStack.cpp \ + third_party/skia/src/core/SkColor.cpp \ + third_party/skia/src/core/SkColorFilter.cpp \ + third_party/skia/src/core/SkColorTable.cpp \ + third_party/skia/src/core/SkComposeShader.cpp \ + third_party/skia/src/core/SkConfig8888.cpp \ + third_party/skia/src/core/SkCordic.cpp \ + third_party/skia/src/core/SkCubicClipper.cpp \ + third_party/skia/src/core/SkData.cpp \ + third_party/skia/src/core/SkDataTable.cpp \ + third_party/skia/src/core/SkDebug.cpp \ + third_party/skia/src/core/SkDeque.cpp \ + third_party/skia/src/core/SkDevice.cpp \ + third_party/skia/src/core/SkDeviceProfile.cpp \ + third_party/skia/src/core/SkDither.cpp \ + third_party/skia/src/core/SkDraw.cpp \ + third_party/skia/src/core/SkEdgeBuilder.cpp \ + third_party/skia/src/core/SkEdgeClipper.cpp \ + third_party/skia/src/core/SkEdge.cpp \ + third_party/skia/src/core/SkError.cpp \ + third_party/skia/src/core/SkFDStream.cpp \ + third_party/skia/src/core/SkFilterProc.cpp \ + third_party/skia/src/core/SkFlattenable.cpp \ + third_party/skia/src/core/SkFlattenableBuffers.cpp \ + third_party/skia/src/core/SkFloat.cpp \ + third_party/skia/src/core/SkFloatBits.cpp \ + third_party/skia/src/core/SkFontHost.cpp \ + third_party/skia/src/core/SkFontDescriptor.cpp \ + third_party/skia/src/core/SkFontStream.cpp \ + third_party/skia/src/core/SkGeometry.cpp \ + third_party/skia/src/core/SkGlyphCache.cpp \ + third_party/skia/src/core/SkGraphics.cpp \ + third_party/skia/src/core/SkInstCnt.cpp \ + third_party/skia/src/core/SkImageFilter.cpp \ + third_party/skia/src/core/SkImageFilterUtils.cpp \ + third_party/skia/src/core/SkLineClipper.cpp \ + third_party/skia/src/core/SkMallocPixelRef.cpp \ + third_party/skia/src/core/SkMask.cpp \ + third_party/skia/src/core/SkMaskFilter.cpp \ + third_party/skia/src/core/SkMaskGamma.cpp \ + third_party/skia/src/core/SkMath.cpp \ + third_party/skia/src/core/SkMatrix.cpp \ + third_party/skia/src/core/SkMetaData.cpp \ + third_party/skia/src/core/SkOrderedReadBuffer.cpp \ + third_party/skia/src/core/SkOrderedWriteBuffer.cpp \ + third_party/skia/src/core/SkPackBits.cpp \ + third_party/skia/src/core/SkPaint.cpp \ + third_party/skia/src/core/SkPaintPriv.cpp \ + third_party/skia/src/core/SkPath.cpp \ + third_party/skia/src/core/SkPathEffect.cpp \ + third_party/skia/src/core/SkPathHeap.cpp \ + third_party/skia/src/core/SkPathMeasure.cpp \ + third_party/skia/src/core/SkPicture.cpp \ + third_party/skia/src/core/SkPictureFlat.cpp \ + third_party/skia/src/core/SkPicturePlayback.cpp \ + third_party/skia/src/core/SkPictureRecord.cpp \ + third_party/skia/src/core/SkPictureStateTree.cpp \ + third_party/skia/src/core/SkPixelRef.cpp \ + third_party/skia/src/core/SkPoint.cpp \ + third_party/skia/src/core/SkProcSpriteBlitter.cpp \ + third_party/skia/src/core/SkPtrRecorder.cpp \ + third_party/skia/src/core/SkQuadClipper.cpp \ + third_party/skia/src/core/SkRasterClip.cpp \ + third_party/skia/src/core/SkRasterizer.cpp \ + third_party/skia/src/core/SkRect.cpp \ + third_party/skia/src/core/SkRefCnt.cpp \ + third_party/skia/src/core/SkRefDict.cpp \ + third_party/skia/src/core/SkRegion.cpp \ + third_party/skia/src/core/SkRegion_path.cpp \ + third_party/skia/src/core/SkRRect.cpp \ + third_party/skia/src/core/SkRTree.cpp \ + third_party/skia/src/core/SkScalar.cpp \ + third_party/skia/src/core/SkScalerContext.cpp \ + third_party/skia/src/core/SkScan.cpp \ + third_party/skia/src/core/SkScan_AntiPath.cpp \ + third_party/skia/src/core/SkScan_Antihair.cpp \ + third_party/skia/src/core/SkScan_Hairline.cpp \ + third_party/skia/src/core/SkScan_Path.cpp \ + third_party/skia/src/core/SkShader.cpp \ + third_party/skia/src/core/SkSpriteBlitter_ARGB32.cpp \ + third_party/skia/src/core/SkSpriteBlitter_RGB16.cpp \ + third_party/skia/src/core/SkStream.cpp \ + third_party/skia/src/core/SkString.cpp \ + third_party/skia/src/core/SkStringUtils.cpp \ + third_party/skia/src/core/SkStroke.cpp \ + third_party/skia/src/core/SkStrokeRec.cpp \ + third_party/skia/src/core/SkStrokerPriv.cpp \ + third_party/skia/src/core/SkTileGrid.cpp \ + third_party/skia/src/core/SkTileGridPicture.cpp \ + third_party/skia/src/core/SkTLS.cpp \ + third_party/skia/src/core/SkTSearch.cpp \ + third_party/skia/src/core/SkTypeface.cpp \ + third_party/skia/src/core/SkTypefaceCache.cpp \ + third_party/skia/src/core/SkUnPreMultiply.cpp \ + third_party/skia/src/core/SkUtils.cpp \ + third_party/skia/src/core/SkWriter32.cpp \ + third_party/skia/src/core/SkXfermode.cpp \ + third_party/skia/src/image/SkDataPixelRef.cpp \ + third_party/skia/src/image/SkImage.cpp \ + third_party/skia/src/image/SkImagePriv.cpp \ + third_party/skia/src/image/SkImage_Picture.cpp \ + third_party/skia/src/image/SkImage_Raster.cpp \ + third_party/skia/src/image/SkSurface.cpp \ + third_party/skia/src/image/SkSurface_Picture.cpp \ + third_party/skia/src/image/SkSurface_Raster.cpp \ + third_party/skia/src/pipe/SkGPipeRead.cpp \ + third_party/skia/src/pipe/SkGPipeWrite.cpp \ + third_party/skia/src/lazy/SkBitmapFactory.cpp \ + third_party/skia/src/lazy/SkLazyPixelRef.cpp \ + third_party/skia/src/lazy/SkLruImageCache.cpp \ + third_party/skia/src/lazy/SkPurgeableMemoryBlock_common.cpp \ + third_party/skia/src/lazy/SkPurgeableImageCache.cpp \ + third_party/skia/src/pathops/SkAddIntersections.cpp \ + third_party/skia/src/pathops/SkDCubicIntersection.cpp \ + third_party/skia/src/pathops/SkDCubicLineIntersection.cpp \ + third_party/skia/src/pathops/SkDCubicToQuads.cpp \ + third_party/skia/src/pathops/SkDLineIntersection.cpp \ + third_party/skia/src/pathops/SkDQuadImplicit.cpp \ + third_party/skia/src/pathops/SkDQuadIntersection.cpp \ + third_party/skia/src/pathops/SkDQuadLineIntersection.cpp \ + third_party/skia/src/pathops/SkIntersections.cpp \ + third_party/skia/src/pathops/SkOpAngle.cpp \ + third_party/skia/src/pathops/SkOpContour.cpp \ + third_party/skia/src/pathops/SkOpEdgeBuilder.cpp \ + third_party/skia/src/pathops/SkOpSegment.cpp \ + third_party/skia/src/pathops/SkPathOpsBounds.cpp \ + third_party/skia/src/pathops/SkPathOpsCommon.cpp \ + third_party/skia/src/pathops/SkPathOpsCubic.cpp \ + third_party/skia/src/pathops/SkPathOpsDebug.cpp \ + third_party/skia/src/pathops/SkPathOpsLine.cpp \ + third_party/skia/src/pathops/SkPathOpsOp.cpp \ + third_party/skia/src/pathops/SkPathOpsPoint.cpp \ + third_party/skia/src/pathops/SkPathOpsQuad.cpp \ + third_party/skia/src/pathops/SkPathOpsRect.cpp \ + third_party/skia/src/pathops/SkPathOpsSimplify.cpp \ + third_party/skia/src/pathops/SkPathOpsTriangle.cpp \ + third_party/skia/src/pathops/SkPathOpsTypes.cpp \ + third_party/skia/src/pathops/SkPathWriter.cpp \ + third_party/skia/src/pathops/SkQuarticRoot.cpp \ + third_party/skia/src/pathops/SkReduceOrder.cpp \ + third_party/skia/src/effects/Sk1DPathEffect.cpp \ + third_party/skia/src/effects/Sk2DPathEffect.cpp \ + third_party/skia/src/effects/SkAvoidXfermode.cpp \ + third_party/skia/src/effects/SkArithmeticMode.cpp \ + third_party/skia/src/effects/SkBicubicImageFilter.cpp \ + third_party/skia/src/effects/SkBitmapSource.cpp \ + third_party/skia/src/effects/SkBlendImageFilter.cpp \ + third_party/skia/src/effects/SkBlurDrawLooper.cpp \ + third_party/skia/src/effects/SkBlurMask.cpp \ + third_party/skia/src/effects/SkBlurImageFilter.cpp \ + third_party/skia/src/effects/SkBlurMaskFilter.cpp \ + third_party/skia/src/effects/SkColorFilters.cpp \ + third_party/skia/src/effects/SkColorFilterImageFilter.cpp \ + third_party/skia/src/effects/SkColorMatrix.cpp \ + third_party/skia/src/effects/SkColorMatrixFilter.cpp \ + third_party/skia/src/effects/SkCornerPathEffect.cpp \ + third_party/skia/src/effects/SkDashPathEffect.cpp \ + third_party/skia/src/effects/SkDiscretePathEffect.cpp \ + third_party/skia/src/effects/SkDisplacementMapEffect.cpp \ + third_party/skia/src/effects/SkEmbossMask.cpp \ + third_party/skia/src/effects/SkEmbossMaskFilter.cpp \ + third_party/skia/src/effects/SkKernel33MaskFilter.cpp \ + third_party/skia/src/effects/SkLayerDrawLooper.cpp \ + third_party/skia/src/effects/SkLayerRasterizer.cpp \ + third_party/skia/src/effects/SkLightingImageFilter.cpp \ + third_party/skia/src/effects/SkMatrixConvolutionImageFilter.cpp \ + third_party/skia/src/effects/SkMergeImageFilter.cpp \ + third_party/skia/src/effects/SkMorphologyImageFilter.cpp \ + third_party/skia/src/effects/SkOffsetImageFilter.cpp \ + third_party/skia/src/effects/SkPaintFlagsDrawFilter.cpp \ + third_party/skia/src/effects/SkPerlinNoiseShader.cpp \ + third_party/skia/src/effects/SkPixelXorXfermode.cpp \ + third_party/skia/src/effects/SkPorterDuff.cpp \ + third_party/skia/src/effects/SkRectShaderImageFilter.cpp \ + third_party/skia/src/effects/SkStippleMaskFilter.cpp \ + third_party/skia/src/effects/SkTableColorFilter.cpp \ + third_party/skia/src/effects/SkTableMaskFilter.cpp \ + third_party/skia/src/effects/SkTestImageFilters.cpp \ + third_party/skia/src/effects/SkTransparentShader.cpp \ + third_party/skia/src/effects/SkMagnifierImageFilter.cpp \ + third_party/skia/src/effects/gradients/SkBitmapCache.cpp \ + third_party/skia/src/effects/gradients/SkClampRange.cpp \ + third_party/skia/src/effects/gradients/SkGradientShader.cpp \ + third_party/skia/src/effects/gradients/SkLinearGradient.cpp \ + third_party/skia/src/effects/gradients/SkRadialGradient.cpp \ + third_party/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp \ + third_party/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp \ + third_party/skia/src/effects/gradients/SkSweepGradient.cpp \ + third_party/skia/src/gpu/GrAAHairLinePathRenderer.cpp \ + third_party/skia/src/gpu/GrAAConvexPathRenderer.cpp \ + third_party/skia/src/gpu/GrAARectRenderer.cpp \ + third_party/skia/src/gpu/GrAddPathRenderers_default.cpp \ + third_party/skia/src/gpu/GrAllocPool.cpp \ + third_party/skia/src/gpu/GrAtlas.cpp \ + third_party/skia/src/gpu/GrBufferAllocPool.cpp \ + third_party/skia/src/gpu/GrCacheID.cpp \ + third_party/skia/src/gpu/GrClipData.cpp \ + third_party/skia/src/gpu/GrContext.cpp \ + third_party/skia/src/gpu/GrDefaultPathRenderer.cpp \ + third_party/skia/src/gpu/GrDrawState.cpp \ + third_party/skia/src/gpu/GrDrawTarget.cpp \ + third_party/skia/src/gpu/GrEffect.cpp \ + third_party/skia/src/gpu/GrGeometryBuffer.cpp \ + third_party/skia/src/gpu/GrClipMaskCache.cpp \ + third_party/skia/src/gpu/GrClipMaskManager.cpp \ + third_party/skia/src/gpu/GrGpu.cpp \ + third_party/skia/src/gpu/GrGpuFactory.cpp \ + third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \ + third_party/skia/src/gpu/GrMemory.cpp \ + third_party/skia/src/gpu/GrMemoryPool.cpp \ + third_party/skia/src/gpu/GrOvalRenderer.cpp \ + third_party/skia/src/gpu/GrPath.cpp \ + third_party/skia/src/gpu/GrPathRendererChain.cpp \ + third_party/skia/src/gpu/GrPathRenderer.cpp \ + third_party/skia/src/gpu/GrPathUtils.cpp \ + third_party/skia/src/gpu/GrRectanizer.cpp \ + third_party/skia/src/gpu/GrRenderTarget.cpp \ + third_party/skia/src/gpu/GrReducedClip.cpp \ + third_party/skia/src/gpu/GrResource.cpp \ + third_party/skia/src/gpu/GrResourceCache.cpp \ + third_party/skia/src/gpu/GrStencil.cpp \ + third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \ + third_party/skia/src/gpu/GrStencilBuffer.cpp \ + third_party/skia/src/gpu/GrSWMaskHelper.cpp \ + third_party/skia/src/gpu/GrSoftwarePathRenderer.cpp \ + third_party/skia/src/gpu/GrSurface.cpp \ + third_party/skia/src/gpu/GrTextContext.cpp \ + third_party/skia/src/gpu/GrTextStrike.cpp \ + third_party/skia/src/gpu/GrTexture.cpp \ + third_party/skia/src/gpu/GrTextureAccess.cpp \ + third_party/skia/src/gpu/gr_unittests.cpp \ + third_party/skia/src/gpu/effects/GrConfigConversionEffect.cpp \ + third_party/skia/src/gpu/effects/GrConvolutionEffect.cpp \ + third_party/skia/src/gpu/effects/GrSimpleTextureEffect.cpp \ + third_party/skia/src/gpu/effects/GrSingleTextureEffect.cpp \ + third_party/skia/src/gpu/effects/GrTextureDomainEffect.cpp \ + third_party/skia/src/gpu/effects/GrTextureStripAtlas.cpp \ + third_party/skia/src/gpu/gl/GrGLBufferImpl.cpp \ + third_party/skia/src/gpu/gl/GrGLCaps.cpp \ + third_party/skia/src/gpu/gl/GrGLContext.cpp \ + third_party/skia/src/gpu/gl/GrGLCreateNativeInterface_none.cpp \ + third_party/skia/src/gpu/gl/GrGLDefaultInterface_none.cpp \ + third_party/skia/src/gpu/gl/GrGLEffect.cpp \ + third_party/skia/src/gpu/gl/GrGLExtensions.cpp \ + third_party/skia/src/gpu/gl/GrGLEffectMatrix.cpp \ + third_party/skia/src/gpu/gl/GrGLIndexBuffer.cpp \ + third_party/skia/src/gpu/gl/GrGLInterface.cpp \ + third_party/skia/src/gpu/gl/GrGLNoOpInterface.cpp \ + third_party/skia/src/gpu/gl/GrGLPath.cpp \ + third_party/skia/src/gpu/gl/GrGLProgram.cpp \ + third_party/skia/src/gpu/gl/GrGLProgramDesc.cpp \ + third_party/skia/src/gpu/gl/GrGLRenderTarget.cpp \ + third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp \ + third_party/skia/src/gpu/gl/GrGLSL.cpp \ + third_party/skia/src/gpu/gl/GrGLStencilBuffer.cpp \ + third_party/skia/src/gpu/gl/GrGLTexture.cpp \ + third_party/skia/src/gpu/gl/GrGLUtil.cpp \ + third_party/skia/src/gpu/gl/GrGLUniformManager.cpp \ + third_party/skia/src/gpu/gl/GrGLVertexArray.cpp \ + third_party/skia/src/gpu/gl/GrGLVertexBuffer.cpp \ + third_party/skia/src/gpu/gl/GrGpuGL.cpp \ + third_party/skia/src/gpu/gl/GrGpuGL_program.cpp \ + third_party/skia/src/gpu/SkGpuDevice.cpp \ + third_party/skia/src/gpu/SkGr.cpp \ + third_party/skia/src/gpu/SkGrFontScaler.cpp \ + third_party/skia/src/gpu/SkGrPixelRef.cpp \ + third_party/skia/src/gpu/SkGrTexturePixelRef.cpp \ + third_party/skia/src/image/SkImage_Gpu.cpp \ + third_party/skia/src/image/SkSurface_Gpu.cpp \ + third_party/skia/src/gpu/gl/SkGLContextHelper.cpp + + +# Flags passed to both C and C++ files. +MY_CFLAGS := \ + --param=ssp-buffer-size=4 \ + -fno-exceptions \ + -fno-strict-aliasing \ + -Wno-unused-parameter \ + -Wno-missing-field-initializers \ + -fvisibility=hidden \ + -pipe \ + -fPIC \ + -Wno-format \ + -m32 \ + -mmmx \ + -march=pentium4 \ + -msse2 \ + -mfpmath=sse \ + -fuse-ld=gold \ + -ffunction-sections \ + -funwind-tables \ + -g \ + -fno-short-enums \ + -finline-limit=64 \ + -Wa,--noexecstack \ + -U_FORTIFY_SOURCE \ + -Wno-extra \ + -Wno-ignored-qualifiers \ + -Wno-type-limits \ + -Wno-address \ + -Wno-format-security \ + -Wno-return-type \ + -Wno-sequence-point \ + -fno-stack-protector \ + -Os \ + -g \ + -fomit-frame-pointer \ + -fdata-sections \ + -ffunction-sections + +MY_CFLAGS_C := + +MY_DEFS := \ + '-D_FILE_OFFSET_BITS=64' \ + '-DUSE_LINUX_BREAKPAD' \ + '-DNO_TCMALLOC' \ + '-DDISABLE_NACL' \ + '-DCHROMIUM_BUILD' \ + '-DUSE_LIBJPEG_TURBO=1' \ + '-DUSE_PROPRIETARY_CODECS' \ + '-DENABLE_GPU=1' \ + '-DUSE_OPENSSL=1' \ + '-DENABLE_EGLIMAGE=1' \ + '-DENABLE_LANGUAGE_DETECTION=1' \ + '-DSK_USE_POSIX_THREADS' \ + '-DSK_BUILD_NO_IMAGE_ENCODE' \ + '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \ + '-DGR_STATIC_RECT_VB=1' \ + '-DGR_AGGRESSIVE_SHADER_OPTS=1' \ + '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \ + '-DSK_ENABLE_INST_COUNT=0' \ + '-DSK_ALLOW_OVER_32K_BITMAPS' \ + '-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=0' \ + '-DSK_DISABLE_PIXELREF_LOCKCOUNT_BALANCE_CHECK' \ + '-DIGNORE_ROT_AA_RECT_OPT' \ + '-DSK_GAMMA_APPLY_TO_A8' \ + '-DSK_GAMMA_EXPONENT=1.4' \ + '-DSK_GAMMA_CONTRAST=0.0' \ + '-DHAVE_PTHREADS' \ + '-DOS_ANDROID' \ + '-DSK_BUILD_FOR_ANDROID_NDK' \ + '-DSK_DEFAULT_FONT_CACHE_LIMIT=(8*1024*1024)' \ + '-DUSE_CHROMIUM_SKIA' \ + '-DANDROID' \ + '-D__GNU_SOURCE=1' \ + '-DUSE_STLPORT=1' \ + '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \ + '-DCHROME_BUILD_ID=""' \ + '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \ + '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \ + '-D_DEBUG' + +LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS) + +# Include paths placed before CFLAGS/CPPFLAGS +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/skia/config \ + $(LOCAL_PATH)/third_party/skia/include/config \ + $(LOCAL_PATH)/third_party/skia/include/core \ + $(LOCAL_PATH)/third_party/skia/include/effects \ + $(LOCAL_PATH)/third_party/skia/include/images \ + $(LOCAL_PATH)/third_party/skia/include/lazy \ + $(LOCAL_PATH)/third_party/skia/include/pathops \ + $(LOCAL_PATH)/third_party/skia/include/pdf \ + $(LOCAL_PATH)/third_party/skia/include/pipe \ + $(LOCAL_PATH)/third_party/skia/include/ports \ + $(LOCAL_PATH)/third_party/skia/include/utils \ + $(LOCAL_PATH)/third_party/skia/src/core \ + $(LOCAL_PATH)/third_party/skia/src/image \ + $(LOCAL_PATH)/third_party/skia/src/sfnt \ + $(LOCAL_PATH)/third_party/skia/src/utils \ + $(LOCAL_PATH)/third_party/skia/src/lazy \ + $(LOCAL_PATH)/third_party/skia/include/gpu \ + $(LOCAL_PATH)/third_party/skia/include/gpu/gl \ + $(LOCAL_PATH)/third_party/skia/src/gpu \ + $(LOCAL_PATH)/third_party/expat/files/lib \ + $(LOCAL_PATH)/third_party/zlib \ + $(GYP_ABS_ANDROID_TOP_DIR)/external/expat/lib \ + $(LOCAL_PATH)/third_party/freetype/include \ + $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \ + $(GYP_ABS_ANDROID_TOP_DIR)/bionic \ + $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport + +LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES) + +# Flags passed to only C++ (and not C) files. +LOCAL_CPPFLAGS := \ + -fno-rtti \ + -fno-threadsafe-statics \ + -fvisibility-inlines-hidden \ + -Wno-deprecated \ + -Wno-error=c++0x-compat \ + -Wno-non-virtual-dtor \ + -Wno-sign-promo \ + -Wno-non-virtual-dtor + +### Rules for final target. + +LOCAL_LDFLAGS := \ + -Wl,-z,now \ + -Wl,-z,relro \ + -Wl,-z,noexecstack \ + -fPIC \ + -m32 \ + -fuse-ld=gold \ + -nostdlib \ + -Wl,--no-undefined \ + -Wl,--exclude-libs=ALL \ + -Wl,--gc-sections \ + -Wl,-O1 \ + -Wl,--as-needed + + +LOCAL_STATIC_LIBRARIES := + +# Enable grouping to fix circular references +LOCAL_GROUP_STATIC_LIBRARIES := true + +LOCAL_SHARED_LIBRARIES := \ + libstlport \ + libdl + +# Add target alias to "gyp_all_modules" target. +.PHONY: gyp_all_modules +gyp_all_modules: skia_skia_gyp + +# Alias gyp target name. +.PHONY: skia +skia: skia_skia_gyp + +include $(BUILD_STATIC_LIBRARY) diff --git a/skia/skia.target.linux-arm.mk b/skia/skia.target.linux-arm.mk index 53376c2fd9..a2607a14ed 100644 --- a/skia/skia.target.linux-arm.mk +++ b/skia/skia.target.linux-arm.mk @@ -62,9 +62,6 @@ GYP_COPIED_SOURCE_ORIGIN_DIRS := \ LOCAL_SRC_FILES := \ third_party/skia/src/core/SkFlate.cpp \ - third_party/skia/src/images/bmpdecoderhelper.cpp \ - third_party/skia/src/images/SkImageDecoder.cpp \ - third_party/skia/src/images/SkImageDecoder_Factory.cpp \ third_party/skia/src/images/SkScaledBitmapSampler.cpp \ third_party/skia/src/ports/SkPurgeableMemoryBlock_none.cpp \ third_party/skia/src/ports/FontHostConfiguration_android.cpp \ @@ -123,6 +120,7 @@ LOCAL_SRC_FILES := \ third_party/skia/src/core/SkCordic.cpp \ third_party/skia/src/core/SkCubicClipper.cpp \ third_party/skia/src/core/SkData.cpp \ + third_party/skia/src/core/SkDataTable.cpp \ third_party/skia/src/core/SkDebug.cpp \ third_party/skia/src/core/SkDeque.cpp \ third_party/skia/src/core/SkDevice.cpp \ @@ -132,6 +130,7 @@ LOCAL_SRC_FILES := \ third_party/skia/src/core/SkEdgeBuilder.cpp \ third_party/skia/src/core/SkEdgeClipper.cpp \ third_party/skia/src/core/SkEdge.cpp \ + third_party/skia/src/core/SkError.cpp \ third_party/skia/src/core/SkFDStream.cpp \ third_party/skia/src/core/SkFilterProc.cpp \ third_party/skia/src/core/SkFlattenable.cpp \ @@ -146,6 +145,7 @@ LOCAL_SRC_FILES := \ third_party/skia/src/core/SkGraphics.cpp \ third_party/skia/src/core/SkInstCnt.cpp \ third_party/skia/src/core/SkImageFilter.cpp \ + third_party/skia/src/core/SkImageFilterUtils.cpp \ third_party/skia/src/core/SkLineClipper.cpp \ third_party/skia/src/core/SkMallocPixelRef.cpp \ third_party/skia/src/core/SkMask.cpp \ @@ -211,7 +211,6 @@ LOCAL_SRC_FILES := \ third_party/skia/src/image/SkDataPixelRef.cpp \ third_party/skia/src/image/SkImage.cpp \ third_party/skia/src/image/SkImagePriv.cpp \ - third_party/skia/src/image/SkImage_Codec.cpp \ third_party/skia/src/image/SkImage_Picture.cpp \ third_party/skia/src/image/SkImage_Raster.cpp \ third_party/skia/src/image/SkSurface.cpp \ @@ -224,6 +223,34 @@ LOCAL_SRC_FILES := \ third_party/skia/src/lazy/SkLruImageCache.cpp \ third_party/skia/src/lazy/SkPurgeableMemoryBlock_common.cpp \ third_party/skia/src/lazy/SkPurgeableImageCache.cpp \ + third_party/skia/src/pathops/SkAddIntersections.cpp \ + third_party/skia/src/pathops/SkDCubicIntersection.cpp \ + third_party/skia/src/pathops/SkDCubicLineIntersection.cpp \ + third_party/skia/src/pathops/SkDCubicToQuads.cpp \ + third_party/skia/src/pathops/SkDLineIntersection.cpp \ + third_party/skia/src/pathops/SkDQuadImplicit.cpp \ + third_party/skia/src/pathops/SkDQuadIntersection.cpp \ + third_party/skia/src/pathops/SkDQuadLineIntersection.cpp \ + third_party/skia/src/pathops/SkIntersections.cpp \ + third_party/skia/src/pathops/SkOpAngle.cpp \ + third_party/skia/src/pathops/SkOpContour.cpp \ + third_party/skia/src/pathops/SkOpEdgeBuilder.cpp \ + third_party/skia/src/pathops/SkOpSegment.cpp \ + third_party/skia/src/pathops/SkPathOpsBounds.cpp \ + third_party/skia/src/pathops/SkPathOpsCommon.cpp \ + third_party/skia/src/pathops/SkPathOpsCubic.cpp \ + third_party/skia/src/pathops/SkPathOpsDebug.cpp \ + third_party/skia/src/pathops/SkPathOpsLine.cpp \ + third_party/skia/src/pathops/SkPathOpsOp.cpp \ + third_party/skia/src/pathops/SkPathOpsPoint.cpp \ + third_party/skia/src/pathops/SkPathOpsQuad.cpp \ + third_party/skia/src/pathops/SkPathOpsRect.cpp \ + third_party/skia/src/pathops/SkPathOpsSimplify.cpp \ + third_party/skia/src/pathops/SkPathOpsTriangle.cpp \ + third_party/skia/src/pathops/SkPathOpsTypes.cpp \ + third_party/skia/src/pathops/SkPathWriter.cpp \ + third_party/skia/src/pathops/SkQuarticRoot.cpp \ + third_party/skia/src/pathops/SkReduceOrder.cpp \ third_party/skia/src/effects/Sk1DPathEffect.cpp \ third_party/skia/src/effects/Sk2DPathEffect.cpp \ third_party/skia/src/effects/SkAvoidXfermode.cpp \ @@ -245,7 +272,6 @@ LOCAL_SRC_FILES := \ third_party/skia/src/effects/SkDisplacementMapEffect.cpp \ third_party/skia/src/effects/SkEmbossMask.cpp \ third_party/skia/src/effects/SkEmbossMaskFilter.cpp \ - third_party/skia/src/effects/SkImageFilterUtils.cpp \ third_party/skia/src/effects/SkKernel33MaskFilter.cpp \ third_party/skia/src/effects/SkLayerDrawLooper.cpp \ third_party/skia/src/effects/SkLayerRasterizer.cpp \ @@ -255,6 +281,7 @@ LOCAL_SRC_FILES := \ third_party/skia/src/effects/SkMorphologyImageFilter.cpp \ third_party/skia/src/effects/SkOffsetImageFilter.cpp \ third_party/skia/src/effects/SkPaintFlagsDrawFilter.cpp \ + third_party/skia/src/effects/SkPerlinNoiseShader.cpp \ third_party/skia/src/effects/SkPixelXorXfermode.cpp \ third_party/skia/src/effects/SkPorterDuff.cpp \ third_party/skia/src/effects/SkRectShaderImageFilter.cpp \ @@ -315,10 +342,8 @@ LOCAL_SRC_FILES := \ third_party/skia/src/gpu/GrTexture.cpp \ third_party/skia/src/gpu/GrTextureAccess.cpp \ third_party/skia/src/gpu/gr_unittests.cpp \ - third_party/skia/src/gpu/effects/GrCircleEdgeEffect.cpp \ third_party/skia/src/gpu/effects/GrConfigConversionEffect.cpp \ third_party/skia/src/gpu/effects/GrConvolutionEffect.cpp \ - third_party/skia/src/gpu/effects/GrEllipseEdgeEffect.cpp \ third_party/skia/src/gpu/effects/GrSimpleTextureEffect.cpp \ third_party/skia/src/gpu/effects/GrSingleTextureEffect.cpp \ third_party/skia/src/gpu/effects/GrTextureDomainEffect.cpp \ @@ -336,6 +361,7 @@ LOCAL_SRC_FILES := \ third_party/skia/src/gpu/gl/GrGLNoOpInterface.cpp \ third_party/skia/src/gpu/gl/GrGLPath.cpp \ third_party/skia/src/gpu/gl/GrGLProgram.cpp \ + third_party/skia/src/gpu/gl/GrGLProgramDesc.cpp \ third_party/skia/src/gpu/gl/GrGLRenderTarget.cpp \ third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp \ third_party/skia/src/gpu/gl/GrGLSL.cpp \ @@ -396,7 +422,6 @@ MY_CFLAGS := \ MY_CFLAGS_C := MY_DEFS := \ - '-DUSE_SKIA' \ '-D_FILE_OFFSET_BITS=64' \ '-DUSE_LINUX_BREAKPAD' \ '-DNO_TCMALLOC' \ @@ -404,7 +429,6 @@ MY_DEFS := \ '-DCHROMIUM_BUILD' \ '-DUSE_LIBJPEG_TURBO=1' \ '-DUSE_PROPRIETARY_CODECS' \ - '-DENABLE_PEPPER_THREADING' \ '-DENABLE_GPU=1' \ '-DUSE_OPENSSL=1' \ '-DENABLE_EGLIMAGE=1' \ @@ -419,10 +443,10 @@ MY_DEFS := \ '-DSK_ALLOW_OVER_32K_BITMAPS' \ '-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=0' \ '-DSK_DISABLE_PIXELREF_LOCKCOUNT_BALANCE_CHECK' \ + '-DIGNORE_ROT_AA_RECT_OPT' \ '-DSK_GAMMA_APPLY_TO_A8' \ '-DSK_GAMMA_EXPONENT=1.4' \ '-DSK_GAMMA_CONTRAST=0.0' \ - '-D__ARM_ARCH__=7' \ '-DHAVE_PTHREADS' \ '-DOS_ANDROID' \ '-DSK_BUILD_FOR_ANDROID_NDK' \ @@ -448,6 +472,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/third_party/skia/include/effects \ $(LOCAL_PATH)/third_party/skia/include/images \ $(LOCAL_PATH)/third_party/skia/include/lazy \ + $(LOCAL_PATH)/third_party/skia/include/pathops \ $(LOCAL_PATH)/third_party/skia/include/pdf \ $(LOCAL_PATH)/third_party/skia/include/pipe \ $(LOCAL_PATH)/third_party/skia/include/ports \ @@ -496,9 +521,9 @@ LOCAL_LDFLAGS := \ -Wl,--no-undefined \ -Wl,--exclude-libs=ALL \ -Wl,--icf=safe \ + -Wl,--gc-sections \ -Wl,-O1 \ - -Wl,--as-needed \ - -Wl,--gc-sections + -Wl,--as-needed LOCAL_STATIC_LIBRARIES := diff --git a/skia/skia.target.linux-x86.mk b/skia/skia.target.linux-x86.mk index 9414725a78..cc6959af74 100644 --- a/skia/skia.target.linux-x86.mk +++ b/skia/skia.target.linux-x86.mk @@ -62,9 +62,6 @@ GYP_COPIED_SOURCE_ORIGIN_DIRS := \ LOCAL_SRC_FILES := \ third_party/skia/src/core/SkFlate.cpp \ - third_party/skia/src/images/bmpdecoderhelper.cpp \ - third_party/skia/src/images/SkImageDecoder.cpp \ - third_party/skia/src/images/SkImageDecoder_Factory.cpp \ third_party/skia/src/images/SkScaledBitmapSampler.cpp \ third_party/skia/src/opts/opts_check_SSE2.cpp \ third_party/skia/src/ports/SkPurgeableMemoryBlock_none.cpp \ @@ -124,6 +121,7 @@ LOCAL_SRC_FILES := \ third_party/skia/src/core/SkCordic.cpp \ third_party/skia/src/core/SkCubicClipper.cpp \ third_party/skia/src/core/SkData.cpp \ + third_party/skia/src/core/SkDataTable.cpp \ third_party/skia/src/core/SkDebug.cpp \ third_party/skia/src/core/SkDeque.cpp \ third_party/skia/src/core/SkDevice.cpp \ @@ -133,6 +131,7 @@ LOCAL_SRC_FILES := \ third_party/skia/src/core/SkEdgeBuilder.cpp \ third_party/skia/src/core/SkEdgeClipper.cpp \ third_party/skia/src/core/SkEdge.cpp \ + third_party/skia/src/core/SkError.cpp \ third_party/skia/src/core/SkFDStream.cpp \ third_party/skia/src/core/SkFilterProc.cpp \ third_party/skia/src/core/SkFlattenable.cpp \ @@ -147,6 +146,7 @@ LOCAL_SRC_FILES := \ third_party/skia/src/core/SkGraphics.cpp \ third_party/skia/src/core/SkInstCnt.cpp \ third_party/skia/src/core/SkImageFilter.cpp \ + third_party/skia/src/core/SkImageFilterUtils.cpp \ third_party/skia/src/core/SkLineClipper.cpp \ third_party/skia/src/core/SkMallocPixelRef.cpp \ third_party/skia/src/core/SkMask.cpp \ @@ -212,7 +212,6 @@ LOCAL_SRC_FILES := \ third_party/skia/src/image/SkDataPixelRef.cpp \ third_party/skia/src/image/SkImage.cpp \ third_party/skia/src/image/SkImagePriv.cpp \ - third_party/skia/src/image/SkImage_Codec.cpp \ third_party/skia/src/image/SkImage_Picture.cpp \ third_party/skia/src/image/SkImage_Raster.cpp \ third_party/skia/src/image/SkSurface.cpp \ @@ -225,6 +224,34 @@ LOCAL_SRC_FILES := \ third_party/skia/src/lazy/SkLruImageCache.cpp \ third_party/skia/src/lazy/SkPurgeableMemoryBlock_common.cpp \ third_party/skia/src/lazy/SkPurgeableImageCache.cpp \ + third_party/skia/src/pathops/SkAddIntersections.cpp \ + third_party/skia/src/pathops/SkDCubicIntersection.cpp \ + third_party/skia/src/pathops/SkDCubicLineIntersection.cpp \ + third_party/skia/src/pathops/SkDCubicToQuads.cpp \ + third_party/skia/src/pathops/SkDLineIntersection.cpp \ + third_party/skia/src/pathops/SkDQuadImplicit.cpp \ + third_party/skia/src/pathops/SkDQuadIntersection.cpp \ + third_party/skia/src/pathops/SkDQuadLineIntersection.cpp \ + third_party/skia/src/pathops/SkIntersections.cpp \ + third_party/skia/src/pathops/SkOpAngle.cpp \ + third_party/skia/src/pathops/SkOpContour.cpp \ + third_party/skia/src/pathops/SkOpEdgeBuilder.cpp \ + third_party/skia/src/pathops/SkOpSegment.cpp \ + third_party/skia/src/pathops/SkPathOpsBounds.cpp \ + third_party/skia/src/pathops/SkPathOpsCommon.cpp \ + third_party/skia/src/pathops/SkPathOpsCubic.cpp \ + third_party/skia/src/pathops/SkPathOpsDebug.cpp \ + third_party/skia/src/pathops/SkPathOpsLine.cpp \ + third_party/skia/src/pathops/SkPathOpsOp.cpp \ + third_party/skia/src/pathops/SkPathOpsPoint.cpp \ + third_party/skia/src/pathops/SkPathOpsQuad.cpp \ + third_party/skia/src/pathops/SkPathOpsRect.cpp \ + third_party/skia/src/pathops/SkPathOpsSimplify.cpp \ + third_party/skia/src/pathops/SkPathOpsTriangle.cpp \ + third_party/skia/src/pathops/SkPathOpsTypes.cpp \ + third_party/skia/src/pathops/SkPathWriter.cpp \ + third_party/skia/src/pathops/SkQuarticRoot.cpp \ + third_party/skia/src/pathops/SkReduceOrder.cpp \ third_party/skia/src/effects/Sk1DPathEffect.cpp \ third_party/skia/src/effects/Sk2DPathEffect.cpp \ third_party/skia/src/effects/SkAvoidXfermode.cpp \ @@ -246,7 +273,6 @@ LOCAL_SRC_FILES := \ third_party/skia/src/effects/SkDisplacementMapEffect.cpp \ third_party/skia/src/effects/SkEmbossMask.cpp \ third_party/skia/src/effects/SkEmbossMaskFilter.cpp \ - third_party/skia/src/effects/SkImageFilterUtils.cpp \ third_party/skia/src/effects/SkKernel33MaskFilter.cpp \ third_party/skia/src/effects/SkLayerDrawLooper.cpp \ third_party/skia/src/effects/SkLayerRasterizer.cpp \ @@ -256,6 +282,7 @@ LOCAL_SRC_FILES := \ third_party/skia/src/effects/SkMorphologyImageFilter.cpp \ third_party/skia/src/effects/SkOffsetImageFilter.cpp \ third_party/skia/src/effects/SkPaintFlagsDrawFilter.cpp \ + third_party/skia/src/effects/SkPerlinNoiseShader.cpp \ third_party/skia/src/effects/SkPixelXorXfermode.cpp \ third_party/skia/src/effects/SkPorterDuff.cpp \ third_party/skia/src/effects/SkRectShaderImageFilter.cpp \ @@ -316,10 +343,8 @@ LOCAL_SRC_FILES := \ third_party/skia/src/gpu/GrTexture.cpp \ third_party/skia/src/gpu/GrTextureAccess.cpp \ third_party/skia/src/gpu/gr_unittests.cpp \ - third_party/skia/src/gpu/effects/GrCircleEdgeEffect.cpp \ third_party/skia/src/gpu/effects/GrConfigConversionEffect.cpp \ third_party/skia/src/gpu/effects/GrConvolutionEffect.cpp \ - third_party/skia/src/gpu/effects/GrEllipseEdgeEffect.cpp \ third_party/skia/src/gpu/effects/GrSimpleTextureEffect.cpp \ third_party/skia/src/gpu/effects/GrSingleTextureEffect.cpp \ third_party/skia/src/gpu/effects/GrTextureDomainEffect.cpp \ @@ -337,6 +362,7 @@ LOCAL_SRC_FILES := \ third_party/skia/src/gpu/gl/GrGLNoOpInterface.cpp \ third_party/skia/src/gpu/gl/GrGLPath.cpp \ third_party/skia/src/gpu/gl/GrGLProgram.cpp \ + third_party/skia/src/gpu/gl/GrGLProgramDesc.cpp \ third_party/skia/src/gpu/gl/GrGLRenderTarget.cpp \ third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp \ third_party/skia/src/gpu/gl/GrGLSL.cpp \ @@ -374,6 +400,7 @@ MY_CFLAGS := \ -march=pentium4 \ -msse2 \ -mfpmath=sse \ + -fuse-ld=gold \ -ffunction-sections \ -funwind-tables \ -g \ @@ -398,7 +425,6 @@ MY_CFLAGS := \ MY_CFLAGS_C := MY_DEFS := \ - '-DUSE_SKIA' \ '-D_FILE_OFFSET_BITS=64' \ '-DUSE_LINUX_BREAKPAD' \ '-DNO_TCMALLOC' \ @@ -406,7 +432,6 @@ MY_DEFS := \ '-DCHROMIUM_BUILD' \ '-DUSE_LIBJPEG_TURBO=1' \ '-DUSE_PROPRIETARY_CODECS' \ - '-DENABLE_PEPPER_THREADING' \ '-DENABLE_GPU=1' \ '-DUSE_OPENSSL=1' \ '-DENABLE_EGLIMAGE=1' \ @@ -421,6 +446,7 @@ MY_DEFS := \ '-DSK_ALLOW_OVER_32K_BITMAPS' \ '-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=0' \ '-DSK_DISABLE_PIXELREF_LOCKCOUNT_BALANCE_CHECK' \ + '-DIGNORE_ROT_AA_RECT_OPT' \ '-DSK_GAMMA_APPLY_TO_A8' \ '-DSK_GAMMA_EXPONENT=1.4' \ '-DSK_GAMMA_CONTRAST=0.0' \ @@ -449,6 +475,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/third_party/skia/include/effects \ $(LOCAL_PATH)/third_party/skia/include/images \ $(LOCAL_PATH)/third_party/skia/include/lazy \ + $(LOCAL_PATH)/third_party/skia/include/pathops \ $(LOCAL_PATH)/third_party/skia/include/pdf \ $(LOCAL_PATH)/third_party/skia/include/pipe \ $(LOCAL_PATH)/third_party/skia/include/ports \ @@ -490,12 +517,13 @@ LOCAL_LDFLAGS := \ -Wl,-z,noexecstack \ -fPIC \ -m32 \ + -fuse-ld=gold \ -nostdlib \ -Wl,--no-undefined \ -Wl,--exclude-libs=ALL \ + -Wl,--gc-sections \ -Wl,-O1 \ - -Wl,--as-needed \ - -Wl,--gc-sections + -Wl,--as-needed LOCAL_STATIC_LIBRARIES := diff --git a/skia/skia_opts.target.darwin-arm.mk b/skia/skia_opts.target.darwin-arm.mk new file mode 100644 index 0000000000..d7c3459e7f --- /dev/null +++ b/skia/skia_opts.target.darwin-arm.mk @@ -0,0 +1,160 @@ +# This file is generated by gyp; do not edit. + +include $(CLEAR_VARS) + +LOCAL_MODULE_CLASS := STATIC_LIBRARIES +LOCAL_MODULE := skia_skia_opts_gyp +LOCAL_MODULE_SUFFIX := .a +LOCAL_MODULE_TAGS := optional +gyp_intermediate_dir := $(call local-intermediates-dir) +gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared) + +# Make sure our deps are built first. +GYP_TARGET_DEPENDENCIES := + +GYP_GENERATED_OUTPUTS := + +# Make sure our deps and generated files are built first. +LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS) + +LOCAL_GENERATED_SOURCES := + +GYP_COPIED_SOURCE_ORIGIN_DIRS := + +LOCAL_SRC_FILES := \ + third_party/skia/src/opts/SkBitmapProcState_opts_arm.cpp \ + third_party/skia/src/opts/memset.arm.S \ + third_party/skia/src/opts/SkBlitRow_opts_arm.cpp \ + third_party/skia/src/opts/opts_check_arm.cpp + + +# Flags passed to both C and C++ files. +MY_CFLAGS := \ + -fstack-protector \ + --param=ssp-buffer-size=4 \ + -fno-exceptions \ + -fno-strict-aliasing \ + -Wno-unused-parameter \ + -Wno-missing-field-initializers \ + -fvisibility=hidden \ + -pipe \ + -fPIC \ + -fomit-frame-pointer \ + -Wno-format \ + -fno-tree-sra \ + -fuse-ld=gold \ + -Wno-psabi \ + -ffunction-sections \ + -funwind-tables \ + -g \ + -fstack-protector \ + -fno-short-enums \ + -finline-limit=64 \ + -Wa,--noexecstack \ + -U_FORTIFY_SOURCE \ + -Wno-extra \ + -Wno-ignored-qualifiers \ + -Wno-type-limits \ + -Wno-address \ + -Wno-format-security \ + -Wno-return-type \ + -Wno-sequence-point \ + -Os \ + -g \ + -fomit-frame-pointer \ + -fdata-sections \ + -ffunction-sections + +MY_CFLAGS_C := + +MY_DEFS := \ + '-D_FILE_OFFSET_BITS=64' \ + '-DUSE_LINUX_BREAKPAD' \ + '-DNO_TCMALLOC' \ + '-DDISABLE_NACL' \ + '-DCHROMIUM_BUILD' \ + '-DUSE_LIBJPEG_TURBO=1' \ + '-DUSE_PROPRIETARY_CODECS' \ + '-DENABLE_GPU=1' \ + '-DUSE_OPENSSL=1' \ + '-DENABLE_EGLIMAGE=1' \ + '-DENABLE_LANGUAGE_DETECTION=1' \ + '-DSK_BUILD_FOR_ANDROID_NDK' \ + '-DANDROID' \ + '-D__GNU_SOURCE=1' \ + '-DUSE_STLPORT=1' \ + '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \ + '-DCHROME_BUILD_ID=""' \ + '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \ + '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \ + '-D_DEBUG' + +LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS) + +# Include paths placed before CFLAGS/CPPFLAGS +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/skia/config \ + $(LOCAL_PATH)/third_party/skia/include/config \ + $(LOCAL_PATH)/third_party/skia/include/core \ + $(LOCAL_PATH)/third_party/skia/include/effects \ + $(LOCAL_PATH)/third_party/skia/include/images \ + $(LOCAL_PATH)/third_party/skia/include/lazy \ + $(LOCAL_PATH)/third_party/skia/include/pathops \ + $(LOCAL_PATH)/third_party/skia/include/utils \ + $(LOCAL_PATH)/third_party/skia/src/core \ + $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \ + $(GYP_ABS_ANDROID_TOP_DIR)/bionic \ + $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport + +LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES) + +# Flags passed to only C++ (and not C) files. +LOCAL_CPPFLAGS := \ + -fno-rtti \ + -fno-threadsafe-statics \ + -fvisibility-inlines-hidden \ + -Wno-deprecated \ + -Wno-abi \ + -Wno-error=c++0x-compat \ + -Wno-non-virtual-dtor \ + -Wno-sign-promo \ + -Wno-non-virtual-dtor + +### Rules for final target. + +LOCAL_LDFLAGS := \ + -Wl,-z,now \ + -Wl,-z,relro \ + -Wl,-z,noexecstack \ + -fPIC \ + -Wl,-z,relro \ + -Wl,-z,now \ + -fuse-ld=gold \ + -nostdlib \ + -Wl,--no-undefined \ + -Wl,--exclude-libs=ALL \ + -Wl,--icf=safe \ + -Wl,--gc-sections \ + -Wl,-O1 \ + -Wl,--as-needed + + +LOCAL_STATIC_LIBRARIES := + +# Enable grouping to fix circular references +LOCAL_GROUP_STATIC_LIBRARIES := true + +LOCAL_SHARED_LIBRARIES := \ + libstlport \ + libdl + +# Add target alias to "gyp_all_modules" target. +.PHONY: gyp_all_modules +gyp_all_modules: skia_skia_opts_gyp + +# Alias gyp target name. +.PHONY: skia_opts +skia_opts: skia_skia_opts_gyp + +include $(BUILD_STATIC_LIBRARY) diff --git a/skia/skia_opts.target.darwin-x86.mk b/skia/skia_opts.target.darwin-x86.mk new file mode 100644 index 0000000000..82e4162a11 --- /dev/null +++ b/skia/skia_opts.target.darwin-x86.mk @@ -0,0 +1,162 @@ +# This file is generated by gyp; do not edit. + +include $(CLEAR_VARS) + +LOCAL_MODULE_CLASS := STATIC_LIBRARIES +LOCAL_MODULE := skia_skia_opts_gyp +LOCAL_MODULE_SUFFIX := .a +LOCAL_MODULE_TAGS := optional +gyp_intermediate_dir := $(call local-intermediates-dir) +gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared) + +# Make sure our deps are built first. +GYP_TARGET_DEPENDENCIES := + +GYP_GENERATED_OUTPUTS := + +# Make sure our deps and generated files are built first. +LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS) + +$(gyp_intermediate_dir)/convolver_SSE2.cpp: $(LOCAL_PATH)/skia/ext/convolver_SSE2.cc + mkdir -p $(@D); cp $< $@ +LOCAL_GENERATED_SOURCES := \ + $(gyp_intermediate_dir)/convolver_SSE2.cpp + +GYP_COPIED_SOURCE_ORIGIN_DIRS := \ + $(LOCAL_PATH)/skia/ext + +LOCAL_SRC_FILES := \ + third_party/skia/src/opts/SkBitmapProcState_opts_SSE2.cpp \ + third_party/skia/src/opts/SkBlitRect_opts_SSE2.cpp \ + third_party/skia/src/opts/SkBlitRow_opts_SSE2.cpp \ + third_party/skia/src/opts/SkUtils_opts_SSE2.cpp + + +# Flags passed to both C and C++ files. +MY_CFLAGS := \ + --param=ssp-buffer-size=4 \ + -fno-exceptions \ + -fno-strict-aliasing \ + -Wno-unused-parameter \ + -Wno-missing-field-initializers \ + -fvisibility=hidden \ + -pipe \ + -fPIC \ + -Wno-format \ + -m32 \ + -mmmx \ + -march=pentium4 \ + -msse2 \ + -mfpmath=sse \ + -fuse-ld=gold \ + -ffunction-sections \ + -funwind-tables \ + -g \ + -fno-short-enums \ + -finline-limit=64 \ + -Wa,--noexecstack \ + -U_FORTIFY_SOURCE \ + -Wno-extra \ + -Wno-ignored-qualifiers \ + -Wno-type-limits \ + -Wno-address \ + -Wno-format-security \ + -Wno-return-type \ + -Wno-sequence-point \ + -fno-stack-protector \ + -Os \ + -g \ + -fomit-frame-pointer \ + -fdata-sections \ + -ffunction-sections + +MY_CFLAGS_C := + +MY_DEFS := \ + '-D_FILE_OFFSET_BITS=64' \ + '-DUSE_LINUX_BREAKPAD' \ + '-DNO_TCMALLOC' \ + '-DDISABLE_NACL' \ + '-DCHROMIUM_BUILD' \ + '-DUSE_LIBJPEG_TURBO=1' \ + '-DUSE_PROPRIETARY_CODECS' \ + '-DENABLE_GPU=1' \ + '-DUSE_OPENSSL=1' \ + '-DENABLE_EGLIMAGE=1' \ + '-DENABLE_LANGUAGE_DETECTION=1' \ + '-DSK_BUILD_FOR_ANDROID_NDK' \ + '-DANDROID' \ + '-D__GNU_SOURCE=1' \ + '-DUSE_STLPORT=1' \ + '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \ + '-DCHROME_BUILD_ID=""' \ + '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \ + '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \ + '-D_DEBUG' + +LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS) + +# Include paths placed before CFLAGS/CPPFLAGS +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/skia/config \ + $(LOCAL_PATH)/third_party/skia/include/config \ + $(LOCAL_PATH)/third_party/skia/include/core \ + $(LOCAL_PATH)/third_party/skia/include/effects \ + $(LOCAL_PATH)/third_party/skia/include/images \ + $(LOCAL_PATH)/third_party/skia/include/lazy \ + $(LOCAL_PATH)/third_party/skia/include/pathops \ + $(LOCAL_PATH)/third_party/skia/include/utils \ + $(LOCAL_PATH)/third_party/skia/src/core \ + $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \ + $(GYP_ABS_ANDROID_TOP_DIR)/bionic \ + $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport + +LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES) + +# Flags passed to only C++ (and not C) files. +LOCAL_CPPFLAGS := \ + -fno-rtti \ + -fno-threadsafe-statics \ + -fvisibility-inlines-hidden \ + -Wno-deprecated \ + -Wno-error=c++0x-compat \ + -Wno-non-virtual-dtor \ + -Wno-sign-promo \ + -Wno-non-virtual-dtor + +### Rules for final target. + +LOCAL_LDFLAGS := \ + -Wl,-z,now \ + -Wl,-z,relro \ + -Wl,-z,noexecstack \ + -fPIC \ + -m32 \ + -fuse-ld=gold \ + -nostdlib \ + -Wl,--no-undefined \ + -Wl,--exclude-libs=ALL \ + -Wl,--gc-sections \ + -Wl,-O1 \ + -Wl,--as-needed + + +LOCAL_STATIC_LIBRARIES := + +# Enable grouping to fix circular references +LOCAL_GROUP_STATIC_LIBRARIES := true + +LOCAL_SHARED_LIBRARIES := \ + libstlport \ + libdl + +# Add target alias to "gyp_all_modules" target. +.PHONY: gyp_all_modules +gyp_all_modules: skia_skia_opts_gyp + +# Alias gyp target name. +.PHONY: skia_opts +skia_opts: skia_skia_opts_gyp + +include $(BUILD_STATIC_LIBRARY) diff --git a/skia/skia_opts.target.linux-arm.mk b/skia/skia_opts.target.linux-arm.mk index fe5a8d4fa2..d7c3459e7f 100644 --- a/skia/skia_opts.target.linux-arm.mk +++ b/skia/skia_opts.target.linux-arm.mk @@ -68,7 +68,6 @@ MY_CFLAGS := \ MY_CFLAGS_C := MY_DEFS := \ - '-DUSE_SKIA' \ '-D_FILE_OFFSET_BITS=64' \ '-DUSE_LINUX_BREAKPAD' \ '-DNO_TCMALLOC' \ @@ -76,13 +75,11 @@ MY_DEFS := \ '-DCHROMIUM_BUILD' \ '-DUSE_LIBJPEG_TURBO=1' \ '-DUSE_PROPRIETARY_CODECS' \ - '-DENABLE_PEPPER_THREADING' \ '-DENABLE_GPU=1' \ '-DUSE_OPENSSL=1' \ '-DENABLE_EGLIMAGE=1' \ '-DENABLE_LANGUAGE_DETECTION=1' \ '-DSK_BUILD_FOR_ANDROID_NDK' \ - '-D__ARM_ARCH__=7' \ '-DANDROID' \ '-D__GNU_SOURCE=1' \ '-DUSE_STLPORT=1' \ @@ -103,6 +100,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/third_party/skia/include/effects \ $(LOCAL_PATH)/third_party/skia/include/images \ $(LOCAL_PATH)/third_party/skia/include/lazy \ + $(LOCAL_PATH)/third_party/skia/include/pathops \ $(LOCAL_PATH)/third_party/skia/include/utils \ $(LOCAL_PATH)/third_party/skia/src/core \ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \ @@ -137,9 +135,9 @@ LOCAL_LDFLAGS := \ -Wl,--no-undefined \ -Wl,--exclude-libs=ALL \ -Wl,--icf=safe \ + -Wl,--gc-sections \ -Wl,-O1 \ - -Wl,--as-needed \ - -Wl,--gc-sections + -Wl,--as-needed LOCAL_STATIC_LIBRARIES := diff --git a/skia/skia_opts.target.linux-x86.mk b/skia/skia_opts.target.linux-x86.mk index 62c4a499a3..82e4162a11 100644 --- a/skia/skia_opts.target.linux-x86.mk +++ b/skia/skia_opts.target.linux-x86.mk @@ -17,9 +17,13 @@ GYP_GENERATED_OUTPUTS := # Make sure our deps and generated files are built first. LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS) -LOCAL_GENERATED_SOURCES := +$(gyp_intermediate_dir)/convolver_SSE2.cpp: $(LOCAL_PATH)/skia/ext/convolver_SSE2.cc + mkdir -p $(@D); cp $< $@ +LOCAL_GENERATED_SOURCES := \ + $(gyp_intermediate_dir)/convolver_SSE2.cpp -GYP_COPIED_SOURCE_ORIGIN_DIRS := +GYP_COPIED_SOURCE_ORIGIN_DIRS := \ + $(LOCAL_PATH)/skia/ext LOCAL_SRC_FILES := \ third_party/skia/src/opts/SkBitmapProcState_opts_SSE2.cpp \ @@ -44,6 +48,7 @@ MY_CFLAGS := \ -march=pentium4 \ -msse2 \ -mfpmath=sse \ + -fuse-ld=gold \ -ffunction-sections \ -funwind-tables \ -g \ @@ -68,7 +73,6 @@ MY_CFLAGS := \ MY_CFLAGS_C := MY_DEFS := \ - '-DUSE_SKIA' \ '-D_FILE_OFFSET_BITS=64' \ '-DUSE_LINUX_BREAKPAD' \ '-DNO_TCMALLOC' \ @@ -76,7 +80,6 @@ MY_DEFS := \ '-DCHROMIUM_BUILD' \ '-DUSE_LIBJPEG_TURBO=1' \ '-DUSE_PROPRIETARY_CODECS' \ - '-DENABLE_PEPPER_THREADING' \ '-DENABLE_GPU=1' \ '-DUSE_OPENSSL=1' \ '-DENABLE_EGLIMAGE=1' \ @@ -102,6 +105,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/third_party/skia/include/effects \ $(LOCAL_PATH)/third_party/skia/include/images \ $(LOCAL_PATH)/third_party/skia/include/lazy \ + $(LOCAL_PATH)/third_party/skia/include/pathops \ $(LOCAL_PATH)/third_party/skia/include/utils \ $(LOCAL_PATH)/third_party/skia/src/core \ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \ @@ -129,12 +133,13 @@ LOCAL_LDFLAGS := \ -Wl,-z,noexecstack \ -fPIC \ -m32 \ + -fuse-ld=gold \ -nostdlib \ -Wl,--no-undefined \ -Wl,--exclude-libs=ALL \ + -Wl,--gc-sections \ -Wl,-O1 \ - -Wl,--as-needed \ - -Wl,--gc-sections + -Wl,--as-needed LOCAL_STATIC_LIBRARIES := diff --git a/skia/skia_test_expectations.txt b/skia/skia_test_expectations.txt index 4327f6e172..52a650032d 100644 --- a/skia/skia_test_expectations.txt +++ b/skia/skia_test_expectations.txt @@ -48,4 +48,9 @@ # # START OVERRIDES HERE +# In r8961 the way Skia draws rotated rects was changed. This resulted +# in a change to the following +crbug.com/237634 virtual/gpu/fast/canvas/image-pattern-rotate.html [ ImageOnlyFailure ] +crbug.com/237634 virtual/gpu/fast/canvas/image-object-in-canvas.html [ ImageOnlyFailure ] + # END OVERRIDES HERE (this line ensures that the file is newline-terminated) |