| OLD | NEW |
| (Empty) |
| 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 | |
| 5 #include "base/debug/trace_event.h" | |
| 6 #include "cc/content_layer_client.h" | |
| 7 #include "cc/debug/rendering_stats.h" | |
| 8 #include "cc/picture.h" | |
| 9 #include "skia/ext/analysis_canvas.h" | |
| 10 #include "third_party/skia/include/core/SkCanvas.h" | |
| 11 #include "third_party/skia/include/core/SkData.h" | |
| 12 #include "third_party/skia/include/utils/SkPictureUtils.h" | |
| 13 #include "ui/gfx/rect_conversions.h" | |
| 14 #include "ui/gfx/skia_util.h" | |
| 15 | |
| 16 namespace { | |
| 17 // URI label for a lazily decoded SkPixelRef. | |
| 18 const char labelLazyDecoded[] = "lazy"; | |
| 19 } | |
| 20 | |
| 21 namespace cc { | |
| 22 | |
| 23 scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) { | |
| 24 return make_scoped_refptr(new Picture(layer_rect)); | |
| 25 } | |
| 26 | |
| 27 Picture::Picture(gfx::Rect layer_rect) | |
| 28 : layer_rect_(layer_rect) { | |
| 29 } | |
| 30 | |
| 31 Picture::Picture(const skia::RefPtr<SkPicture>& picture, | |
| 32 gfx::Rect layer_rect, | |
| 33 gfx::Rect opaque_rect) : | |
| 34 layer_rect_(layer_rect), | |
| 35 opaque_rect_(opaque_rect), | |
| 36 picture_(picture) { | |
| 37 } | |
| 38 | |
| 39 Picture::~Picture() { | |
| 40 } | |
| 41 | |
| 42 scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread( | |
| 43 unsigned thread_index) const { | |
| 44 // SkPicture is not thread-safe to rasterize with, this returns a clone | |
| 45 // to rasterize with on a specific thread. | |
| 46 CHECK_GT(clones_.size(), thread_index); | |
| 47 return clones_[thread_index]; | |
| 48 } | |
| 49 | |
| 50 void Picture::CloneForDrawing(int num_threads) { | |
| 51 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); | |
| 52 | |
| 53 DCHECK(picture_); | |
| 54 scoped_array<SkPicture> clones(new SkPicture[num_threads]); | |
| 55 picture_->clone(&clones[0], num_threads); | |
| 56 | |
| 57 clones_.clear(); | |
| 58 for (int i = 0; i < num_threads; i++) { | |
| 59 scoped_refptr<Picture> clone = make_scoped_refptr( | |
| 60 new Picture(skia::AdoptRef(new SkPicture(clones[i])), | |
| 61 layer_rect_, | |
| 62 opaque_rect_)); | |
| 63 clones_.push_back(clone); | |
| 64 } | |
| 65 } | |
| 66 | |
| 67 void Picture::Record(ContentLayerClient* painter, | |
| 68 RenderingStats* stats, | |
| 69 const SkTileGridPicture::TileGridInfo& tileGridInfo) { | |
| 70 TRACE_EVENT2("cc", "Picture::Record", | |
| 71 "width", layer_rect_.width(), "height", layer_rect_.height()); | |
| 72 | |
| 73 // Record() should only be called once. | |
| 74 DCHECK(!picture_); | |
| 75 DCHECK(!tileGridInfo.fTileInterval.isEmpty()); | |
| 76 picture_ = skia::AdoptRef(new SkTileGridPicture( | |
| 77 layer_rect_.width(), layer_rect_.height(), tileGridInfo)); | |
| 78 | |
| 79 SkCanvas* canvas = picture_->beginRecording( | |
| 80 layer_rect_.width(), | |
| 81 layer_rect_.height(), | |
| 82 SkPicture::kUsePathBoundsForClip_RecordingFlag | | |
| 83 SkPicture::kOptimizeForClippedPlayback_RecordingFlag); | |
| 84 | |
| 85 canvas->save(); | |
| 86 canvas->translate(SkFloatToScalar(-layer_rect_.x()), | |
| 87 SkFloatToScalar(-layer_rect_.y())); | |
| 88 | |
| 89 SkPaint paint; | |
| 90 paint.setAntiAlias(false); | |
| 91 paint.setXfermodeMode(SkXfermode::kClear_Mode); | |
| 92 SkRect layer_skrect = SkRect::MakeXYWH(layer_rect_.x(), | |
| 93 layer_rect_.y(), | |
| 94 layer_rect_.width(), | |
| 95 layer_rect_.height()); | |
| 96 canvas->clipRect(layer_skrect); | |
| 97 canvas->drawRect(layer_skrect, paint); | |
| 98 | |
| 99 gfx::RectF opaque_layer_rect; | |
| 100 base::TimeTicks begin_paint_time; | |
| 101 if (stats) | |
| 102 begin_paint_time = base::TimeTicks::Now(); | |
| 103 painter->PaintContents(canvas, layer_rect_, &opaque_layer_rect); | |
| 104 if (stats) { | |
| 105 stats->totalPaintTime += base::TimeTicks::Now() - begin_paint_time; | |
| 106 stats->totalPixelsPainted += | |
| 107 layer_rect_.width() * layer_rect_.height(); | |
| 108 } | |
| 109 | |
| 110 canvas->restore(); | |
| 111 picture_->endRecording(); | |
| 112 | |
| 113 opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); | |
| 114 } | |
| 115 | |
| 116 void Picture::Raster( | |
| 117 SkCanvas* canvas, | |
| 118 gfx::Rect content_rect, | |
| 119 float contents_scale) { | |
| 120 TRACE_EVENT2("cc", "Picture::Raster", | |
| 121 "layer width", layer_rect_.width(), | |
| 122 "layer height", layer_rect_.height()); | |
| 123 DCHECK(picture_); | |
| 124 | |
| 125 canvas->save(); | |
| 126 canvas->clipRect(gfx::RectToSkRect(content_rect)); | |
| 127 canvas->scale(contents_scale, contents_scale); | |
| 128 canvas->translate(layer_rect_.x(), layer_rect_.y()); | |
| 129 canvas->drawPicture(*picture_); | |
| 130 canvas->restore(); | |
| 131 } | |
| 132 | |
| 133 void Picture::GatherPixelRefs(const gfx::Rect& layer_rect, | |
| 134 std::list<skia::LazyPixelRef*>& pixel_ref_list) { | |
| 135 DCHECK(picture_); | |
| 136 SkData* pixel_refs = SkPictureUtils::GatherPixelRefs( | |
| 137 picture_.get(), SkRect::MakeXYWH(layer_rect.x(), | |
| 138 layer_rect.y(), | |
| 139 layer_rect.width(), | |
| 140 layer_rect.height())); | |
| 141 if (!pixel_refs) | |
| 142 return; | |
| 143 | |
| 144 void* data = const_cast<void*>(pixel_refs->data()); | |
| 145 if (!data) { | |
| 146 pixel_refs->unref(); | |
| 147 return; | |
| 148 } | |
| 149 | |
| 150 SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data); | |
| 151 for (unsigned int i = 0; i < pixel_refs->size() / sizeof(SkPixelRef*); ++i) { | |
| 152 if (*refs && (*refs)->getURI() && !strncmp( | |
| 153 (*refs)->getURI(), labelLazyDecoded, 4)) { | |
| 154 pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs)); | |
| 155 } | |
| 156 refs++; | |
| 157 } | |
| 158 pixel_refs->unref(); | |
| 159 } | |
| 160 | |
| 161 } // namespace cc | |
| OLD | NEW |