summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-07 08:11:50 +0000
committervmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-07 08:11:50 +0000
commit046a9712362dcf891a2634fee98bd9cf20bbabfb (patch)
treeea6c64a37c5f5fd1ae62224a8e68ee4242b35681
parentf13c66f37537585f2a3a6949ad4f72046573d047 (diff)
downloadchromium_src-046a9712362dcf891a2634fee98bd9cf20bbabfb.zip
chromium_src-046a9712362dcf891a2634fee98bd9cf20bbabfb.tar.gz
chromium_src-046a9712362dcf891a2634fee98bd9cf20bbabfb.tar.bz2
cc: Low quality support for low res tiles
This adds low quality for low res tiles. When a low res tile becomes something else, then the reraster is scheduled. BUG=180196 Review URL: https://chromiumcodereview.appspot.com/15995033 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204747 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/layers/picture_layer_impl.cc28
-rw-r--r--cc/resources/managed_tile_state.cc6
-rw-r--r--cc/resources/managed_tile_state.h6
-rw-r--r--cc/resources/picture.cc22
-rw-r--r--cc/resources/picture.h3
-rw-r--r--cc/resources/picture_layer_tiling.cc5
-rw-r--r--cc/resources/picture_layer_tiling_set.cc2
-rw-r--r--cc/resources/picture_layer_tiling_set_unittest.cc5
-rw-r--r--cc/resources/picture_pile_impl.cc3
-rw-r--r--cc/resources/picture_pile_impl.h4
-rw-r--r--cc/resources/tile.h35
-rw-r--r--cc/resources/tile_manager.cc231
-rw-r--r--cc/resources/tile_manager.h16
-rw-r--r--cc/test/skia_common.cc2
-rw-r--r--content/renderer/skia_benchmarking_extension.cc2
15 files changed, 256 insertions, 114 deletions
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 77d4bca..c130588 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -163,8 +163,10 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
++iter) {
SkColor color;
float width;
- if (*iter && iter->tile_version().IsReadyToDraw()) {
- ManagedTileState::TileVersion::Mode mode = iter->tile_version().mode();
+ TileRasterMode raster_mode;
+ if (*iter && iter->IsReadyToDraw(&raster_mode)) {
+ ManagedTileState::TileVersion::Mode mode =
+ iter->tile_version(raster_mode).mode();
if (mode == ManagedTileState::TileVersion::SOLID_COLOR_MODE) {
color = DebugColors::SolidColorTileBorderColor();
width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
@@ -207,7 +209,8 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
iter;
++iter) {
gfx::Rect geometry_rect = iter.geometry_rect();
- if (!*iter || !iter->tile_version().IsReadyToDraw()) {
+ TileRasterMode raster_mode;
+ if (!*iter || !iter->IsReadyToDraw(&raster_mode)) {
if (DrawCheckerboardForMissingTiles()) {
// TODO(enne): Figure out how to show debug "invalidated checker" color
scoped_ptr<CheckerboardDrawQuad> quad = CheckerboardDrawQuad::Create();
@@ -227,7 +230,8 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
continue;
}
- const ManagedTileState::TileVersion& tile_version = iter->tile_version();
+ const ManagedTileState::TileVersion& tile_version =
+ iter->tile_version(raster_mode);
switch (tile_version.mode()) {
case ManagedTileState::TileVersion::RESOURCE_MODE: {
gfx::RectF texture_rect = iter.texture_rect();
@@ -613,15 +617,19 @@ ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const {
iter;
++iter) {
// Mask resource not ready yet.
- if (!*iter ||
- iter->tile_version().mode() !=
- ManagedTileState::TileVersion::RESOURCE_MODE ||
- !iter->tile_version().IsReadyToDraw())
+ TileRasterMode raster_mode;
+ if (!*iter || !iter->IsReadyToDraw(&raster_mode))
return 0;
+
+ if (iter->tile_version(raster_mode).mode() !=
+ ManagedTileState::TileVersion::RESOURCE_MODE)
+ return 0;
+
// Masks only supported if they fit on exactly one tile.
if (iter.geometry_rect() != content_rect)
return 0;
- return iter->tile_version().get_resource_id();
+
+ return iter->tile_version(raster_mode).get_resource_id();
}
return 0;
}
@@ -671,7 +679,7 @@ void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
rect);
iter;
++iter) {
- if (!*iter || !iter->tile_version().IsReadyToDraw())
+ if (!*iter || !iter->IsReadyToDraw(NULL))
continue;
// This iteration is over the visible content rect which is potentially
diff --git a/cc/resources/managed_tile_state.cc b/cc/resources/managed_tile_state.cc
index d137b8d..a319cf7 100644
--- a/cc/resources/managed_tile_state.cc
+++ b/cc/resources/managed_tile_state.cc
@@ -11,7 +11,8 @@
namespace cc {
ManagedTileState::ManagedTileState()
- : picture_pile_analyzed(false),
+ : raster_mode(LOW_QUALITY_RASTER_MODE),
+ picture_pile_analyzed(false),
gpu_memmgr_stats_bin(NEVER_BIN),
resolution(NON_IDEAL_RESOLUTION),
required_for_activation(false),
@@ -58,7 +59,8 @@ ManagedTileState::~ManagedTileState() {
scoped_ptr<base::Value> ManagedTileState::AsValue() const {
scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
- state->SetBoolean("has_resource", tile_version.resource_.get() != 0);
+ state->SetBoolean("has_resource",
+ tile_versions[raster_mode].resource_.get() != 0);
state->Set("bin.0", TileManagerBinAsValue(bin[ACTIVE_TREE]).release());
state->Set("bin.1", TileManagerBinAsValue(bin[PENDING_TREE]).release());
state->Set("gpu_memmgr_stats_bin",
diff --git a/cc/resources/managed_tile_state.h b/cc/resources/managed_tile_state.h
index 2305b26..26322c9 100644
--- a/cc/resources/managed_tile_state.h
+++ b/cc/resources/managed_tile_state.h
@@ -105,6 +105,7 @@ class CC_EXPORT ManagedTileState {
scoped_ptr<ResourcePool::Resource> resource_;
GLenum resource_format_;
bool forced_upload_;
+ RasterWorkerPool::RasterTask raster_task_;
};
@@ -114,10 +115,11 @@ class CC_EXPORT ManagedTileState {
scoped_ptr<base::Value> AsValue() const;
// Persisted state: valid all the time.
- TileVersion tile_version;
+ TileVersion tile_versions[NUM_RASTER_MODES];
+ TileRasterMode raster_mode;
+
bool picture_pile_analyzed;
PicturePileImpl::Analysis picture_pile_analysis;
- RasterWorkerPool::RasterTask raster_task;
// Ephemeral state, valid only during TileManager::ManageTiles.
bool is_in_never_bin_on_both_trees() const {
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc
index 6d3ae60..bc081c9 100644
--- a/cc/resources/picture.cc
+++ b/cc/resources/picture.cc
@@ -80,18 +80,6 @@ bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) {
return false;
}
-class DisableLCDTextFilter : public SkDrawFilter {
- public:
- // SkDrawFilter interface.
- virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) OVERRIDE {
- if (type != SkDrawFilter::kText_Type)
- return true;
-
- paint->setLCDRenderText(false);
- return true;
- }
-};
-
} // namespace
scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) {
@@ -312,24 +300,16 @@ void Picture::Raster(
SkCanvas* canvas,
SkDrawPictureCallback* callback,
gfx::Rect content_rect,
- float contents_scale,
- bool enable_lcd_text) {
+ float contents_scale) {
TRACE_EVENT_BEGIN1("cc", "Picture::Raster",
"data", AsTraceableRasterData(content_rect, contents_scale));
DCHECK(picture_);
- skia::RefPtr<DisableLCDTextFilter> disable_lcd_text_filter;
-
canvas->save();
canvas->clipRect(gfx::RectToSkRect(content_rect));
canvas->scale(contents_scale, contents_scale);
canvas->translate(layer_rect_.x(), layer_rect_.y());
- // Pictures by default have LCD text enabled.
- if (!enable_lcd_text) {
- disable_lcd_text_filter = skia::AdoptRef(new DisableLCDTextFilter);
- canvas->setDrawFilter(disable_lcd_text_filter.get());
- }
picture_->draw(canvas, callback);
SkIRect bounds;
canvas->getClipDeviceBounds(&bounds);
diff --git a/cc/resources/picture.h b/cc/resources/picture.h
index 79c2720..e48a40b 100644
--- a/cc/resources/picture.h
+++ b/cc/resources/picture.h
@@ -74,8 +74,7 @@ class CC_EXPORT Picture
void Raster(SkCanvas* canvas,
SkDrawPictureCallback* callback,
gfx::Rect content_rect,
- float contents_scale,
- bool enable_lcd_text);
+ float contents_scale);
scoped_ptr<base::Value> AsValue() const;
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index 4394e79..90ac60f 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -497,7 +497,10 @@ size_t PictureLayerTiling::GPUMemoryUsageInBytes() const {
size_t amount = 0;
for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
const Tile* tile = it->second.get();
- amount += tile->tile_version().GPUMemoryUsageInBytes();
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ amount += tile->tile_version(
+ static_cast<TileRasterMode>(mode)).GPUMemoryUsageInBytes();
+ }
}
return amount;
}
diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc
index 8a82d93..9ca9a6a 100644
--- a/cc/resources/picture_layer_tiling_set.cc
+++ b/cc/resources/picture_layer_tiling_set.cc
@@ -198,7 +198,7 @@ PictureLayerTilingSet::CoverageIterator::operator++() {
// Loop until we find a valid place to stop.
while (true) {
while (tiling_iter_ &&
- (!*tiling_iter_ || !tiling_iter_->tile_version().IsReadyToDraw())) {
+ (!*tiling_iter_ || !tiling_iter_->IsReadyToDraw(NULL))) {
missing_region_.Union(tiling_iter_.geometry_rect());
++tiling_iter_;
}
diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc
index 46473c8..0f3d9a5 100644
--- a/cc/resources/picture_layer_tiling_set_unittest.cc
+++ b/cc/resources/picture_layer_tiling_set_unittest.cc
@@ -69,14 +69,15 @@ class PictureLayerTilingSetTestWithResources : public testing::Test {
PictureLayerTilingSet set(&client, layer_bounds);
float scale = min_scale;
+ TileRasterMode mode = HIGH_QUALITY_RASTER_MODE;
for (int i = 0; i < num_tilings; ++i, scale += scale_increment) {
PictureLayerTiling* tiling = set.AddTiling(scale);
tiling->CreateAllTilesForTesting();
std::vector<Tile*> tiles = tiling->AllTilesForTesting();
for (size_t i = 0; i < tiles.size(); ++i) {
- EXPECT_FALSE(tiles[i]->tile_version().GetResourceForTesting());
+ EXPECT_FALSE(tiles[i]->tile_version(mode).GetResourceForTesting());
- tiles[i]->tile_version().SetResourceForTesting(
+ tiles[i]->tile_version(mode).SetResourceForTesting(
make_scoped_ptr(new ResourcePool::Resource(
resource_provider.get(),
gfx::Size(1, 1),
diff --git a/cc/resources/picture_pile_impl.cc b/cc/resources/picture_pile_impl.cc
index 46aa79f..496ca09 100644
--- a/cc/resources/picture_pile_impl.cc
+++ b/cc/resources/picture_pile_impl.cc
@@ -208,8 +208,7 @@ void PicturePileImpl::RasterCommon(
if (raster_stats)
start_time = base::TimeTicks::HighResNow();
- (*i)->Raster(
- canvas, callback, content_clip, contents_scale, enable_lcd_text_);
+ (*i)->Raster(canvas, callback, content_clip, contents_scale);
if (raster_stats) {
base::TimeDelta duration = base::TimeTicks::HighResNow() - start_time;
diff --git a/cc/resources/picture_pile_impl.h b/cc/resources/picture_pile_impl.h
index 234a390..c00875e 100644
--- a/cc/resources/picture_pile_impl.h
+++ b/cc/resources/picture_pile_impl.h
@@ -111,6 +111,10 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase {
void DidBeginTracing();
+ bool can_use_lcd_text() const {
+ return enable_lcd_text_;
+ }
+
protected:
friend class PicturePile;
friend class PixelRefIterator;
diff --git a/cc/resources/tile.h b/cc/resources/tile.h
index 2aa4c65..6f9d987 100644
--- a/cc/resources/tile.h
+++ b/cc/resources/tile.h
@@ -10,6 +10,7 @@
#include "base/memory/scoped_vector.h"
#include "cc/resources/managed_tile_state.h"
#include "cc/resources/picture_pile_impl.h"
+#include "cc/resources/tile_manager.h"
#include "cc/resources/tile_priority.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "ui/gfx/rect.h"
@@ -18,7 +19,6 @@
namespace cc {
class Tile;
-class TileManager;
class CC_EXPORT Tile : public base::RefCounted<Tile> {
public:
@@ -35,6 +35,10 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> {
return picture_pile_.get();
}
+ const PicturePileImpl* picture_pile() const {
+ return picture_pile_.get();
+ }
+
const TilePriority& priority(WhichTree tree) const {
return priority_[tree];
}
@@ -58,11 +62,23 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> {
scoped_ptr<base::Value> AsValue() const;
- const ManagedTileState::TileVersion& tile_version() const {
- return managed_state_.tile_version;
+ bool IsReadyToDraw(TileRasterMode* ready_mode) const {
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ if (managed_state_.tile_versions[mode].IsReadyToDraw()) {
+ if (ready_mode)
+ *ready_mode = static_cast<TileRasterMode>(mode);
+ return true;
+ }
+ }
+ return false;
}
- ManagedTileState::TileVersion& tile_version() {
- return managed_state_.tile_version;
+
+ const ManagedTileState::TileVersion& tile_version(TileRasterMode mode) const {
+ return managed_state_.tile_versions[mode];
+ }
+
+ ManagedTileState::TileVersion& tile_version(TileRasterMode mode) {
+ return managed_state_.tile_versions[mode];
}
gfx::Rect opaque_rect() const { return opaque_rect_; }
@@ -84,10 +100,15 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> {
// For test only methods.
bool HasRasterTaskForTesting() const {
- return !managed_state().raster_task.is_null();
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ if (!managed_state().tile_versions[mode].raster_task_.is_null())
+ return true;
+ }
+ return false;
}
void ResetRasterTaskForTesting() {
- managed_state().raster_task.Reset();
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode)
+ managed_state().tile_versions[mode].raster_task_.Reset();
}
private:
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index 4060146..1cc3373 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -16,6 +16,7 @@
#include "cc/resources/image_raster_worker_pool.h"
#include "cc/resources/pixel_buffer_raster_worker_pool.h"
#include "cc/resources/tile.h"
+#include "skia/ext/paint_simplifier.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/rect_conversions.h"
@@ -23,6 +24,18 @@ namespace cc {
namespace {
+class DisableLCDTextFilter : public SkDrawFilter {
+ public:
+ // SkDrawFilter interface.
+ virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) OVERRIDE {
+ if (type != SkDrawFilter::kText_Type)
+ return true;
+
+ paint->setLCDRenderText(false);
+ return true;
+ }
+};
+
// Determine bin based on three categories of tiles: things we need now,
// things we need soon, and eventually.
inline TileManagerBin BinFromTilePriority(const TilePriority& prio) {
@@ -306,15 +319,23 @@ void TileManager::CheckForCompletedTileUploads() {
it != tiles_that_need_to_be_initialized_for_activation_.end();
++it) {
Tile* tile = *it;
- if (!tile->managed_state().raster_task.is_null() &&
- !tile->tile_version().forced_upload_) {
- if (!raster_worker_pool_->ForceUploadToComplete(
- tile->managed_state().raster_task))
- continue;
+ ManagedTileState& mts = tile->managed_state();
- // Setting |forced_upload_| to true makes this tile ready to draw.
- tile->tile_version().forced_upload_ = true;
- initialized_tiles.insert(tile);
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ ManagedTileState::TileVersion& pending_version =
+ mts.tile_versions[mode];
+ if (!pending_version.raster_task_.is_null() &&
+ !pending_version.forced_upload_) {
+ if (!raster_worker_pool_->ForceUploadToComplete(
+ pending_version.raster_task_)) {
+ continue;
+ }
+ // Setting |forced_upload_| to true makes this tile version
+ // ready to draw.
+ pending_version.forced_upload_ = true;
+ initialized_tiles.insert(tile);
+ break;
+ }
}
}
@@ -323,7 +344,7 @@ void TileManager::CheckForCompletedTileUploads() {
++it) {
Tile* tile = *it;
DidFinishTileInitialization(tile);
- DCHECK(tile->tile_version().IsReadyToDraw());
+ DCHECK(tile->IsReadyToDraw(NULL));
}
}
@@ -338,10 +359,13 @@ void TileManager::GetMemoryStats(
it != tiles_.end();
++it) {
const Tile* tile = *it;
- if (!tile->tile_version().requires_resource())
+ const ManagedTileState& mts = tile->managed_state();
+
+ TileRasterMode mode;
+ if (tile->IsReadyToDraw(&mode) &&
+ !mts.tile_versions[mode].requires_resource())
continue;
- const ManagedTileState& mts = tile->managed_state();
size_t tile_bytes = tile->bytes_consumed_if_allocated();
if (mts.gpu_memmgr_stats_bin == NOW_BIN)
*memory_required_bytes += tile_bytes;
@@ -393,6 +417,22 @@ void TileManager::AddRequiredTileForActivation(Tile* tile) {
tiles_that_need_to_be_initialized_for_activation_.insert(tile);
}
+TileRasterMode TileManager::DetermineRasterMode(const Tile* tile) const {
+ DCHECK(tile);
+ DCHECK(tile->picture_pile());
+
+ TileRasterMode raster_mode;
+
+ if (tile->managed_state().resolution == LOW_RESOLUTION)
+ raster_mode = LOW_QUALITY_RASTER_MODE;
+ else if (!tile->picture_pile()->can_use_lcd_text())
+ raster_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE;
+ else
+ raster_mode = HIGH_QUALITY_RASTER_MODE;
+
+ return raster_mode;
+}
+
void TileManager::AssignGpuMemoryToTiles() {
TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
@@ -406,8 +446,11 @@ void TileManager::AssignGpuMemoryToTiles() {
it != tiles_.end();
++it) {
const Tile* tile = *it;
- if (tile->tile_version().resource_)
- bytes_releasable += tile->bytes_consumed_if_allocated();
+ const ManagedTileState& mts = tile->managed_state();
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ if (mts.tile_versions[mode].resource_)
+ bytes_releasable += tile->bytes_consumed_if_allocated();
+ }
}
// Cast to prevent overflow.
@@ -429,7 +472,13 @@ void TileManager::AssignGpuMemoryToTiles() {
++it) {
Tile* tile = *it;
ManagedTileState& mts = tile->managed_state();
- ManagedTileState::TileVersion& tile_version = tile->tile_version();
+
+ // Pick the better version out of the one we already set,
+ // and the one that is required.
+ mts.raster_mode = std::min(mts.raster_mode, DetermineRasterMode(tile));
+
+ ManagedTileState::TileVersion& tile_version =
+ mts.tile_versions[mts.raster_mode];
// If this tile doesn't need a resource, then nothing to do.
if (!tile_version.requires_resource())
@@ -444,18 +493,19 @@ void TileManager::AssignGpuMemoryToTiles() {
size_t tile_bytes = 0;
// It costs to maintain a resource.
- if (tile_version.resource_)
- tile_bytes += tile->bytes_consumed_if_allocated();
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ if (mts.tile_versions[mode].resource_)
+ tile_bytes += tile->bytes_consumed_if_allocated();
+ }
- // It will cost to allocate a resource.
- // Note that this is separate from the above condition,
- // so that it's clear why we're adding memory.
- if (!tile_version.resource_ && mts.raster_task.is_null())
+ // If we don't have the required version, and it's not in flight
+ // then we'll have to pay to create a new task.
+ if (!tile_version.resource_ && tile_version.raster_task_.is_null())
tile_bytes += tile->bytes_consumed_if_allocated();
// Tile is OOM.
if (tile_bytes > bytes_left) {
- tile->tile_version().set_rasterize_on_demand();
+ mts.tile_versions[mts.raster_mode].set_rasterize_on_demand();
if (mts.tree_bin[PENDING_TREE] == NOW_BIN) {
tiles_requiring_memory_but_oomed.push_back(tile);
bytes_oom_in_now_bin_on_pending_tree += tile_bytes;
@@ -480,8 +530,10 @@ void TileManager::AssignGpuMemoryToTiles() {
if (!tile_version.resource_)
tiles_that_need_to_be_rasterized_.push_back(tile);
- if (!tile_version.resource_ && tile->required_for_activation())
+ if (!tile->IsReadyToDraw(NULL) &&
+ tile->required_for_activation()) {
AddRequiredTileForActivation(tile);
+ }
}
// In OOM situation, we iterate tiles_, remove the memory for active tree
@@ -491,33 +543,44 @@ void TileManager::AssignGpuMemoryToTiles() {
for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
Tile* tile = *it;
ManagedTileState& mts = tile->managed_state();
- ManagedTileState::TileVersion& tile_version = tile->tile_version();
- if (tile_version.resource_ &&
- mts.tree_bin[PENDING_TREE] == NEVER_BIN &&
+ if (mts.tree_bin[PENDING_TREE] == NEVER_BIN &&
mts.tree_bin[ACTIVE_TREE] != NOW_BIN) {
- DCHECK(!tile->required_for_activation());
- FreeResourcesForTile(tile);
- tile_version.set_rasterize_on_demand();
- bytes_freed += tile->bytes_consumed_if_allocated();
- TileVector::iterator it = std::find(
- tiles_that_need_to_be_rasterized_.begin(),
- tiles_that_need_to_be_rasterized_.end(),
- tile);
- if (it != tiles_that_need_to_be_rasterized_.end())
- tiles_that_need_to_be_rasterized_.erase(it);
- if (bytes_oom_in_now_bin_on_pending_tree <= bytes_freed)
- break;
+ size_t bytes_that_can_be_freed = 0;
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ ManagedTileState::TileVersion& tile_version =
+ mts.tile_versions[mode];
+ if (tile_version.resource_) {
+ DCHECK(!tile->required_for_activation());
+ bytes_that_can_be_freed += tile->bytes_consumed_if_allocated();
+ }
+ }
+
+ if (bytes_that_can_be_freed > 0) {
+ FreeResourcesForTile(tile);
+ bytes_freed += bytes_that_can_be_freed;
+ mts.tile_versions[mts.raster_mode].set_rasterize_on_demand();
+ TileVector::iterator it = std::find(
+ tiles_that_need_to_be_rasterized_.begin(),
+ tiles_that_need_to_be_rasterized_.end(),
+ tile);
+ if (it != tiles_that_need_to_be_rasterized_.end())
+ tiles_that_need_to_be_rasterized_.erase(it);
+ }
}
+
+ if (bytes_oom_in_now_bin_on_pending_tree <= bytes_freed)
+ break;
}
for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin();
it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0;
++it) {
Tile* tile = *it;
+ ManagedTileState& mts = tile->managed_state();
size_t bytes_needed = tile->bytes_consumed_if_allocated();
if (bytes_needed > bytes_freed)
continue;
- tile->tile_version().set_use_resource();
+ mts.tile_versions[mts.raster_mode].set_use_resource();
bytes_freed -= bytes_needed;
tiles_that_need_to_be_rasterized_.push_back(tile);
if (tile->required_for_activation())
@@ -542,12 +605,28 @@ void TileManager::AssignGpuMemoryToTiles() {
bytes_that_exceeded_memory_budget_in_now_bin;
}
-void TileManager::FreeResourcesForTile(Tile* tile) {
- tile->tile_version().resource_id_ = 0;
- tile->tile_version().forced_upload_ = false;
- if (tile->tile_version().resource_) {
+void TileManager::FreeResourceForTile(Tile* tile, TileRasterMode mode) {
+ ManagedTileState& mts = tile->managed_state();
+ if (mts.tile_versions[mode].resource_) {
resource_pool_->ReleaseResource(
- tile->tile_version().resource_.Pass());
+ mts.tile_versions[mode].resource_.Pass());
+ }
+ mts.tile_versions[mode].resource_id_ = 0;
+ mts.tile_versions[mode].forced_upload_ = false;
+}
+
+void TileManager::FreeResourcesForTile(Tile* tile) {
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ FreeResourceForTile(tile, static_cast<TileRasterMode>(mode));
+ }
+}
+
+void TileManager::FreeUnusedResourcesForTile(Tile* tile) {
+ TileRasterMode used_mode;
+ bool version_is_used = tile->IsReadyToDraw(&used_mode);
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ if (!version_is_used || mode != used_mode)
+ FreeResourceForTile(tile, static_cast<TileRasterMode>(mode));
}
}
@@ -563,16 +642,16 @@ void TileManager::ScheduleTasks() {
++it) {
Tile* tile = *it;
ManagedTileState& mts = tile->managed_state();
+ ManagedTileState::TileVersion& tile_version =
+ mts.tile_versions[mts.raster_mode];
- DCHECK(tile->tile_version().requires_resource());
- DCHECK(!tile->tile_version().resource_);
+ DCHECK(tile_version.requires_resource());
+ DCHECK(!tile_version.resource_);
- // Create raster task for this tile if necessary.
- if (mts.raster_task.is_null())
- mts.raster_task = CreateRasterTask(tile, &decoded_images);
+ if (tile_version.raster_task_.is_null())
+ tile_version.raster_task_ = CreateRasterTask(tile, &decoded_images);
- // Finally append raster task.
- tasks.Append(mts.raster_task);
+ tasks.Append(tile_version.raster_task_);
}
// Schedule running of |tasks|. This replaces any previously
@@ -614,6 +693,7 @@ TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata(
metadata.layer_id = tile.layer_id();
metadata.tile_id = &tile;
metadata.source_frame_number = tile.source_frame_number();
+ metadata.raster_mode = mts.raster_mode;
return metadata;
}
@@ -622,15 +702,17 @@ RasterWorkerPool::RasterTask TileManager::CreateRasterTask(
PixelRefSet* decoded_images) {
TRACE_EVENT0("cc", "TileManager::CreateRasterTask");
+ ManagedTileState& mts = tile->managed_state();
+
scoped_ptr<ResourcePool::Resource> resource =
resource_pool_->AcquireResource(
tile->tile_size_.size(),
- tile->tile_version().resource_format_);
+ mts.tile_versions[mts.raster_mode].resource_format_);
const Resource* const_resource = resource.get();
- DCHECK(!tile->tile_version().resource_id_);
- DCHECK(!tile->tile_version().forced_upload_);
- tile->tile_version().resource_id_ = resource->id();
+ DCHECK(!mts.tile_versions[mts.raster_mode].resource_id_);
+ DCHECK(!mts.tile_versions[mts.raster_mode].forced_upload_);
+ mts.tile_versions[mts.raster_mode].resource_id_ = resource->id();
PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis;
@@ -667,6 +749,7 @@ RasterWorkerPool::RasterTask TileManager::CreateRasterTask(
pending_decode_tasks_[id] = decode_task;
}
+ RasterTaskMetadata metadata = GetRasterTaskMetadata(*tile);
return RasterWorkerPool::RasterTask(
tile->picture_pile(),
const_resource,
@@ -676,19 +759,20 @@ RasterWorkerPool::RasterTask TileManager::CreateRasterTask(
tile->content_rect(),
tile->contents_scale(),
use_color_estimator_,
- GetRasterTaskMetadata(*tile),
+ metadata,
rendering_stats_instrumentation_),
base::Bind(&TileManager::RunRasterTask,
analysis,
tile->content_rect(),
tile->contents_scale(),
- GetRasterTaskMetadata(*tile),
+ metadata,
rendering_stats_instrumentation_)),
base::Bind(&TileManager::OnRasterTaskCompleted,
base::Unretained(this),
make_scoped_refptr(tile),
base::Passed(&resource),
- base::Owned(analysis)),
+ base::Owned(analysis),
+ metadata.raster_mode),
&decode_tasks);
}
@@ -696,13 +780,16 @@ void TileManager::OnRasterTaskCompleted(
scoped_refptr<Tile> tile,
scoped_ptr<ResourcePool::Resource> resource,
PicturePileImpl::Analysis* analysis,
+ TileRasterMode raster_mode,
bool was_canceled) {
TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted",
"was_canceled", was_canceled);
ManagedTileState& mts = tile->managed_state();
- DCHECK(!mts.raster_task.is_null());
- mts.raster_task.Reset();
+ ManagedTileState::TileVersion& tile_version =
+ mts.tile_versions[raster_mode];
+ DCHECK(!tile_version.raster_task_.is_null());
+ tile_version.raster_task_.Reset();
if (was_canceled) {
resource_pool_->ReleaseResource(resource.Pass());
@@ -713,13 +800,15 @@ void TileManager::OnRasterTaskCompleted(
mts.picture_pile_analyzed = true;
if (analysis->is_solid_color) {
- tile->tile_version().set_solid_color(analysis->solid_color);
+ tile_version.set_solid_color(analysis->solid_color);
resource_pool_->ReleaseResource(resource.Pass());
} else {
- tile->tile_version().resource_ = resource.Pass();
- tile->tile_version().forced_upload_ = false;
+ tile_version.resource_ = resource.Pass();
+ tile_version.forced_upload_ = false;
}
+ FreeUnusedResourcesForTile(tile.get());
+
DidFinishTileInitialization(tile.get());
}
@@ -803,6 +892,7 @@ scoped_ptr<base::Value> TileManager::RasterTaskMetadata::AsValue() const {
is_tile_in_pending_tree_now_bin);
res->Set("resolution", TileResolutionAsValue(tile_resolution).release());
res->SetInteger("source_frame_number", source_frame_number);
+ res->SetInteger("raster_mode", raster_mode);
return res.PassAs<base::Value>();
}
@@ -830,6 +920,23 @@ bool TileManager::RunRasterTask(
SkCanvas canvas(device);
+ skia::RefPtr<SkDrawFilter> draw_filter;
+ switch (metadata.raster_mode) {
+ case LOW_QUALITY_RASTER_MODE:
+ draw_filter = skia::AdoptRef(new skia::PaintSimplifier);
+ break;
+ case HIGH_QUALITY_NO_LCD_RASTER_MODE:
+ draw_filter = skia::AdoptRef(new DisableLCDTextFilter);
+ break;
+ case HIGH_QUALITY_RASTER_MODE:
+ break;
+ case NUM_RASTER_MODES:
+ default:
+ NOTREACHED();
+ }
+
+ canvas.setDrawFilter(draw_filter.get());
+
if (stats_instrumentation->record_rendering_stats()) {
PicturePileImpl::RasterStats raster_stats;
picture_pile->RasterToBitmap(&canvas, rect, contents_scale, &raster_stats);
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h
index d22b78e..8623820 100644
--- a/cc/resources/tile_manager.h
+++ b/cc/resources/tile_manager.h
@@ -24,6 +24,17 @@ class ResourceProvider;
class Tile;
class TileVersion;
+// Low quality implies no lcd test;
+// high quality implies lcd text.
+// Note that the order of these matters, from "better" to "worse" in terms of
+// quality.
+enum TileRasterMode {
+ HIGH_QUALITY_RASTER_MODE = 0,
+ HIGH_QUALITY_NO_LCD_RASTER_MODE = 1,
+ LOW_QUALITY_RASTER_MODE = 2,
+ NUM_RASTER_MODES = 3
+};
+
class CC_EXPORT TileManagerClient {
public:
virtual void ScheduleManageTiles() = 0;
@@ -124,12 +135,16 @@ class CC_EXPORT TileManager {
int layer_id;
const void* tile_id;
int source_frame_number;
+ TileRasterMode raster_mode;
};
void AssignBinsToTiles();
void SortTiles();
+ TileRasterMode DetermineRasterMode(const Tile* tile) const;
void AssignGpuMemoryToTiles();
+ void FreeResourceForTile(Tile* tile, TileRasterMode mode);
void FreeResourcesForTile(Tile* tile);
+ void FreeUnusedResourcesForTile(Tile* tile);
void ScheduleManageTiles() {
if (manage_tiles_pending_)
return;
@@ -149,6 +164,7 @@ class CC_EXPORT TileManager {
scoped_refptr<Tile> tile,
scoped_ptr<ResourcePool::Resource> resource,
PicturePileImpl::Analysis* analysis,
+ TileRasterMode raster_mode,
bool was_canceled);
void DidFinishTileInitialization(Tile* tile);
void DidTileTreeBinChange(Tile* tile,
diff --git a/cc/test/skia_common.cc b/cc/test/skia_common.cc
index e726716..c81ae8d 100644
--- a/cc/test/skia_common.cc
+++ b/cc/test/skia_common.cc
@@ -64,7 +64,7 @@ void DrawPicture(unsigned char* buffer,
SkDevice device(bitmap);
SkCanvas canvas(&device);
canvas.clipRect(gfx::RectToSkRect(layer_rect));
- picture->Raster(&canvas, NULL, layer_rect, 1.0f, false);
+ picture->Raster(&canvas, NULL, layer_rect, 1.0f);
}
void CreateBitmap(gfx::Size size, const char* uri, SkBitmap* bitmap) {
diff --git a/content/renderer/skia_benchmarking_extension.cc b/content/renderer/skia_benchmarking_extension.cc
index c869576..7d9b74f 100644
--- a/content/renderer/skia_benchmarking_extension.cc
+++ b/content/renderer/skia_benchmarking_extension.cc
@@ -116,7 +116,7 @@ class SkiaBenchmarkingWrapper : public v8::Extension {
SkCanvas canvas(bitmap);
canvas.translate(SkFloatToScalar(-clip.x()),
SkFloatToScalar(-clip.y()));
- picture->Raster(&canvas, NULL, snapped_clip, scale, true);
+ picture->Raster(&canvas, NULL, snapped_clip, scale);
WebKit::WebArrayBuffer buffer =
WebKit::WebArrayBuffer::create(bitmap.getSize(), 1);