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 "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/core/SkTileGridPicture.h"
13 #include "third_party/skia/include/utils/SkPictureUtils.h"
14 #include "ui/gfx/rect_conversions.h"
15 #include "ui/gfx/skia_util.h"
18 // URI label for a lazily decoded SkPixelRef.
19 const char labelLazyDecoded
[] = "lazy";
20 // Tile size in recording coordinates used by SkTileGridPicture
21 const int tileGridSize
= 256;
26 scoped_refptr
<Picture
> Picture::Create(gfx::Rect layer_rect
) {
27 return make_scoped_refptr(new Picture(layer_rect
));
30 Picture::Picture(gfx::Rect layer_rect
)
31 : layer_rect_(layer_rect
) {
34 Picture::Picture(const skia::RefPtr
<SkPicture
>& picture
,
36 gfx::Rect opaque_rect
) :
37 layer_rect_(layer_rect
),
38 opaque_rect_(opaque_rect
),
45 scoped_refptr
<Picture
> Picture::Clone() const {
46 // SkPicture is not thread-safe to rasterize with, so return a thread-safe
49 skia::RefPtr
<SkPicture
> clone
= skia::AdoptRef(picture_
->clone());
50 return make_scoped_refptr(new Picture(clone
, layer_rect_
, opaque_rect_
));
53 void Picture::Record(ContentLayerClient
* painter
,
54 RenderingStats
* stats
) {
55 TRACE_EVENT2("cc", "Picture::Record",
56 "width", layer_rect_
.width(), "height", layer_rect_
.height());
58 // Record() should only be called once.
60 picture_
= skia::AdoptRef(new SkTileGridPicture(
61 tileGridSize
, tileGridSize
, layer_rect_
.width(), layer_rect_
.height()));
63 SkCanvas
* canvas
= picture_
->beginRecording(
66 SkPicture::kUsePathBoundsForClip_RecordingFlag
|
67 SkPicture::kOptimizeForClippedPlayback_RecordingFlag
);
70 canvas
->translate(SkFloatToScalar(-layer_rect_
.x()),
71 SkFloatToScalar(-layer_rect_
.y()));
74 paint
.setAntiAlias(false);
75 paint
.setXfermodeMode(SkXfermode::kClear_Mode
);
76 SkRect layer_skrect
= SkRect::MakeXYWH(layer_rect_
.x(),
79 layer_rect_
.height());
80 canvas
->clipRect(layer_skrect
);
81 canvas
->drawRect(layer_skrect
, paint
);
83 gfx::RectF opaque_layer_rect
;
84 base::TimeTicks begin_paint_time
;
86 begin_paint_time
= base::TimeTicks::Now();
87 painter
->paintContents(canvas
, layer_rect_
, opaque_layer_rect
);
89 stats
->totalPaintTime
+= base::TimeTicks::Now() - begin_paint_time
;
90 stats
->totalPixelsPainted
+=
91 layer_rect_
.width() * layer_rect_
.height();
95 picture_
->endRecording();
97 opaque_rect_
= gfx::ToEnclosedRect(opaque_layer_rect
);
100 void Picture::Raster(
102 gfx::Rect content_rect
,
103 float contents_scale
) {
104 TRACE_EVENT2("cc", "Picture::Raster",
105 "layer width", layer_rect_
.width(),
106 "layer height", layer_rect_
.height());
110 canvas
->clipRect(gfx::RectToSkRect(content_rect
));
111 canvas
->scale(contents_scale
, contents_scale
);
112 canvas
->translate(layer_rect_
.x(), layer_rect_
.y());
113 canvas
->drawPicture(*picture_
);
117 bool Picture::IsCheapInRect(const gfx::Rect
& layer_rect
) const {
118 TRACE_EVENT0("cc", "Picture::IsCheapInRect");
120 SkBitmap emptyBitmap
;
121 emptyBitmap
.setConfig(SkBitmap::kNo_Config
, layer_rect
.width(),
122 layer_rect
.height());
123 skia::AnalysisDevice
device(emptyBitmap
);
124 skia::AnalysisCanvas
canvas(&device
);
126 canvas
.drawPicture(*picture_
);
127 return canvas
.isCheap();
130 void Picture::GatherPixelRefs(const gfx::Rect
& layer_rect
,
131 std::list
<skia::LazyPixelRef
*>& pixel_ref_list
) {
133 SkData
* pixel_refs
= SkPictureUtils::GatherPixelRefs(
134 picture_
.get(), SkRect::MakeXYWH(layer_rect
.x(),
137 layer_rect
.height()));
141 void* data
= const_cast<void*>(pixel_refs
->data());
147 SkPixelRef
** refs
= reinterpret_cast<SkPixelRef
**>(data
);
148 for (unsigned int i
= 0; i
< pixel_refs
->size() / sizeof(SkPixelRef
*); ++i
) {
149 if (*refs
&& (*refs
)->getURI() && !strncmp(
150 (*refs
)->getURI(), labelLazyDecoded
, 4)) {
151 pixel_ref_list
.push_back(static_cast<skia::LazyPixelRef
*>(*refs
));