enne@chromium.org | d98c024 | 2012-11-08 06:22:35 | [diff] [blame] | 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 | |
danakj | 92015685 | 2015-05-18 20:22:29 | [diff] [blame^] | 5 | #include "cc/playback/picture.h" |
vmpstr@chromium.org | f95cc39 | 2013-04-20 01:14:59 | [diff] [blame] | 6 | |
vmpstr@chromium.org | 991db24 | 2013-04-25 19:11:57 | [diff] [blame] | 7 | #include <set> |
weiliangc | 7e508dd | 2015-03-10 17:15:19 | [diff] [blame] | 8 | #include <string> |
vmpstr@chromium.org | 991db24 | 2013-04-25 19:11:57 | [diff] [blame] | 9 | |
vmpstr@chromium.org | f95cc39 | 2013-04-20 01:14:59 | [diff] [blame] | 10 | #include "base/base64.h" |
ssid | 904ce3b | 2015-01-27 15:20:16 | [diff] [blame] | 11 | #include "base/trace_event/trace_event.h" |
| 12 | #include "base/trace_event/trace_event_argument.h" |
pdr@chromium.org | aafcd276 | 2013-05-14 11:11:18 | [diff] [blame] | 13 | #include "base/values.h" |
nduca@chromium.org | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 14 | #include "cc/base/math_util.h" |
vmpstr@chromium.org | 991db24 | 2013-04-25 19:11:57 | [diff] [blame] | 15 | #include "cc/base/util.h" |
ajuma | d7dd21a | 2015-01-09 00:57:31 | [diff] [blame] | 16 | #include "cc/debug/picture_debug_util.h" |
pdr@chromium.org | aafcd276 | 2013-05-14 11:11:18 | [diff] [blame] | 17 | #include "cc/debug/traced_picture.h" |
| 18 | #include "cc/debug/traced_value.h" |
jamesr@chromium.org | cc3cfaa | 2013-03-18 09:05:52 | [diff] [blame] | 19 | #include "cc/layers/content_layer_client.h" |
reveman@chromium.org | 16a2f50 | 2014-01-08 21:57:10 | [diff] [blame] | 20 | #include "skia/ext/pixel_ref_utils.h" |
enne@chromium.org | 3621e18 | 2012-11-09 22:37:09 | [diff] [blame] | 21 | #include "third_party/skia/include/core/SkCanvas.h" |
robertphillips | 9033483 | 2015-01-06 20:02:45 | [diff] [blame] | 22 | #include "third_party/skia/include/core/SkDrawPictureCallback.h" |
enne@chromium.org | d7eb8c7 | 2013-03-23 22:57:13 | [diff] [blame] | 23 | #include "third_party/skia/include/core/SkPaint.h" |
robertphillips@google.com | de14c2c | 2014-04-24 01:02:25 | [diff] [blame] | 24 | #include "third_party/skia/include/core/SkPictureRecorder.h" |
vmpstr@chromium.org | f95cc39 | 2013-04-20 01:14:59 | [diff] [blame] | 25 | #include "third_party/skia/include/core/SkStream.h" |
scottmg@chromium.org | 600b6e8 | 2014-04-04 23:48:21 | [diff] [blame] | 26 | #include "third_party/skia/include/utils/SkNullCanvas.h" |
schenney | 6450d05 | 2014-12-03 02:12:31 | [diff] [blame] | 27 | #include "third_party/skia/include/utils/SkPictureUtils.h" |
vmpstr@chromium.org | 4434e29 | 2013-05-20 05:51:37 | [diff] [blame] | 28 | #include "ui/gfx/codec/jpeg_codec.h" |
| 29 | #include "ui/gfx/codec/png_codec.h" |
heejin.r.chung | d28506ba | 2014-10-23 16:36:20 | [diff] [blame] | 30 | #include "ui/gfx/geometry/rect_conversions.h" |
enne@chromium.org | ce37a15 | 2013-01-08 17:12:33 | [diff] [blame] | 31 | #include "ui/gfx/skia_util.h" |
qinmin@chromium.org | f760de8 | 2012-12-13 04:28:05 | [diff] [blame] | 32 | |
reveman@chromium.org | 87564e2 | 2013-05-03 05:32:59 | [diff] [blame] | 33 | namespace cc { |
| 34 | |
qinmin@chromium.org | f760de8 | 2012-12-13 04:28:05 | [diff] [blame] | 35 | namespace { |
vmpstr@chromium.org | 4434e29 | 2013-05-20 05:51:37 | [diff] [blame] | 36 | |
| 37 | bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) { |
| 38 | const unsigned char* data = static_cast<const unsigned char *>(buffer); |
| 39 | |
| 40 | // Try PNG first. |
| 41 | if (gfx::PNGCodec::Decode(data, size, bm)) |
| 42 | return true; |
| 43 | |
| 44 | // Try JPEG. |
| 45 | scoped_ptr<SkBitmap> decoded_jpeg(gfx::JPEGCodec::Decode(data, size)); |
| 46 | if (decoded_jpeg) { |
| 47 | *bm = *decoded_jpeg; |
| 48 | return true; |
| 49 | } |
| 50 | return false; |
| 51 | } |
enne@chromium.org | d7eb8c7 | 2013-03-23 22:57:13 | [diff] [blame] | 52 | |
reveman@chromium.org | 87564e2 | 2013-05-03 05:32:59 | [diff] [blame] | 53 | } // namespace |
enne@chromium.org | d98c024 | 2012-11-08 06:22:35 | [diff] [blame] | 54 | |
schenney | 0154bfa | 2015-02-05 19:46:49 | [diff] [blame] | 55 | scoped_refptr<Picture> Picture::Create( |
| 56 | const gfx::Rect& layer_rect, |
| 57 | ContentLayerClient* client, |
| 58 | const gfx::Size& tile_grid_size, |
| 59 | bool gather_pixel_refs, |
| 60 | RecordingSource::RecordingMode recording_mode) { |
weiliangc | 7e508dd | 2015-03-10 17:15:19 | [diff] [blame] | 61 | scoped_refptr<Picture> picture = |
| 62 | make_scoped_refptr(new Picture(layer_rect, tile_grid_size)); |
dominikg@chromium.org | d851e2f | 2014-02-07 21:33:21 | [diff] [blame] | 63 | |
weiliangc | 7e508dd | 2015-03-10 17:15:19 | [diff] [blame] | 64 | picture->Record(client, recording_mode); |
dominikg@chromium.org | d851e2f | 2014-02-07 21:33:21 | [diff] [blame] | 65 | if (gather_pixel_refs) |
weiliangc | 7e508dd | 2015-03-10 17:15:19 | [diff] [blame] | 66 | picture->GatherPixelRefs(); |
dominikg@chromium.org | d851e2f | 2014-02-07 21:33:21 | [diff] [blame] | 67 | |
| 68 | return picture; |
enne@chromium.org | 3621e18 | 2012-11-09 22:37:09 | [diff] [blame] | 69 | } |
| 70 | |
weiliangc | 7e508dd | 2015-03-10 17:15:19 | [diff] [blame] | 71 | Picture::Picture(const gfx::Rect& layer_rect, const gfx::Size& tile_grid_size) |
| 72 | : layer_rect_(layer_rect), pixel_refs_(tile_grid_size) { |
pdr@chromium.org | aafcd276 | 2013-05-14 11:11:18 | [diff] [blame] | 73 | // Instead of recording a trace event for object creation here, we wait for |
| 74 | // the picture to be recorded in Picture::Record. |
vmpstr@chromium.org | f95cc39 | 2013-04-20 01:14:59 | [diff] [blame] | 75 | } |
| 76 | |
dsinclair@chromium.org | c883e8b | 2013-09-01 23:36:31 | [diff] [blame] | 77 | scoped_refptr<Picture> Picture::CreateFromSkpValue(const base::Value* value) { |
| 78 | // Decode the picture from base64. |
| 79 | std::string encoded; |
| 80 | if (!value->GetAsString(&encoded)) |
| 81 | return NULL; |
| 82 | |
| 83 | std::string decoded; |
| 84 | base::Base64Decode(encoded, &decoded); |
| 85 | SkMemoryStream stream(decoded.data(), decoded.size()); |
| 86 | |
| 87 | // Read the picture. This creates an empty picture on failure. |
| 88 | SkPicture* skpicture = SkPicture::CreateFromStream(&stream, &DecodeBitmap); |
| 89 | if (skpicture == NULL) |
| 90 | return NULL; |
| 91 | |
reed | ba7b16f7 | 2014-12-13 00:01:00 | [diff] [blame] | 92 | gfx::Rect layer_rect(gfx::SkIRectToRect(skpicture->cullRect().roundOut())); |
danakj | 1799b72d | 2014-09-12 21:29:51 | [diff] [blame] | 93 | return make_scoped_refptr(new Picture(skpicture, layer_rect)); |
dsinclair@chromium.org | c883e8b | 2013-09-01 23:36:31 | [diff] [blame] | 94 | } |
| 95 | |
scroggo@google.com | 2927bea | 2013-07-03 21:49:53 | [diff] [blame] | 96 | scoped_refptr<Picture> Picture::CreateFromValue(const base::Value* raw_value) { |
nduca@chromium.org | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 97 | const base::DictionaryValue* value = NULL; |
scroggo@google.com | 2927bea | 2013-07-03 21:49:53 | [diff] [blame] | 98 | if (!raw_value->GetAsDictionary(&value)) |
| 99 | return NULL; |
nduca@chromium.org | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 100 | |
vmpstr@chromium.org | f95cc39 | 2013-04-20 01:14:59 | [diff] [blame] | 101 | // Decode the picture from base64. |
nduca@chromium.org | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 102 | std::string encoded; |
scroggo@google.com | 2927bea | 2013-07-03 21:49:53 | [diff] [blame] | 103 | if (!value->GetString("skp64", &encoded)) |
| 104 | return NULL; |
nduca@chromium.org | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 105 | |
vmpstr@chromium.org | f95cc39 | 2013-04-20 01:14:59 | [diff] [blame] | 106 | std::string decoded; |
nduca@chromium.org | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 107 | base::Base64Decode(encoded, &decoded); |
vmpstr@chromium.org | f95cc39 | 2013-04-20 01:14:59 | [diff] [blame] | 108 | SkMemoryStream stream(decoded.data(), decoded.size()); |
| 109 | |
scroggo@google.com | 2927bea | 2013-07-03 21:49:53 | [diff] [blame] | 110 | const base::Value* layer_rect_value = NULL; |
| 111 | if (!value->Get("params.layer_rect", &layer_rect_value)) |
| 112 | return NULL; |
vmpstr@chromium.org | f95cc39 | 2013-04-20 01:14:59 | [diff] [blame] | 113 | |
scroggo@google.com | 2927bea | 2013-07-03 21:49:53 | [diff] [blame] | 114 | gfx::Rect layer_rect; |
| 115 | if (!MathUtil::FromValue(layer_rect_value, &layer_rect)) |
| 116 | return NULL; |
| 117 | |
vmpstr@chromium.org | f95cc39 | 2013-04-20 01:14:59 | [diff] [blame] | 118 | // Read the picture. This creates an empty picture on failure. |
scroggo@google.com | 2927bea | 2013-07-03 21:49:53 | [diff] [blame] | 119 | SkPicture* skpicture = SkPicture::CreateFromStream(&stream, &DecodeBitmap); |
| 120 | if (skpicture == NULL) |
| 121 | return NULL; |
| 122 | |
danakj | 1799b72d | 2014-09-12 21:29:51 | [diff] [blame] | 123 | return make_scoped_refptr(new Picture(skpicture, layer_rect)); |
scroggo@google.com | 2927bea | 2013-07-03 21:49:53 | [diff] [blame] | 124 | } |
| 125 | |
danakj | 1799b72d | 2014-09-12 21:29:51 | [diff] [blame] | 126 | Picture::Picture(SkPicture* picture, const gfx::Rect& layer_rect) |
| 127 | : layer_rect_(layer_rect), |
| 128 | picture_(skia::AdoptRef(picture)), |
weiliangc | 7e508dd | 2015-03-10 17:15:19 | [diff] [blame] | 129 | pixel_refs_(layer_rect.size()) { |
enne@chromium.org | 3621e18 | 2012-11-09 22:37:09 | [diff] [blame] | 130 | } |
| 131 | |
danakj@chromium.org | 1940c4e | 2012-12-04 05:08:15 | [diff] [blame] | 132 | Picture::Picture(const skia::RefPtr<SkPicture>& picture, |
prashant.n@samsung.com | 0023fc7 | 2014-01-10 20:05:06 | [diff] [blame] | 133 | const gfx::Rect& layer_rect, |
weiliangc | 7e508dd | 2015-03-10 17:15:19 | [diff] [blame] | 134 | const PixelRefMap& pixel_refs) |
| 135 | : layer_rect_(layer_rect), picture_(picture), pixel_refs_(pixel_refs) { |
enne@chromium.org | d98c024 | 2012-11-08 06:22:35 | [diff] [blame] | 136 | } |
| 137 | |
| 138 | Picture::~Picture() { |
pdr@chromium.org | aafcd276 | 2013-05-14 11:11:18 | [diff] [blame] | 139 | TRACE_EVENT_OBJECT_DELETED_WITH_ID( |
jungjik.lee | d9172a7 | 2015-01-09 02:35:32 | [diff] [blame] | 140 | TRACE_DISABLED_BY_DEFAULT("cc.debug.picture"), "cc::Picture", this); |
enne@chromium.org | d98c024 | 2012-11-08 06:22:35 | [diff] [blame] | 141 | } |
| 142 | |
hendrikw | 69965524 | 2014-12-03 21:48:04 | [diff] [blame] | 143 | bool Picture::IsSuitableForGpuRasterization(const char** reason) const { |
alokp@chromium.org | 6a41ea0c | 2014-04-10 15:12:15 | [diff] [blame] | 144 | DCHECK(picture_); |
| 145 | |
hendrikw | 69965524 | 2014-12-03 21:48:04 | [diff] [blame] | 146 | // TODO(hendrikw): SkPicture::suitableForGpuRasterization takes a GrContext. |
| 147 | // Currently the GrContext isn't used, and should probably be removed from |
| 148 | // skia. |
| 149 | return picture_->suitableForGpuRasterization(nullptr, reason); |
alokp@chromium.org | 6a41ea0c | 2014-04-10 15:12:15 | [diff] [blame] | 150 | } |
| 151 | |
hendrikw | c60f5fb | 2014-08-27 00:08:54 | [diff] [blame] | 152 | int Picture::ApproximateOpCount() const { |
| 153 | DCHECK(picture_); |
| 154 | return picture_->approximateOpCount(); |
| 155 | } |
| 156 | |
schenney | 6450d05 | 2014-12-03 02:12:31 | [diff] [blame] | 157 | size_t Picture::ApproximateMemoryUsage() const { |
| 158 | DCHECK(picture_); |
| 159 | return SkPictureUtils::ApproximateBytesUsed(picture_.get()); |
| 160 | } |
| 161 | |
ajuma@chromium.org | e942c7d | 2014-08-21 14:58:57 | [diff] [blame] | 162 | bool Picture::HasText() const { |
| 163 | DCHECK(picture_); |
| 164 | return picture_->hasText(); |
enne@chromium.org | 3621e18 | 2012-11-09 22:37:09 | [diff] [blame] | 165 | } |
| 166 | |
aelias@chromium.org | c97dfc6 | 2012-12-04 09:51:20 | [diff] [blame] | 167 | void Picture::Record(ContentLayerClient* painter, |
schenney | 0154bfa | 2015-02-05 19:46:49 | [diff] [blame] | 168 | RecordingSource::RecordingMode recording_mode) { |
scottmg@chromium.org | 600b6e8 | 2014-04-04 23:48:21 | [diff] [blame] | 169 | TRACE_EVENT2("cc", |
| 170 | "Picture::Record", |
| 171 | "data", |
| 172 | AsTraceableRecordData(), |
| 173 | "recording_mode", |
| 174 | recording_mode); |
reveman@chromium.org | 3b93eb00 | 2012-11-29 08:00:33 | [diff] [blame] | 175 | |
dominikg@chromium.org | d851e2f | 2014-02-07 21:33:21 | [diff] [blame] | 176 | DCHECK(!picture_); |
robertphillips@google.com | e93fbdd | 2014-04-16 17:34:21 | [diff] [blame] | 177 | |
mtklein | 8c91f2c | 2014-11-18 17:52:36 | [diff] [blame] | 178 | SkRTreeFactory factory; |
robertphillips@google.com | de14c2c | 2014-04-24 01:02:25 | [diff] [blame] | 179 | SkPictureRecorder recorder; |
reveman@chromium.org | 3b93eb00 | 2012-11-29 08:00:33 | [diff] [blame] | 180 | |
scottmg@chromium.org | 600b6e8 | 2014-04-04 23:48:21 | [diff] [blame] | 181 | skia::RefPtr<SkCanvas> canvas; |
robertphillips@google.com | 151f368 | 2014-06-12 18:29:02 | [diff] [blame] | 182 | canvas = skia::SharePtr(recorder.beginRecording( |
robertphillips | 5980d99 | 2014-11-18 14:48:46 | [diff] [blame] | 183 | layer_rect_.width(), layer_rect_.height(), &factory, |
| 184 | SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag)); |
robertphillips@google.com | e93fbdd | 2014-04-16 17:34:21 | [diff] [blame] | 185 | |
schenney | 0154bfa | 2015-02-05 19:46:49 | [diff] [blame] | 186 | ContentLayerClient::PaintingControlSetting painting_control = |
| 187 | ContentLayerClient::PAINTING_BEHAVIOR_NORMAL; |
schenney@chromium.org | 276172b | 2014-05-02 21:03:03 | [diff] [blame] | 188 | |
scottmg@chromium.org | 600b6e8 | 2014-04-04 23:48:21 | [diff] [blame] | 189 | switch (recording_mode) { |
schenney | 0154bfa | 2015-02-05 19:46:49 | [diff] [blame] | 190 | case RecordingSource::RECORD_NORMALLY: |
schenney@chromium.org | 276172b | 2014-05-02 21:03:03 | [diff] [blame] | 191 | // Already setup for normal recording. |
scottmg@chromium.org | 600b6e8 | 2014-04-04 23:48:21 | [diff] [blame] | 192 | break; |
schenney | 0154bfa | 2015-02-05 19:46:49 | [diff] [blame] | 193 | case RecordingSource::RECORD_WITH_SK_NULL_CANVAS: |
scottmg@chromium.org | 600b6e8 | 2014-04-04 23:48:21 | [diff] [blame] | 194 | canvas = skia::AdoptRef(SkCreateNullCanvas()); |
| 195 | break; |
schenney | 0154bfa | 2015-02-05 19:46:49 | [diff] [blame] | 196 | case RecordingSource::RECORD_WITH_PAINTING_DISABLED: |
schenney@chromium.org | 276172b | 2014-05-02 21:03:03 | [diff] [blame] | 197 | // We pass a disable flag through the paint calls when perfromance |
| 198 | // testing (the only time this case should ever arise) when we want to |
| 199 | // prevent the Blink GraphicsContext object from consuming any compute |
| 200 | // time. |
| 201 | canvas = skia::AdoptRef(SkCreateNullCanvas()); |
schenney | 68d12cf | 2015-04-23 18:31:08 | [diff] [blame] | 202 | painting_control = ContentLayerClient::DISPLAY_LIST_PAINTING_DISABLED; |
schenney | 0154bfa | 2015-02-05 19:46:49 | [diff] [blame] | 203 | break; |
| 204 | case RecordingSource::RECORD_WITH_CACHING_DISABLED: |
| 205 | // This mode should give the same results as RECORD_NORMALLY. |
| 206 | painting_control = ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED; |
mtklein@chromium.org | bc912d6 | 2014-04-30 14:53:44 | [diff] [blame] | 207 | break; |
scottmg@chromium.org | 600b6e8 | 2014-04-04 23:48:21 | [diff] [blame] | 208 | default: |
schenney | 68d12cf | 2015-04-23 18:31:08 | [diff] [blame] | 209 | // case RecordingSource::RECORD_WITH_CONSTRUCTION_DISABLED should |
| 210 | // not be reached |
scottmg@chromium.org | 600b6e8 | 2014-04-04 23:48:21 | [diff] [blame] | 211 | NOTREACHED(); |
| 212 | } |
enne@chromium.org | 3621e18 | 2012-11-09 22:37:09 | [diff] [blame] | 213 | |
schenney@chromium.org | 276172b | 2014-05-02 21:03:03 | [diff] [blame] | 214 | canvas->save(); |
| 215 | canvas->translate(SkFloatToScalar(-layer_rect_.x()), |
| 216 | SkFloatToScalar(-layer_rect_.y())); |
enne@chromium.org | 3621e18 | 2012-11-09 22:37:09 | [diff] [blame] | 217 | |
danakj | 0e10bbd | 2015-03-19 04:14:51 | [diff] [blame] | 218 | canvas->clipRect(gfx::RectToSkRect(layer_rect_)); |
vmpstr@chromium.org | 50785d1 | 2013-05-07 23:42:40 | [diff] [blame] | 219 | |
schenney | 0154bfa | 2015-02-05 19:46:49 | [diff] [blame] | 220 | painter->PaintContents(canvas.get(), layer_rect_, painting_control); |
nick@chromium.org | cdc429bc | 2014-04-03 22:47:42 | [diff] [blame] | 221 | |
schenney@chromium.org | 276172b | 2014-05-02 21:03:03 | [diff] [blame] | 222 | canvas->restore(); |
thestig | 3523bf8 | 2015-04-08 18:49:00 | [diff] [blame] | 223 | picture_ = skia::AdoptRef(recorder.endRecordingAsPicture()); |
robertphillips@google.com | e93fbdd | 2014-04-16 17:34:21 | [diff] [blame] | 224 | DCHECK(picture_); |
pdr@chromium.org | aafcd276 | 2013-05-14 11:11:18 | [diff] [blame] | 225 | |
nduca@chromium.org | 37349bc | 2013-06-04 01:31:52 | [diff] [blame] | 226 | EmitTraceSnapshot(); |
reveman@chromium.org | 87564e2 | 2013-05-03 05:32:59 | [diff] [blame] | 227 | } |
vmpstr@chromium.org | 991db24 | 2013-04-25 19:11:57 | [diff] [blame] | 228 | |
weiliangc | 7e508dd | 2015-03-10 17:15:19 | [diff] [blame] | 229 | void Picture::GatherPixelRefs() { |
reveman@chromium.org | 87564e2 | 2013-05-03 05:32:59 | [diff] [blame] | 230 | TRACE_EVENT2("cc", "Picture::GatherPixelRefs", |
| 231 | "width", layer_rect_.width(), |
| 232 | "height", layer_rect_.height()); |
| 233 | |
| 234 | DCHECK(picture_); |
dominikg@chromium.org | d851e2f | 2014-02-07 21:33:21 | [diff] [blame] | 235 | DCHECK(pixel_refs_.empty()); |
enne@chromium.org | 2b65462 | 2013-12-17 02:07:18 | [diff] [blame] | 236 | if (!WillPlayBackBitmaps()) |
| 237 | return; |
reveman@chromium.org | 87564e2 | 2013-05-03 05:32:59 | [diff] [blame] | 238 | |
weiliangc | 7e508dd | 2015-03-10 17:15:19 | [diff] [blame] | 239 | pixel_refs_.GatherPixelRefsFromPicture(picture_.get()); |
enne@chromium.org | 3621e18 | 2012-11-09 22:37:09 | [diff] [blame] | 240 | } |
| 241 | |
reveman@chromium.org | 2b46519 | 2014-08-22 07:24:01 | [diff] [blame] | 242 | int Picture::Raster(SkCanvas* canvas, |
fmalita | f5190e0 | 2015-02-26 15:48:42 | [diff] [blame] | 243 | SkPicture::AbortCallback* callback, |
reveman@chromium.org | 2b46519 | 2014-08-22 07:24:01 | [diff] [blame] | 244 | const Region& negated_content_region, |
| 245 | float contents_scale) const { |
ernstm@chromium.org | adbe30f | 2013-10-11 21:12:33 | [diff] [blame] | 246 | TRACE_EVENT_BEGIN1( |
vmpstr@chromium.org | f1baa59 | 2013-10-29 04:46:45 | [diff] [blame] | 247 | "cc", |
| 248 | "Picture::Raster", |
| 249 | "data", |
| 250 | AsTraceableRasterData(contents_scale)); |
pdr@chromium.org | aafcd276 | 2013-05-14 11:11:18 | [diff] [blame] | 251 | |
danakj@chromium.org | 1940c4e | 2012-12-04 05:08:15 | [diff] [blame] | 252 | DCHECK(picture_); |
enne@chromium.org | ce37a15 | 2013-01-08 17:12:33 | [diff] [blame] | 253 | |
enne@chromium.org | 3621e18 | 2012-11-09 22:37:09 | [diff] [blame] | 254 | canvas->save(); |
vmpstr@chromium.org | f1baa59 | 2013-10-29 04:46:45 | [diff] [blame] | 255 | |
| 256 | for (Region::Iterator it(negated_content_region); it.has_rect(); it.next()) |
| 257 | canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op); |
| 258 | |
enne@chromium.org | ce37a15 | 2013-01-08 17:12:33 | [diff] [blame] | 259 | canvas->scale(contents_scale, contents_scale); |
reveman@google.com | c96e821 | 2012-11-27 22:48:08 | [diff] [blame] | 260 | canvas->translate(layer_rect_.x(), layer_rect_.y()); |
mtklein | c893bf973 | 2014-10-17 15:16:05 | [diff] [blame] | 261 | if (callback) { |
hendrikw | 04cea97 | 2014-09-23 20:50:53 | [diff] [blame] | 262 | // If we have a callback, we need to call |draw()|, |drawPicture()| doesn't |
| 263 | // take a callback. This is used by |AnalysisCanvas| to early out. |
reed | 74eefda9 | 2014-12-15 19:01:10 | [diff] [blame] | 264 | picture_->playback(canvas, callback); |
hendrikw | 04cea97 | 2014-09-23 20:50:53 | [diff] [blame] | 265 | } else { |
| 266 | // Prefer to call |drawPicture()| on the canvas since it could place the |
| 267 | // entire picture on the canvas instead of parsing the skia operations. |
| 268 | canvas->drawPicture(picture_.get()); |
mtklein@chromium.org | bc912d6 | 2014-04-30 14:53:44 | [diff] [blame] | 269 | } |
ernstm@chromium.org | c98059a | 2013-05-18 08:59:24 | [diff] [blame] | 270 | SkIRect bounds; |
| 271 | canvas->getClipDeviceBounds(&bounds); |
enne@chromium.org | 3621e18 | 2012-11-09 22:37:09 | [diff] [blame] | 272 | canvas->restore(); |
ernstm@chromium.org | adbe30f | 2013-10-11 21:12:33 | [diff] [blame] | 273 | TRACE_EVENT_END1( |
| 274 | "cc", "Picture::Raster", |
| 275 | "num_pixels_rasterized", bounds.width() * bounds.height()); |
| 276 | return bounds.width() * bounds.height(); |
qinmin@chromium.org | f760de8 | 2012-12-13 04:28:05 | [diff] [blame] | 277 | } |
| 278 | |
fmalita | f5190e0 | 2015-02-26 15:48:42 | [diff] [blame] | 279 | void Picture::Replay(SkCanvas* canvas, SkPicture::AbortCallback* callback) { |
fmalita@chromium.org | ef20a40 | 2013-07-02 04:30:43 | [diff] [blame] | 280 | TRACE_EVENT_BEGIN0("cc", "Picture::Replay"); |
| 281 | DCHECK(picture_); |
fmalita | f5190e0 | 2015-02-26 15:48:42 | [diff] [blame] | 282 | picture_->playback(canvas, callback); |
fmalita@chromium.org | ef20a40 | 2013-07-02 04:30:43 | [diff] [blame] | 283 | SkIRect bounds; |
| 284 | canvas->getClipDeviceBounds(&bounds); |
| 285 | TRACE_EVENT_END1("cc", "Picture::Replay", |
| 286 | "num_pixels_replayed", bounds.width() * bounds.height()); |
| 287 | } |
| 288 | |
brettw@chromium.org | 0c6c1e4 | 2013-06-21 19:42:19 | [diff] [blame] | 289 | scoped_ptr<base::Value> Picture::AsValue() const { |
vmpstr@chromium.org | f95cc39 | 2013-04-20 01:14:59 | [diff] [blame] | 290 | // Encode the picture as base64. |
nduca@chromium.org | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 291 | scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); |
| 292 | res->Set("params.layer_rect", MathUtil::AsValue(layer_rect_).release()); |
nduca@chromium.org | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 293 | std::string b64_picture; |
ajuma | d7dd21a | 2015-01-09 00:57:31 | [diff] [blame] | 294 | PictureDebugUtil::SerializeAsBase64(picture_.get(), &b64_picture); |
nduca@chromium.org | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 295 | res->SetString("skp64", b64_picture); |
danakj | f446a07 | 2014-09-27 21:55:48 | [diff] [blame] | 296 | return res.Pass(); |
vmpstr@chromium.org | 991db24 | 2013-04-25 19:11:57 | [diff] [blame] | 297 | } |
| 298 | |
dominikg@chromium.org | d851e2f | 2014-02-07 21:33:21 | [diff] [blame] | 299 | void Picture::EmitTraceSnapshot() const { |
caseq@chromium.org | 8af1ce1 | 2014-06-15 12:18:36 | [diff] [blame] | 300 | TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
jungjik.lee | d9172a7 | 2015-01-09 02:35:32 | [diff] [blame] | 301 | TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") "," |
| 302 | TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"), |
caseq@chromium.org | 8af1ce1 | 2014-06-15 12:18:36 | [diff] [blame] | 303 | "cc::Picture", |
| 304 | this, |
| 305 | TracedPicture::AsTraceablePicture(this)); |
nduca@chromium.org | 37349bc | 2013-06-04 01:31:52 | [diff] [blame] | 306 | } |
| 307 | |
dominikg@chromium.org | d851e2f | 2014-02-07 21:33:21 | [diff] [blame] | 308 | void Picture::EmitTraceSnapshotAlias(Picture* original) const { |
vmpstr@chromium.org | 054b11c1 | 2013-09-04 01:14:12 | [diff] [blame] | 309 | TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
jungjik.lee | d9172a7 | 2015-01-09 02:35:32 | [diff] [blame] | 310 | TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") "," |
| 311 | TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"), |
vmpstr@chromium.org | 054b11c1 | 2013-09-04 01:14:12 | [diff] [blame] | 312 | "cc::Picture", |
| 313 | this, |
| 314 | TracedPicture::AsTraceablePictureAlias(original)); |
| 315 | } |
| 316 | |
weiliangc | 7e508dd | 2015-03-10 17:15:19 | [diff] [blame] | 317 | PixelRefMap::Iterator Picture::GetPixelRefMapIterator( |
| 318 | const gfx::Rect& layer_rect) const { |
| 319 | return PixelRefMap::Iterator(layer_rect, this); |
vmpstr@chromium.org | 991db24 | 2013-04-25 19:11:57 | [diff] [blame] | 320 | } |
| 321 | |
ssid | 911e40e | 2015-02-09 17:55:20 | [diff] [blame] | 322 | scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
vmpstr@chromium.org | f1baa59 | 2013-10-29 04:46:45 | [diff] [blame] | 323 | Picture::AsTraceableRasterData(float scale) const { |
ssid | 911e40e | 2015-02-09 17:55:20 | [diff] [blame] | 324 | scoped_refptr<base::trace_event::TracedValue> raster_data = |
| 325 | new base::trace_event::TracedValue(); |
yurys@chromium.org | d12aa93 | 2014-08-01 13:10:38 | [diff] [blame] | 326 | TracedValue::SetIDRef(this, raster_data.get(), "picture_id"); |
pdr@chromium.org | aafcd276 | 2013-05-14 11:11:18 | [diff] [blame] | 327 | raster_data->SetDouble("scale", scale); |
yurys@chromium.org | d12aa93 | 2014-08-01 13:10:38 | [diff] [blame] | 328 | return raster_data; |
pdr@chromium.org | aafcd276 | 2013-05-14 11:11:18 | [diff] [blame] | 329 | } |
| 330 | |
ssid | 911e40e | 2015-02-09 17:55:20 | [diff] [blame] | 331 | scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
enne@chromium.org | be62465 | 2013-07-19 02:09:15 | [diff] [blame] | 332 | Picture::AsTraceableRecordData() const { |
ssid | 911e40e | 2015-02-09 17:55:20 | [diff] [blame] | 333 | scoped_refptr<base::trace_event::TracedValue> record_data = |
| 334 | new base::trace_event::TracedValue(); |
yurys@chromium.org | d12aa93 | 2014-08-01 13:10:38 | [diff] [blame] | 335 | TracedValue::SetIDRef(this, record_data.get(), "picture_id"); |
jungjik.lee | 50f9c8e | 2015-01-21 14:06:16 | [diff] [blame] | 336 | MathUtil::AddToTracedValue("layer_rect", layer_rect_, record_data.get()); |
yurys@chromium.org | d12aa93 | 2014-08-01 13:10:38 | [diff] [blame] | 337 | return record_data; |
enne@chromium.org | be62465 | 2013-07-19 02:09:15 | [diff] [blame] | 338 | } |
| 339 | |
enne@chromium.org | d98c024 | 2012-11-08 06:22:35 | [diff] [blame] | 340 | } // namespace cc |