• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ContentLayerPainter(ContentLayerClient * client)18 ContentLayerPainter::ContentLayerPainter(ContentLayerClient* client)
19     : client_(client) {}
20 
Create(ContentLayerClient * client)21 scoped_ptr<ContentLayerPainter> ContentLayerPainter::Create(
22     ContentLayerClient* client) {
23   return make_scoped_ptr(new ContentLayerPainter(client));
24 }
25 
Paint(SkCanvas * canvas,gfx::Rect content_rect,gfx::RectF * opaque)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   // The start and end times might be the same if the paint was very fast or if
33   // our timer granularity is poor. Treat this as a very short time duration
34   // instead of none to avoid dividing by zero.
35   if (paint_end == paint_start)
36     paint_end += base::TimeDelta::FromMicroseconds(1);
37 
38   double pixels_per_sec = (content_rect.width() * content_rect.height()) /
39                           (paint_end - paint_start).InSecondsF();
40   UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.AccelContentPaintDurationMS",
41                               (paint_end - paint_start).InMilliseconds(),
42                               0,
43                               120,
44                               30);
45   UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.AccelContentPaintMegapixPerSecond",
46                               pixels_per_sec / 1000000,
47                               10,
48                               210,
49                               30);
50 }
51 
Create(ContentLayerClient * client)52 scoped_refptr<ContentLayer> ContentLayer::Create(ContentLayerClient* client) {
53   return make_scoped_refptr(new ContentLayer(client));
54 }
55 
ContentLayer(ContentLayerClient * client)56 ContentLayer::ContentLayer(ContentLayerClient* client)
57     : TiledLayer(),
58       client_(client),
59       can_use_lcd_text_last_frame_(can_use_lcd_text()) {
60 }
61 
~ContentLayer()62 ContentLayer::~ContentLayer() {}
63 
DrawsContent() const64 bool ContentLayer::DrawsContent() const {
65   return TiledLayer::DrawsContent() && client_;
66 }
67 
SetLayerTreeHost(LayerTreeHost * host)68 void ContentLayer::SetLayerTreeHost(LayerTreeHost* host) {
69   TiledLayer::SetLayerTreeHost(host);
70 
71   if (!updater_.get())
72     return;
73 
74   if (host) {
75     updater_->set_rendering_stats_instrumentation(
76         host->rendering_stats_instrumentation());
77   } else {
78     updater_->set_rendering_stats_instrumentation(NULL);
79   }
80 }
81 
SetTexturePriorities(const PriorityCalculator & priority_calc)82 void ContentLayer::SetTexturePriorities(
83     const PriorityCalculator& priority_calc) {
84   // Update the tile data before creating all the layer's tiles.
85   UpdateTileSizeAndTilingOption();
86 
87   TiledLayer::SetTexturePriorities(priority_calc);
88 }
89 
Update(ResourceUpdateQueue * queue,const OcclusionTracker * occlusion)90 bool ContentLayer::Update(ResourceUpdateQueue* queue,
91                           const OcclusionTracker* occlusion) {
92   {
93     base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
94                                                   true);
95 
96     CreateUpdaterIfNeeded();
97     UpdateCanUseLCDText();
98   }
99 
100   bool updated = TiledLayer::Update(queue, occlusion);
101   return updated;
102 }
103 
NeedMoreUpdates()104 bool ContentLayer::NeedMoreUpdates() {
105   return NeedsIdlePaint();
106 }
107 
Updater() const108 LayerUpdater* ContentLayer::Updater() const {
109   return updater_.get();
110 }
111 
CreateUpdaterIfNeeded()112 void ContentLayer::CreateUpdaterIfNeeded() {
113   if (updater_.get())
114     return;
115   scoped_ptr<LayerPainter> painter =
116       ContentLayerPainter::Create(client_).PassAs<LayerPainter>();
117   if (layer_tree_host()->settings().per_tile_painting_enabled) {
118     updater_ = BitmapSkPictureContentLayerUpdater::Create(
119         painter.Pass(),
120         rendering_stats_instrumentation(),
121         id());
122   } else {
123     updater_ = BitmapContentLayerUpdater::Create(
124         painter.Pass(),
125         rendering_stats_instrumentation(),
126         id());
127   }
128   updater_->SetOpaque(contents_opaque());
129 
130   SetTextureFormat(
131       layer_tree_host()->GetRendererCapabilities().best_texture_format);
132 }
133 
SetContentsOpaque(bool opaque)134 void ContentLayer::SetContentsOpaque(bool opaque) {
135   Layer::SetContentsOpaque(opaque);
136   if (updater_.get())
137     updater_->SetOpaque(opaque);
138 }
139 
UpdateCanUseLCDText()140 void ContentLayer::UpdateCanUseLCDText() {
141   if (can_use_lcd_text_last_frame_ == can_use_lcd_text())
142     return;
143 
144   can_use_lcd_text_last_frame_ = can_use_lcd_text();
145   if (client_)
146     client_->DidChangeLayerCanUseLCDText();
147 }
148 
SupportsLCDText() const149 bool ContentLayer::SupportsLCDText() const {
150   return true;
151 }
152 
GetPicture() const153 skia::RefPtr<SkPicture> ContentLayer::GetPicture() const {
154   if (!DrawsContent())
155     return skia::RefPtr<SkPicture>();
156 
157   int width = bounds().width();
158   int height = bounds().height();
159   gfx::RectF opaque;
160 
161   skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture);
162   SkCanvas* canvas = picture->beginRecording(width, height);
163   client_->PaintContents(canvas, gfx::Rect(width, height), &opaque);
164   picture->endRecording();
165   return picture;
166 }
167 
OnOutputSurfaceCreated()168 void ContentLayer::OnOutputSurfaceCreated() {
169   SetTextureFormat(
170       layer_tree_host()->GetRendererCapabilities().best_texture_format);
171   TiledLayer::OnOutputSurfaceCreated();
172 }
173 
174 }  // namespace cc
175