diff options
22 files changed, 290 insertions, 366 deletions
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc index 179a2cf..2c3d71b 100644 --- a/cc/layers/picture_layer.cc +++ b/cc/layers/picture_layer.cc @@ -46,8 +46,7 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) { // See PictureLayerImpl::PushPropertiesTo for more details. layer_impl->invalidation_.Clear(); layer_impl->invalidation_.Swap(&pile_invalidation_); - layer_impl->pile_ = PicturePileImpl::CreateFromOther( - pile_.get(), layer_impl->is_using_lcd_text_); + layer_impl->pile_ = PicturePileImpl::CreateFromOther(pile_.get()); layer_impl->SyncFromActiveLayer(); } diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 73131ae..816a79b 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -32,7 +32,7 @@ namespace cc { PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id) : LayerImpl(tree_impl, id), twin_layer_(NULL), - pile_(PicturePileImpl::Create(true)), + pile_(PicturePileImpl::Create()), last_content_scale_(0), is_mask_(false), ideal_page_scale_(0.f), @@ -86,14 +86,15 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { layer_impl->SetIsMask(is_mask_); layer_impl->TransferTilingSet(tilings_.Pass()); layer_impl->pile_ = pile_; - pile_ = PicturePileImpl::Create(is_using_lcd_text_); + pile_ = PicturePileImpl::Create(); layer_impl->raster_page_scale_ = raster_page_scale_; layer_impl->raster_device_scale_ = raster_device_scale_; layer_impl->raster_source_scale_ = raster_source_scale_; layer_impl->raster_contents_scale_ = raster_contents_scale_; layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_; - layer_impl->is_using_lcd_text_ = is_using_lcd_text_; + + layer_impl->UpdateLCDTextStatus(is_using_lcd_text_); // As an optimization, don't make a copy of this potentially complex region, // and swap it directly from the pending to the active layer. In general, any @@ -321,7 +322,7 @@ void PictureLayerImpl::UpdateTilePriorities() { // At this point, tile priorities are going to be modified. layer_tree_impl()->WillModifyTilePriorities(); - UpdateLCDTextStatus(); + UpdateLCDTextStatus(can_use_lcd_text()); gfx::Transform current_screen_space_transform = screen_space_transform(); @@ -453,7 +454,8 @@ scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling, contents_opaque() ? content_rect : gfx::Rect(), tiling->contents_scale(), id(), - layer_tree_impl()->source_frame_number())); + layer_tree_impl()->source_frame_number(), + is_using_lcd_text_)); } void PictureLayerImpl::UpdatePile(Tile* tile) { @@ -536,8 +538,7 @@ void PictureLayerImpl::SyncFromActiveLayer() { } void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) { - // UpdateLCDTextStatus() depends on LCD text status always being synced. - is_using_lcd_text_ = other->is_using_lcd_text_; + UpdateLCDTextStatus(other->is_using_lcd_text_); if (!DrawsContent()) { ResetRasterScale(); @@ -959,40 +960,16 @@ float PictureLayerImpl::MinimumContentsScale() const { return std::max(1.f / min_dimension, setting_min); } -void PictureLayerImpl::UpdateLCDTextStatus() { +void PictureLayerImpl::UpdateLCDTextStatus(bool new_status) { // Once this layer is not using lcd text, don't switch back. if (!is_using_lcd_text_) return; - if (is_using_lcd_text_ == can_use_lcd_text()) - return; - - is_using_lcd_text_ = can_use_lcd_text(); - - // As a trade-off between jank and drawing with the incorrect resources, - // don't ever update the active tree's resources in place. Instead, - // update lcd text on the pending tree. If this is the active tree and - // there is no pending twin, then call set needs commit to create one. - if (layer_tree_impl()->IsActiveTree() && !twin_layer_) { - // TODO(enne): Handle this by updating these resources in-place instead. - layer_tree_impl()->SetNeedsCommit(); - return; - } - - // The heuristic of never switching back to lcd text enabled implies that - // this property needs to be synchronized to the pending tree right now. - PictureLayerImpl* pending_layer = - layer_tree_impl()->IsActiveTree() ? twin_layer_ : this; - if (layer_tree_impl()->IsActiveTree() && - pending_layer->is_using_lcd_text_ == is_using_lcd_text_) + if (is_using_lcd_text_ == new_status) return; - // Further tiles created due to new tilings should be considered invalidated. - pending_layer->invalidation_.Union(gfx::Rect(bounds())); - pending_layer->is_using_lcd_text_ = is_using_lcd_text_; - pending_layer->pile_ = PicturePileImpl::CreateFromOther( - pending_layer->pile_.get(), is_using_lcd_text_); - pending_layer->tilings_->DestroyAndRecreateTilesWithText(); + is_using_lcd_text_ = new_status; + tilings_->SetCanUseLCDText(is_using_lcd_text_); } void PictureLayerImpl::ResetRasterScale() { diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index cc56c01..13e64e1 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h @@ -90,7 +90,7 @@ class CC_EXPORT PictureLayerImpl void CleanUpTilingsOnActiveLayer( std::vector<PictureLayerTiling*> used_tilings); float MinimumContentsScale() const; - void UpdateLCDTextStatus(); + void UpdateLCDTextStatus(bool new_status); void ResetRasterScale(); void MarkVisibleResourcesAsRequired() const; diff --git a/cc/quads/draw_quad_unittest.cc b/cc/quads/draw_quad_unittest.cc index 671cf00..333af3f 100644 --- a/cc/quads/draw_quad_unittest.cc +++ b/cc/quads/draw_quad_unittest.cc @@ -663,7 +663,7 @@ TEST(DrawQuadTest, CopyPictureDrawQuad) { gfx::Rect content_rect(30, 40, 20, 30); float contents_scale = 3.141592f; bool can_draw_direct_to_backbuffer = true; - scoped_refptr<PicturePileImpl> picture_pile = PicturePileImpl::Create(false); + scoped_refptr<PicturePileImpl> picture_pile = PicturePileImpl::Create(); CREATE_SHARED_STATE(); CREATE_QUAD_8_NEW(PictureDrawQuad, @@ -890,7 +890,7 @@ TEST_F(DrawQuadIteratorTest, DISABLED_PictureDrawQuad) { gfx::Rect content_rect(30, 40, 20, 30); float contents_scale = 3.141592f; bool can_draw_direct_to_backbuffer = true; - scoped_refptr<PicturePileImpl> picture_pile = PicturePileImpl::Create(false); + scoped_refptr<PicturePileImpl> picture_pile = PicturePileImpl::Create(); CREATE_SHARED_STATE(); CREATE_QUAD_8_NEW(PictureDrawQuad, diff --git a/cc/resources/managed_tile_state.h b/cc/resources/managed_tile_state.h index 4effe1d2..c76838d 100644 --- a/cc/resources/managed_tile_state.h +++ b/cc/resources/managed_tile_state.h @@ -64,10 +64,15 @@ class CC_EXPORT ManagedTileState { void SetResourceForTesting(scoped_ptr<ResourcePool::Resource> resource) { resource_ = resource.Pass(); } - const ResourcePool::Resource* GetResourceForTesting() const { return resource_.get(); } + void SetSolidColorForTesting(SkColor color) { + set_solid_color(color); + } + void SetHasTextForTesting(bool has_text) { + has_text_ = has_text; + } private: friend class TileManager; diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc index 0dc42fa..40ac4d5 100644 --- a/cc/resources/picture_layer_tiling.cc +++ b/cc/resources/picture_layer_tiling.cc @@ -16,13 +16,6 @@ namespace cc { -bool PictureLayerTilingClient::TileMayHaveLCDText(Tile* tile) { - RasterMode raster_mode = HIGH_QUALITY_RASTER_MODE; - if (!tile->IsReadyToDraw(&raster_mode)) - return true; - return tile->has_text(raster_mode); -} - scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( float contents_scale, gfx::Size layer_bounds, @@ -114,18 +107,9 @@ Region PictureLayerTiling::OpaqueRegionInContentRect( return opaque_region; } -void PictureLayerTiling::DestroyAndRecreateTilesWithText() { - std::vector<TileMapKey> new_tiles; - for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { - if (client_->TileMayHaveLCDText(it->second.get())) - new_tiles.push_back(it->first); - } - - const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); - for (size_t i = 0; i < new_tiles.size(); ++i) { - tiles_.erase(new_tiles[i]); - CreateTile(new_tiles[i].first, new_tiles[i].second, twin_tiling); - } +void PictureLayerTiling::SetCanUseLCDText(bool can_use_lcd_text) { + for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) + it->second->set_can_use_lcd_text(can_use_lcd_text); } PictureLayerTiling::CoverageIterator::CoverageIterator() diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h index dad6134..66ef942 100644 --- a/cc/resources/picture_layer_tiling.h +++ b/cc/resources/picture_layer_tiling.h @@ -36,9 +36,6 @@ class CC_EXPORT PictureLayerTilingClient { virtual const PictureLayerTiling* GetTwinTiling( const PictureLayerTiling* tiling) = 0; - // This is on the client so tests can override behaviour. - virtual bool TileMayHaveLCDText(Tile* tile); - protected: virtual ~PictureLayerTilingClient() {} }; @@ -53,7 +50,7 @@ class CC_EXPORT PictureLayerTiling { gfx::Size layer_bounds, PictureLayerTilingClient* client); gfx::Size layer_bounds() const { return layer_bounds_; } - void DestroyAndRecreateTilesWithText(); + void SetCanUseLCDText(bool can_use_lcd_text); void SetClient(PictureLayerTilingClient* client); void set_resolution(TileResolution resolution) { resolution_ = resolution; } diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc index 9ca9a6a..06095e7 100644 --- a/cc/resources/picture_layer_tiling_set.cc +++ b/cc/resources/picture_layer_tiling_set.cc @@ -58,9 +58,9 @@ void PictureLayerTilingSet::AddTilingsToMatchScales( tilings_.sort(LargestToSmallestScaleFunctor()); } -void PictureLayerTilingSet::DestroyAndRecreateTilesWithText() { +void PictureLayerTilingSet::SetCanUseLCDText(bool can_use_lcd_text) { for (size_t i = 0; i < tilings_.size(); ++i) - tilings_[i]->DestroyAndRecreateTilesWithText(); + tilings_[i]->SetCanUseLCDText(can_use_lcd_text); } PictureLayerTiling* PictureLayerTilingSet::AddTiling(float contents_scale) { diff --git a/cc/resources/picture_layer_tiling_set.h b/cc/resources/picture_layer_tiling_set.h index 3a7b251..f8264c4 100644 --- a/cc/resources/picture_layer_tiling_set.h +++ b/cc/resources/picture_layer_tiling_set.h @@ -26,7 +26,7 @@ class CC_EXPORT PictureLayerTilingSet { gfx::Size layer_bounds() const { return layer_bounds_; } - void DestroyAndRecreateTilesWithText(); + void SetCanUseLCDText(bool can_use_lcd_text); PictureLayerTiling* AddTiling(float contents_scale); size_t num_tilings() const { return tilings_.size(); } diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc index 7d92d83..1cab8c6 100644 --- a/cc/resources/picture_layer_tiling_set_unittest.cc +++ b/cc/resources/picture_layer_tiling_set_unittest.cc @@ -69,7 +69,7 @@ class PictureLayerTilingSetTestWithResources : public testing::Test { PictureLayerTilingSet set(&client, layer_bounds); float scale = min_scale; - RasterMode mode = HIGH_QUALITY_RASTER_MODE; + RasterMode mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; for (int i = 0; i < num_tilings; ++i, scale += scale_increment) { PictureLayerTiling* tiling = set.AddTiling(scale); tiling->CreateAllTilesForTesting(); diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc index e708251..7225a77 100644 --- a/cc/resources/picture_layer_tiling_unittest.cc +++ b/cc/resources/picture_layer_tiling_unittest.cc @@ -138,6 +138,7 @@ class PictureLayerTilingIteratorTest : public testing::Test { FakePictureLayerTilingClient client_; scoped_ptr<TestablePictureLayerTiling> tiling_; + private: DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingIteratorTest); }; @@ -712,174 +713,5 @@ TEST_F(PictureLayerTilingIteratorTest, AddTilingsToMatchScale) { base::Bind(&TileExists, true)); } -TEST_F(PictureLayerTilingIteratorTest, LCDText) { - gfx::Size layer_bounds(1099, 801); - gfx::Size tile_size(100, 100); - - Initialize(tile_size, 1.f, layer_bounds); - - - tiling_->UpdateTilePriorities( - PENDING_TREE, - layer_bounds, // device viewport - gfx::Rect(layer_bounds), // viewport in layer space - gfx::Rect(layer_bounds), // visible content rect - layer_bounds, // last layer bounds - layer_bounds, // current layer bounds - 1.f, // last contents scale - 1.f, // current contents scale - gfx::Transform(), // last screen transform - gfx::Transform(), // current screen transform - 1.0, // current frame time - 10000); // max tiles in tile manager - - VerifyTiles(tiling_.get(), - 1.f, - gfx::Rect(layer_bounds), - base::Bind(&TileExists, true)); - - // Mark tiles in this rect as having text. - gfx::Rect text_rect(350, 350, 400, 400); - client_.set_text_rect(text_rect); - - // Prevent new tiles from being created. - client_.set_allow_create_tile(false); - - client_.set_invalidation(gfx::Rect(layer_bounds)); - tiling_->DestroyAndRecreateTilesWithText(); - - // Tiles touching the text_rect should be gone. - VerifyTiles(tiling_.get(), - 1.f, - gfx::Rect(layer_bounds), - base::Bind(&TilesIntersectingRectExist, text_rect, false)); -} - -TEST_F(PictureLayerTilingIteratorTest, LCDText_CanRecreate) { - gfx::Size layer_bounds(1099, 801); - gfx::Size tile_size(100, 100); - - Initialize(tile_size, 1.f, layer_bounds); - - - tiling_->UpdateTilePriorities( - PENDING_TREE, - layer_bounds, // device viewport - gfx::Rect(layer_bounds), // viewport in layer space - gfx::Rect(layer_bounds), // visible content rect - layer_bounds, // last layer bounds - layer_bounds, // current layer bounds - 1.f, // last contents scale - 1.f, // current contents scale - gfx::Transform(), // last screen transform - gfx::Transform(), // current screen transform - 1.0, // current frame time - 10000); // max tiles in tile manager - - VerifyTiles(tiling_.get(), - 1.f, - gfx::Rect(layer_bounds), - base::Bind(&TileExists, true)); - - // Mark tiles in this rect as having text. - gfx::Rect text_rect(350, 350, 400, 400); - client_.set_text_rect(text_rect); - - client_.set_invalidation(gfx::Rect(layer_bounds)); - tiling_->DestroyAndRecreateTilesWithText(); - - // Tiles touching the text_rect are recreated. - VerifyTiles(tiling_.get(), - 1.f, - gfx::Rect(layer_bounds), - base::Bind(&TileExists, true)); -} - -TEST_F(PictureLayerTilingIteratorTest, LCDText_WithTwin) { - gfx::Size layer_bounds(1099, 801); - gfx::Size tile_size(100, 100); - - Initialize(tile_size, 1.f, layer_bounds); - - // Make a twin tiling for |tiling_|. - FakePictureLayerTilingClient twin_client; - twin_client.SetTileSize(tile_size); - - scoped_ptr<PictureLayerTiling> twin_tiling = - PictureLayerTiling::Create(1.f, layer_bounds, &twin_client); - client_.set_twin_tiling(twin_tiling.get()); - - VerifyTiles(tiling_.get(), - 1.f, - gfx::Rect(layer_bounds), - base::Bind(&TileExists, false)); - VerifyTiles(twin_tiling.get(), - 1.f, - gfx::Rect(layer_bounds), - base::Bind(&TileExists, false)); - - tiling_->UpdateTilePriorities( - PENDING_TREE, - layer_bounds, // device viewport - gfx::Rect(layer_bounds), // viewport in layer space - gfx::Rect(layer_bounds), // visible content rect - layer_bounds, // last layer bounds - layer_bounds, // current layer bounds - 1.f, // last contents scale - 1.f, // current contents scale - gfx::Transform(), // last screen transform - gfx::Transform(), // current screen transform - 1.0, // current frame time - 10000); // max tiles in tile manager - twin_tiling->UpdateTilePriorities( - PENDING_TREE, - layer_bounds, // device viewport - gfx::Rect(layer_bounds), // viewport in layer space - gfx::Rect(layer_bounds), // visible content rect - layer_bounds, // last layer bounds - layer_bounds, // current layer bounds - 1.f, // last contents scale - 1.f, // current contents scale - gfx::Transform(), // last screen transform - gfx::Transform(), // current screen transform - 1.0, // current frame time - 10000); // max tiles in tile manager - - VerifyTiles(tiling_.get(), - 1.f, - gfx::Rect(layer_bounds), - base::Bind(&TileExists, true)); - VerifyTiles(twin_tiling.get(), - 1.f, - gfx::Rect(layer_bounds), - base::Bind(&TileExists, true)); - - // Mark tiles in this rect as having text. - gfx::Rect text_rect(350, 350, 400, 400); - client_.set_text_rect(text_rect); - - // Prevent new tiles from being created by the |tiling_|. It can still - // get tiles from its twin. - client_.set_allow_create_tile(false); - - client_.set_invalidation(gfx::Rect(layer_bounds)); - tiling_->DestroyAndRecreateTilesWithText(); - - // Tiles touching the text_rect should be gone. Tiles from our twin are - // not used because we are invalidated. - VerifyTiles(tiling_.get(), - 1.f, - gfx::Rect(layer_bounds), - base::Bind(&TilesIntersectingRectExist, text_rect, false)); - VerifyTiles(twin_tiling.get(), - 1.f, - gfx::Rect(layer_bounds), - base::Bind(&TileExists, true)); - - // Destroy all tilings before the twin_client. - tiling_.reset(); - twin_tiling.reset(); -} - } // namespace } // namespace cc diff --git a/cc/resources/picture_pile_impl.cc b/cc/resources/picture_pile_impl.cc index 3d8ab82..fda7ecf 100644 --- a/cc/resources/picture_pile_impl.cc +++ b/cc/resources/picture_pile_impl.cc @@ -31,14 +31,13 @@ PicturePileImpl::ClonesForDrawing::ClonesForDrawing( PicturePileImpl::ClonesForDrawing::~ClonesForDrawing() { } -scoped_refptr<PicturePileImpl> PicturePileImpl::Create(bool enable_lcd_text) { - return make_scoped_refptr(new PicturePileImpl(enable_lcd_text)); +scoped_refptr<PicturePileImpl> PicturePileImpl::Create() { + return make_scoped_refptr(new PicturePileImpl); } scoped_refptr<PicturePileImpl> PicturePileImpl::CreateFromOther( - const PicturePileBase* other, - bool enable_lcd_text) { - return make_scoped_refptr(new PicturePileImpl(other, enable_lcd_text)); + const PicturePileBase* other) { + return make_scoped_refptr(new PicturePileImpl(other)); } scoped_refptr<PicturePileImpl> PicturePileImpl::CreateCloneForDrawing( @@ -46,22 +45,18 @@ scoped_refptr<PicturePileImpl> PicturePileImpl::CreateCloneForDrawing( return make_scoped_refptr(new PicturePileImpl(other, thread_index)); } -PicturePileImpl::PicturePileImpl(bool enable_lcd_text) - : enable_lcd_text_(enable_lcd_text), - clones_for_drawing_(ClonesForDrawing(this, 0)) { +PicturePileImpl::PicturePileImpl() + : clones_for_drawing_(ClonesForDrawing(this, 0)) { } -PicturePileImpl::PicturePileImpl(const PicturePileBase* other, - bool enable_lcd_text) +PicturePileImpl::PicturePileImpl(const PicturePileBase* other) : PicturePileBase(other), - enable_lcd_text_(enable_lcd_text), clones_for_drawing_(ClonesForDrawing(this, num_raster_threads())) { } PicturePileImpl::PicturePileImpl( const PicturePileImpl* other, unsigned thread_index) : PicturePileBase(other, thread_index), - enable_lcd_text_(other->enable_lcd_text_), clones_for_drawing_(ClonesForDrawing(this, 0)) { } diff --git a/cc/resources/picture_pile_impl.h b/cc/resources/picture_pile_impl.h index c00875e..7dc3a4b 100644 --- a/cc/resources/picture_pile_impl.h +++ b/cc/resources/picture_pile_impl.h @@ -21,10 +21,9 @@ struct RenderingStats; class CC_EXPORT PicturePileImpl : public PicturePileBase { public: - static scoped_refptr<PicturePileImpl> Create(bool enable_lcd_text); + static scoped_refptr<PicturePileImpl> Create(); static scoped_refptr<PicturePileImpl> CreateFromOther( - const PicturePileBase* other, - bool enable_lcd_text); + const PicturePileBase* other); // Get paint-safe version of this picture for a specific thread. PicturePileImpl* GetCloneForDrawingOnThread(unsigned thread_index) const; @@ -111,16 +110,12 @@ 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; - explicit PicturePileImpl(bool enable_lcd_text); - PicturePileImpl(const PicturePileBase* other, bool enable_lcd_text); + PicturePileImpl(); + explicit PicturePileImpl(const PicturePileBase* other); virtual ~PicturePileImpl(); private: @@ -145,8 +140,6 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase { float contents_scale, RasterStats* raster_stats); - bool enable_lcd_text_; - // Once instantiated, |clones_for_drawing_| can't be modified. This // guarantees thread-safe access during the life time of a PicturePileImpl // instance. This member variable must be last so that other member diff --git a/cc/resources/raster_worker_pool.cc b/cc/resources/raster_worker_pool.cc index 35f90a8..84a8e8a 100644 --- a/cc/resources/raster_worker_pool.cc +++ b/cc/resources/raster_worker_pool.cc @@ -17,6 +17,25 @@ namespace cc { namespace { +scoped_ptr<base::Value> RasterModeAsValue(RasterMode raster_mode) { + switch (raster_mode) { + case HIGH_QUALITY_NO_LCD_RASTER_MODE: + return scoped_ptr<base::Value>( + base::Value::CreateStringValue("HIGH_QUALITY_NO_LCD_RASTER_MODE")); + case HIGH_QUALITY_RASTER_MODE: + return scoped_ptr<base::Value>( + base::Value::CreateStringValue("HIGH_QUALITY_RASTER_MODE")); + case LOW_QUALITY_RASTER_MODE: + return scoped_ptr<base::Value>( + base::Value::CreateStringValue("LOW_QUALITY_RASTER_MODE")); + case NUM_RASTER_MODES: + default: + NOTREACHED() << "Unrecognized RasterMode value " << raster_mode; + return scoped_ptr<base::Value>( + base::Value::CreateStringValue("<unknown RasterMode value>")); + } +} + class DisableLCDTextFilter : public SkDrawFilter { public: // SkDrawFilter interface. @@ -80,9 +99,14 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { } bool RunRasterOnThread(SkDevice* device, unsigned thread_index) { - TRACE_EVENT1( - "cc", "RasterWorkerPoolTaskImpl::RunRasterOnThread", - "metadata", TracedValue::FromValue(metadata_.AsValue().release())); + TRACE_EVENT2( + "cc", + "RasterWorkerPoolTaskImpl::RunRasterOnThread", + "metadata", + TracedValue::FromValue(metadata_.AsValue().release()), + "raster_mode", + TracedValue::FromValue(RasterModeAsValue(raster_mode_).release())); + devtools_instrumentation::ScopedLayerTask raster_task( devtools_instrumentation::kRasterTask, metadata_.layer_id); diff --git a/cc/resources/raster_worker_pool.h b/cc/resources/raster_worker_pool.h index e6e777c..972cbdc 100644 --- a/cc/resources/raster_worker_pool.h +++ b/cc/resources/raster_worker_pool.h @@ -77,14 +77,16 @@ template <> struct hash<cc::internal::RasterWorkerPoolTask*> { namespace cc { -// 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. +// Low quality implies no lcd test; high quality implies lcd text. +// Note that the order of these matters. It is organized in the order in which +// we can promote tiles. That is, we always move from higher number enum to +// lower number: low quality can be re-rastered as high quality with or without +// LCD text; high quality LCD can only move to high quality no LCD mode. We +// currently don't support moving from no LCD to LCD high quality. // TODO(vmpstr): Find a better place for this. enum RasterMode { - HIGH_QUALITY_RASTER_MODE = 0, - HIGH_QUALITY_NO_LCD_RASTER_MODE = 1, + HIGH_QUALITY_NO_LCD_RASTER_MODE = 0, + HIGH_QUALITY_RASTER_MODE = 1, LOW_QUALITY_RASTER_MODE = 2, NUM_RASTER_MODES = 3 }; diff --git a/cc/resources/tile.cc b/cc/resources/tile.cc index 0efe7eb..753ab0b 100644 --- a/cc/resources/tile.cc +++ b/cc/resources/tile.cc @@ -17,14 +17,16 @@ Tile::Tile(TileManager* tile_manager, gfx::Rect opaque_rect, float contents_scale, int layer_id, - int source_frame_number) + int source_frame_number, + bool can_use_lcd_text) : tile_manager_(tile_manager), tile_size_(tile_size), content_rect_(content_rect), contents_scale_(contents_scale), opaque_rect_(opaque_rect), layer_id_(layer_id), - source_frame_number_(source_frame_number) { + source_frame_number_(source_frame_number), + can_use_lcd_text_(can_use_lcd_text) { set_picture_pile(picture_pile); tile_manager_->RegisterTile(this); } diff --git a/cc/resources/tile.h b/cc/resources/tile.h index 2cd4997..497aff71 100644 --- a/cc/resources/tile.h +++ b/cc/resources/tile.h @@ -29,7 +29,8 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> { gfx::Rect opaque_rect, float contents_scale, int layer_id, - int source_frame_number); + int source_frame_number, + bool can_use_lcd_text); PicturePileImpl* picture_pile() { return picture_pile_.get(); @@ -60,6 +61,14 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> { return priority_[PENDING_TREE].required_for_activation; } + void set_can_use_lcd_text(bool can_use_lcd_text) { + can_use_lcd_text_ = can_use_lcd_text; + } + + bool can_use_lcd_text() const { + return can_use_lcd_text_; + } + scoped_ptr<base::Value> AsValue() const; bool IsReadyToDraw(RasterMode* ready_mode) const { @@ -110,6 +119,9 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> { for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) managed_state().tile_versions[mode].raster_task_.Reset(); } + RasterMode GetRasterModeForTesting() const { + return managed_state().raster_mode; + } private: // Methods called by by tile manager. @@ -138,6 +150,7 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> { ManagedTileState managed_state_; int layer_id_; int source_frame_number_; + bool can_use_lcd_text_; DISALLOW_COPY_AND_ASSIGN(Tile); }; diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc index f313bf6..6c41a30 100644 --- a/cc/resources/tile_manager.cc +++ b/cc/resources/tile_manager.cc @@ -335,7 +335,7 @@ void TileManager::GetMemoryStats( const Tile* tile = *it; const ManagedTileState& mts = tile->managed_state(); - RasterMode mode = HIGH_QUALITY_RASTER_MODE; + RasterMode mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; if (tile->IsReadyToDraw(&mode) && !mts.tile_versions[mode].requires_resource()) continue; @@ -395,16 +395,19 @@ RasterMode TileManager::DetermineRasterMode(const Tile* tile) const { DCHECK(tile); DCHECK(tile->picture_pile()); - RasterMode raster_mode; + const ManagedTileState& mts = tile->managed_state(); + RasterMode current_mode = mts.raster_mode; + RasterMode raster_mode = HIGH_QUALITY_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 + else if (tile->can_use_lcd_text()) raster_mode = HIGH_QUALITY_RASTER_MODE; + else if (mts.tile_versions[current_mode].has_text_ || + !mts.tile_versions[current_mode].IsReadyToDraw()) + raster_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; - return raster_mode; + return std::min(raster_mode, current_mode); } void TileManager::AssignGpuMemoryToTiles() { @@ -447,9 +450,7 @@ void TileManager::AssignGpuMemoryToTiles() { Tile* tile = *it; ManagedTileState& mts = tile->managed_state(); - // 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)); + mts.raster_mode = DetermineRasterMode(tile); ManagedTileState::TileVersion& tile_version = mts.tile_versions[mts.raster_mode]; diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc index 80b2bbc..1014c98 100644 --- a/cc/resources/tile_manager_unittest.cc +++ b/cc/resources/tile_manager_unittest.cc @@ -14,7 +14,7 @@ namespace { class FakePicturePileImpl : public PicturePileImpl { public: - FakePicturePileImpl() : PicturePileImpl(false) { + FakePicturePileImpl() { gfx::Size size(std::numeric_limits<int>::max(), std::numeric_limits<int>::max()); Resize(size); @@ -92,7 +92,8 @@ class TileManagerTest : public testing::Test { gfx::Rect(), 1.0, 0, - 0)); + 0, + true)); tile->SetPriority(ACTIVE_TREE, active_priority); tile->SetPriority(PENDING_TREE, pending_priority); tiles.push_back(tile); @@ -104,7 +105,7 @@ class TileManagerTest : public testing::Test { return tile_manager_.get(); } - int AssignedMemoryCounts(const TileVector& tiles) { + int AssignedMemoryCount(const TileVector& tiles) { int has_memory_count = 0; for (TileVector::const_iterator it = tiles.begin(); it != tiles.end(); @@ -116,6 +117,18 @@ class TileManagerTest : public testing::Test { return has_memory_count; } + int TilesWithLCDCount(const TileVector& tiles) { + int has_lcd_count = 0; + for (TileVector::const_iterator it = tiles.begin(); + it != tiles.end(); + ++it) { + if ((*it)->GetRasterModeForTesting() == HIGH_QUALITY_RASTER_MODE) + ++has_lcd_count; + (*it)->ResetRasterTaskForTesting(); + } + return has_lcd_count; + } + private: FakeTileManagerClient tile_manager_client_; LayerTreeSettings settings_; @@ -139,17 +152,10 @@ TEST_F(TileManagerTest, EnoughMemoryAllowAnything) { tile_manager()->ManageTiles(); - EXPECT_EQ(3, AssignedMemoryCounts(active_now)); - EXPECT_EQ(3, AssignedMemoryCounts(pending_now)); - EXPECT_EQ(3, AssignedMemoryCounts(active_pending_soon)); - EXPECT_EQ(0, AssignedMemoryCounts(never_bin)); - - active_now.clear(); - pending_now.clear(); - active_pending_soon.clear(); - never_bin.clear(); - - TearDown(); + EXPECT_EQ(3, AssignedMemoryCount(active_now)); + EXPECT_EQ(3, AssignedMemoryCount(pending_now)); + EXPECT_EQ(3, AssignedMemoryCount(active_pending_soon)); + EXPECT_EQ(0, AssignedMemoryCount(never_bin)); } TEST_F(TileManagerTest, EnoughMemoryAllowPrepaintOnly) { @@ -167,16 +173,10 @@ TEST_F(TileManagerTest, EnoughMemoryAllowPrepaintOnly) { tile_manager()->ManageTiles(); - EXPECT_EQ(3, AssignedMemoryCounts(active_now)); - EXPECT_EQ(3, AssignedMemoryCounts(pending_now)); - EXPECT_EQ(3, AssignedMemoryCounts(active_pending_soon)); - EXPECT_EQ(0, AssignedMemoryCounts(never_bin)); - - active_now.clear(); - pending_now.clear(); - active_pending_soon.clear(); - never_bin.clear(); - TearDown(); + EXPECT_EQ(3, AssignedMemoryCount(active_now)); + EXPECT_EQ(3, AssignedMemoryCount(pending_now)); + EXPECT_EQ(3, AssignedMemoryCount(active_pending_soon)); + EXPECT_EQ(0, AssignedMemoryCount(never_bin)); } TEST_F(TileManagerTest, EnoughMemoryAllowAbsoluteMinimum) { @@ -194,16 +194,10 @@ TEST_F(TileManagerTest, EnoughMemoryAllowAbsoluteMinimum) { tile_manager()->ManageTiles(); - EXPECT_EQ(3, AssignedMemoryCounts(active_now)); - EXPECT_EQ(3, AssignedMemoryCounts(pending_now)); - EXPECT_EQ(0, AssignedMemoryCounts(active_pending_soon)); - EXPECT_EQ(0, AssignedMemoryCounts(never_bin)); - - active_now.clear(); - pending_now.clear(); - active_pending_soon.clear(); - never_bin.clear(); - TearDown(); + EXPECT_EQ(3, AssignedMemoryCount(active_now)); + EXPECT_EQ(3, AssignedMemoryCount(pending_now)); + EXPECT_EQ(0, AssignedMemoryCount(active_pending_soon)); + EXPECT_EQ(0, AssignedMemoryCount(never_bin)); } TEST_F(TileManagerTest, EnoughMemoryAllowNothing) { @@ -221,16 +215,10 @@ TEST_F(TileManagerTest, EnoughMemoryAllowNothing) { tile_manager()->ManageTiles(); - EXPECT_EQ(0, AssignedMemoryCounts(active_now)); - EXPECT_EQ(0, AssignedMemoryCounts(pending_now)); - EXPECT_EQ(0, AssignedMemoryCounts(active_pending_soon)); - EXPECT_EQ(0, AssignedMemoryCounts(never_bin)); - - active_now.clear(); - pending_now.clear(); - active_pending_soon.clear(); - never_bin.clear(); - TearDown(); + EXPECT_EQ(0, AssignedMemoryCount(active_now)); + EXPECT_EQ(0, AssignedMemoryCount(pending_now)); + EXPECT_EQ(0, AssignedMemoryCount(active_pending_soon)); + EXPECT_EQ(0, AssignedMemoryCount(never_bin)); } TEST_F(TileManagerTest, PartialOOMMemoryToPending) { @@ -246,12 +234,8 @@ TEST_F(TileManagerTest, PartialOOMMemoryToPending) { tile_manager()->ManageTiles(); - EXPECT_EQ(3, AssignedMemoryCounts(active_tree_tiles)); - EXPECT_EQ(5, AssignedMemoryCounts(pending_tree_tiles)); - - pending_tree_tiles.clear(); - active_tree_tiles.clear(); - TearDown(); + EXPECT_EQ(3, AssignedMemoryCount(active_tree_tiles)); + EXPECT_EQ(5, AssignedMemoryCount(pending_tree_tiles)); } TEST_F(TileManagerTest, PartialOOMMemoryToActive) { @@ -267,12 +251,8 @@ TEST_F(TileManagerTest, PartialOOMMemoryToActive) { tile_manager()->ManageTiles(); - EXPECT_EQ(5, AssignedMemoryCounts(active_tree_tiles)); - EXPECT_EQ(3, AssignedMemoryCounts(pending_tree_tiles)); - - pending_tree_tiles.clear(); - active_tree_tiles.clear(); - TearDown(); + EXPECT_EQ(5, AssignedMemoryCount(active_tree_tiles)); + EXPECT_EQ(3, AssignedMemoryCount(pending_tree_tiles)); } TEST_F(TileManagerTest, TotalOOMMemoryToPending) { @@ -288,12 +268,8 @@ TEST_F(TileManagerTest, TotalOOMMemoryToPending) { tile_manager()->ManageTiles(); - EXPECT_EQ(0, AssignedMemoryCounts(active_tree_tiles)); - EXPECT_EQ(4, AssignedMemoryCounts(pending_tree_tiles)); - - pending_tree_tiles.clear(); - active_tree_tiles.clear(); - TearDown(); + EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles)); + EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles)); } TEST_F(TileManagerTest, TotalOOMActiveSoonMemoryToPending) { @@ -309,12 +285,8 @@ TEST_F(TileManagerTest, TotalOOMActiveSoonMemoryToPending) { tile_manager()->ManageTiles(); - EXPECT_EQ(0, AssignedMemoryCounts(active_tree_tiles)); - EXPECT_EQ(4, AssignedMemoryCounts(pending_tree_tiles)); - - pending_tree_tiles.clear(); - active_tree_tiles.clear(); - TearDown(); + EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles)); + EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles)); } TEST_F(TileManagerTest, TotalOOMMemoryToActive) { @@ -330,12 +302,148 @@ TEST_F(TileManagerTest, TotalOOMMemoryToActive) { tile_manager()->ManageTiles(); - EXPECT_EQ(4, AssignedMemoryCounts(active_tree_tiles)); - EXPECT_EQ(0, AssignedMemoryCounts(pending_tree_tiles)); + EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles)); + EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles)); +} + +TEST_F(TileManagerTest, RasterAsLCD) { + Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); + TileVector active_tree_tiles = + CreateTiles(5, TilePriorityForNowBin(), TilePriority()); + TileVector pending_tree_tiles = + CreateTiles(5, TilePriority(), TilePriorityForNowBin()); + + tile_manager()->ManageTiles(); + + EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles)); + EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles)); +} + +TEST_F(TileManagerTest, RasterAsNoLCD) { + Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); + TileVector active_tree_tiles = + CreateTiles(5, TilePriorityForNowBin(), TilePriority()); + TileVector pending_tree_tiles = + CreateTiles(5, TilePriority(), TilePriorityForNowBin()); + + for (TileVector::iterator it = active_tree_tiles.begin(); + it != active_tree_tiles.end(); + ++it) { + (*it)->set_can_use_lcd_text(false); + } + for (TileVector::iterator it = pending_tree_tiles.begin(); + it != pending_tree_tiles.end(); + ++it) { + (*it)->set_can_use_lcd_text(false); + } + + tile_manager()->ManageTiles(); + + EXPECT_EQ(0, TilesWithLCDCount(active_tree_tiles)); + EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles)); +} + +TEST_F(TileManagerTest, ReRasterAsNoLCD) { + Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); + TileVector active_tree_tiles = + CreateTiles(5, TilePriorityForNowBin(), TilePriority()); + TileVector pending_tree_tiles = + CreateTiles(5, TilePriority(), TilePriorityForNowBin()); + + tile_manager()->ManageTiles(); + + EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles)); + EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles)); + + for (TileVector::iterator it = active_tree_tiles.begin(); + it != active_tree_tiles.end(); + ++it) { + (*it)->set_can_use_lcd_text(false); + } + for (TileVector::iterator it = pending_tree_tiles.begin(); + it != pending_tree_tiles.end(); + ++it) { + (*it)->set_can_use_lcd_text(false); + } + + tile_manager()->ManageTiles(); + + EXPECT_EQ(0, TilesWithLCDCount(active_tree_tiles)); + EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles)); +} + +TEST_F(TileManagerTest, NoTextDontReRasterAsNoLCD) { + Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); + TileVector active_tree_tiles = + CreateTiles(5, TilePriorityForNowBin(), TilePriority()); + TileVector pending_tree_tiles = + CreateTiles(5, TilePriority(), TilePriorityForNowBin()); + + tile_manager()->ManageTiles(); + + EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles)); + EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles)); + + for (TileVector::iterator it = active_tree_tiles.begin(); + it != active_tree_tiles.end(); + ++it) { + (*it)->set_can_use_lcd_text(false); + (*it)->tile_version(HIGH_QUALITY_RASTER_MODE).SetSolidColorForTesting( + SkColorSetARGB(0, 0, 0, 0)); + EXPECT_TRUE((*it)->IsReadyToDraw(NULL)); + } + for (TileVector::iterator it = pending_tree_tiles.begin(); + it != pending_tree_tiles.end(); + ++it) { + (*it)->set_can_use_lcd_text(false); + (*it)->tile_version(HIGH_QUALITY_RASTER_MODE).SetSolidColorForTesting( + SkColorSetARGB(0, 0, 0, 0)); + EXPECT_TRUE((*it)->IsReadyToDraw(NULL)); + } + + tile_manager()->ManageTiles(); + + EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles)); + EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles)); +} + +TEST_F(TileManagerTest, TextReRasterAsNoLCD) { + Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); + TileVector active_tree_tiles = + CreateTiles(5, TilePriorityForNowBin(), TilePriority()); + TileVector pending_tree_tiles = + CreateTiles(5, TilePriority(), TilePriorityForNowBin()); + + tile_manager()->ManageTiles(); + + EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles)); + EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles)); + + for (TileVector::iterator it = active_tree_tiles.begin(); + it != active_tree_tiles.end(); + ++it) { + (*it)->set_can_use_lcd_text(false); + (*it)->tile_version(HIGH_QUALITY_RASTER_MODE).SetSolidColorForTesting( + SkColorSetARGB(0, 0, 0, 0)); + (*it)->tile_version(HIGH_QUALITY_RASTER_MODE).SetHasTextForTesting(true); + + EXPECT_TRUE((*it)->IsReadyToDraw(NULL)); + } + for (TileVector::iterator it = pending_tree_tiles.begin(); + it != pending_tree_tiles.end(); + ++it) { + (*it)->set_can_use_lcd_text(false); + (*it)->tile_version(HIGH_QUALITY_RASTER_MODE).SetSolidColorForTesting( + SkColorSetARGB(0, 0, 0, 0)); + (*it)->tile_version(HIGH_QUALITY_RASTER_MODE).SetHasTextForTesting(true); + + EXPECT_TRUE((*it)->IsReadyToDraw(NULL)); + } + + tile_manager()->ManageTiles(); - pending_tree_tiles.clear(); - active_tree_tiles.clear(); - TearDown(); + EXPECT_EQ(0, TilesWithLCDCount(active_tree_tiles)); + EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles)); } } // namespace diff --git a/cc/test/fake_picture_layer_tiling_client.cc b/cc/test/fake_picture_layer_tiling_client.cc index 652b712..4127b01 100644 --- a/cc/test/fake_picture_layer_tiling_client.cc +++ b/cc/test/fake_picture_layer_tiling_client.cc @@ -12,8 +12,7 @@ namespace cc { class FakeInfinitePicturePileImpl : public PicturePileImpl { public: - FakeInfinitePicturePileImpl() - : PicturePileImpl(false) { + FakeInfinitePicturePileImpl() { gfx::Size size(std::numeric_limits<int>::max(), std::numeric_limits<int>::max()); Resize(size); @@ -45,7 +44,8 @@ scoped_refptr<Tile> FakePictureLayerTilingClient::CreateTile( gfx::Rect(), 1, 0, - 0); + 0, + true); } void FakePictureLayerTilingClient::SetTileSize(gfx::Size tile_size) { @@ -66,10 +66,4 @@ const PictureLayerTiling* FakePictureLayerTilingClient::GetTwinTiling( return twin_tiling_; } -bool FakePictureLayerTilingClient::TileMayHaveLCDText(Tile* tile) { - if (text_rect_.IsEmpty()) - return false; - return tile->content_rect().Intersects(text_rect_); -} - } // namespace cc diff --git a/cc/test/fake_picture_layer_tiling_client.h b/cc/test/fake_picture_layer_tiling_client.h index 3593661..4b8c8cd 100644 --- a/cc/test/fake_picture_layer_tiling_client.h +++ b/cc/test/fake_picture_layer_tiling_client.h @@ -33,7 +33,6 @@ class FakePictureLayerTilingClient : public PictureLayerTilingClient { virtual const Region* GetInvalidation() OVERRIDE; virtual const PictureLayerTiling* GetTwinTiling( const PictureLayerTiling* tiling) OVERRIDE; - virtual bool TileMayHaveLCDText(Tile* tile) OVERRIDE; void set_twin_tiling(PictureLayerTiling* tiling) { twin_tiling_ = tiling; } void set_text_rect(gfx::Rect rect) { text_rect_ = rect; } diff --git a/cc/test/fake_picture_pile_impl.cc b/cc/test/fake_picture_pile_impl.cc index b14a6e9..bce205f 100644 --- a/cc/test/fake_picture_pile_impl.cc +++ b/cc/test/fake_picture_pile_impl.cc @@ -11,8 +11,7 @@ namespace cc { -FakePicturePileImpl::FakePicturePileImpl() - : PicturePileImpl(false) {} +FakePicturePileImpl::FakePicturePileImpl() {} FakePicturePileImpl::~FakePicturePileImpl() {} |