Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1366)

Side by Side Diff: cc/picture_pile_impl.cc

Issue 12471007: Part 8 of cc/ directory shuffles: resources (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/picture_pile_impl.h ('k') | cc/platform_color.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2012 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 "base/debug/trace_event.h"
6 #include "cc/base/region.h"
7 #include "cc/debug/debug_colors.h"
8 #include "cc/debug/rendering_stats.h"
9 #include "cc/picture_pile_impl.h"
10 #include "skia/ext/analysis_canvas.h"
11 #include "third_party/skia/include/core/SkCanvas.h"
12 #include "third_party/skia/include/core/SkSize.h"
13 #include "ui/gfx/rect_conversions.h"
14 #include "ui/gfx/size_conversions.h"
15 #include "ui/gfx/skia_util.h"
16
17 namespace cc {
18
19 PicturePileImpl::ClonesForDrawing::ClonesForDrawing(
20 const PicturePileImpl* pile, int num_threads) {
21 for (int i = 0; i < num_threads; i++) {
22 scoped_refptr<PicturePileImpl> clone =
23 PicturePileImpl::CreateCloneForDrawing(pile, i);
24 clones_.push_back(clone);
25 }
26 }
27
28 PicturePileImpl::ClonesForDrawing::~ClonesForDrawing() {
29 }
30
31 scoped_refptr<PicturePileImpl> PicturePileImpl::Create() {
32 return make_scoped_refptr(new PicturePileImpl());
33 }
34
35 scoped_refptr<PicturePileImpl> PicturePileImpl::CreateFromOther(
36 const PicturePileBase* other) {
37 return make_scoped_refptr(new PicturePileImpl(other));
38 }
39
40 scoped_refptr<PicturePileImpl> PicturePileImpl::CreateCloneForDrawing(
41 const PicturePileImpl* other, unsigned thread_index) {
42 return make_scoped_refptr(new PicturePileImpl(other, thread_index));
43 }
44
45 PicturePileImpl::PicturePileImpl()
46 : clones_for_drawing_(ClonesForDrawing(this, 0)) {
47 }
48
49 PicturePileImpl::PicturePileImpl(const PicturePileBase* other)
50 : PicturePileBase(other),
51 clones_for_drawing_(ClonesForDrawing(this, num_raster_threads())) {
52 }
53
54 PicturePileImpl::PicturePileImpl(
55 const PicturePileImpl* other, unsigned thread_index)
56 : PicturePileBase(other, thread_index),
57 clones_for_drawing_(ClonesForDrawing(this, 0)) {
58 }
59
60 PicturePileImpl::~PicturePileImpl() {
61 }
62
63 PicturePileImpl* PicturePileImpl::GetCloneForDrawingOnThread(
64 unsigned thread_index) const {
65 CHECK_GT(clones_for_drawing_.clones_.size(), thread_index);
66 return clones_for_drawing_.clones_[thread_index];
67 }
68
69 void PicturePileImpl::Raster(
70 SkCanvas* canvas,
71 gfx::Rect canvas_rect,
72 float contents_scale,
73 int64* total_pixels_rasterized) {
74
75 DCHECK(contents_scale >= min_contents_scale_);
76
77 #ifndef NDEBUG
78 // Any non-painted areas will be left in this color.
79 canvas->clear(DebugColors::NonPaintedFillColor());
80 #endif // NDEBUG
81
82 canvas->save();
83 canvas->translate(-canvas_rect.x(), -canvas_rect.y());
84
85 gfx::SizeF total_content_size = gfx::ScaleSize(tiling_.total_size(),
86 contents_scale);
87 gfx::Rect total_content_rect(gfx::ToCeiledSize(total_content_size));
88 gfx::Rect content_rect = total_content_rect;
89 content_rect.Intersect(canvas_rect);
90
91 // Clear one texel inside the right/bottom edge of the content rect,
92 // as it may only be partially covered by the picture playback.
93 // Also clear one texel outside the right/bottom edge of the content rect,
94 // as it may get blended in by linear filtering when zoomed in.
95 gfx::Rect deflated_content_rect = total_content_rect;
96 deflated_content_rect.Inset(0, 0, 1, 1);
97
98 gfx::Rect canvas_outside_content_rect = canvas_rect;
99 canvas_outside_content_rect.Subtract(deflated_content_rect);
100
101 if (!canvas_outside_content_rect.IsEmpty()) {
102 gfx::Rect inflated_content_rect = total_content_rect;
103 inflated_content_rect.Inset(0, 0, -1, -1);
104 canvas->clipRect(gfx::RectToSkRect(inflated_content_rect),
105 SkRegion::kReplace_Op);
106 canvas->clipRect(gfx::RectToSkRect(deflated_content_rect),
107 SkRegion::kDifference_Op);
108 canvas->drawColor(background_color_, SkXfermode::kSrc_Mode);
109 }
110
111 // Rasterize the collection of relevant picture piles.
112 gfx::Rect layer_rect = gfx::ToEnclosingRect(
113 gfx::ScaleRect(content_rect, 1.f / contents_scale));
114
115 canvas->clipRect(gfx::RectToSkRect(content_rect),
116 SkRegion::kReplace_Op);
117 Region unclipped(content_rect);
118 for (TilingData::Iterator tile_iter(&tiling_, layer_rect);
119 tile_iter; ++tile_iter) {
120 PictureListMap::iterator map_iter =
121 picture_list_map_.find(tile_iter.index());
122 if (map_iter == picture_list_map_.end())
123 continue;
124 PictureList& pic_list= map_iter->second;
125 if (pic_list.empty())
126 continue;
127
128 // Raster through the picture list top down, using clips to make sure that
129 // pictures on top are not overdrawn by pictures on the bottom.
130 for (PictureList::reverse_iterator i = pic_list.rbegin();
131 i != pic_list.rend(); ++i) {
132 // This is intentionally *enclosed* rect, so that the clip is aligned on
133 // integral post-scale content pixels and does not extend past the edges
134 // of the picture's layer rect. The min_contents_scale enforces that
135 // enough buffer pixels have been added such that the enclosed rect
136 // encompasses all invalidated pixels at any larger scale level.
137 gfx::Rect content_clip = gfx::ToEnclosedRect(
138 gfx::ScaleRect((*i)->LayerRect(), contents_scale));
139 DCHECK(!content_clip.IsEmpty());
140 if (!unclipped.Intersects(content_clip))
141 continue;
142
143 if (slow_down_raster_scale_factor_for_debug_) {
144 for (int j = 0; j < slow_down_raster_scale_factor_for_debug_; ++j)
145 (*i)->Raster(canvas, content_clip, contents_scale);
146 } else {
147 (*i)->Raster(canvas, content_clip, contents_scale);
148 }
149
150 // Don't allow pictures underneath to draw where this picture did.
151 canvas->clipRect(
152 gfx::RectToSkRect(content_clip),
153 SkRegion::kDifference_Op);
154 unclipped.Subtract(content_clip);
155
156 *total_pixels_rasterized +=
157 content_clip.width() * content_clip.height();
158 }
159 }
160
161 #ifndef NDEBUG
162 // Fill the remaining clip with debug color. This allows us to
163 // distinguish between non painted areas and problems with missing
164 // pictures.
165 SkPaint paint;
166 paint.setColor(DebugColors::MissingPictureFillColor());
167 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
168 canvas->drawPaint(paint);
169 #endif // NDEBUG
170
171 // We should always paint some part of |content_rect|.
172 DCHECK(!unclipped.Contains(content_rect));
173
174 canvas->restore();
175 }
176
177 void PicturePileImpl::GatherPixelRefs(
178 gfx::Rect content_rect,
179 float contents_scale,
180 std::list<skia::LazyPixelRef*>& pixel_refs) {
181 std::list<skia::LazyPixelRef*> result;
182
183 gfx::Rect layer_rect = gfx::ToEnclosingRect(
184 gfx::ScaleRect(content_rect, 1.f / contents_scale));
185
186 for (TilingData::Iterator tile_iter(&tiling_, layer_rect);
187 tile_iter; ++tile_iter) {
188 PictureListMap::iterator map_iter =
189 picture_list_map_.find(tile_iter.index());
190 if (map_iter == picture_list_map_.end())
191 continue;
192
193 PictureList& pic_list = map_iter->second;
194 for (PictureList::const_iterator i = pic_list.begin();
195 i != pic_list.end(); ++i) {
196 (*i)->GatherPixelRefs(layer_rect, result);
197 pixel_refs.splice(pixel_refs.end(), result);
198 }
199 }
200 }
201
202 skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() {
203 TRACE_EVENT0("cc", "PicturePileImpl::GetFlattenedPicture");
204
205 gfx::Rect layer_rect(tiling_.total_size());
206 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture);
207 if (layer_rect.IsEmpty())
208 return picture;
209
210 SkCanvas* canvas = picture->beginRecording(
211 layer_rect.width(),
212 layer_rect.height(),
213 SkPicture::kUsePathBoundsForClip_RecordingFlag);
214
215 int64 total_pixels_rasterized = 0;
216 Raster(canvas, layer_rect, 1.0, &total_pixels_rasterized);
217 picture->endRecording();
218
219 return picture;
220 }
221
222 void PicturePileImpl::AnalyzeInRect(const gfx::Rect& content_rect,
223 float contents_scale,
224 PicturePileImpl::Analysis* analysis) {
225 DCHECK(analysis);
226 TRACE_EVENT0("cc", "PicturePileImpl::AnalyzeInRect");
227
228 gfx::Rect layer_rect = gfx::ToEnclosingRect(
229 gfx::ScaleRect(content_rect, 1.f / contents_scale));
230
231 SkBitmap emptyBitmap;
232 emptyBitmap.setConfig(SkBitmap::kNo_Config, content_rect.width(),
233 content_rect.height());
234 skia::AnalysisDevice device(emptyBitmap);
235 skia::AnalysisCanvas canvas(&device);
236
237 int64 total_pixels_rasterized = 0;
238 Raster(&canvas, content_rect, contents_scale, &total_pixels_rasterized);
239
240 analysis->is_transparent = canvas.isTransparent();
241 analysis->is_solid_color = canvas.getColorIfSolid(&analysis->solid_color);
242 analysis->is_cheap_to_raster = canvas.isCheap();
243 }
244
245 PicturePileImpl::Analysis::Analysis() :
246 is_solid_color(false),
247 is_transparent(false),
248 is_cheap_to_raster(false) {
249 }
250
251 } // namespace cc
OLDNEW
« no previous file with comments | « cc/picture_pile_impl.h ('k') | cc/platform_color.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698