diff options
author | vmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-07 08:11:50 +0000 |
---|---|---|
committer | vmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-07 08:11:50 +0000 |
commit | 046a9712362dcf891a2634fee98bd9cf20bbabfb (patch) | |
tree | ea6c64a37c5f5fd1ae62224a8e68ee4242b35681 | |
parent | f13c66f37537585f2a3a6949ad4f72046573d047 (diff) | |
download | chromium_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.cc | 28 | ||||
-rw-r--r-- | cc/resources/managed_tile_state.cc | 6 | ||||
-rw-r--r-- | cc/resources/managed_tile_state.h | 6 | ||||
-rw-r--r-- | cc/resources/picture.cc | 22 | ||||
-rw-r--r-- | cc/resources/picture.h | 3 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling.cc | 5 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_set.cc | 2 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_set_unittest.cc | 5 | ||||
-rw-r--r-- | cc/resources/picture_pile_impl.cc | 3 | ||||
-rw-r--r-- | cc/resources/picture_pile_impl.h | 4 | ||||
-rw-r--r-- | cc/resources/tile.h | 35 | ||||
-rw-r--r-- | cc/resources/tile_manager.cc | 231 | ||||
-rw-r--r-- | cc/resources/tile_manager.h | 16 | ||||
-rw-r--r-- | cc/test/skia_common.cc | 2 | ||||
-rw-r--r-- | content/renderer/skia_benchmarking_extension.cc | 2 |
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); |