summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-02 18:00:40 +0000
committerbrianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-02 18:00:40 +0000
commit43f7c3d79d7e73ad092ffe8e69c556143e4323a7 (patch)
tree12e8fb6d7e2a9d2f2f8a9c658e550ba5566f3616
parent689dfa60ce033bbba001df3aed52fc5e747f0e1f (diff)
downloadchromium_src-43f7c3d79d7e73ad092ffe8e69c556143e4323a7.zip
chromium_src-43f7c3d79d7e73ad092ffe8e69c556143e4323a7.tar.gz
chromium_src-43f7c3d79d7e73ad092ffe8e69c556143e4323a7.tar.bz2
cc: Remove texture scaling and clear edge texels of a layer.
Removes texture scaling and does the following instead: - Clears one texel inside the right/bottom edge of the content rect, as it may only be partially covered by the picture playback. - Also clears one texel outside the right/bottom edge of the content rect, as it may get blended in by linear filtering when zoomed in. The root layer is cleared to its background color. Other layers are cleared to transparent. BUG=178273 Review URL: https://chromiumcodereview.appspot.com/12383060 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@185732 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/picture_layer.cc6
-rw-r--r--cc/picture_layer_tiling.cc46
-rw-r--r--cc/picture_layer_tiling.h3
-rw-r--r--cc/picture_pile.cc14
-rw-r--r--cc/picture_pile.h1
-rw-r--r--cc/picture_pile_base.cc5
-rw-r--r--cc/picture_pile_base.h1
-rw-r--r--cc/picture_pile_impl.cc35
-rw-r--r--cc/picture_pile_impl.h2
9 files changed, 67 insertions, 46 deletions
diff --git a/cc/picture_layer.cc b/cc/picture_layer.cc
index 348d952..cfa90ab 100644
--- a/cc/picture_layer.cc
+++ b/cc/picture_layer.cc
@@ -79,7 +79,11 @@ void PictureLayer::update(ResourceUpdateQueue&, const OcclusionTracker*,
gfx::Rect visible_layer_rect = gfx::ToEnclosingRect(
gfx::ScaleRect(visibleContentRect(), 1.f / contentsScaleX()));
devtools_instrumentation::ScopedPaintLayer paint_layer(id());
- pile_->Update(client_, pile_invalidation_, visible_layer_rect, stats);
+ pile_->Update(client_,
+ backgroundColor(),
+ pile_invalidation_,
+ visible_layer_rect,
+ stats);
}
void PictureLayer::setIsMask(bool is_mask) {
diff --git a/cc/picture_layer_tiling.cc b/cc/picture_layer_tiling.cc
index e0a2544..e760e4a 100644
--- a/cc/picture_layer_tiling.cc
+++ b/cc/picture_layer_tiling.cc
@@ -190,8 +190,7 @@ PictureLayerTiling::Iterator::Iterator(const PictureLayerTiling* tiling,
: tiling_(tiling),
dest_rect_(dest_rect),
current_tile_(NULL),
- dest_to_content_scale_x_(0),
- dest_to_content_scale_y_(0),
+ dest_to_content_scale_(0),
tile_i_(0),
tile_j_(0),
left_(0),
@@ -202,42 +201,17 @@ PictureLayerTiling::Iterator::Iterator(const PictureLayerTiling* tiling,
if (dest_rect_.IsEmpty())
return;
- float dest_to_content_scale = tiling_->contents_scale_ / dest_scale;
+ dest_to_content_scale_ = tiling_->contents_scale_ / dest_scale;
// This is the maximum size that the dest rect can be, given the content size.
gfx::Size dest_content_size = gfx::ToCeiledSize(gfx::ScaleSize(
tiling_->ContentRect().size(),
- 1 / dest_to_content_scale,
- 1 / dest_to_content_scale));
-
- // The last row/column of texels may not have full rasterization coverage,
- // which can happen if the ceiled content size does not equal the floored
- // content size. These texels will sample outside of the recording to
- // generate their pixels. Use the floored size here to ignore them.
- gfx::Size content_size_floor = gfx::ToFlooredSize(tiling->ContentSizeF());
- dest_to_content_scale_x_ = content_size_floor.width() /
- static_cast<float>(dest_content_size.width());
- dest_to_content_scale_y_ = content_size_floor.height() /
- static_cast<float>(dest_content_size.height());
-
- // It's possible that when drawing a quad with texel:pixel ratio < 1
- // GL_LINEAR will cause us to blend in invalid texels.
- // We stretch the content a little more to prevent sampling past the
- // middle of the last texel.
- if (layerDeviceAlignment == LayerAlignedToDevice){
- if (dest_to_content_scale_x_ < 1.0)
- dest_to_content_scale_x_ -= 0.5f / dest_content_size.width();
- if (dest_to_content_scale_y_ < 1.0)
- dest_to_content_scale_y_ -= 0.5f / dest_content_size.height();
- }
- else if (layerDeviceAlignment == LayerNotAlignedToDevice) {
- dest_to_content_scale_x_ -= 0.5f / dest_content_size.width();
- dest_to_content_scale_y_ -= 0.5f / dest_content_size.height();
- }
+ 1 / dest_to_content_scale_,
+ 1 / dest_to_content_scale_));
gfx::Rect content_rect =
gfx::ToEnclosingRect(gfx::ScaleRect(dest_rect_,
- dest_to_content_scale_x_,
- dest_to_content_scale_y_));
+ dest_to_content_scale_,
+ dest_to_content_scale_));
// IndexFromSrcCoord clamps to valid tile ranges, so it's necessary to
// check for non-intersection first.
content_rect.Intersect(gfx::Rect(tiling_->tiling_data_.total_size()));
@@ -286,8 +260,8 @@ PictureLayerTiling::Iterator& PictureLayerTiling::Iterator::operator++() {
gfx::Rect content_rect = tiling_->tiling_data_.TileBounds(tile_i_, tile_j_);
current_geometry_rect_ = gfx::ToEnclosingRect(
- gfx::ScaleRect(content_rect, 1 / dest_to_content_scale_x_,
- 1 / dest_to_content_scale_y_));
+ gfx::ScaleRect(content_rect, 1 / dest_to_content_scale_,
+ 1 / dest_to_content_scale_));
current_geometry_rect_.Intersect(dest_rect_);
@@ -336,8 +310,8 @@ gfx::RectF PictureLayerTiling::Iterator::texture_rect() const {
// Convert from dest space => content space => texture space.
gfx::RectF texture_rect(current_geometry_rect_);
- texture_rect.Scale(dest_to_content_scale_x_,
- dest_to_content_scale_y_);
+ texture_rect.Scale(dest_to_content_scale_,
+ dest_to_content_scale_);
texture_rect.Offset(-tex_origin.OffsetFromOrigin());
texture_rect.Intersect(tiling_->ContentRect());
diff --git a/cc/picture_layer_tiling.h b/cc/picture_layer_tiling.h
index ab0aa2e..14127ac 100644
--- a/cc/picture_layer_tiling.h
+++ b/cc/picture_layer_tiling.h
@@ -109,8 +109,7 @@ class CC_EXPORT PictureLayerTiling {
private:
const PictureLayerTiling* tiling_;
gfx::Rect dest_rect_;
- float dest_to_content_scale_x_;
- float dest_to_content_scale_y_;
+ float dest_to_content_scale_;
Tile* current_tile_;
gfx::Rect current_geometry_rect_;
diff --git a/cc/picture_pile.cc b/cc/picture_pile.cc
index d94835a..b30d8c7 100644
--- a/cc/picture_pile.cc
+++ b/cc/picture_pile.cc
@@ -31,9 +31,12 @@ PicturePile::~PicturePile() {
void PicturePile::Update(
ContentLayerClient* painter,
+ SkColor background_color,
const Region& invalidation,
gfx::Rect visible_layer_rect,
RenderingStats* stats) {
+ background_color_ = background_color;
+
gfx::Rect interest_rect = visible_layer_rect;
interest_rect.Inset(
-kPixelDistanceToRecord,
@@ -82,8 +85,15 @@ void PicturePile::Update(
// Create a picture in this list if it doesn't exist.
PictureList& pic_list = picture_list_map_[iter.index()];
if (pic_list.empty()) {
- gfx::Rect tile =
- tiling_.TileBoundsWithBorder(iter.index_x(), iter.index_y());
+ // Inflate the base picture with a margin, similar to invalidations, so
+ // that when scaled down to at least min_contents_scale, the enclosed
+ // rect still includes content all the way to the edge of the layer.
+ gfx::Rect tile = tiling_.TileBounds(iter.index_x(), iter.index_y());
+ tile.Inset(
+ -buffer_pixels(),
+ -buffer_pixels(),
+ -buffer_pixels(),
+ -buffer_pixels());
scoped_refptr<Picture> base_picture = Picture::Create(tile);
pic_list.push_back(base_picture);
}
diff --git a/cc/picture_pile.h b/cc/picture_pile.h
index a6271fa..475f74b 100644
--- a/cc/picture_pile.h
+++ b/cc/picture_pile.h
@@ -21,6 +21,7 @@ class CC_EXPORT PicturePile : public PicturePileBase {
// Invalidations are in layer space.
void Update(
ContentLayerClient* painter,
+ SkColor background_color,
const Region& invalidation,
gfx::Rect visible_layer_rect,
RenderingStats* stats);
diff --git a/cc/picture_pile_base.cc b/cc/picture_pile_base.cc
index c855167..08ea4ee 100644
--- a/cc/picture_pile_base.cc
+++ b/cc/picture_pile_base.cc
@@ -5,6 +5,7 @@
#include "cc/picture_pile_base.h"
#include "base/logging.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/rect_conversions.h"
namespace {
@@ -17,7 +18,8 @@ const int kTileGridBorderPixels = 1;
namespace cc {
PicturePileBase::PicturePileBase()
- : min_contents_scale_(0) {
+ : min_contents_scale_(0)
+ , background_color_(SkColorSetARGBInline(0, 0, 0, 0)) {
tiling_.SetMaxTextureSize(gfx::Size(kBasePictureSize, kBasePictureSize));
tile_grid_info_.fTileInterval.setEmpty();
tile_grid_info_.fMargin.setEmpty();
@@ -105,6 +107,7 @@ void PicturePileBase::PushPropertiesTo(PicturePileBase* other) {
other->recorded_region_ = recorded_region_;
other->min_contents_scale_ = min_contents_scale_;
other->tile_grid_info_ = tile_grid_info_;
+ other->background_color_ = background_color_;
}
void PicturePileBase::UpdateRecordedRegion() {
diff --git a/cc/picture_pile_base.h b/cc/picture_pile_base.h
index aea9477..a6aac25 100644
--- a/cc/picture_pile_base.h
+++ b/cc/picture_pile_base.h
@@ -56,6 +56,7 @@ class CC_EXPORT PicturePileBase : public base::RefCounted<PicturePileBase> {
Region recorded_region_;
float min_contents_scale_;
SkTileGridPicture::TileGridInfo tile_grid_info_;
+ SkColor background_color_;
private:
void SetBufferPixels(int buffer_pixels);
diff --git a/cc/picture_pile_impl.cc b/cc/picture_pile_impl.cc
index 4bb01a3..bada009 100644
--- a/cc/picture_pile_impl.cc
+++ b/cc/picture_pile_impl.cc
@@ -10,6 +10,7 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSize.h"
#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/size_conversions.h"
#include "ui/gfx/skia_util.h"
namespace cc {
@@ -60,7 +61,7 @@ scoped_refptr<PicturePileImpl> PicturePileImpl::CloneForDrawing() const {
void PicturePileImpl::Raster(
SkCanvas* canvas,
- gfx::Rect content_rect,
+ gfx::Rect canvas_rect,
float contents_scale,
int64* total_pixels_rasterized) {
@@ -72,12 +73,40 @@ void PicturePileImpl::Raster(
#endif // NDEBUG
canvas->save();
- canvas->translate(-content_rect.x(), -content_rect.y());
- canvas->clipRect(gfx::RectToSkRect(content_rect));
+ canvas->translate(-canvas_rect.x(), -canvas_rect.y());
+
+ gfx::SizeF total_content_size = gfx::ScaleSize(tiling_.total_size(),
+ contents_scale);
+ gfx::Rect total_content_rect(gfx::ToCeiledSize(total_content_size));
+ gfx::Rect content_rect = total_content_rect;
+ content_rect.Intersect(canvas_rect);
+
+ // Clear one texel inside the right/bottom edge of the content rect,
+ // as it may only be partially covered by the picture playback.
+ // Also clear one texel outside the right/bottom edge of the content rect,
+ // as it may get blended in by linear filtering when zoomed in.
+ gfx::Rect deflated_content_rect = total_content_rect;
+ deflated_content_rect.Inset(0, 0, 1, 1);
+
+ gfx::Rect canvas_outside_content_rect = canvas_rect;
+ canvas_outside_content_rect.Subtract(deflated_content_rect);
+
+ if (!canvas_outside_content_rect.IsEmpty()) {
+ gfx::Rect inflated_content_rect = total_content_rect;
+ 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);
+ }
+ // Rasterize the collection of relevant picture piles.
gfx::Rect layer_rect = gfx::ToEnclosingRect(
gfx::ScaleRect(content_rect, 1.f / contents_scale));
+ canvas->clipRect(gfx::RectToSkRect(content_rect),
+ SkRegion::kReplace_Op);
Region unclipped(content_rect);
for (TilingData::Iterator tile_iter(&tiling_, layer_rect);
tile_iter; ++tile_iter) {
diff --git a/cc/picture_pile_impl.h b/cc/picture_pile_impl.h
index 157f9e2..7eea998 100644
--- a/cc/picture_pile_impl.h
+++ b/cc/picture_pile_impl.h
@@ -32,7 +32,7 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase {
// It is assumed that contentsScale has already been applied to this canvas.
void Raster(
SkCanvas* canvas,
- gfx::Rect content_rect,
+ gfx::Rect canvas_rect,
float contents_scale,
int64* total_pixels_rasterized);