| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/resources/picture.h" | 5 #include "cc/resources/picture.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 SkData* EncodeBitmap(size_t* offset, const SkBitmap& bm) { | 38 SkData* EncodeBitmap(size_t* offset, const SkBitmap& bm) { |
| 39 const int kJpegQuality = 80; | 39 const int kJpegQuality = 80; |
| 40 std::vector<unsigned char> data; | 40 std::vector<unsigned char> data; |
| 41 | 41 |
| 42 // If bitmap is opaque, encode as JPEG. | 42 // If bitmap is opaque, encode as JPEG. |
| 43 // Otherwise encode as PNG. | 43 // Otherwise encode as PNG. |
| 44 bool encoding_succeeded = false; | 44 bool encoding_succeeded = false; |
| 45 if (bm.isOpaque()) { | 45 if (bm.isOpaque()) { |
| 46 SkAutoLockPixels lock_bitmap(bm); | 46 SkAutoLockPixels lock_bitmap(bm); |
| 47 if (bm.empty()) | 47 if (bm.empty()) |
| 48 return NULL; | 48 return nullptr; |
| 49 | 49 |
| 50 encoding_succeeded = gfx::JPEGCodec::Encode( | 50 encoding_succeeded = gfx::JPEGCodec::Encode( |
| 51 reinterpret_cast<unsigned char*>(bm.getAddr32(0, 0)), | 51 reinterpret_cast<unsigned char*>(bm.getAddr32(0, 0)), |
| 52 gfx::JPEGCodec::FORMAT_SkBitmap, | 52 gfx::JPEGCodec::FORMAT_SkBitmap, |
| 53 bm.width(), | 53 bm.width(), |
| 54 bm.height(), | 54 bm.height(), |
| 55 bm.rowBytes(), | 55 bm.rowBytes(), |
| 56 kJpegQuality, | 56 kJpegQuality, |
| 57 &data); | 57 &data); |
| 58 } else { | 58 } else { |
| 59 encoding_succeeded = gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &data); | 59 encoding_succeeded = gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &data); |
| 60 } | 60 } |
| 61 | 61 |
| 62 if (encoding_succeeded) { | 62 if (encoding_succeeded) { |
| 63 *offset = 0; | 63 *offset = 0; |
| 64 return SkData::NewWithCopy(&data.front(), data.size()); | 64 return SkData::NewWithCopy(&data.front(), data.size()); |
| 65 } | 65 } |
| 66 return NULL; | 66 return nullptr; |
| 67 } | 67 } |
| 68 | 68 |
| 69 bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) { | 69 bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) { |
| 70 const unsigned char* data = static_cast<const unsigned char *>(buffer); | 70 const unsigned char* data = static_cast<const unsigned char *>(buffer); |
| 71 | 71 |
| 72 // Try PNG first. | 72 // Try PNG first. |
| 73 if (gfx::PNGCodec::Decode(data, size, bm)) | 73 if (gfx::PNGCodec::Decode(data, size, bm)) |
| 74 return true; | 74 return true; |
| 75 | 75 |
| 76 // Try JPEG. | 76 // Try JPEG. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 103 : layer_rect_(layer_rect), | 103 : layer_rect_(layer_rect), |
| 104 cell_size_(layer_rect.size()) { | 104 cell_size_(layer_rect.size()) { |
| 105 // Instead of recording a trace event for object creation here, we wait for | 105 // Instead of recording a trace event for object creation here, we wait for |
| 106 // the picture to be recorded in Picture::Record. | 106 // the picture to be recorded in Picture::Record. |
| 107 } | 107 } |
| 108 | 108 |
| 109 scoped_refptr<Picture> Picture::CreateFromSkpValue(const base::Value* value) { | 109 scoped_refptr<Picture> Picture::CreateFromSkpValue(const base::Value* value) { |
| 110 // Decode the picture from base64. | 110 // Decode the picture from base64. |
| 111 std::string encoded; | 111 std::string encoded; |
| 112 if (!value->GetAsString(&encoded)) | 112 if (!value->GetAsString(&encoded)) |
| 113 return NULL; | 113 return nullptr; |
| 114 | 114 |
| 115 std::string decoded; | 115 std::string decoded; |
| 116 base::Base64Decode(encoded, &decoded); | 116 base::Base64Decode(encoded, &decoded); |
| 117 SkMemoryStream stream(decoded.data(), decoded.size()); | 117 SkMemoryStream stream(decoded.data(), decoded.size()); |
| 118 | 118 |
| 119 // Read the picture. This creates an empty picture on failure. | 119 // Read the picture. This creates an empty picture on failure. |
| 120 SkPicture* skpicture = SkPicture::CreateFromStream(&stream, &DecodeBitmap); | 120 SkPicture* skpicture = SkPicture::CreateFromStream(&stream, &DecodeBitmap); |
| 121 if (skpicture == NULL) | 121 if (skpicture == nullptr) |
| 122 return NULL; | 122 return nullptr; |
| 123 | 123 |
| 124 gfx::Rect layer_rect(skpicture->width(), skpicture->height()); | 124 gfx::Rect layer_rect(skpicture->width(), skpicture->height()); |
| 125 return make_scoped_refptr(new Picture(skpicture, layer_rect)); | 125 return make_scoped_refptr(new Picture(skpicture, layer_rect)); |
| 126 } | 126 } |
| 127 | 127 |
| 128 scoped_refptr<Picture> Picture::CreateFromValue(const base::Value* raw_value) { | 128 scoped_refptr<Picture> Picture::CreateFromValue(const base::Value* raw_value) { |
| 129 const base::DictionaryValue* value = NULL; | 129 const base::DictionaryValue* value = nullptr; |
| 130 if (!raw_value->GetAsDictionary(&value)) | 130 if (!raw_value->GetAsDictionary(&value)) |
| 131 return NULL; | 131 return nullptr; |
| 132 | 132 |
| 133 // Decode the picture from base64. | 133 // Decode the picture from base64. |
| 134 std::string encoded; | 134 std::string encoded; |
| 135 if (!value->GetString("skp64", &encoded)) | 135 if (!value->GetString("skp64", &encoded)) |
| 136 return NULL; | 136 return nullptr; |
| 137 | 137 |
| 138 std::string decoded; | 138 std::string decoded; |
| 139 base::Base64Decode(encoded, &decoded); | 139 base::Base64Decode(encoded, &decoded); |
| 140 SkMemoryStream stream(decoded.data(), decoded.size()); | 140 SkMemoryStream stream(decoded.data(), decoded.size()); |
| 141 | 141 |
| 142 const base::Value* layer_rect_value = NULL; | 142 const base::Value* layer_rect_value = nullptr; |
| 143 if (!value->Get("params.layer_rect", &layer_rect_value)) | 143 if (!value->Get("params.layer_rect", &layer_rect_value)) |
| 144 return NULL; | 144 return nullptr; |
| 145 | 145 |
| 146 gfx::Rect layer_rect; | 146 gfx::Rect layer_rect; |
| 147 if (!MathUtil::FromValue(layer_rect_value, &layer_rect)) | 147 if (!MathUtil::FromValue(layer_rect_value, &layer_rect)) |
| 148 return NULL; | 148 return nullptr; |
| 149 | 149 |
| 150 // Read the picture. This creates an empty picture on failure. | 150 // Read the picture. This creates an empty picture on failure. |
| 151 SkPicture* skpicture = SkPicture::CreateFromStream(&stream, &DecodeBitmap); | 151 SkPicture* skpicture = SkPicture::CreateFromStream(&stream, &DecodeBitmap); |
| 152 if (skpicture == NULL) | 152 if (skpicture == nullptr) |
| 153 return NULL; | 153 return nullptr; |
| 154 | 154 |
| 155 return make_scoped_refptr(new Picture(skpicture, layer_rect)); | 155 return make_scoped_refptr(new Picture(skpicture, layer_rect)); |
| 156 } | 156 } |
| 157 | 157 |
| 158 Picture::Picture(SkPicture* picture, const gfx::Rect& layer_rect) | 158 Picture::Picture(SkPicture* picture, const gfx::Rect& layer_rect) |
| 159 : layer_rect_(layer_rect), | 159 : layer_rect_(layer_rect), |
| 160 picture_(skia::AdoptRef(picture)), | 160 picture_(skia::AdoptRef(picture)), |
| 161 cell_size_(layer_rect.size()) { | 161 cell_size_(layer_rect.size()) { |
| 162 } | 162 } |
| 163 | 163 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 176 } | 176 } |
| 177 | 177 |
| 178 bool Picture::IsSuitableForGpuRasterization() const { | 178 bool Picture::IsSuitableForGpuRasterization() const { |
| 179 DCHECK(picture_); | 179 DCHECK(picture_); |
| 180 | 180 |
| 181 // TODO(alokp): SkPicture::suitableForGpuRasterization needs a GrContext. | 181 // TODO(alokp): SkPicture::suitableForGpuRasterization needs a GrContext. |
| 182 // Ideally this GrContext should be the same as that for rasterizing this | 182 // Ideally this GrContext should be the same as that for rasterizing this |
| 183 // picture. But we are on the main thread while the rasterization context | 183 // picture. But we are on the main thread while the rasterization context |
| 184 // may be on the compositor or raster thread. | 184 // may be on the compositor or raster thread. |
| 185 // SkPicture::suitableForGpuRasterization is not implemented yet. | 185 // SkPicture::suitableForGpuRasterization is not implemented yet. |
| 186 // Pass a NULL context for now and discuss with skia folks if the context | 186 // Pass a nullptr context for now and discuss with skia folks if the context |
| 187 // is really needed. | 187 // is really needed. |
| 188 return picture_->suitableForGpuRasterization(NULL); | 188 return picture_->suitableForGpuRasterization(nullptr); |
| 189 } | 189 } |
| 190 | 190 |
| 191 int Picture::ApproximateOpCount() const { | 191 int Picture::ApproximateOpCount() const { |
| 192 DCHECK(picture_); | 192 DCHECK(picture_); |
| 193 return picture_->approximateOpCount(); | 193 return picture_->approximateOpCount(); |
| 194 } | 194 } |
| 195 | 195 |
| 196 bool Picture::HasText() const { | 196 bool Picture::HasText() const { |
| 197 DCHECK(picture_); | 197 DCHECK(picture_); |
| 198 return picture_->hasText(); | 198 return picture_->hasText(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 220 canvas = skia::SharePtr(recorder.beginRecording( | 220 canvas = skia::SharePtr(recorder.beginRecording( |
| 221 layer_rect_.width(), layer_rect_.height(), &factory)); | 221 layer_rect_.width(), layer_rect_.height(), &factory)); |
| 222 | 222 |
| 223 ContentLayerClient::GraphicsContextStatus graphics_context_status = | 223 ContentLayerClient::GraphicsContextStatus graphics_context_status = |
| 224 ContentLayerClient::GRAPHICS_CONTEXT_ENABLED; | 224 ContentLayerClient::GRAPHICS_CONTEXT_ENABLED; |
| 225 | 225 |
| 226 switch (recording_mode) { | 226 switch (recording_mode) { |
| 227 case RECORD_NORMALLY: | 227 case RECORD_NORMALLY: |
| 228 // Already setup for normal recording. | 228 // Already setup for normal recording. |
| 229 break; | 229 break; |
| 230 case RECORD_WITH_SK_NULL_CANVAS: | 230 case RECORD_WITH_SK_nullptr_CANVAS: |
| 231 canvas = skia::AdoptRef(SkCreateNullCanvas()); | 231 canvas = skia::AdoptRef(SkCreateNullCanvas()); |
| 232 break; | 232 break; |
| 233 case RECORD_WITH_PAINTING_DISABLED: | 233 case RECORD_WITH_PAINTING_DISABLED: |
| 234 // We pass a disable flag through the paint calls when perfromance | 234 // We pass a disable flag through the paint calls when perfromance |
| 235 // testing (the only time this case should ever arise) when we want to | 235 // testing (the only time this case should ever arise) when we want to |
| 236 // prevent the Blink GraphicsContext object from consuming any compute | 236 // prevent the Blink GraphicsContext object from consuming any compute |
| 237 // time. | 237 // time. |
| 238 canvas = skia::AdoptRef(SkCreateNullCanvas()); | 238 canvas = skia::AdoptRef(SkCreateNullCanvas()); |
| 239 graphics_context_status = ContentLayerClient::GRAPHICS_CONTEXT_DISABLED; | 239 graphics_context_status = ContentLayerClient::GRAPHICS_CONTEXT_DISABLED; |
| 240 break; | 240 break; |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 | 385 |
| 386 scoped_ptr<base::Value> Picture::AsValue() const { | 386 scoped_ptr<base::Value> Picture::AsValue() const { |
| 387 SkDynamicMemoryWStream stream; | 387 SkDynamicMemoryWStream stream; |
| 388 | 388 |
| 389 if (playback_) { | 389 if (playback_) { |
| 390 // SkPlayback can't serialize itself, so re-record into an SkPicture. | 390 // SkPlayback can't serialize itself, so re-record into an SkPicture. |
| 391 SkPictureRecorder recorder; | 391 SkPictureRecorder recorder; |
| 392 skia::RefPtr<SkCanvas> canvas(skia::SharePtr(recorder.beginRecording( | 392 skia::RefPtr<SkCanvas> canvas(skia::SharePtr(recorder.beginRecording( |
| 393 layer_rect_.width(), | 393 layer_rect_.width(), |
| 394 layer_rect_.height(), | 394 layer_rect_.height(), |
| 395 NULL))); // Default (no) bounding-box hierarchy is fastest. | 395 nullptr))); // Default (no) bounding-box hierarchy is fastest. |
| 396 playback_->draw(canvas.get()); | 396 playback_->draw(canvas.get()); |
| 397 skia::RefPtr<SkPicture> picture(skia::AdoptRef(recorder.endRecording())); | 397 skia::RefPtr<SkPicture> picture(skia::AdoptRef(recorder.endRecording())); |
| 398 picture->serialize(&stream, &EncodeBitmap); | 398 picture->serialize(&stream, &EncodeBitmap); |
| 399 } else { | 399 } else { |
| 400 // Serialize the picture. | 400 // Serialize the picture. |
| 401 picture_->serialize(&stream, &EncodeBitmap); | 401 picture_->serialize(&stream, &EncodeBitmap); |
| 402 } | 402 } |
| 403 | 403 |
| 404 // Encode the picture as base64. | 404 // Encode the picture as base64. |
| 405 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); | 405 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 430 "devtools.timeline.picture"), | 430 "devtools.timeline.picture"), |
| 431 "cc::Picture", | 431 "cc::Picture", |
| 432 this, | 432 this, |
| 433 TracedPicture::AsTraceablePictureAlias(original)); | 433 TracedPicture::AsTraceablePictureAlias(original)); |
| 434 } | 434 } |
| 435 | 435 |
| 436 base::LazyInstance<Picture::PixelRefs> | 436 base::LazyInstance<Picture::PixelRefs> |
| 437 Picture::PixelRefIterator::empty_pixel_refs_; | 437 Picture::PixelRefIterator::empty_pixel_refs_; |
| 438 | 438 |
| 439 Picture::PixelRefIterator::PixelRefIterator() | 439 Picture::PixelRefIterator::PixelRefIterator() |
| 440 : picture_(NULL), | 440 : picture_(nullptr), |
| 441 current_pixel_refs_(empty_pixel_refs_.Pointer()), | 441 current_pixel_refs_(empty_pixel_refs_.Pointer()), |
| 442 current_index_(0), | 442 current_index_(0), |
| 443 min_point_(-1, -1), | 443 min_point_(-1, -1), |
| 444 max_point_(-1, -1), | 444 max_point_(-1, -1), |
| 445 current_x_(0), | 445 current_x_(0), |
| 446 current_y_(0) { | 446 current_y_(0) { |
| 447 } | 447 } |
| 448 | 448 |
| 449 Picture::PixelRefIterator::PixelRefIterator( | 449 Picture::PixelRefIterator::PixelRefIterator( |
| 450 const gfx::Rect& rect, | 450 const gfx::Rect& rect, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 scoped_refptr<base::debug::TracedValue> record_data = | 547 scoped_refptr<base::debug::TracedValue> record_data = |
| 548 new base::debug::TracedValue(); | 548 new base::debug::TracedValue(); |
| 549 TracedValue::SetIDRef(this, record_data.get(), "picture_id"); | 549 TracedValue::SetIDRef(this, record_data.get(), "picture_id"); |
| 550 record_data->BeginArray("layer_rect"); | 550 record_data->BeginArray("layer_rect"); |
| 551 MathUtil::AddToTracedValue(layer_rect_, record_data.get()); | 551 MathUtil::AddToTracedValue(layer_rect_, record_data.get()); |
| 552 record_data->EndArray(); | 552 record_data->EndArray(); |
| 553 return record_data; | 553 return record_data; |
| 554 } | 554 } |
| 555 | 555 |
| 556 } // namespace cc | 556 } // namespace cc |
| OLD | NEW |