diff options
author | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-18 08:24:40 +0000 |
---|---|---|
committer | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-18 08:24:40 +0000 |
commit | e12dd0e802b2a80112cb40e01fabcc5c0475f05b (patch) | |
tree | fbfd355be68b05d64c98e4c0618e1d4ad8122f6a /cc/resources/picture.cc | |
parent | 0d4f1f4b15d63e5976f0a2c0205d414da861c8a5 (diff) | |
download | chromium_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.cc | 161 |
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 |