| Index: cc/resources/picture.cc
|
| diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc
|
| deleted file mode 100644
|
| index e88ff21dc42076570a14aa2b71562182298da2f7..0000000000000000000000000000000000000000
|
| --- a/cc/resources/picture.cc
|
| +++ /dev/null
|
| @@ -1,338 +0,0 @@
|
| -// Copyright 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "cc/resources/picture.h"
|
| -
|
| -#include <set>
|
| -#include <string>
|
| -
|
| -#include "base/base64.h"
|
| -#include "base/trace_event/trace_event.h"
|
| -#include "base/trace_event/trace_event_argument.h"
|
| -#include "base/values.h"
|
| -#include "cc/base/math_util.h"
|
| -#include "cc/base/util.h"
|
| -#include "cc/debug/picture_debug_util.h"
|
| -#include "cc/debug/traced_picture.h"
|
| -#include "cc/debug/traced_value.h"
|
| -#include "cc/layers/content_layer_client.h"
|
| -#include "skia/ext/pixel_ref_utils.h"
|
| -#include "third_party/skia/include/core/SkCanvas.h"
|
| -#include "third_party/skia/include/core/SkDrawPictureCallback.h"
|
| -#include "third_party/skia/include/core/SkPaint.h"
|
| -#include "third_party/skia/include/core/SkPictureRecorder.h"
|
| -#include "third_party/skia/include/core/SkStream.h"
|
| -#include "third_party/skia/include/utils/SkNullCanvas.h"
|
| -#include "third_party/skia/include/utils/SkPictureUtils.h"
|
| -#include "ui/gfx/codec/jpeg_codec.h"
|
| -#include "ui/gfx/codec/png_codec.h"
|
| -#include "ui/gfx/geometry/rect_conversions.h"
|
| -#include "ui/gfx/skia_util.h"
|
| -
|
| -namespace cc {
|
| -
|
| -namespace {
|
| -
|
| -bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) {
|
| - const unsigned char* data = static_cast<const unsigned char *>(buffer);
|
| -
|
| - // Try PNG first.
|
| - if (gfx::PNGCodec::Decode(data, size, bm))
|
| - return true;
|
| -
|
| - // Try JPEG.
|
| - scoped_ptr<SkBitmap> decoded_jpeg(gfx::JPEGCodec::Decode(data, size));
|
| - if (decoded_jpeg) {
|
| - *bm = *decoded_jpeg;
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -scoped_refptr<Picture> Picture::Create(
|
| - const gfx::Rect& layer_rect,
|
| - ContentLayerClient* client,
|
| - const gfx::Size& tile_grid_size,
|
| - bool gather_pixel_refs,
|
| - RecordingSource::RecordingMode recording_mode) {
|
| - scoped_refptr<Picture> picture =
|
| - make_scoped_refptr(new Picture(layer_rect, tile_grid_size));
|
| -
|
| - picture->Record(client, recording_mode);
|
| - if (gather_pixel_refs)
|
| - picture->GatherPixelRefs();
|
| -
|
| - return picture;
|
| -}
|
| -
|
| -Picture::Picture(const gfx::Rect& layer_rect, const gfx::Size& tile_grid_size)
|
| - : layer_rect_(layer_rect), pixel_refs_(tile_grid_size) {
|
| - // Instead of recording a trace event for object creation here, we wait for
|
| - // the picture to be recorded in Picture::Record.
|
| -}
|
| -
|
| -scoped_refptr<Picture> Picture::CreateFromSkpValue(const base::Value* value) {
|
| - // Decode the picture from base64.
|
| - std::string encoded;
|
| - if (!value->GetAsString(&encoded))
|
| - return NULL;
|
| -
|
| - std::string decoded;
|
| - base::Base64Decode(encoded, &decoded);
|
| - SkMemoryStream stream(decoded.data(), decoded.size());
|
| -
|
| - // Read the picture. This creates an empty picture on failure.
|
| - SkPicture* skpicture = SkPicture::CreateFromStream(&stream, &DecodeBitmap);
|
| - if (skpicture == NULL)
|
| - return NULL;
|
| -
|
| - gfx::Rect layer_rect(gfx::SkIRectToRect(skpicture->cullRect().roundOut()));
|
| - return make_scoped_refptr(new Picture(skpicture, layer_rect));
|
| -}
|
| -
|
| -scoped_refptr<Picture> Picture::CreateFromValue(const base::Value* raw_value) {
|
| - const base::DictionaryValue* value = NULL;
|
| - if (!raw_value->GetAsDictionary(&value))
|
| - return NULL;
|
| -
|
| - // Decode the picture from base64.
|
| - std::string encoded;
|
| - if (!value->GetString("skp64", &encoded))
|
| - return NULL;
|
| -
|
| - std::string decoded;
|
| - base::Base64Decode(encoded, &decoded);
|
| - SkMemoryStream stream(decoded.data(), decoded.size());
|
| -
|
| - const base::Value* layer_rect_value = NULL;
|
| - if (!value->Get("params.layer_rect", &layer_rect_value))
|
| - return NULL;
|
| -
|
| - gfx::Rect layer_rect;
|
| - if (!MathUtil::FromValue(layer_rect_value, &layer_rect))
|
| - return NULL;
|
| -
|
| - // Read the picture. This creates an empty picture on failure.
|
| - SkPicture* skpicture = SkPicture::CreateFromStream(&stream, &DecodeBitmap);
|
| - if (skpicture == NULL)
|
| - return NULL;
|
| -
|
| - return make_scoped_refptr(new Picture(skpicture, layer_rect));
|
| -}
|
| -
|
| -Picture::Picture(SkPicture* picture, const gfx::Rect& layer_rect)
|
| - : layer_rect_(layer_rect),
|
| - picture_(skia::AdoptRef(picture)),
|
| - pixel_refs_(layer_rect.size()) {
|
| -}
|
| -
|
| -Picture::Picture(const skia::RefPtr<SkPicture>& picture,
|
| - const gfx::Rect& layer_rect,
|
| - const PixelRefMap& pixel_refs)
|
| - : layer_rect_(layer_rect), picture_(picture), pixel_refs_(pixel_refs) {
|
| -}
|
| -
|
| -Picture::~Picture() {
|
| - TRACE_EVENT_OBJECT_DELETED_WITH_ID(
|
| - TRACE_DISABLED_BY_DEFAULT("cc.debug.picture"), "cc::Picture", this);
|
| -}
|
| -
|
| -bool Picture::IsSuitableForGpuRasterization(const char** reason) const {
|
| - DCHECK(picture_);
|
| -
|
| - // TODO(hendrikw): SkPicture::suitableForGpuRasterization takes a GrContext.
|
| - // Currently the GrContext isn't used, and should probably be removed from
|
| - // skia.
|
| - return picture_->suitableForGpuRasterization(nullptr, reason);
|
| -}
|
| -
|
| -int Picture::ApproximateOpCount() const {
|
| - DCHECK(picture_);
|
| - return picture_->approximateOpCount();
|
| -}
|
| -
|
| -size_t Picture::ApproximateMemoryUsage() const {
|
| - DCHECK(picture_);
|
| - return SkPictureUtils::ApproximateBytesUsed(picture_.get());
|
| -}
|
| -
|
| -bool Picture::HasText() const {
|
| - DCHECK(picture_);
|
| - return picture_->hasText();
|
| -}
|
| -
|
| -void Picture::Record(ContentLayerClient* painter,
|
| - RecordingSource::RecordingMode recording_mode) {
|
| - TRACE_EVENT2("cc",
|
| - "Picture::Record",
|
| - "data",
|
| - AsTraceableRecordData(),
|
| - "recording_mode",
|
| - recording_mode);
|
| -
|
| - DCHECK(!picture_);
|
| -
|
| - SkRTreeFactory factory;
|
| - SkPictureRecorder recorder;
|
| -
|
| - skia::RefPtr<SkCanvas> canvas;
|
| - canvas = skia::SharePtr(recorder.beginRecording(
|
| - layer_rect_.width(), layer_rect_.height(), &factory,
|
| - SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag));
|
| -
|
| - ContentLayerClient::PaintingControlSetting painting_control =
|
| - ContentLayerClient::PAINTING_BEHAVIOR_NORMAL;
|
| -
|
| - switch (recording_mode) {
|
| - case RecordingSource::RECORD_NORMALLY:
|
| - // Already setup for normal recording.
|
| - break;
|
| - case RecordingSource::RECORD_WITH_SK_NULL_CANVAS:
|
| - canvas = skia::AdoptRef(SkCreateNullCanvas());
|
| - break;
|
| - case RecordingSource::RECORD_WITH_PAINTING_DISABLED:
|
| - // We pass a disable flag through the paint calls when perfromance
|
| - // testing (the only time this case should ever arise) when we want to
|
| - // prevent the Blink GraphicsContext object from consuming any compute
|
| - // time.
|
| - canvas = skia::AdoptRef(SkCreateNullCanvas());
|
| - painting_control = ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED;
|
| - break;
|
| - case RecordingSource::RECORD_WITH_CACHING_DISABLED:
|
| - // This mode should give the same results as RECORD_NORMALLY.
|
| - painting_control = ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED;
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - }
|
| -
|
| - canvas->save();
|
| - canvas->translate(SkFloatToScalar(-layer_rect_.x()),
|
| - SkFloatToScalar(-layer_rect_.y()));
|
| -
|
| - canvas->clipRect(gfx::RectToSkRect(layer_rect_));
|
| -
|
| - painter->PaintContents(canvas.get(), layer_rect_, painting_control);
|
| -
|
| - canvas->restore();
|
| - picture_ = skia::AdoptRef(recorder.endRecording());
|
| - DCHECK(picture_);
|
| -
|
| - EmitTraceSnapshot();
|
| -}
|
| -
|
| -void Picture::GatherPixelRefs() {
|
| - TRACE_EVENT2("cc", "Picture::GatherPixelRefs",
|
| - "width", layer_rect_.width(),
|
| - "height", layer_rect_.height());
|
| -
|
| - DCHECK(picture_);
|
| - DCHECK(pixel_refs_.empty());
|
| - if (!WillPlayBackBitmaps())
|
| - return;
|
| -
|
| - pixel_refs_.GatherPixelRefsFromPicture(picture_.get());
|
| -}
|
| -
|
| -int Picture::Raster(SkCanvas* canvas,
|
| - SkPicture::AbortCallback* callback,
|
| - const Region& negated_content_region,
|
| - float contents_scale) const {
|
| - TRACE_EVENT_BEGIN1(
|
| - "cc",
|
| - "Picture::Raster",
|
| - "data",
|
| - AsTraceableRasterData(contents_scale));
|
| -
|
| - DCHECK(picture_);
|
| -
|
| - canvas->save();
|
| -
|
| - for (Region::Iterator it(negated_content_region); it.has_rect(); it.next())
|
| - canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op);
|
| -
|
| - canvas->scale(contents_scale, contents_scale);
|
| - canvas->translate(layer_rect_.x(), layer_rect_.y());
|
| - if (callback) {
|
| - // If we have a callback, we need to call |draw()|, |drawPicture()| doesn't
|
| - // take a callback. This is used by |AnalysisCanvas| to early out.
|
| - picture_->playback(canvas, callback);
|
| - } else {
|
| - // Prefer to call |drawPicture()| on the canvas since it could place the
|
| - // entire picture on the canvas instead of parsing the skia operations.
|
| - canvas->drawPicture(picture_.get());
|
| - }
|
| - SkIRect bounds;
|
| - canvas->getClipDeviceBounds(&bounds);
|
| - canvas->restore();
|
| - TRACE_EVENT_END1(
|
| - "cc", "Picture::Raster",
|
| - "num_pixels_rasterized", bounds.width() * bounds.height());
|
| - return bounds.width() * bounds.height();
|
| -}
|
| -
|
| -void Picture::Replay(SkCanvas* canvas, SkPicture::AbortCallback* callback) {
|
| - TRACE_EVENT_BEGIN0("cc", "Picture::Replay");
|
| - DCHECK(picture_);
|
| - picture_->playback(canvas, callback);
|
| - SkIRect bounds;
|
| - canvas->getClipDeviceBounds(&bounds);
|
| - TRACE_EVENT_END1("cc", "Picture::Replay",
|
| - "num_pixels_replayed", bounds.width() * bounds.height());
|
| -}
|
| -
|
| -scoped_ptr<base::Value> Picture::AsValue() const {
|
| - // Encode the picture as base64.
|
| - scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
|
| - res->Set("params.layer_rect", MathUtil::AsValue(layer_rect_).release());
|
| - std::string b64_picture;
|
| - PictureDebugUtil::SerializeAsBase64(picture_.get(), &b64_picture);
|
| - res->SetString("skp64", b64_picture);
|
| - return res.Pass();
|
| -}
|
| -
|
| -void Picture::EmitTraceSnapshot() const {
|
| - TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
|
| - TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") ","
|
| - TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"),
|
| - "cc::Picture",
|
| - this,
|
| - TracedPicture::AsTraceablePicture(this));
|
| -}
|
| -
|
| -void Picture::EmitTraceSnapshotAlias(Picture* original) const {
|
| - TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
|
| - TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") ","
|
| - TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"),
|
| - "cc::Picture",
|
| - this,
|
| - TracedPicture::AsTraceablePictureAlias(original));
|
| -}
|
| -
|
| -PixelRefMap::Iterator Picture::GetPixelRefMapIterator(
|
| - const gfx::Rect& layer_rect) const {
|
| - return PixelRefMap::Iterator(layer_rect, this);
|
| -}
|
| -
|
| -scoped_refptr<base::trace_event::ConvertableToTraceFormat>
|
| - Picture::AsTraceableRasterData(float scale) const {
|
| - scoped_refptr<base::trace_event::TracedValue> raster_data =
|
| - new base::trace_event::TracedValue();
|
| - TracedValue::SetIDRef(this, raster_data.get(), "picture_id");
|
| - raster_data->SetDouble("scale", scale);
|
| - return raster_data;
|
| -}
|
| -
|
| -scoped_refptr<base::trace_event::ConvertableToTraceFormat>
|
| - Picture::AsTraceableRecordData() const {
|
| - scoped_refptr<base::trace_event::TracedValue> record_data =
|
| - new base::trace_event::TracedValue();
|
| - TracedValue::SetIDRef(this, record_data.get(), "picture_id");
|
| - MathUtil::AddToTracedValue("layer_rect", layer_rect_, record_data.get());
|
| - return record_data;
|
| -}
|
| -
|
| -} // namespace cc
|
|
|