summaryrefslogtreecommitdiffstats
path: root/cc/resources/picture.cc
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-18 08:24:40 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-18 08:24:40 +0000
commite12dd0e802b2a80112cb40e01fabcc5c0475f05b (patch)
treefbfd355be68b05d64c98e4c0618e1d4ad8122f6a /cc/resources/picture.cc
parent0d4f1f4b15d63e5976f0a2c0205d414da861c8a5 (diff)
downloadchromium_src-e12dd0e802b2a80112cb40e01fabcc5c0475f05b.zip
chromium_src-e12dd0e802b2a80112cb40e01fabcc5c0475f05b.tar.gz
chromium_src-e12dd0e802b2a80112cb40e01fabcc5c0475f05b.tar.bz2
Part 8 of cc/ directory shuffles: resources
Continuation of https://src.chromium.org/viewvc/chrome?view=rev&revision=188681 BUG=190824 TBR=enne@chromium.org, piman@chromium.org, jschuh@chromium.org Review URL: https://codereview.chromium.org/12471007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188696 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/resources/picture.cc')
-rw-r--r--cc/resources/picture.cc161
1 files changed, 161 insertions, 0 deletions
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc
new file mode 100644
index 0000000..52ae35e
--- /dev/null
+++ b/cc/resources/picture.cc
@@ -0,0 +1,161 @@
+// 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 "base/debug/trace_event.h"
+#include "cc/content_layer_client.h"
+#include "cc/debug/rendering_stats.h"
+#include "cc/resources/picture.h"
+#include "skia/ext/analysis_canvas.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkData.h"
+#include "third_party/skia/include/utils/SkPictureUtils.h"
+#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/skia_util.h"
+
+namespace {
+// URI label for a lazily decoded SkPixelRef.
+const char labelLazyDecoded[] = "lazy";
+}
+
+namespace cc {
+
+scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) {
+ return make_scoped_refptr(new Picture(layer_rect));
+}
+
+Picture::Picture(gfx::Rect layer_rect)
+ : layer_rect_(layer_rect) {
+}
+
+Picture::Picture(const skia::RefPtr<SkPicture>& picture,
+ gfx::Rect layer_rect,
+ gfx::Rect opaque_rect) :
+ layer_rect_(layer_rect),
+ opaque_rect_(opaque_rect),
+ picture_(picture) {
+}
+
+Picture::~Picture() {
+}
+
+scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread(
+ unsigned thread_index) const {
+ // SkPicture is not thread-safe to rasterize with, this returns a clone
+ // to rasterize with on a specific thread.
+ CHECK_GT(clones_.size(), thread_index);
+ return clones_[thread_index];
+}
+
+void Picture::CloneForDrawing(int num_threads) {
+ TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads);
+
+ DCHECK(picture_);
+ scoped_array<SkPicture> clones(new SkPicture[num_threads]);
+ picture_->clone(&clones[0], num_threads);
+
+ clones_.clear();
+ for (int i = 0; i < num_threads; i++) {
+ scoped_refptr<Picture> clone = make_scoped_refptr(
+ new Picture(skia::AdoptRef(new SkPicture(clones[i])),
+ layer_rect_,
+ opaque_rect_));
+ clones_.push_back(clone);
+ }
+}
+
+void Picture::Record(ContentLayerClient* painter,
+ RenderingStats* stats,
+ const SkTileGridPicture::TileGridInfo& tileGridInfo) {
+ TRACE_EVENT2("cc", "Picture::Record",
+ "width", layer_rect_.width(), "height", layer_rect_.height());
+
+ // Record() should only be called once.
+ DCHECK(!picture_);
+ DCHECK(!tileGridInfo.fTileInterval.isEmpty());
+ picture_ = skia::AdoptRef(new SkTileGridPicture(
+ layer_rect_.width(), layer_rect_.height(), tileGridInfo));
+
+ SkCanvas* canvas = picture_->beginRecording(
+ layer_rect_.width(),
+ layer_rect_.height(),
+ SkPicture::kUsePathBoundsForClip_RecordingFlag |
+ SkPicture::kOptimizeForClippedPlayback_RecordingFlag);
+
+ canvas->save();
+ canvas->translate(SkFloatToScalar(-layer_rect_.x()),
+ SkFloatToScalar(-layer_rect_.y()));
+
+ SkPaint paint;
+ paint.setAntiAlias(false);
+ paint.setXfermodeMode(SkXfermode::kClear_Mode);
+ SkRect layer_skrect = SkRect::MakeXYWH(layer_rect_.x(),
+ layer_rect_.y(),
+ layer_rect_.width(),
+ layer_rect_.height());
+ canvas->clipRect(layer_skrect);
+ canvas->drawRect(layer_skrect, paint);
+
+ gfx::RectF opaque_layer_rect;
+ base::TimeTicks begin_paint_time;
+ if (stats)
+ begin_paint_time = base::TimeTicks::Now();
+ painter->PaintContents(canvas, layer_rect_, &opaque_layer_rect);
+ if (stats) {
+ stats->totalPaintTime += base::TimeTicks::Now() - begin_paint_time;
+ stats->totalPixelsPainted +=
+ layer_rect_.width() * layer_rect_.height();
+ }
+
+ canvas->restore();
+ picture_->endRecording();
+
+ opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect);
+}
+
+void Picture::Raster(
+ SkCanvas* canvas,
+ gfx::Rect content_rect,
+ float contents_scale) {
+ TRACE_EVENT2("cc", "Picture::Raster",
+ "layer width", layer_rect_.width(),
+ "layer height", layer_rect_.height());
+ DCHECK(picture_);
+
+ canvas->save();
+ canvas->clipRect(gfx::RectToSkRect(content_rect));
+ canvas->scale(contents_scale, contents_scale);
+ canvas->translate(layer_rect_.x(), layer_rect_.y());
+ canvas->drawPicture(*picture_);
+ canvas->restore();
+}
+
+void Picture::GatherPixelRefs(const gfx::Rect& layer_rect,
+ std::list<skia::LazyPixelRef*>& pixel_ref_list) {
+ DCHECK(picture_);
+ SkData* pixel_refs = SkPictureUtils::GatherPixelRefs(
+ picture_.get(), SkRect::MakeXYWH(layer_rect.x(),
+ layer_rect.y(),
+ layer_rect.width(),
+ layer_rect.height()));
+ if (!pixel_refs)
+ return;
+
+ void* data = const_cast<void*>(pixel_refs->data());
+ if (!data) {
+ pixel_refs->unref();
+ return;
+ }
+
+ SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data);
+ for (unsigned int i = 0; i < pixel_refs->size() / sizeof(SkPixelRef*); ++i) {
+ if (*refs && (*refs)->getURI() && !strncmp(
+ (*refs)->getURI(), labelLazyDecoded, 4)) {
+ pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs));
+ }
+ refs++;
+ }
+ pixel_refs->unref();
+}
+
+} // namespace cc