1 // Copyright 2010 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "cc/layers/content_layer.h" 6 7 #include "base/auto_reset.h" 8 #include "base/metrics/histogram.h" 9 #include "base/time/time.h" 10 #include "cc/layers/content_layer_client.h" 11 #include "cc/resources/bitmap_content_layer_updater.h" 12 #include "cc/resources/bitmap_skpicture_content_layer_updater.h" 13 #include "cc/resources/layer_painter.h" 14 #include "cc/trees/layer_tree_host.h" 15 16 namespace cc { 17 18 ContentLayerPainter::ContentLayerPainter(ContentLayerClient* client) 19 : client_(client) {} 20 21 scoped_ptr<ContentLayerPainter> ContentLayerPainter::Create( 22 ContentLayerClient* client) { 23 return make_scoped_ptr(new ContentLayerPainter(client)); 24 } 25 26 void ContentLayerPainter::Paint(SkCanvas* canvas, 27 gfx::Rect content_rect, 28 gfx::RectF* opaque) { 29 base::TimeTicks paint_start = base::TimeTicks::HighResNow(); 30 client_->PaintContents(canvas, content_rect, opaque); 31 base::TimeTicks paint_end = base::TimeTicks::HighResNow(); 32 double pixels_per_sec = (content_rect.width() * content_rect.height()) / 33 (paint_end - paint_start).InSecondsF(); 34 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.AccelContentPaintDurationMS", 35 (paint_end - paint_start).InMilliseconds(), 36 0, 37 120, 38 30); 39 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.AccelContentPaintMegapixPerSecond", 40 pixels_per_sec / 1000000, 41 10, 42 210, 43 30); 44 } 45 46 scoped_refptr<ContentLayer> ContentLayer::Create(ContentLayerClient* client) { 47 return make_scoped_refptr(new ContentLayer(client)); 48 } 49 50 ContentLayer::ContentLayer(ContentLayerClient* client) 51 : TiledLayer(), 52 client_(client), 53 can_use_lcd_text_last_frame_(can_use_lcd_text()) { 54 } 55 56 ContentLayer::~ContentLayer() {} 57 58 bool ContentLayer::DrawsContent() const { 59 return TiledLayer::DrawsContent() && client_; 60 } 61 62 void ContentLayer::SetLayerTreeHost(LayerTreeHost* host) { 63 TiledLayer::SetLayerTreeHost(host); 64 65 if (!updater_.get()) 66 return; 67 68 if (host) { 69 updater_->set_rendering_stats_instrumentation( 70 host->rendering_stats_instrumentation()); 71 } else { 72 updater_->set_rendering_stats_instrumentation(NULL); 73 } 74 } 75 76 void ContentLayer::SetTexturePriorities( 77 const PriorityCalculator& priority_calc) { 78 // Update the tile data before creating all the layer's tiles. 79 UpdateTileSizeAndTilingOption(); 80 81 TiledLayer::SetTexturePriorities(priority_calc); 82 } 83 84 bool ContentLayer::Update(ResourceUpdateQueue* queue, 85 const OcclusionTracker* occlusion) { 86 { 87 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, 88 true); 89 90 CreateUpdaterIfNeeded(); 91 UpdateCanUseLCDText(); 92 } 93 94 bool updated = TiledLayer::Update(queue, occlusion); 95 return updated; 96 } 97 98 bool ContentLayer::NeedMoreUpdates() { 99 return NeedsIdlePaint(); 100 } 101 102 LayerUpdater* ContentLayer::Updater() const { 103 return updater_.get(); 104 } 105 106 void ContentLayer::CreateUpdaterIfNeeded() { 107 if (updater_.get()) 108 return; 109 scoped_ptr<LayerPainter> painter = 110 ContentLayerPainter::Create(client_).PassAs<LayerPainter>(); 111 if (layer_tree_host()->settings().per_tile_painting_enabled) { 112 updater_ = BitmapSkPictureContentLayerUpdater::Create( 113 painter.Pass(), 114 rendering_stats_instrumentation(), 115 id()); 116 } else { 117 updater_ = BitmapContentLayerUpdater::Create( 118 painter.Pass(), 119 rendering_stats_instrumentation(), 120 id()); 121 } 122 updater_->SetOpaque(contents_opaque()); 123 124 unsigned texture_format = 125 layer_tree_host()->GetRendererCapabilities().best_texture_format; 126 SetTextureFormat(texture_format); 127 } 128 129 void ContentLayer::SetContentsOpaque(bool opaque) { 130 Layer::SetContentsOpaque(opaque); 131 if (updater_.get()) 132 updater_->SetOpaque(opaque); 133 } 134 135 void ContentLayer::UpdateCanUseLCDText() { 136 if (can_use_lcd_text_last_frame_ == can_use_lcd_text()) 137 return; 138 139 can_use_lcd_text_last_frame_ = can_use_lcd_text(); 140 if (client_) 141 client_->DidChangeLayerCanUseLCDText(); 142 } 143 144 bool ContentLayer::SupportsLCDText() const { 145 return true; 146 } 147 148 } // namespace cc 149