diff options
author | alokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-08 22:45:18 +0000 |
---|---|---|
committer | alokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-08 22:45:18 +0000 |
commit | 58838bf7106c6f2a0c75af275e7b60bd1faea3d6 (patch) | |
tree | 1fc2954fb35830073ffcee016d50d3d22fe29624 /skia/ext | |
parent | 1389a03f1ac25bf7e80fb88cdbff5e48abd875a1 (diff) | |
download | chromium_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.cc | 19 | ||||
-rw-r--r-- | skia/ext/analysis_canvas.h | 3 | ||||
-rw-r--r-- | skia/ext/analysis_canvas_unittest.cc | 125 |
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 |