summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordominikg@chromium.org <dominikg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-07 21:33:21 +0000
committerdominikg@chromium.org <dominikg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-07 21:33:21 +0000
commitd851e2fe6bc837a135dfb36a0e8861b4d84d738f (patch)
treed418d9039fcd145a4f2e7e4e62f9e01432e02605
parente8ff1ad4a40d8f525a457b1231f31ff1068fc7a7 (diff)
downloadchromium_src-d851e2fe6bc837a135dfb36a0e8861b4d84d738f.zip
chromium_src-d851e2fe6bc837a135dfb36a0e8861b4d84d738f.tar.gz
chromium_src-d851e2fe6bc837a135dfb36a0e8861b4d84d738f.tar.bz2
Make cc::Picture immutable except for Raster and Replay.
Makes methods involved in picture recording private so they're only called from within factory methods. All public methods, apart from Raster and Replay, are now const. This CL also adds a DCHECK to ensure that cc::Picture::Raster and ::Replay are always called from the same thread. BUG=333855 Review URL: https://codereview.chromium.org/139313003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249791 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/debug/picture_record_benchmark.cc4
-rw-r--r--cc/debug/rasterize_and_record_benchmark.cc4
-rw-r--r--cc/debug/traced_picture.cc10
-rw-r--r--cc/debug/traced_picture.h8
-rw-r--r--cc/resources/picture.cc32
-rw-r--r--cc/resources/picture.h36
-rw-r--r--cc/resources/picture_pile.cc19
-rw-r--r--cc/resources/picture_unittest.cc33
-rw-r--r--cc/test/fake_picture_pile_impl.cc5
9 files changed, 88 insertions, 63 deletions
diff --git a/cc/debug/picture_record_benchmark.cc b/cc/debug/picture_record_benchmark.cc
index 430d1d0..220d8e7 100644
--- a/cc/debug/picture_record_benchmark.cc
+++ b/cc/debug/picture_record_benchmark.cc
@@ -110,8 +110,8 @@ void PictureRecordBenchmark::RunOnLayer(PictureLayer* layer) {
base::TimeTicks start = base::TimeTicks::HighResNow();
- scoped_refptr<Picture> picture = Picture::Create(rect);
- picture->Record(painter, tile_grid_info);
+ scoped_refptr<Picture> picture =
+ Picture::Create(rect, painter, tile_grid_info, false, 0);
base::TimeTicks end = base::TimeTicks::HighResNow();
base::TimeDelta duration = end - start;
diff --git a/cc/debug/rasterize_and_record_benchmark.cc b/cc/debug/rasterize_and_record_benchmark.cc
index 4646afd..d95e25a 100644
--- a/cc/debug/rasterize_and_record_benchmark.cc
+++ b/cc/debug/rasterize_and_record_benchmark.cc
@@ -116,13 +116,13 @@ void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) {
if (visible_content_rect.IsEmpty())
return;
- scoped_refptr<Picture> picture = Picture::Create(visible_content_rect);
base::TimeDelta min_time =
base::TimeDelta::FromInternalValue(std::numeric_limits<int64>::max());
for (int i = 0; i < record_repeat_count_; ++i) {
base::TimeTicks start = Now();
- picture->Record(painter, tile_grid_info);
+ scoped_refptr<Picture> picture = Picture::Create(
+ visible_content_rect, painter, tile_grid_info, false, 0);
base::TimeTicks end = Now();
base::TimeDelta duration = end - start;
if (duration < min_time)
diff --git a/cc/debug/traced_picture.cc b/cc/debug/traced_picture.cc
index 143f0b8..89d988f 100644
--- a/cc/debug/traced_picture.cc
+++ b/cc/debug/traced_picture.cc
@@ -11,22 +11,20 @@
namespace cc {
-TracedPicture::TracedPicture(scoped_refptr<Picture> picture)
- : picture_(picture),
- is_alias_(false) {
-}
+TracedPicture::TracedPicture(scoped_refptr<const Picture> picture)
+ : picture_(picture), is_alias_(false) {}
TracedPicture::~TracedPicture() {
}
scoped_refptr<base::debug::ConvertableToTraceFormat>
- TracedPicture::AsTraceablePicture(Picture* picture) {
+TracedPicture::AsTraceablePicture(const Picture* picture) {
return scoped_refptr<base::debug::ConvertableToTraceFormat>(
new TracedPicture(picture));
}
scoped_refptr<base::debug::ConvertableToTraceFormat>
- TracedPicture::AsTraceablePictureAlias(Picture* original) {
+TracedPicture::AsTraceablePictureAlias(const Picture* original) {
scoped_refptr<TracedPicture> ptr = new TracedPicture(original);
ptr->is_alias_ = true;
return scoped_refptr<base::debug::ConvertableToTraceFormat>(ptr);
diff --git a/cc/debug/traced_picture.h b/cc/debug/traced_picture.h
index cc212ce..638f00b 100644
--- a/cc/debug/traced_picture.h
+++ b/cc/debug/traced_picture.h
@@ -15,13 +15,13 @@ namespace cc {
class TracedPicture : public base::debug::ConvertableToTraceFormat {
public:
- explicit TracedPicture(scoped_refptr<Picture>);
+ explicit TracedPicture(scoped_refptr<const Picture>);
static scoped_refptr<base::debug::ConvertableToTraceFormat>
- AsTraceablePicture(Picture* picture);
+ AsTraceablePicture(const Picture* picture);
static scoped_refptr<base::debug::ConvertableToTraceFormat>
- AsTraceablePictureAlias(Picture* original);
+ AsTraceablePictureAlias(const Picture* original);
virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE;
@@ -31,7 +31,7 @@ class TracedPicture : public base::debug::ConvertableToTraceFormat {
void AppendPicture(std::string* out) const;
void AppendPictureAlias(std::string* out) const;
- scoped_refptr<Picture> picture_;
+ scoped_refptr<const Picture> picture_;
bool is_alias_;
DISALLOW_COPY_AND_ASSIGN(TracedPicture);
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc
index bfb905f..2034ecb 100644
--- a/cc/resources/picture.cc
+++ b/cc/resources/picture.cc
@@ -81,8 +81,24 @@ bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) {
} // namespace
-scoped_refptr<Picture> Picture::Create(const gfx::Rect& layer_rect) {
- return make_scoped_refptr(new Picture(layer_rect));
+scoped_refptr<Picture> Picture::Create(
+ const gfx::Rect& layer_rect,
+ ContentLayerClient* client,
+ const SkTileGridPicture::TileGridInfo& tile_grid_info,
+ bool gather_pixel_refs,
+ int num_raster_threads) {
+ scoped_refptr<Picture> picture = make_scoped_refptr(new Picture(layer_rect));
+
+ picture->Record(client, tile_grid_info);
+ if (gather_pixel_refs)
+ picture->GatherPixelRefs(tile_grid_info);
+ if (num_raster_threads > 0)
+ picture->CloneForDrawing(num_raster_threads);
+
+ // This picture may be rasterized on a different thread.
+ picture->raster_thread_checker_.DetachFromThread();
+
+ return picture;
}
Picture::Picture(const gfx::Rect& layer_rect)
@@ -188,10 +204,11 @@ void Picture::CloneForDrawing(int num_threads) {
TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads);
DCHECK(picture_);
+ DCHECK(clones_.empty());
+
scoped_ptr<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])),
@@ -201,6 +218,7 @@ void Picture::CloneForDrawing(int num_threads) {
clones_.push_back(clone);
clone->EmitTraceSnapshotAlias(this);
+ clone->raster_thread_checker_.DetachFromThread();
}
}
@@ -209,6 +227,7 @@ void Picture::Record(ContentLayerClient* painter,
TRACE_EVENT1("cc", "Picture::Record",
"data", AsTraceableRecordData());
+ DCHECK(!picture_);
DCHECK(!tile_grid_info.fTileInterval.isEmpty());
picture_ = skia::AdoptRef(new SkTileGridPicture(
layer_rect_.width(), layer_rect_.height(), tile_grid_info));
@@ -248,6 +267,7 @@ void Picture::GatherPixelRefs(
"height", layer_rect_.height());
DCHECK(picture_);
+ DCHECK(pixel_refs_.empty());
if (!WillPlayBackBitmaps())
return;
cell_size_ = gfx::Size(
@@ -301,6 +321,7 @@ int Picture::Raster(
SkDrawPictureCallback* callback,
const Region& negated_content_region,
float contents_scale) {
+ DCHECK(raster_thread_checker_.CalledOnValidThread());
TRACE_EVENT_BEGIN1(
"cc",
"Picture::Raster",
@@ -327,6 +348,7 @@ int Picture::Raster(
}
void Picture::Replay(SkCanvas* canvas) {
+ DCHECK(raster_thread_checker_.CalledOnValidThread());
TRACE_EVENT_BEGIN0("cc", "Picture::Replay");
DCHECK(picture_);
@@ -358,12 +380,12 @@ scoped_ptr<base::Value> Picture::AsValue() const {
return res.PassAs<base::Value>();
}
-void Picture::EmitTraceSnapshot() {
+void Picture::EmitTraceSnapshot() const {
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"cc::Picture", this, TracedPicture::AsTraceablePicture(this));
}
-void Picture::EmitTraceSnapshotAlias(Picture* original) {
+void Picture::EmitTraceSnapshotAlias(Picture* original) const {
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"cc::Picture",
diff --git a/cc/resources/picture.h b/cc/resources/picture.h
index 92afccd..441c540 100644
--- a/cc/resources/picture.h
+++ b/cc/resources/picture.h
@@ -16,6 +16,7 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread_checker.h"
#include "cc/base/cc_export.h"
#include "cc/base/region.h"
#include "skia/ext/refptr.h"
@@ -43,7 +44,12 @@ class CC_EXPORT Picture
typedef std::vector<SkPixelRef*> PixelRefs;
typedef base::hash_map<PixelRefMapKey, PixelRefs> PixelRefMap;
- static scoped_refptr<Picture> Create(const gfx::Rect& layer_rect);
+ static scoped_refptr<Picture> Create(
+ const gfx::Rect& layer_rect,
+ ContentLayerClient* client,
+ const SkTileGridPicture::TileGridInfo& tile_grid_info,
+ bool gather_pixels_refs,
+ int num_raster_threads);
static scoped_refptr<Picture> CreateFromValue(const base::Value* value);
static scoped_refptr<Picture> CreateFromSkpValue(const base::Value* value);
@@ -54,17 +60,6 @@ class CC_EXPORT Picture
scoped_refptr<Picture> GetCloneForDrawingOnThread(
unsigned thread_index) const;
- // Make thread-safe clones for rasterizing with.
- void CloneForDrawing(int num_threads);
-
- // Record a paint operation. To be able to safely use this SkPicture for
- // playback on a different thread this can only be called once.
- void Record(ContentLayerClient* client,
- const SkTileGridPicture::TileGridInfo& tile_grid_info);
-
- // Gather pixel refs from recording.
- void GatherPixelRefs(const SkTileGridPicture::TileGridInfo& tile_grid_info);
-
// Has Record() been called yet?
bool HasRecording() const { return picture_.get() != NULL; }
@@ -114,8 +109,8 @@ class CC_EXPORT Picture
int current_y_;
};
- void EmitTraceSnapshot();
- void EmitTraceSnapshotAlias(Picture* original);
+ void EmitTraceSnapshot() const;
+ void EmitTraceSnapshotAlias(Picture* original) const;
bool WillPlayBackBitmaps() const { return picture_->willPlayBackBitmaps(); }
@@ -133,6 +128,17 @@ class CC_EXPORT Picture
const gfx::Rect& opaque_rect);
~Picture();
+ // Make thread-safe clones for rasterizing with.
+ void CloneForDrawing(int num_threads);
+
+ // Record a paint operation. To be able to safely use this SkPicture for
+ // playback on a different thread this can only be called once.
+ void Record(ContentLayerClient* client,
+ const SkTileGridPicture::TileGridInfo& tile_grid_info);
+
+ // Gather pixel refs from recording.
+ void GatherPixelRefs(const SkTileGridPicture::TileGridInfo& tile_grid_info);
+
gfx::Rect layer_rect_;
gfx::Rect opaque_rect_;
skia::RefPtr<SkPicture> picture_;
@@ -150,6 +156,8 @@ class CC_EXPORT Picture
scoped_refptr<base::debug::ConvertableToTraceFormat>
AsTraceableRecordData() const;
+ base::ThreadChecker raster_thread_checker_;
+
friend class base::RefCountedThreadSafe<Picture>;
friend class PixelRefIterator;
DISALLOW_COPY_AND_ASSIGN(Picture);
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc
index 443f8be..7e5a822 100644
--- a/cc/resources/picture_pile.cc
+++ b/cc/resources/picture_pile.cc
@@ -218,25 +218,32 @@ bool PicturePile::Update(
record_rect = PadRect(record_rect);
int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
- scoped_refptr<Picture> picture = Picture::Create(record_rect);
+ scoped_refptr<Picture> picture;
+ int num_raster_threads = RasterWorkerPool::GetNumRasterThreads();
+
+ // Note: Currently, gathering of pixel refs when using a single
+ // raster thread doesn't provide any benefit. This might change
+ // in the future but we avoid it for now to reduce the cost of
+ // Picture::Create.
+ bool gather_pixel_refs = num_raster_threads > 1;
{
base::TimeDelta best_duration = base::TimeDelta::FromInternalValue(
std::numeric_limits<int64>::max());
for (int i = 0; i < repeat_count; i++) {
base::TimeTicks start_time = stats_instrumentation->StartRecording();
- picture->Record(painter, tile_grid_info_);
+ picture = Picture::Create(record_rect,
+ painter,
+ tile_grid_info_,
+ gather_pixel_refs,
+ num_raster_threads);
base::TimeDelta duration =
stats_instrumentation->EndRecording(start_time);
best_duration = std::min(duration, best_duration);
}
int recorded_pixel_count =
picture->LayerRect().width() * picture->LayerRect().height();
- int num_raster_threads = RasterWorkerPool::GetNumRasterThreads();
stats_instrumentation->AddRecord(best_duration, recorded_pixel_count);
- if (num_raster_threads > 1)
- picture->GatherPixelRefs(tile_grid_info_);
- picture->CloneForDrawing(num_raster_threads);
}
for (TilingData::Iterator it(&tiling_, record_rect);
diff --git a/cc/resources/picture_unittest.cc b/cc/resources/picture_unittest.cc
index a7cde02..b0b6486 100644
--- a/cc/resources/picture_unittest.cc
+++ b/cc/resources/picture_unittest.cc
@@ -48,9 +48,8 @@ TEST(PictureTest, AsBase64String) {
// Single full-size rect picture.
content_layer_client.add_draw_rect(layer_rect, red_paint);
- scoped_refptr<Picture> one_rect_picture = Picture::Create(layer_rect);
- one_rect_picture->Record(&content_layer_client,
- tile_grid_info);
+ scoped_refptr<Picture> one_rect_picture = Picture::Create(
+ layer_rect, &content_layer_client, tile_grid_info, false, 0);
scoped_ptr<base::Value> serialized_one_rect(
one_rect_picture->AsValue());
@@ -74,9 +73,8 @@ TEST(PictureTest, AsBase64String) {
// Two rect picture.
content_layer_client.add_draw_rect(gfx::Rect(25, 25, 50, 50), green_paint);
- scoped_refptr<Picture> two_rect_picture = Picture::Create(layer_rect);
- two_rect_picture->Record(&content_layer_client,
- tile_grid_info);
+ scoped_refptr<Picture> two_rect_picture = Picture::Create(
+ layer_rect, &content_layer_client, tile_grid_info, false, 0);
scoped_ptr<base::Value> serialized_two_rect(
two_rect_picture->AsValue());
@@ -134,10 +132,8 @@ TEST(PictureTest, PixelRefIterator) {
}
}
- scoped_refptr<Picture> picture = Picture::Create(layer_rect);
- picture->Record(&content_layer_client,
- tile_grid_info);
- picture->GatherPixelRefs(tile_grid_info);
+ scoped_refptr<Picture> picture = Picture::Create(
+ layer_rect, &content_layer_client, tile_grid_info, true, 0);
// Default iterator does not have any pixel refs
{
@@ -233,10 +229,8 @@ TEST(PictureTest, PixelRefIteratorNonZeroLayer) {
}
}
- scoped_refptr<Picture> picture = Picture::Create(layer_rect);
- picture->Record(&content_layer_client,
- tile_grid_info);
- picture->GatherPixelRefs(tile_grid_info);
+ scoped_refptr<Picture> picture = Picture::Create(
+ layer_rect, &content_layer_client, tile_grid_info, true, 0);
// Default iterator does not have any pixel refs
{
@@ -355,10 +349,8 @@ TEST(PictureTest, PixelRefIteratorOnePixelQuery) {
}
}
- scoped_refptr<Picture> picture = Picture::Create(layer_rect);
- picture->Record(&content_layer_client,
- tile_grid_info);
- picture->GatherPixelRefs(tile_grid_info);
+ scoped_refptr<Picture> picture = Picture::Create(
+ layer_rect, &content_layer_client, tile_grid_info, true, 0);
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
@@ -402,9 +394,8 @@ TEST(PictureTest, CreateFromSkpValue) {
// Single full-size rect picture.
content_layer_client.add_draw_rect(layer_rect, red_paint);
- scoped_refptr<Picture> one_rect_picture = Picture::Create(layer_rect);
- one_rect_picture->Record(&content_layer_client,
- tile_grid_info);
+ scoped_refptr<Picture> one_rect_picture = Picture::Create(
+ layer_rect, &content_layer_client, tile_grid_info, false, 0);
scoped_ptr<base::Value> serialized_one_rect(
one_rect_picture->AsValue());
diff --git a/cc/test/fake_picture_pile_impl.cc b/cc/test/fake_picture_pile_impl.cc
index 9b168e6..bb60034 100644
--- a/cc/test/fake_picture_pile_impl.cc
+++ b/cc/test/fake_picture_pile_impl.cc
@@ -75,9 +75,8 @@ void FakePicturePileImpl::AddRecordingAt(int x, int y) {
gfx::Rect bounds(tiling().TileBounds(x, y));
bounds.Inset(-buffer_pixels(), -buffer_pixels());
- scoped_refptr<Picture> picture(Picture::Create(bounds));
- picture->Record(&client_, tile_grid_info_);
- picture->GatherPixelRefs(tile_grid_info_);
+ scoped_refptr<Picture> picture(
+ Picture::Create(bounds, &client_, tile_grid_info_, true, 0));
picture_map_[std::pair<int, int>(x, y)].SetPicture(picture);
EXPECT_TRUE(HasRecordingAt(x, y));