summaryrefslogtreecommitdiff
path: root/skia
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2013-05-09 18:35:53 +0100
committerTorne (Richard Coles) <torne@google.com>2013-05-13 13:57:14 +0100
commitc2e0dbddbe15c98d52c4786dac06cb8952a8ae6d (patch)
tree1dbdbb0624cc869ab25ee7f46971984c6fee3e7a /skia
parent2d519ce2457219605d4f472da8d2ffd469796035 (diff)
downloadchromium_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.cc2
-rw-r--r--skia/ext/analysis_canvas.cc209
-rw-r--r--skia/ext/analysis_canvas.h35
-rw-r--r--skia/ext/analysis_canvas_unittest.cc330
-rw-r--r--skia/ext/convolver.cc788
-rw-r--r--skia/ext/convolver.h73
-rw-r--r--skia/ext/convolver_SSE2.cc456
-rw-r--r--skia/ext/convolver_SSE2.h26
-rw-r--r--skia/ext/convolver_unittest.cc158
-rw-r--r--skia/ext/image_operations.cc24
-rw-r--r--skia/ext/image_operations_unittest.cc86
-rw-r--r--skia/ext/platform_device.h4
-rw-r--r--skia/ext/vector_canvas_unittest.cc5
-rw-r--r--skia/skia.gyp45
-rw-r--r--skia/skia.target.darwin-arm.mk546
-rw-r--r--skia/skia.target.darwin-x86.mk546
-rw-r--r--skia/skia.target.linux-arm.mk49
-rw-r--r--skia/skia.target.linux-x86.mk50
-rw-r--r--skia/skia_opts.target.darwin-arm.mk160
-rw-r--r--skia/skia_opts.target.darwin-x86.mk162
-rw-r--r--skia/skia_opts.target.linux-arm.mk8
-rw-r--r--skia/skia_opts.target.linux-x86.mk17
-rw-r--r--skia/skia_test_expectations.txt5
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)