OLD | NEW |
| (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/content_layer_client.h" | |
7 #include "cc/debug/rendering_stats.h" | |
8 #include "cc/picture.h" | |
9 #include "skia/ext/analysis_canvas.h" | |
10 #include "third_party/skia/include/core/SkCanvas.h" | |
11 #include "third_party/skia/include/core/SkData.h" | |
12 #include "third_party/skia/include/utils/SkPictureUtils.h" | |
13 #include "ui/gfx/rect_conversions.h" | |
14 #include "ui/gfx/skia_util.h" | |
15 | |
16 namespace { | |
17 // URI label for a lazily decoded SkPixelRef. | |
18 const char labelLazyDecoded[] = "lazy"; | |
19 } | |
20 | |
21 namespace cc { | |
22 | |
23 scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) { | |
24 return make_scoped_refptr(new Picture(layer_rect)); | |
25 } | |
26 | |
27 Picture::Picture(gfx::Rect layer_rect) | |
28 : layer_rect_(layer_rect) { | |
29 } | |
30 | |
31 Picture::Picture(const skia::RefPtr<SkPicture>& picture, | |
32 gfx::Rect layer_rect, | |
33 gfx::Rect opaque_rect) : | |
34 layer_rect_(layer_rect), | |
35 opaque_rect_(opaque_rect), | |
36 picture_(picture) { | |
37 } | |
38 | |
39 Picture::~Picture() { | |
40 } | |
41 | |
42 scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread( | |
43 unsigned thread_index) const { | |
44 // SkPicture is not thread-safe to rasterize with, this returns a clone | |
45 // to rasterize with on a specific thread. | |
46 CHECK_GT(clones_.size(), thread_index); | |
47 return clones_[thread_index]; | |
48 } | |
49 | |
50 void Picture::CloneForDrawing(int num_threads) { | |
51 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); | |
52 | |
53 DCHECK(picture_); | |
54 scoped_array<SkPicture> clones(new SkPicture[num_threads]); | |
55 picture_->clone(&clones[0], num_threads); | |
56 | |
57 clones_.clear(); | |
58 for (int i = 0; i < num_threads; i++) { | |
59 scoped_refptr<Picture> clone = make_scoped_refptr( | |
60 new Picture(skia::AdoptRef(new SkPicture(clones[i])), | |
61 layer_rect_, | |
62 opaque_rect_)); | |
63 clones_.push_back(clone); | |
64 } | |
65 } | |
66 | |
67 void Picture::Record(ContentLayerClient* painter, | |
68 RenderingStats* stats, | |
69 const SkTileGridPicture::TileGridInfo& tileGridInfo) { | |
70 TRACE_EVENT2("cc", "Picture::Record", | |
71 "width", layer_rect_.width(), "height", layer_rect_.height()); | |
72 | |
73 // Record() should only be called once. | |
74 DCHECK(!picture_); | |
75 DCHECK(!tileGridInfo.fTileInterval.isEmpty()); | |
76 picture_ = skia::AdoptRef(new SkTileGridPicture( | |
77 layer_rect_.width(), layer_rect_.height(), tileGridInfo)); | |
78 | |
79 SkCanvas* canvas = picture_->beginRecording( | |
80 layer_rect_.width(), | |
81 layer_rect_.height(), | |
82 SkPicture::kUsePathBoundsForClip_RecordingFlag | | |
83 SkPicture::kOptimizeForClippedPlayback_RecordingFlag); | |
84 | |
85 canvas->save(); | |
86 canvas->translate(SkFloatToScalar(-layer_rect_.x()), | |
87 SkFloatToScalar(-layer_rect_.y())); | |
88 | |
89 SkPaint paint; | |
90 paint.setAntiAlias(false); | |
91 paint.setXfermodeMode(SkXfermode::kClear_Mode); | |
92 SkRect layer_skrect = SkRect::MakeXYWH(layer_rect_.x(), | |
93 layer_rect_.y(), | |
94 layer_rect_.width(), | |
95 layer_rect_.height()); | |
96 canvas->clipRect(layer_skrect); | |
97 canvas->drawRect(layer_skrect, paint); | |
98 | |
99 gfx::RectF opaque_layer_rect; | |
100 base::TimeTicks begin_paint_time; | |
101 if (stats) | |
102 begin_paint_time = base::TimeTicks::Now(); | |
103 painter->PaintContents(canvas, layer_rect_, &opaque_layer_rect); | |
104 if (stats) { | |
105 stats->totalPaintTime += base::TimeTicks::Now() - begin_paint_time; | |
106 stats->totalPixelsPainted += | |
107 layer_rect_.width() * layer_rect_.height(); | |
108 } | |
109 | |
110 canvas->restore(); | |
111 picture_->endRecording(); | |
112 | |
113 opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); | |
114 } | |
115 | |
116 void Picture::Raster( | |
117 SkCanvas* canvas, | |
118 gfx::Rect content_rect, | |
119 float contents_scale) { | |
120 TRACE_EVENT2("cc", "Picture::Raster", | |
121 "layer width", layer_rect_.width(), | |
122 "layer height", layer_rect_.height()); | |
123 DCHECK(picture_); | |
124 | |
125 canvas->save(); | |
126 canvas->clipRect(gfx::RectToSkRect(content_rect)); | |
127 canvas->scale(contents_scale, contents_scale); | |
128 canvas->translate(layer_rect_.x(), layer_rect_.y()); | |
129 canvas->drawPicture(*picture_); | |
130 canvas->restore(); | |
131 } | |
132 | |
133 void Picture::GatherPixelRefs(const gfx::Rect& layer_rect, | |
134 std::list<skia::LazyPixelRef*>& pixel_ref_list) { | |
135 DCHECK(picture_); | |
136 SkData* pixel_refs = SkPictureUtils::GatherPixelRefs( | |
137 picture_.get(), SkRect::MakeXYWH(layer_rect.x(), | |
138 layer_rect.y(), | |
139 layer_rect.width(), | |
140 layer_rect.height())); | |
141 if (!pixel_refs) | |
142 return; | |
143 | |
144 void* data = const_cast<void*>(pixel_refs->data()); | |
145 if (!data) { | |
146 pixel_refs->unref(); | |
147 return; | |
148 } | |
149 | |
150 SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data); | |
151 for (unsigned int i = 0; i < pixel_refs->size() / sizeof(SkPixelRef*); ++i) { | |
152 if (*refs && (*refs)->getURI() && !strncmp( | |
153 (*refs)->getURI(), labelLazyDecoded, 4)) { | |
154 pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs)); | |
155 } | |
156 refs++; | |
157 } | |
158 pixel_refs->unref(); | |
159 } | |
160 | |
161 } // namespace cc | |
OLD | NEW |