summaryrefslogtreecommitdiffstats
path: root/skia/ext
diff options
context:
space:
mode:
authoralokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-08 22:45:18 +0000
committeralokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-08 22:45:18 +0000
commit58838bf7106c6f2a0c75af275e7b60bd1faea3d6 (patch)
tree1fc2954fb35830073ffcee016d50d3d22fe29624 /skia/ext
parent1389a03f1ac25bf7e80fb88cdbff5e48abd875a1 (diff)
downloadchromium_src-58838bf7106c6f2a0c75af275e7b60bd1faea3d6.zip
chromium_src-58838bf7106c6f2a0c75af275e7b60bd1faea3d6.tar.gz
chromium_src-58838bf7106c6f2a0c75af275e7b60bd1faea3d6.tar.bz2
Smart layer invalidation for LCD text.
When LCD text needs to be disabled for a layer, we can invalidate just the tiles containing text. This only works with impl-side painting where it is very cheap to mark tiles that have text. BUG=181245 Review URL: https://chromiumcodereview.appspot.com/13726013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192936 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/ext')
-rw-r--r--skia/ext/analysis_canvas.cc19
-rw-r--r--skia/ext/analysis_canvas.h3
-rw-r--r--skia/ext/analysis_canvas_unittest.cc125
3 files changed, 145 insertions, 2 deletions
diff --git a/skia/ext/analysis_canvas.cc b/skia/ext/analysis_canvas.cc
index 93580b0..0af76f2 100644
--- a/skia/ext/analysis_canvas.cc
+++ b/skia/ext/analysis_canvas.cc
@@ -96,8 +96,8 @@ AnalysisDevice::AnalysisDevice(const SkBitmap& bm)
, isForcedNotSolid_(false)
, isForcedNotTransparent_(false)
, isSolidColor_(false)
- , isTransparent_(false) {
-
+ , isTransparent_(false)
+ , hasText_(false) {
}
AnalysisDevice::~AnalysisDevice() {
@@ -118,6 +118,10 @@ bool AnalysisDevice::isTransparent() const {
return isTransparent_;
}
+bool AnalysisDevice::hasText() const {
+ return hasText_;
+}
+
void AnalysisDevice::setForceNotSolid(bool flag) {
isForcedNotSolid_ = flag;
if (isForcedNotSolid_)
@@ -181,6 +185,7 @@ void AnalysisDevice::clear(SkColor color) {
estimatedCost_ += kUnknownExpensiveCost;
isTransparent_ = (!isForcedNotTransparent_ && SkColorGetA(color) == 0);
+ hasText_ = false;
if (!isForcedNotSolid_ && SkColorGetA(color) == 255) {
isSolidColor_ = true;
@@ -246,6 +251,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) {
@@ -262,6 +268,7 @@ void AnalysisDevice::drawRect(const SkDraw& draw, const SkRect& rect,
doesCoverCanvas) {
isSolidColor_ = true;
color_ = paint.getColor();
+ hasText_ = false;
}
else {
isSolidColor_ = false;
@@ -346,6 +353,7 @@ void AnalysisDevice::drawText(const SkDraw&, const void* text, size_t len,
}
isSolidColor_ = false;
isTransparent_ = false;
+ hasText_ = true;
}
void AnalysisDevice::drawPosText(const SkDraw& draw, const void* text,
@@ -361,6 +369,7 @@ void AnalysisDevice::drawPosText(const SkDraw& draw, const void* text,
}
isSolidColor_ = false;
isTransparent_ = false;
+ hasText_ = true;
}
void AnalysisDevice::drawTextOnPath(const SkDraw&, const void* text,
@@ -374,6 +383,7 @@ void AnalysisDevice::drawTextOnPath(const SkDraw&, const void* text,
}
isSolidColor_ = false;
isTransparent_ = false;
+ hasText_ = true;
}
#ifdef SK_BUILD_FOR_ANDROID
@@ -388,6 +398,7 @@ void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw, const void* text,
}
isSolidColor_ = false;
isTransparent_ = false;
+ hasText_ = true;
}
#endif
@@ -441,6 +452,10 @@ bool AnalysisCanvas::isTransparent() const {
return (static_cast<AnalysisDevice*>(getDevice()))->isTransparent();
}
+bool AnalysisCanvas::hasText() const {
+ return (static_cast<AnalysisDevice*>(getDevice()))->hasText();
+}
+
int AnalysisCanvas::getEstimatedCost() const {
return (static_cast<AnalysisDevice*>(getDevice()))->getEstimatedCost();
}
diff --git a/skia/ext/analysis_canvas.h b/skia/ext/analysis_canvas.h
index 3c2daaf..4ebf793 100644
--- a/skia/ext/analysis_canvas.h
+++ b/skia/ext/analysis_canvas.h
@@ -35,6 +35,7 @@ class SK_API AnalysisCanvas : public SkCanvas {
bool isCheap() const;
bool getColorIfSolid(SkColor* color) const;
bool isTransparent() const;
+ bool hasText() const;
void consumeLazyPixelRefs(LazyPixelRefList* pixelRefs);
// Returns the estimated cost of drawing, in arbitrary units.
@@ -76,6 +77,7 @@ class SK_API AnalysisDevice : public SkDevice {
int getEstimatedCost() const;
bool getColorIfSolid(SkColor* color) const;
bool isTransparent() const;
+ bool hasText() const;
void consumeLazyPixelRefs(LazyPixelRefList* pixelRefs);
void setForceNotSolid(bool flag);
@@ -144,6 +146,7 @@ class SK_API AnalysisDevice : public SkDevice {
bool isSolidColor_;
SkColor color_;
bool isTransparent_;
+ bool hasText_;
IdSet existingPixelRefIDs_;
LazyPixelRefList lazyPixelRefs_;
};
diff --git a/skia/ext/analysis_canvas_unittest.cc b/skia/ext/analysis_canvas_unittest.cc
index 46c9645..a8a9d0d 100644
--- a/skia/ext/analysis_canvas_unittest.cc
+++ b/skia/ext/analysis_canvas_unittest.cc
@@ -454,4 +454,129 @@ TEST(AnalysisCanvasTest, PixelRefsFromPaint) {
}
}
+TEST(AnalysisCanvasTest, HasText) {
+ int width = 200;
+ int height = 100;
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kNo_Config, width, height);
+
+ const char* text = "A";
+ size_t byteLength = 1;
+
+ SkPoint point = SkPoint::Make(SkIntToScalar(25), SkIntToScalar(25));
+ SkPath path;
+ path.moveTo(point);
+ path.lineTo(SkIntToScalar(75), SkIntToScalar(75));
+
+ 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());
+ }
+}
+
} // namespace skia