From ad672f645e82ca677978b097a170c908c614d184 Mon Sep 17 00:00:00 2001 From: danakj Date: Mon, 17 Nov 2014 13:47:49 -0800 Subject: [PATCH] cc: Toggle LCD text at raster time instead of record time. Always tell blink that it can use LCD text (in future this can stop being passed at all). And at raster time: - If LCD text is allowed initialize SkSurfaceProps with the LegacyHost parameter which will cause skia to pick an LCD text format matching current behaviour. - If LCD is not allowed initialize SkSurfaceProps with an "unknown pixelformat" causing LCD text to not be used. This also removes the need for SK_SUPPORT_LEGACY_TEXTRENDERMODE from resource_provider.cc. R=enne,reveman BUG=430617 Review URL: https://codereview.chromium.org/684543006 Cr-Commit-Position: refs/heads/master@{#304486} --- cc/blink/web_content_layer_impl.cc | 25 +--- cc/blink/web_content_layer_impl.h | 1 - cc/layers/content_layer.cc | 14 +-- cc/layers/content_layer.h | 3 - cc/layers/content_layer_client.h | 4 - cc/layers/picture_image_layer.h | 1 - cc/layers/picture_layer.cc | 29 ++--- cc/layers/picture_layer.h | 4 +- cc/layers/picture_layer_impl_unittest.cc | 6 +- cc/layers/picture_layer_unittest.cc | 1 - cc/resources/gpu_raster_worker_pool.cc | 3 +- cc/resources/picture_pile.cc | 35 ++++-- cc/resources/picture_pile.h | 2 + cc/resources/picture_pile_impl.cc | 6 + cc/resources/picture_pile_impl.h | 2 + cc/resources/picture_pile_unittest.cc | 2 +- cc/resources/raster_source.h | 3 + cc/resources/raster_worker_pool.cc | 18 ++- cc/resources/recording_source.h | 1 + cc/resources/resource_provider.cc | 39 ++++-- cc/resources/resource_provider.h | 6 +- cc/test/fake_content_layer_client.h | 1 - cc/test/layer_tree_host_common_test.cc | 8 +- cc/test/layer_tree_host_common_test.h | 23 ++-- cc/test/solid_color_content_layer_client.h | 1 - cc/trees/layer_tree_host.cc | 15 +-- cc/trees/layer_tree_host_common.cc | 19 +-- cc/trees/layer_tree_host_common.h | 5 + cc/trees/layer_tree_host_common_perftest.cc | 23 ++-- cc/trees/layer_tree_host_common_unittest.cc | 116 ++++++++++-------- cc/trees/layer_tree_host_pixeltest_masks.cc | 2 - ...er_tree_host_pixeltest_on_demand_raster.cc | 2 - cc/trees/layer_tree_host_unittest.cc | 91 ++++++++------ cc/trees/layer_tree_impl.cc | 16 +-- cc/trees/layer_tree_settings.cc | 1 + cc/trees/layer_tree_settings.h | 1 + ui/compositor/compositor.cc | 4 + ui/compositor/layer.h | 1 - 38 files changed, 282 insertions(+), 252 deletions(-) diff --git a/cc/blink/web_content_layer_impl.cc b/cc/blink/web_content_layer_impl.cc index 6dfdad9c160fc5..d0a4cca4722b57 100644 --- a/cc/blink/web_content_layer_impl.cc +++ b/cc/blink/web_content_layer_impl.cc @@ -19,13 +19,12 @@ using cc::PictureLayer; namespace cc_blink { WebContentLayerImpl::WebContentLayerImpl(blink::WebContentLayerClient* client) - : client_(client), ignore_lcd_text_change_(false) { + : client_(client) { if (WebLayerImpl::UsingPictureLayer()) layer_ = make_scoped_ptr(new WebLayerImpl(PictureLayer::Create(this))); else layer_ = make_scoped_ptr(new WebLayerImpl(ContentLayer::Create(this))); layer_->layer()->SetIsDrawable(true); - can_use_lcd_text_ = layer_->layer()->can_use_lcd_text(); } WebContentLayerImpl::~WebContentLayerImpl() { @@ -54,30 +53,16 @@ void WebContentLayerImpl::PaintContents( if (!client_) return; + // TODO(danakj): Stop passing this to blink it should always use LCD when it + // wants to. crbug.com/430617 + bool can_use_lcd_text = true; client_->paintContents( - canvas, - clip, - can_use_lcd_text_, + canvas, clip, can_use_lcd_text, graphics_context_status == ContentLayerClient::GRAPHICS_CONTEXT_ENABLED ? blink::WebContentLayerClient::GraphicsContextEnabled : blink::WebContentLayerClient::GraphicsContextDisabled); } -void WebContentLayerImpl::DidChangeLayerCanUseLCDText() { - // It is important to make this comparison because the LCD text status - // here can get out of sync with that in the layer. - if (can_use_lcd_text_ == layer_->layer()->can_use_lcd_text()) - return; - - // LCD text cannot be enabled once disabled. - if (layer_->layer()->can_use_lcd_text() && ignore_lcd_text_change_) - return; - - can_use_lcd_text_ = layer_->layer()->can_use_lcd_text(); - ignore_lcd_text_change_ = true; - layer_->invalidate(); -} - bool WebContentLayerImpl::FillsBoundsCompletely() const { return false; } diff --git a/cc/blink/web_content_layer_impl.h b/cc/blink/web_content_layer_impl.h index b9bb8713854c54..2966bd4953b667 100644 --- a/cc/blink/web_content_layer_impl.h +++ b/cc/blink/web_content_layer_impl.h @@ -40,7 +40,6 @@ class WebContentLayerImpl : public blink::WebContentLayer, const gfx::Rect& clip, ContentLayerClient::GraphicsContextStatus graphics_context_status) override; - void DidChangeLayerCanUseLCDText() override; bool FillsBoundsCompletely() const override; scoped_ptr layer_; diff --git a/cc/layers/content_layer.cc b/cc/layers/content_layer.cc index 88031e49631cfd..53c7120c09b11b 100644 --- a/cc/layers/content_layer.cc +++ b/cc/layers/content_layer.cc @@ -36,9 +36,7 @@ scoped_refptr ContentLayer::Create(ContentLayerClient* client) { } ContentLayer::ContentLayer(ContentLayerClient* client) - : TiledLayer(), - client_(client), - can_use_lcd_text_last_frame_(can_use_lcd_text()) { + : TiledLayer(), client_(client) { } ContentLayer::~ContentLayer() {} @@ -74,7 +72,6 @@ bool ContentLayer::Update(ResourceUpdateQueue* queue, true); CreateUpdaterIfNeeded(); - UpdateCanUseLCDText(); } bool updated = TiledLayer::Update(queue, occlusion); @@ -118,15 +115,6 @@ void ContentLayer::SetContentsOpaque(bool opaque) { updater_->SetOpaque(opaque); } -void ContentLayer::UpdateCanUseLCDText() { - if (can_use_lcd_text_last_frame_ == can_use_lcd_text()) - return; - - can_use_lcd_text_last_frame_ = can_use_lcd_text(); - if (client_) - client_->DidChangeLayerCanUseLCDText(); -} - bool ContentLayer::SupportsLCDText() const { return true; } diff --git a/cc/layers/content_layer.h b/cc/layers/content_layer.h index fe0bd37970f432..22dd8fd8df6c65 100644 --- a/cc/layers/content_layer.h +++ b/cc/layers/content_layer.h @@ -65,11 +65,8 @@ class CC_EXPORT ContentLayer : public TiledLayer { // TiledLayer implementation. void CreateUpdaterIfNeeded() override; - void UpdateCanUseLCDText(); - ContentLayerClient* client_; scoped_refptr updater_; - bool can_use_lcd_text_last_frame_; DISALLOW_COPY_AND_ASSIGN(ContentLayer); }; diff --git a/cc/layers/content_layer_client.h b/cc/layers/content_layer_client.h index 0140513cbb866a..ea22e9798919ba 100644 --- a/cc/layers/content_layer_client.h +++ b/cc/layers/content_layer_client.h @@ -27,10 +27,6 @@ class CC_EXPORT ContentLayerClient { const gfx::Rect& clip, GraphicsContextStatus gc_status) = 0; - // Called by the content layer during the update phase. - // If the client paints LCD text, it may want to invalidate the layer. - virtual void DidChangeLayerCanUseLCDText() = 0; - // If true the layer may skip clearing the background before rasterizing, // because it will cover any uncleared data with content. virtual bool FillsBoundsCompletely() const = 0; diff --git a/cc/layers/picture_image_layer.h b/cc/layers/picture_image_layer.h index 3575d8821c878d..3f8d68da8c6e79 100644 --- a/cc/layers/picture_image_layer.h +++ b/cc/layers/picture_image_layer.h @@ -27,7 +27,6 @@ class CC_EXPORT PictureImageLayer : public PictureLayer, ContentLayerClient { SkCanvas* canvas, const gfx::Rect& clip, ContentLayerClient::GraphicsContextStatus gc_status) override; - void DidChangeLayerCanUseLCDText() override {} bool FillsBoundsCompletely() const override; protected: diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc index dbfa63c76cbbb8..29190a0588d7e4 100644 --- a/cc/layers/picture_layer.cc +++ b/cc/layers/picture_layer.cc @@ -23,7 +23,7 @@ PictureLayer::PictureLayer(ContentLayerClient* client) recording_source_(new PicturePile), instrumentation_object_tracker_(id()), update_source_frame_number_(-1), - can_use_lcd_text_last_frame_(can_use_lcd_text()) { + can_use_lcd_text_for_update_(true) { } PictureLayer::PictureLayer(ContentLayerClient* client, @@ -95,18 +95,14 @@ bool PictureLayer::Update(ResourceUpdateQueue* queue, update_source_frame_number_ = layer_tree_host()->source_frame_number(); bool updated = Layer::Update(queue, occlusion); - { - base::AutoReset ignore_set_needs_commit(&ignore_set_needs_commit_, - true); - UpdateCanUseLCDText(); - } + bool can_use_lcd_text_changed = UpdateCanUseLCDText(); gfx::Rect visible_layer_rect = gfx::ScaleToEnclosingRect( visible_content_rect(), 1.f / contents_scale_x()); gfx::Size layer_size = paint_properties().bounds; if (last_updated_visible_content_rect_ == visible_content_rect() && - recording_source_->GetSize() == layer_size && + recording_source_->GetSize() == layer_size && !can_use_lcd_text_changed && pending_invalidation_.IsEmpty()) { // Only early out if the visible content rect of this layer hasn't changed. return updated; @@ -136,9 +132,9 @@ bool PictureLayer::Update(ResourceUpdateQueue* queue, DCHECK(client_); updated |= recording_source_->UpdateAndExpandInvalidation( client_, &recording_invalidation_, SafeOpaqueBackgroundColor(), - contents_opaque(), client_->FillsBoundsCompletely(), layer_size, - visible_layer_rect, update_source_frame_number_, - Picture::RECORD_NORMALLY); + contents_opaque(), client_->FillsBoundsCompletely(), + can_use_lcd_text_for_update_, layer_size, visible_layer_rect, + update_source_frame_number_, Picture::RECORD_NORMALLY); last_updated_visible_content_rect_ = visible_content_rect(); if (updated) { @@ -160,13 +156,14 @@ bool PictureLayer::SupportsLCDText() const { return true; } -void PictureLayer::UpdateCanUseLCDText() { - if (can_use_lcd_text_last_frame_ == can_use_lcd_text()) - return; +bool PictureLayer::UpdateCanUseLCDText() { + if (!can_use_lcd_text_for_update_) + return false; // Don't allow the LCD text state to change once disabled. + if (can_use_lcd_text_for_update_ == can_use_lcd_text()) + return false; - can_use_lcd_text_last_frame_ = can_use_lcd_text(); - if (client_) - client_->DidChangeLayerCanUseLCDText(); + can_use_lcd_text_for_update_ = can_use_lcd_text(); + return true; } skia::RefPtr PictureLayer::GetPicture() const { diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h index ebd6427c708437..4d84371927670e 100644 --- a/cc/layers/picture_layer.h +++ b/cc/layers/picture_layer.h @@ -50,7 +50,7 @@ class CC_EXPORT PictureLayer : public Layer { ~PictureLayer() override; bool HasDrawableContent() const override; - void UpdateCanUseLCDText(); + bool UpdateCanUseLCDText(); private: ContentLayerClient* client_; @@ -64,7 +64,7 @@ class CC_EXPORT PictureLayer : public Layer { gfx::Rect last_updated_visible_content_rect_; int update_source_frame_number_; - bool can_use_lcd_text_last_frame_; + bool can_use_lcd_text_for_update_; DISALLOW_COPY_AND_ASSIGN(PictureLayer); }; diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index bd0585e52bab39..3c1b9b2b2e6c59 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -4502,7 +4502,7 @@ void PictureLayerImplTest::TestQuadsForSolidColor(bool test_for_solid) { Region invalidation(layer_rect); recording_source->UpdateAndExpandInvalidation( - &client, &invalidation, SK_ColorWHITE, false, false, layer_bounds, + &client, &invalidation, SK_ColorWHITE, false, false, false, layer_bounds, layer_rect, frame_number++, Picture::RECORD_NORMALLY); scoped_refptr pending_raster_source = @@ -4569,7 +4569,7 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { Region invalidation1(layer_rect); recording_source->UpdateAndExpandInvalidation( - &client, &invalidation1, SK_ColorWHITE, false, false, layer_bounds, + &client, &invalidation1, SK_ColorWHITE, false, false, false, layer_bounds, layer_rect, frame_number++, Picture::RECORD_NORMALLY); scoped_refptr raster_source1 = @@ -4587,7 +4587,7 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { Region invalidation2(layer_rect); recording_source->UpdateAndExpandInvalidation( - &client, &invalidation2, SK_ColorWHITE, false, false, layer_bounds, + &client, &invalidation2, SK_ColorWHITE, false, false, false, layer_bounds, layer_rect, frame_number++, Picture::RECORD_NORMALLY); scoped_refptr raster_source2 = diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc index 7873b487834939..3f81ef8629e11f 100644 --- a/cc/layers/picture_layer_unittest.cc +++ b/cc/layers/picture_layer_unittest.cc @@ -24,7 +24,6 @@ class MockContentLayerClient : public ContentLayerClient { SkCanvas* canvas, const gfx::Rect& clip, ContentLayerClient::GraphicsContextStatus gc_status) override {} - void DidChangeLayerCanUseLCDText() override {} bool FillsBoundsCompletely() const override { return false; }; }; diff --git a/cc/resources/gpu_raster_worker_pool.cc b/cc/resources/gpu_raster_worker_pool.cc index c9139706f81bf9..a304a4a0dc786f 100644 --- a/cc/resources/gpu_raster_worker_pool.cc +++ b/cc/resources/gpu_raster_worker_pool.cc @@ -41,7 +41,8 @@ class RasterBufferImpl : public RasterBuffer { bool use_distance_field_text = use_distance_field_text_ || raster_source->ShouldAttemptToUseDistanceFieldText(); - SkSurface* sk_surface = lock_.GetSkSurface(use_distance_field_text); + SkSurface* sk_surface = lock_.GetSkSurface(use_distance_field_text, + raster_source->CanUseLCDText()); if (!sk_surface) return; diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc index ab138cab658f17..4daa2c3ce4f04c 100644 --- a/cc/resources/picture_pile.cc +++ b/cc/resources/picture_pile.cc @@ -193,6 +193,7 @@ bool PicturePile::UpdateAndExpandInvalidation( SkColor background_color, bool contents_opaque, bool contents_fill_bounds_completely, + bool can_use_lcd_text, const gfx::Size& layer_size, const gfx::Rect& visible_layer_rect, int frame_number, @@ -200,15 +201,25 @@ bool PicturePile::UpdateAndExpandInvalidation( background_color_ = background_color; contents_opaque_ = contents_opaque; contents_fill_bounds_completely_ = contents_fill_bounds_completely; + bool can_use_lcd_text_changed = can_use_lcd_text_ != can_use_lcd_text; + can_use_lcd_text_ = can_use_lcd_text; bool updated = false; - Region resize_invalidation; + Region synthetic_invalidation; gfx::Size old_tiling_size = GetSize(); if (old_tiling_size != layer_size) { tiling_.SetTilingSize(layer_size); updated = true; } + if (can_use_lcd_text_changed) { + // When LCD text is enabled/disabled, we must drop any raster tiles for + // the pile, so they can be recreated in a manner consistent with the new + // setting. We do this with |synthetic_invalidation| since we don't need to + // do a new recording, just invalidate rastered content. + synthetic_invalidation.Union(gfx::Rect(GetSize())); + updated = true; + } gfx::Rect interest_rect = visible_layer_rect; interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_); @@ -372,11 +383,11 @@ bool PicturePile::UpdateAndExpandInvalidation( exposed_top, exposed_left_until - exposed_left, exposed_bottom - exposed_top); - resize_invalidation.Union(left_rect); - resize_invalidation.Union(right_rect); - resize_invalidation.Union(top_rect); - resize_invalidation.Union(bottom_rect); - resize_invalidation.Union(exposed_rect); + synthetic_invalidation.Union(left_rect); + synthetic_invalidation.Union(right_rect); + synthetic_invalidation.Union(top_rect); + synthetic_invalidation.Union(bottom_rect); + synthetic_invalidation.Union(exposed_rect); } if (min_toss_y < tiling_.num_tiles_y()) { // The same thing occurs here as in the case above, but the invalidation @@ -408,11 +419,11 @@ bool PicturePile::UpdateAndExpandInvalidation( exposed_top, exposed_right - exposed_left, exposed_top_until - exposed_top); - resize_invalidation.Union(left_rect); - resize_invalidation.Union(right_rect); - resize_invalidation.Union(top_rect); - resize_invalidation.Union(bottom_rect); - resize_invalidation.Union(exposed_rect); + synthetic_invalidation.Union(left_rect); + synthetic_invalidation.Union(right_rect); + synthetic_invalidation.Union(top_rect); + synthetic_invalidation.Union(bottom_rect); + synthetic_invalidation.Union(exposed_rect); } } @@ -474,7 +485,7 @@ bool PicturePile::UpdateAndExpandInvalidation( invalidation->Union(invalidation_expanded_to_full_tiles); } - invalidation->Union(resize_invalidation); + invalidation->Union(synthetic_invalidation); // Make a list of all invalid tiles; we will attempt to // cluster these into multiple invalidation regions. diff --git a/cc/resources/picture_pile.h b/cc/resources/picture_pile.h index 1f41d018d927f6..767a6c2282279d 100644 --- a/cc/resources/picture_pile.h +++ b/cc/resources/picture_pile.h @@ -28,6 +28,7 @@ class CC_EXPORT PicturePile : public RecordingSource { SkColor background_color, bool contents_opaque, bool contents_fill_bounds_completely, + bool can_use_lcd_text, const gfx::Size& layer_size, const gfx::Rect& visible_layer_rect, int frame_number, @@ -101,6 +102,7 @@ class CC_EXPORT PicturePile : public RecordingSource { int slow_down_raster_scale_factor_for_debug_; bool contents_opaque_; bool contents_fill_bounds_completely_; + bool can_use_lcd_text_; bool clear_canvas_with_debug_color_; // A hint about whether there are any recordings. This may be a false // positive. diff --git a/cc/resources/picture_pile_impl.cc b/cc/resources/picture_pile_impl.cc index 7ec92521273193..ee0ad478d65799 100644 --- a/cc/resources/picture_pile_impl.cc +++ b/cc/resources/picture_pile_impl.cc @@ -29,6 +29,7 @@ PicturePileImpl::PicturePileImpl() : background_color_(SK_ColorTRANSPARENT), contents_opaque_(false), contents_fill_bounds_completely_(false), + can_use_lcd_text_(false), is_solid_color_(false), solid_color_(SK_ColorTRANSPARENT), has_any_recordings_(false), @@ -45,6 +46,7 @@ PicturePileImpl::PicturePileImpl(const PicturePile* other) background_color_(other->background_color_), contents_opaque_(other->contents_opaque_), contents_fill_bounds_completely_(other->contents_fill_bounds_completely_), + can_use_lcd_text_(other->can_use_lcd_text_), is_solid_color_(other->is_solid_color_), solid_color_(other->solid_color_), recorded_viewport_(other->recorded_viewport_), @@ -427,6 +429,10 @@ bool PicturePileImpl::IsMask() const { return is_mask_; } +bool PicturePileImpl::CanUseLCDText() const { + return can_use_lcd_text_; +} + PicturePileImpl::PixelRefIterator::PixelRefIterator( const gfx::Rect& content_rect, float contents_scale, diff --git a/cc/resources/picture_pile_impl.h b/cc/resources/picture_pile_impl.h index 9f5b5f61af5b0d..0160ec27bb5534 100644 --- a/cc/resources/picture_pile_impl.h +++ b/cc/resources/picture_pile_impl.h @@ -60,6 +60,7 @@ class CC_EXPORT PicturePileImpl : public RasterSource { SkColor GetSolidColor() const override; bool HasRecordings() const override; bool IsMask() const override; + bool CanUseLCDText() const override; // Tracing functionality. void DidBeginTracing() override; @@ -110,6 +111,7 @@ class CC_EXPORT PicturePileImpl : public RasterSource { SkColor background_color_; bool contents_opaque_; bool contents_fill_bounds_completely_; + bool can_use_lcd_text_; bool is_solid_color_; SkColor solid_color_; gfx::Rect recorded_viewport_; diff --git a/cc/resources/picture_pile_unittest.cc b/cc/resources/picture_pile_unittest.cc index bfb4692dd18b2e..55e432eb8fc138 100644 --- a/cc/resources/picture_pile_unittest.cc +++ b/cc/resources/picture_pile_unittest.cc @@ -45,7 +45,7 @@ class PicturePileTestBase { frame_number_++; return pile_.UpdateAndExpandInvalidation( &client_, invalidation, background_color_, contents_opaque_, false, - layer_size, visible_layer_rect, frame_number_, + false, layer_size, visible_layer_rect, frame_number_, Picture::RECORD_NORMALLY); } diff --git a/cc/resources/raster_source.h b/cc/resources/raster_source.h index f7ea2716b03820..bcc28d19b20366 100644 --- a/cc/resources/raster_source.h +++ b/cc/resources/raster_source.h @@ -93,6 +93,9 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe { // TODO(vmpstr): This should be a layer property. virtual bool IsMask() const = 0; + // Return true if LCD anti-aliasing may be used when rastering text. + virtual bool CanUseLCDText() const = 0; + protected: friend class base::RefCountedThreadSafe; diff --git a/cc/resources/raster_worker_pool.cc b/cc/resources/raster_worker_pool.cc index ca26edd6a41f3c..4511f9d561f093 100644 --- a/cc/resources/raster_worker_pool.cc +++ b/cc/resources/raster_worker_pool.cc @@ -228,28 +228,26 @@ void RasterWorkerPool::PlaybackToMemory(void* memory, SkColorType buffer_color_type = ResourceFormatToSkColorType(format); bool needs_copy = buffer_color_type != info.colorType(); - // TODO(danakj): Make a SkSurfaceProps with an SkPixelGeometry to enable or - // disable LCD text. - // TODO(danakj): Disable LCD text on Mac during layout tests: - // https://cs.chromium.org#chromium/src/third_party/WebKit/Source/platform/fonts/mac/FontPlatformDataMac.mm&l=55 - // TODO(danakj): On Windows when LCD text is disabled, ask skia to draw LCD - // text offscreen and downsample it to AA text. - // https://cs.chromium.org#chromium/src/third_party/WebKit/Source/platform/fonts/win/FontPlatformDataWin.cpp&l=86 - SkSurfaceProps* surface_props = nullptr; + // Use unknown pixel geometry to disable LCD text. + SkSurfaceProps surface_props(0, kUnknown_SkPixelGeometry); + if (raster_source->CanUseLCDText()) { + // LegacyFontHost will get LCD text and skia figures out what type to use. + surface_props = SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType); + } if (!stride) stride = info.minRowBytes(); if (!needs_copy) { skia::RefPtr surface = skia::AdoptRef( - SkSurface::NewRasterDirect(info, memory, stride, surface_props)); + SkSurface::NewRasterDirect(info, memory, stride, &surface_props)); skia::RefPtr canvas = skia::SharePtr(surface->getCanvas()); raster_source->PlaybackToCanvas(canvas.get(), rect, scale); return; } skia::RefPtr surface = - skia::AdoptRef(SkSurface::NewRaster(info, surface_props)); + skia::AdoptRef(SkSurface::NewRaster(info, &surface_props)); skia::RefPtr canvas = skia::SharePtr(surface->getCanvas()); raster_source->PlaybackToCanvas(canvas.get(), rect, scale); diff --git a/cc/resources/recording_source.h b/cc/resources/recording_source.h index d2b0893ba128a9..ecb64fab4337ad 100644 --- a/cc/resources/recording_source.h +++ b/cc/resources/recording_source.h @@ -31,6 +31,7 @@ class CC_EXPORT RecordingSource { SkColor background_color, bool contents_opaque, bool contents_fill_bounds_completely, + bool can_use_lcd_text, const gfx::Size& layer_size, const gfx::Rect& visible_layer_rect, int frame_number, diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index 023a1cdbf06883..4939c4856733da 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -1100,15 +1100,15 @@ ResourceProvider::ScopedWriteLockGr::~ScopedWriteLockGr() { } SkSurface* ResourceProvider::ScopedWriteLockGr::GetSkSurface( - bool use_distance_field_text) { + bool use_distance_field_text, + bool can_use_lcd_text) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(resource_->locked_for_write); - // If the surface doesn't exist, or doesn't have the correct dff setting, - // recreate the surface within the resource. - if (!resource_->sk_surface || - use_distance_field_text != - resource_->sk_surface->props().isUseDistanceFieldFonts()) { + bool create_surface = + !resource_->sk_surface.get() || + !SurfaceHasMatchingProperties(use_distance_field_text, can_use_lcd_text); + if (create_surface) { class GrContext* gr_context = resource_provider_->GrContext(); // TODO(alokp): Implement TestContextProvider::GrContext(). if (!gr_context) @@ -1127,15 +1127,34 @@ SkSurface* ResourceProvider::ScopedWriteLockGr::GetSkSurface( skia::AdoptRef(gr_context->wrapBackendTexture(desc)); if (!gr_texture) return nullptr; - SkSurface::TextRenderMode text_render_mode = - use_distance_field_text ? SkSurface::kDistanceField_TextRenderMode - : SkSurface::kStandard_TextRenderMode; + uint32_t flags = use_distance_field_text + ? SkSurfaceProps::kUseDistanceFieldFonts_Flag + : 0; + // Use unknown pixel geometry to disable LCD text. + SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry); + if (can_use_lcd_text) { + // LegacyFontHost will get LCD text and skia figures out what type to use. + surface_props = + SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType); + } resource_->sk_surface = skia::AdoptRef(SkSurface::NewRenderTargetDirect( - gr_texture->asRenderTarget(), text_render_mode)); + gr_texture->asRenderTarget(), &surface_props)); } return resource_->sk_surface.get(); } +bool ResourceProvider::ScopedWriteLockGr::SurfaceHasMatchingProperties( + bool use_distance_field_text, + bool can_use_lcd_text) const { + const SkSurface* surface = resource_->sk_surface.get(); + bool surface_uses_distance_field_text = + surface->props().isUseDistanceFieldFonts(); + bool surface_can_use_lcd_text = + surface->props().pixelGeometry() != kUnknown_SkPixelGeometry; + return use_distance_field_text == surface_uses_distance_field_text && + can_use_lcd_text == surface_can_use_lcd_text; +} + ResourceProvider::SynchronousFence::SynchronousFence( gpu::gles2::GLES2Interface* gl) : gl_(gl), has_synchronized_(true) { diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index 40103f6b3e336c..c2f349ff05fd7b 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h @@ -335,9 +335,13 @@ class CC_EXPORT ResourceProvider { ResourceProvider::ResourceId resource_id); ~ScopedWriteLockGr(); - SkSurface* GetSkSurface(bool use_distance_field_text); + SkSurface* GetSkSurface(bool use_distance_field_text, + bool can_use_lcd_text); private: + bool SurfaceHasMatchingProperties(bool use_distance_field_text, + bool can_use_lcd_text) const; + ResourceProvider* resource_provider_; ResourceProvider::Resource* resource_; base::ThreadChecker thread_checker_; diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h index 7a7cc44b2d547e..141bc9712e69d1 100644 --- a/cc/test/fake_content_layer_client.h +++ b/cc/test/fake_content_layer_client.h @@ -31,7 +31,6 @@ class FakeContentLayerClient : public ContentLayerClient { SkCanvas* canvas, const gfx::Rect& rect, ContentLayerClient::GraphicsContextStatus gc_status) override; - void DidChangeLayerCanUseLCDText() override {} bool FillsBoundsCompletely() const override; void set_fill_with_nonsolid_color(bool nonsolid) { diff --git a/cc/test/layer_tree_host_common_test.cc b/cc/test/layer_tree_host_common_test.cc index 33e0cafc47c1f0..844165720f6fdb 100644 --- a/cc/test/layer_tree_host_common_test.cc +++ b/cc/test/layer_tree_host_common_test.cc @@ -59,7 +59,8 @@ void LayerTreeHostCommonTestBase::ExecuteCalculateDrawProperties( float device_scale_factor, float page_scale_factor, Layer* page_scale_application_layer, - bool can_use_lcd_text) { + bool can_use_lcd_text, + bool layers_always_allowed_lcd_text) { EXPECT_TRUE(page_scale_application_layer || (page_scale_factor == 1.f)); gfx::Transform identity_matrix; gfx::Size device_viewport_size = @@ -77,6 +78,7 @@ void LayerTreeHostCommonTestBase::ExecuteCalculateDrawProperties( inputs.page_scale_factor = page_scale_factor; inputs.page_scale_application_layer = page_scale_application_layer; inputs.can_use_lcd_text = can_use_lcd_text; + inputs.layers_always_allowed_lcd_text = layers_always_allowed_lcd_text; inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); } @@ -86,7 +88,8 @@ void LayerTreeHostCommonTestBase::ExecuteCalculateDrawProperties( float device_scale_factor, float page_scale_factor, LayerImpl* page_scale_application_layer, - bool can_use_lcd_text) { + bool can_use_lcd_text, + bool layers_always_allowed_lcd_text) { gfx::Transform identity_matrix; gfx::Size device_viewport_size = gfx::Size(root_layer->bounds().width() * device_scale_factor, @@ -103,6 +106,7 @@ void LayerTreeHostCommonTestBase::ExecuteCalculateDrawProperties( inputs.page_scale_factor = page_scale_factor; inputs.page_scale_application_layer = page_scale_application_layer; inputs.can_use_lcd_text = can_use_lcd_text; + inputs.layers_always_allowed_lcd_text = layers_always_allowed_lcd_text; inputs.can_adjust_raster_scales = true; ++render_surface_layer_list_count_; diff --git a/cc/test/layer_tree_host_common_test.h b/cc/test/layer_tree_host_common_test.h index 38b57d496d7f58..456183f5c34929 100644 --- a/cc/test/layer_tree_host_common_test.h +++ b/cc/test/layer_tree_host_common_test.h @@ -68,30 +68,29 @@ class LayerTreeHostCommonTestBase { float device_scale_factor, float page_scale_factor, Layer* page_scale_application_layer, - bool can_use_lcd_text); + bool can_use_lcd_text, + bool layers_always_allowed_lcd_text); void ExecuteCalculateDrawProperties(LayerImpl* root_layer, float device_scale_factor, float page_scale_factor, LayerImpl* page_scale_application_layer, - bool can_use_lcd_text); + bool can_use_lcd_text, + bool layers_always_allowed_lcd_text); template void ExecuteCalculateDrawProperties(LayerType* root_layer) { LayerType* page_scale_application_layer = NULL; - ExecuteCalculateDrawProperties( - root_layer, 1.f, 1.f, page_scale_application_layer, false); + ExecuteCalculateDrawProperties(root_layer, 1.f, 1.f, + page_scale_application_layer, false, false); } template void ExecuteCalculateDrawProperties(LayerType* root_layer, float device_scale_factor) { LayerType* page_scale_application_layer = NULL; - ExecuteCalculateDrawProperties(root_layer, - device_scale_factor, - 1.f, - page_scale_application_layer, - false); + ExecuteCalculateDrawProperties(root_layer, device_scale_factor, 1.f, + page_scale_application_layer, false, false); } template @@ -99,11 +98,9 @@ class LayerTreeHostCommonTestBase { float device_scale_factor, float page_scale_factor, LayerType* page_scale_application_layer) { - ExecuteCalculateDrawProperties(root_layer, - device_scale_factor, + ExecuteCalculateDrawProperties(root_layer, device_scale_factor, page_scale_factor, - page_scale_application_layer, - false); + page_scale_application_layer, false, false); } RenderSurfaceLayerList* render_surface_layer_list() const { diff --git a/cc/test/solid_color_content_layer_client.h b/cc/test/solid_color_content_layer_client.h index a851b7202d3f2d..7a962cfd448d18 100644 --- a/cc/test/solid_color_content_layer_client.h +++ b/cc/test/solid_color_content_layer_client.h @@ -16,7 +16,6 @@ class SolidColorContentLayerClient : public ContentLayerClient { explicit SolidColorContentLayerClient(SkColor color) : color_(color) {} // ContentLayerClient implementation. - void DidChangeLayerCanUseLCDText() override {} void PaintContents( SkCanvas* canvas, const gfx::Rect& rect, diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index f85d4e7bc00fdc..808bf21a767fc7 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -845,17 +845,12 @@ bool LayerTreeHost::UpdateLayers(Layer* root_layer, // Change this if this information is required. int render_surface_layer_list_id = 0; LayerTreeHostCommon::CalcDrawPropsMainInputs inputs( - root_layer, - device_viewport_size(), - gfx::Transform(), - device_scale_factor_, - page_scale_factor_, - page_scale_layer, - GetRendererCapabilities().max_texture_size, - settings_.can_use_lcd_text, + root_layer, device_viewport_size(), gfx::Transform(), + device_scale_factor_, page_scale_factor_, page_scale_layer, + GetRendererCapabilities().max_texture_size, settings_.can_use_lcd_text, + settings_.layers_always_allowed_lcd_text, can_render_to_separate_surface, - settings_.layer_transforms_should_scale_layer_contents, - &update_list, + settings_.layer_transforms_should_scale_layer_contents, &update_list, render_surface_layer_list_id); LayerTreeHostCommon::CalculateDrawProperties(&inputs); diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index 0ff66084cc76ad..818abf512f4c97 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc @@ -1269,6 +1269,7 @@ struct SubtreeGlobals { const LayerType* page_scale_application_layer; bool can_adjust_raster_scales; bool can_render_to_separate_surface; + bool layers_always_allowed_lcd_text; }; template @@ -1791,13 +1792,15 @@ static void CalculateDrawPropertiesInternal( // causes jank. bool adjust_text_aa = !animating_opacity_to_screen && !animating_transform_to_screen; - // To avoid color fringing, LCD text should only be used on opaque layers with - // just integral translation. - bool layer_can_use_lcd_text = - data_from_ancestor.subtree_can_use_lcd_text && - accumulated_draw_opacity == 1.f && - layer_draw_properties.target_space_transform. - IsIdentityOrIntegerTranslation(); + bool layer_can_use_lcd_text = true; + if (!globals.layers_always_allowed_lcd_text) { + // To avoid color fringing, LCD text should only be used on opaque layers + // with just integral translation. + layer_can_use_lcd_text = data_from_ancestor.subtree_can_use_lcd_text && + accumulated_draw_opacity == 1.f && + layer_draw_properties.target_space_transform + .IsIdentityOrIntegerTranslation(); + } gfx::Rect content_rect(layer->content_bounds()); @@ -2374,6 +2377,8 @@ static void ProcessCalcDrawPropsInputs( globals->can_render_to_separate_surface = inputs.can_render_to_separate_surface; globals->can_adjust_raster_scales = inputs.can_adjust_raster_scales; + globals->layers_always_allowed_lcd_text = + inputs.layers_always_allowed_lcd_text; data_for_recursion->parent_matrix = scaled_device_transform; data_for_recursion->full_hierarchy_matrix = identity_matrix; diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h index 089fe2933f274e..349b341f6ba978 100644 --- a/cc/trees/layer_tree_host_common.h +++ b/cc/trees/layer_tree_host_common.h @@ -40,6 +40,7 @@ class CC_EXPORT LayerTreeHostCommon { const LayerType* page_scale_application_layer, int max_texture_size, bool can_use_lcd_text, + bool layers_always_allowed_lcd_text, bool can_render_to_separate_surface, bool can_adjust_raster_scales, RenderSurfaceLayerListType* render_surface_layer_list, @@ -52,6 +53,7 @@ class CC_EXPORT LayerTreeHostCommon { page_scale_application_layer(page_scale_application_layer), max_texture_size(max_texture_size), can_use_lcd_text(can_use_lcd_text), + layers_always_allowed_lcd_text(layers_always_allowed_lcd_text), can_render_to_separate_surface(can_render_to_separate_surface), can_adjust_raster_scales(can_adjust_raster_scales), render_surface_layer_list(render_surface_layer_list), @@ -66,6 +68,7 @@ class CC_EXPORT LayerTreeHostCommon { const LayerType* page_scale_application_layer; int max_texture_size; bool can_use_lcd_text; + bool layers_always_allowed_lcd_text; bool can_render_to_separate_surface; bool can_adjust_raster_scales; RenderSurfaceLayerListType* render_surface_layer_list; @@ -222,6 +225,7 @@ LayerTreeHostCommon::CalcDrawPropsInputsForTesting::max() / 2, false, + false, true, false, render_surface_layer_list, @@ -246,6 +250,7 @@ LayerTreeHostCommon::CalcDrawPropsInputsForTesting::max() / 2, false, + false, true, false, render_surface_layer_list, diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc index 12e7a5e2f9d5eb..39bcbe628cc60c 100644 --- a/cc/trees/layer_tree_host_common_perftest.cc +++ b/cc/trees/layer_tree_host_common_perftest.cc @@ -93,19 +93,17 @@ class CalcDrawPropsMainTest : public LayerTreeHostCommonPerfTest { RenderSurfaceLayerList update_list; LayerTreeHostCommon::CalcDrawPropsMainInputs inputs( layer_tree_host()->root_layer(), - layer_tree_host()->device_viewport_size(), - gfx::Transform(), + layer_tree_host()->device_viewport_size(), gfx::Transform(), layer_tree_host()->device_scale_factor(), layer_tree_host()->page_scale_factor(), - layer_tree_host()->page_scale_layer(), - max_texture_size, + layer_tree_host()->page_scale_layer(), max_texture_size, layer_tree_host()->settings().can_use_lcd_text, + layer_tree_host()->settings().layers_always_allowed_lcd_text, can_render_to_separate_surface, layer_tree_host() ->settings() .layer_transforms_should_scale_layer_contents, - &update_list, - 0); + &update_list, 0); LayerTreeHostCommon::CalculateDrawProperties(&inputs); timer_.NextLap(); @@ -147,18 +145,15 @@ class CalcDrawPropsImplTest : public LayerTreeHostCommonPerfTest { LayerTreeHostImpl* host_impl) { LayerImplList update_list; LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( - active_tree->root_layer(), - active_tree->DrawViewportSize(), - host_impl->DrawTransform(), - active_tree->device_scale_factor(), + active_tree->root_layer(), active_tree->DrawViewportSize(), + host_impl->DrawTransform(), active_tree->device_scale_factor(), active_tree->total_page_scale_factor(), - active_tree->InnerViewportContainerLayer(), - max_texture_size, + active_tree->InnerViewportContainerLayer(), max_texture_size, host_impl->settings().can_use_lcd_text, + host_impl->settings().layers_always_allowed_lcd_text, can_render_to_separate_surface, host_impl->settings().layer_transforms_should_scale_layer_contents, - &update_list, - 0); + &update_list, 0); LayerTreeHostCommon::CalculateDrawProperties(&inputs); } }; diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index b40f66db486ddf..1a2c0a0fc4f679 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc @@ -59,7 +59,6 @@ class MockContentLayerClient : public ContentLayerClient { SkCanvas* canvas, const gfx::Rect& clip, ContentLayerClient::GraphicsContextStatus gc_status) override {} - void DidChangeLayerCanUseLCDText() override {} bool FillsBoundsCompletely() const override { return false; } }; @@ -5644,13 +5643,14 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { ASSERT_EQ(2u, root->render_surface()->layer_list().size()); } -typedef std::tr1::tuple LCDTextTestParam; +using LCDTextTestParam = std::tr1::tuple; class LCDTextTest : public LayerTreeHostCommonTestBase, public testing::TestWithParam { protected: virtual void SetUp() { can_use_lcd_text_ = std::tr1::get<0>(GetParam()); + layers_always_allowed_lcd_text_ = std::tr1::get<1>(GetParam()); root_ = Layer::Create(); child_ = Layer::Create(); @@ -5681,13 +5681,14 @@ class LCDTextTest true, false); - child_->SetForceRenderSurface(std::tr1::get<1>(GetParam())); + child_->SetForceRenderSurface(std::tr1::get<2>(GetParam())); host_ = CreateFakeLayerTreeHost(); host_->SetRootLayer(root_); } bool can_use_lcd_text_; + bool layers_always_allowed_lcd_text_; scoped_ptr host_; scoped_refptr root_; scoped_refptr child_; @@ -5695,108 +5696,115 @@ class LCDTextTest }; TEST_P(LCDTextTest, CanUseLCDText) { + bool expect_lcd_text = can_use_lcd_text_ || layers_always_allowed_lcd_text_; + bool expect_not_lcd_text = layers_always_allowed_lcd_text_; + // Case 1: Identity transform. gfx::Transform identity_matrix; - ExecuteCalculateDrawProperties( - root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); - EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); - EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text()); - EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text()); + ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_, + layers_always_allowed_lcd_text_); + EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text()); // Case 2: Integral translation. gfx::Transform integral_translation; integral_translation.Translate(1.0, 2.0); child_->SetTransform(integral_translation); - ExecuteCalculateDrawProperties( - root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); - EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); - EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text()); - EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text()); + ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_, + layers_always_allowed_lcd_text_); + EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text()); // Case 3: Non-integral translation. gfx::Transform non_integral_translation; non_integral_translation.Translate(1.5, 2.5); child_->SetTransform(non_integral_translation); - ExecuteCalculateDrawProperties( - root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); - EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); - EXPECT_FALSE(child_->can_use_lcd_text()); - EXPECT_FALSE(grand_child_->can_use_lcd_text()); + ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_, + layers_always_allowed_lcd_text_); + EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text()); + EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text()); + EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text()); // Case 4: Rotation. gfx::Transform rotation; rotation.Rotate(10.0); child_->SetTransform(rotation); - ExecuteCalculateDrawProperties( - root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); - EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); - EXPECT_FALSE(child_->can_use_lcd_text()); - EXPECT_FALSE(grand_child_->can_use_lcd_text()); + ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_, + layers_always_allowed_lcd_text_); + EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text()); + EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text()); + EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text()); // Case 5: Scale. gfx::Transform scale; scale.Scale(2.0, 2.0); child_->SetTransform(scale); - ExecuteCalculateDrawProperties( - root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); - EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); - EXPECT_FALSE(child_->can_use_lcd_text()); - EXPECT_FALSE(grand_child_->can_use_lcd_text()); + ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_, + layers_always_allowed_lcd_text_); + EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text()); + EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text()); + EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text()); // Case 6: Skew. gfx::Transform skew; skew.SkewX(10.0); child_->SetTransform(skew); - ExecuteCalculateDrawProperties( - root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); - EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); - EXPECT_FALSE(child_->can_use_lcd_text()); - EXPECT_FALSE(grand_child_->can_use_lcd_text()); + ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_, + layers_always_allowed_lcd_text_); + EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text()); + EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text()); + EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text()); // Case 7: Translucent. child_->SetTransform(identity_matrix); child_->SetOpacity(0.5f); - ExecuteCalculateDrawProperties( - root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); - EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); - EXPECT_FALSE(child_->can_use_lcd_text()); - EXPECT_FALSE(grand_child_->can_use_lcd_text()); + ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_, + layers_always_allowed_lcd_text_); + EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text()); + EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text()); + EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text()); // Case 8: Sanity check: restore transform and opacity. child_->SetTransform(identity_matrix); child_->SetOpacity(1.f); - ExecuteCalculateDrawProperties( - root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); - EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); - EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text()); - EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text()); + ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_, + layers_always_allowed_lcd_text_); + EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text()); } TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) { + bool expect_lcd_text = can_use_lcd_text_ || layers_always_allowed_lcd_text_; + // Sanity check: Make sure can_use_lcd_text_ is set on each node. - ExecuteCalculateDrawProperties( - root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); - EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); - EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text()); - EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text()); + ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_, + layers_always_allowed_lcd_text_); + EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text()); // Add opacity animation. child_->SetOpacity(0.9f); AddOpacityTransitionToController( child_->layer_animation_controller(), 10.0, 0.9f, 0.1f, false); - ExecuteCalculateDrawProperties( - root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); + ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_, + layers_always_allowed_lcd_text_); // Text AA should not be adjusted while animation is active. // Make sure LCD text AA setting remains unchanged. - EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); - EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text()); - EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text()); + EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text()); } INSTANTIATE_TEST_CASE_P(LayerTreeHostCommonTest, LCDTextTest, - testing::Combine(testing::Bool(), testing::Bool())); + testing::Combine(testing::Bool(), + testing::Bool(), + testing::Bool())); TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) { FakeImplProxy proxy; diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc index f4f174c49817b5..4d0717d4a59c3b 100644 --- a/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/cc/trees/layer_tree_host_pixeltest_masks.cc @@ -24,8 +24,6 @@ class MaskContentLayerClient : public ContentLayerClient { explicit MaskContentLayerClient(const gfx::Size& bounds) : bounds_(bounds) {} ~MaskContentLayerClient() override {} - void DidChangeLayerCanUseLCDText() override {} - bool FillsBoundsCompletely() const override { return false; } void PaintContents( diff --git a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc index d703e22a31c228..e7dd14916445db 100644 --- a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc +++ b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc @@ -59,8 +59,6 @@ class BlueYellowLayerClient : public ContentLayerClient { explicit BlueYellowLayerClient(gfx::Rect layer_rect) : layer_rect_(layer_rect) {} - void DidChangeLayerCanUseLCDText() override {} - bool FillsBoundsCompletely() const override { return false; } void PaintContents( diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index d9f7b83a2067d9..b78dd5c92d9f0e 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -1114,7 +1114,6 @@ class TestOpacityChangeLayerDelegate : public ContentLayerClient { if (test_layer_) test_layer_->SetOpacity(0.f); } - void DidChangeLayerCanUseLCDText() override {} bool FillsBoundsCompletely() const override { return false; } private: @@ -2308,46 +2307,41 @@ class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F( LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted); -class LayerTreeHostTestLCDNotification : public LayerTreeHostTest { +class LayerTreeHostTestLCDChange : public LayerTreeHostTest { public: - class NotificationClient : public ContentLayerClient { + class PaintClient : public FakeContentLayerClient { public: - NotificationClient() - : layer_(0), paint_count_(0), lcd_notification_count_(0) {} + PaintClient() : paint_count_(0) {} - void set_layer(Layer* layer) { layer_ = layer; } int paint_count() const { return paint_count_; } - int lcd_notification_count() const { return lcd_notification_count_; } void PaintContents( SkCanvas* canvas, const gfx::Rect& clip, ContentLayerClient::GraphicsContextStatus gc_status) override { + FakeContentLayerClient::PaintContents(canvas, clip, gc_status); ++paint_count_; } - void DidChangeLayerCanUseLCDText() override { - ++lcd_notification_count_; - layer_->SetNeedsDisplay(); - } + bool FillsBoundsCompletely() const override { return false; } private: - Layer* layer_; int paint_count_; - int lcd_notification_count_; }; void SetupTree() override { + num_tiles_rastered_ = 0; + scoped_refptr root_layer; if (layer_tree_host()->settings().impl_side_painting) root_layer = PictureLayer::Create(&client_); else root_layer = ContentLayer::Create(&client_); + client_.set_fill_with_nonsolid_color(true); root_layer->SetIsDrawable(true); - root_layer->SetBounds(gfx::Size(1, 1)); + root_layer->SetBounds(gfx::Size(10, 10)); layer_tree_host()->SetRootLayer(root_layer); - client_.set_layer(root_layer.get()); // The expecations are based on the assumption that the default // LCD settings are: @@ -2358,49 +2352,76 @@ class LayerTreeHostTestLCDNotification : public LayerTreeHostTest { } void BeginTest() override { PostSetNeedsCommitToMainThread(); } - void AfterTest() override {} - void DidCommit() override { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 1: - // The first update consists of one LCD notification and one paint. - EXPECT_EQ(1, client_.lcd_notification_count()); + // The first update consists of a paint of the whole layer. EXPECT_EQ(1, client_.paint_count()); // LCD text must have been enabled on the layer. EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text()); PostSetNeedsCommitToMainThread(); break; case 2: - // Since nothing changed on layer, there should be no notification - // or paint on the second update. - EXPECT_EQ(1, client_.lcd_notification_count()); + // Since nothing changed on layer, there should be no paint. EXPECT_EQ(1, client_.paint_count()); // LCD text must not have changed. EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text()); - // Change layer opacity that should trigger lcd notification. + // Change layer opacity that should trigger lcd change. layer_tree_host()->root_layer()->SetOpacity(.5f); - // No need to request a commit - setting opacity will do it. break; - default: - // Verify that there is no extra commit due to layer invalidation. - EXPECT_EQ(3, layer_tree_host()->source_frame_number()); - // LCD notification count should have incremented due to - // change in layer opacity. - EXPECT_EQ(2, client_.lcd_notification_count()); - // Paint count should be incremented due to invalidation. - EXPECT_EQ(2, client_.paint_count()); + case 3: + // LCD text doesn't require re-recording, so no painting should occur. + EXPECT_EQ(1, client_.paint_count()); // LCD text must have been disabled on the layer due to opacity. EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text()); + // Change layer opacity that should not trigger lcd change. + layer_tree_host()->root_layer()->SetOpacity(1.f); + break; + case 4: + // LCD text doesn't require re-recording, so no painting should occur. + EXPECT_EQ(1, client_.paint_count()); + // Even though LCD text could be allowed. + EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text()); EndTest(); break; } } + void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, + const Tile* tile) override { + ++num_tiles_rastered_; + } + + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { + switch (host_impl->active_tree()->source_frame_number()) { + case 0: + // The first draw. + EXPECT_EQ(1, num_tiles_rastered_); + break; + case 1: + // Nothing changed on the layer. + EXPECT_EQ(1, num_tiles_rastered_); + break; + case 2: + // LCD text was disabled, it should be re-rastered with LCD text off. + EXPECT_EQ(2, num_tiles_rastered_); + break; + case 3: + // LCD text was enabled but it's sticky and stays off. + EXPECT_EQ(2, num_tiles_rastered_); + break; + } + } + + void AfterTest() override {} + private: - NotificationClient client_; + PaintClient client_; + int num_tiles_rastered_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDNotification); +SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange); // Verify that the BeginFrame notification is used to initiate rendering. class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest { @@ -2571,8 +2592,6 @@ class LayerTreeHostTestChangeLayerPropertiesInPaintContents layer_->SetBounds(gfx::Size(2, 2)); } - void DidChangeLayerCanUseLCDText() override {} - bool FillsBoundsCompletely() const override { return false; } private: diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 6b2b37f2c5f762..c005a182161449 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc @@ -490,18 +490,14 @@ bool LayerTreeImpl::UpdateDrawProperties() { ++render_surface_layer_list_id_; LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( - root_layer(), - DrawViewportSize(), - layer_tree_host_impl_->DrawTransform(), - device_scale_factor(), - total_page_scale_factor(), - page_scale_layer, - resource_provider()->max_texture_size(), - settings().can_use_lcd_text, + root_layer(), DrawViewportSize(), + layer_tree_host_impl_->DrawTransform(), device_scale_factor(), + total_page_scale_factor(), page_scale_layer, + resource_provider()->max_texture_size(), settings().can_use_lcd_text, + settings().layers_always_allowed_lcd_text, can_render_to_separate_surface, settings().layer_transforms_should_scale_layer_contents, - &render_surface_layer_list_, - render_surface_layer_list_id_); + &render_surface_layer_list_, render_surface_layer_list_id_); LayerTreeHostCommon::CalculateDrawProperties(&inputs); } diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc index 48c41330978850..14c1defd0eba1f 100644 --- a/cc/trees/layer_tree_settings.cc +++ b/cc/trees/layer_tree_settings.cc @@ -43,6 +43,7 @@ LayerTreeSettings::LayerTreeSettings() timeout_and_draw_when_animation_checkerboards(true), maximum_number_of_failed_draws_before_draw_is_forced_(3), layer_transforms_should_scale_layer_contents(false), + layers_always_allowed_lcd_text(false), minimum_contents_scale(0.0625f), low_res_contents_scale_factor(0.25f), top_controls_height(0.f), diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 3097e59028246d..69ac995d228853 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h @@ -54,6 +54,7 @@ class CC_EXPORT LayerTreeSettings { bool timeout_and_draw_when_animation_checkerboards; int maximum_number_of_failed_draws_before_draw_is_forced_; bool layer_transforms_should_scale_layer_contents; + bool layers_always_allowed_lcd_text; float minimum_contents_scale; float low_res_contents_scale_factor; float top_controls_height; diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index e85c5790536e23..607a8ea8efc933 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc @@ -90,6 +90,10 @@ Compositor::Compositor(gfx::AcceleratedWidget widget, CommandLine* command_line = CommandLine::ForCurrentProcess(); cc::LayerTreeSettings settings; + // When impl-side painting is enabled, this will ensure PictureLayers always + // can have LCD text, to match the previous behaviour with ContentLayers, + // where LCD-not-allowed notifications were ignored. + settings.layers_always_allowed_lcd_text = true; settings.refresh_rate = context_factory_->DoesCreateTestContexts() ? kTestRefreshRate diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index 52c1f453c36d60..ee17f60fbe0bfb 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h @@ -339,7 +339,6 @@ class COMPOSITOR_EXPORT Layer SkCanvas* canvas, const gfx::Rect& clip, ContentLayerClient::GraphicsContextStatus gc_status) override; - void DidChangeLayerCanUseLCDText() override {} bool FillsBoundsCompletely() const override; cc::Layer* cc_layer() { return cc_layer_; }