Index: cc/resources/content_layer_updater.cc |
diff --git a/cc/resources/content_layer_updater.cc b/cc/resources/content_layer_updater.cc |
index 8bd90e9d5a174768abab9709b7a3928540a2eac7..2aa908f61ec49fdf98445b5aed276996e764eb1b 100644 |
--- a/cc/resources/content_layer_updater.cc |
+++ b/cc/resources/content_layer_updater.cc |
@@ -14,6 +14,7 @@ |
#include "third_party/skia/include/core/SkScalar.h" |
#include "ui/gfx/rect_conversions.h" |
#include "ui/gfx/rect_f.h" |
+#include "ui/gfx/skia_util.h" |
namespace cc { |
@@ -25,7 +26,9 @@ ContentLayerUpdater::ContentLayerUpdater( |
layer_id_(layer_id), |
layer_is_opaque_(false), |
layer_fills_bounds_completely_(false), |
- painter_(painter.Pass()) {} |
+ painter_(painter.Pass()), |
+ background_color_(SK_ColorTRANSPARENT) { |
+} |
ContentLayerUpdater::~ContentLayerUpdater() {} |
@@ -35,27 +38,57 @@ void ContentLayerUpdater::set_rendering_stats_instrumentation( |
} |
void ContentLayerUpdater::PaintContents(SkCanvas* canvas, |
- const gfx::Rect& content_rect, |
+ const gfx::Size& content_size, |
danakj
2014/09/19 22:02:58
layer_content_size
sky
2014/09/22 17:59:59
Done.
|
+ const gfx::Rect& paint_rect, |
float contents_width_scale, |
float contents_height_scale) { |
TRACE_EVENT0("cc", "ContentLayerUpdater::PaintContents"); |
if (!canvas) |
return; |
canvas->save(); |
- canvas->translate(SkFloatToScalar(-content_rect.x()), |
- SkFloatToScalar(-content_rect.y())); |
- |
- // The |canvas| backing should be sized to hold the |content_rect|. |
- DCHECK_EQ(content_rect.width(), canvas->getBaseLayerSize().width()); |
- DCHECK_EQ(content_rect.height(), canvas->getBaseLayerSize().height()); |
+ canvas->translate(SkIntToScalar(-paint_rect.x()), |
+ SkIntToScalar(-paint_rect.y())); |
+ |
+ // The |canvas| backing should be sized to hold the |paint_rect|. |
+ DCHECK_EQ(paint_rect.width(), canvas->getBaseLayerSize().width()); |
+ DCHECK_EQ(paint_rect.height(), canvas->getBaseLayerSize().height()); |
+ |
+ gfx::Rect layer_rect = paint_rect; |
danakj
2014/09/19 22:02:57
move down to where the rest of the computation of
sky
2014/09/22 17:59:59
Done.
|
+ const bool is_scaled = |
+ contents_width_scale != 1.f || contents_height_scale != 1.f; |
+ |
+ if (is_scaled && (layer_is_opaque_ || layer_fills_bounds_completely_)) { |
+ // Even if completely covered, for rasterizations that touch the edge of the |
+ // layer, we also need to raster the background color underneath the last |
+ // texel (since the recording won't cover it) and outside the last texel |
danakj
2014/09/19 22:02:57
s/recording/paint/
sky
2014/09/22 17:59:59
Done.
|
+ // (due to linear filtering when using this texture). |
danakj
2014/09/19 22:02:57
this "outside the last texel" isn't needed here, b
sky
2014/09/22 18:00:00
Done.
|
+ // The final texel of content may only be partially covered by a |
danakj
2014/09/19 22:02:57
whitespace above to separate
sky
2014/09/22 17:59:59
Done.
|
+ // rasterization; this rect represents the content rect that is fully |
+ // covered by content. |
+ const gfx::Rect content_rect = gfx::Rect(content_size); |
danakj
2014/09/19 22:02:57
layer_content_rect
sky
2014/09/22 18:00:00
Done.
|
+ gfx::Rect deflated_content_rect = content_rect; |
danakj
2014/09/19 22:02:58
deflated_layer_content_rect
sky
2014/09/22 17:59:59
Done.
|
+ deflated_content_rect.Inset(0, 0, 1, 1); |
danakj
2014/09/19 22:02:57
whitespace below to separate, make it clear the co
sky
2014/09/22 18:00:00
Done.
|
+ if (!content_rect.Contains(paint_rect)) { |
danakj
2014/09/19 22:02:57
deflated_content_rect
sky
2014/09/22 17:59:59
Done.
|
+ // Drawing at most 2 x 2 x (canvas width + canvas height) texels is 2-3X |
danakj
2014/09/19 22:02:58
s/2/1/
sky
2014/09/22 17:59:59
Done.
|
+ // faster than clearing, so special case this. |
danakj
2014/09/19 22:02:58
can you DCHECK_LE(paint_rect.right(), content_rect
sky
2014/09/22 17:59:59
Done.
|
+ canvas->save(); |
+ gfx::Rect inflated_content_rect = content_rect; |
danakj
2014/09/19 22:02:57
remove this just use the content_rect
sky
2014/09/22 17:59:59
Done.
|
+ inflated_content_rect.Inset(0, 0, -1, -1); |
+ canvas->clipRect(gfx::RectToSkRect(inflated_content_rect), |
+ SkRegion::kReplace_Op); |
+ canvas->clipRect(gfx::RectToSkRect(deflated_content_rect), |
+ SkRegion::kDifference_Op); |
+ canvas->drawColor(background_color_, SkXfermode::kSrc_Mode); |
+ canvas->restore(); |
+ } |
+ } |
- gfx::Rect layer_rect = content_rect; |
- if (contents_width_scale != 1.f || contents_height_scale != 1.f) { |
+ if (is_scaled) { |
canvas->scale(SkFloatToScalar(contents_width_scale), |
SkFloatToScalar(contents_height_scale)); |
layer_rect = gfx::ScaleToEnclosingRect( |
- content_rect, 1.f / contents_width_scale, 1.f / contents_height_scale); |
+ paint_rect, 1.f / contents_width_scale, 1.f / contents_height_scale); |
} |
SkRect layer_sk_rect = SkRect::MakeXYWH( |
@@ -73,7 +106,7 @@ void ContentLayerUpdater::PaintContents(SkCanvas* canvas, |
painter_->Paint(canvas, layer_rect); |
canvas->restore(); |
- content_rect_ = content_rect; |
+ paint_rect_ = paint_rect; |
} |
void ContentLayerUpdater::SetOpaque(bool opaque) { |
@@ -84,4 +117,8 @@ void ContentLayerUpdater::SetFillsBoundsCompletely(bool fills_bounds) { |
layer_fills_bounds_completely_ = fills_bounds; |
} |
+void ContentLayerUpdater::SetBackgroundColor(SkColor background_color) { |
+ background_color_ = background_color; |
+} |
+ |
} // namespace cc |