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.
5 #include "base/debug/trace_event.h"
6 #include "cc/content_layer_client.h"
7 #include "cc/picture.h"
8 #include "cc/rendering_stats.h"
9 #include "third_party/skia/include/core/SkCanvas.h"
10 #include "third_party/skia/include/core/SkData.h"
11 #include "third_party/skia/include/utils/SkPictureUtils.h"
12 #include "ui/gfx/rect_conversions.h"
15 // URI label for a lazily decoded SkPixelRef.
16 const char labelLazyDecoded
[] = "lazy";
21 scoped_refptr
<Picture
> Picture::Create(gfx::Rect layer_rect
) {
22 return make_scoped_refptr(new Picture(layer_rect
));
25 Picture::Picture(gfx::Rect layer_rect
)
26 : layer_rect_(layer_rect
) {
29 Picture::Picture(const skia::RefPtr
<SkPicture
>& picture
,
31 gfx::Rect opaque_rect
) :
32 layer_rect_(layer_rect
),
33 opaque_rect_(opaque_rect
),
40 scoped_refptr
<Picture
> Picture::Clone() const {
41 // SkPicture is not thread-safe to rasterize with, so return a thread-safe
44 skia::RefPtr
<SkPicture
> clone
= skia::AdoptRef(picture_
->clone());
45 return make_scoped_refptr(new Picture(clone
, layer_rect_
, opaque_rect_
));
48 void Picture::Record(ContentLayerClient
* painter
,
49 RenderingStats
& stats
) {
50 TRACE_EVENT0("cc", "Picture::Record");
52 // Record() should only be called once.
54 picture_
= skia::AdoptRef(new SkPicture
);
56 // TODO(enne): Use SkPicture::kOptimizeForClippedPlayback_RecordingFlag
57 // once http://code.google.com/p/skia/issues/detail?id=1014 is fixed.
58 SkCanvas
* canvas
= picture_
->beginRecording(
61 SkPicture::kUsePathBoundsForClip_RecordingFlag
);
64 canvas
->translate(SkFloatToScalar(-layer_rect_
.x()),
65 SkFloatToScalar(-layer_rect_
.y()));
68 paint
.setAntiAlias(false);
69 paint
.setXfermodeMode(SkXfermode::kClear_Mode
);
70 SkRect layer_skrect
= SkRect::MakeXYWH(layer_rect_
.x(),
73 layer_rect_
.height());
74 canvas
->clipRect(layer_skrect
);
75 canvas
->drawRect(layer_skrect
, paint
);
77 gfx::RectF opaque_layer_rect
;
78 base::TimeTicks beginPaintTime
= base::TimeTicks::Now();
79 painter
->paintContents(canvas
, layer_rect_
, opaque_layer_rect
);
80 double delta
= (base::TimeTicks::Now() - beginPaintTime
).InSecondsF();
81 stats
.totalPaintTimeInSeconds
+= delta
;
82 stats
.totalPixelsPainted
+= layer_rect_
.width() *
86 picture_
->endRecording();
88 opaque_rect_
= gfx::ToEnclosedRect(opaque_layer_rect
);
91 void Picture::Raster(SkCanvas
* canvas
) {
92 TRACE_EVENT0("cc", "Picture::Raster");
95 canvas
->translate(layer_rect_
.x(), layer_rect_
.y());
96 canvas
->drawPicture(*picture_
);
100 void Picture::GatherPixelRefs(const gfx::Rect
& rect
,
101 std::list
<skia::LazyPixelRef
*>& result
) {
103 SkData
* pixel_refs
= SkPictureUtils::GatherPixelRefs(
104 picture_
.get(), SkRect::MakeXYWH(rect
.x(),
111 void* data
= const_cast<void*>(pixel_refs
->data());
117 SkPixelRef
** refs
= reinterpret_cast<SkPixelRef
**>(data
);
118 for (unsigned int i
= 0; i
< pixel_refs
->size() / sizeof(SkPixelRef
*); ++i
) {
119 if (*refs
&& (*refs
)->getURI() && !strncmp(
120 (*refs
)->getURI(), labelLazyDecoded
, 4)) {
121 result
.push_back(static_cast<skia::LazyPixelRef
*>(*refs
));