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 #ifndef CC_RESOURCES_PICTURE_H_ 6 #define CC_RESOURCES_PICTURE_H_ 7 8 #include <string> 9 #include <utility> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/containers/hash_tables.h" 14 #include "base/debug/trace_event.h" 15 #include "base/lazy_instance.h" 16 #include "base/logging.h" 17 #include "base/memory/ref_counted.h" 18 #include "base/memory/scoped_ptr.h" 19 #include "cc/base/cc_export.h" 20 #include "cc/base/region.h" 21 #include "skia/ext/refptr.h" 22 #include "third_party/skia/include/core/SkBBHFactory.h" 23 #include "third_party/skia/include/core/SkPicture.h" 24 #include "third_party/skia/include/record/SkRecording.h" 25 #include "ui/gfx/rect.h" 26 27 class SkPixelRef; 28 29 namespace base { 30 class Value; 31 } 32 33 namespace skia { 34 class AnalysisCanvas; 35 } 36 37 namespace cc { 38 39 class ContentLayerClient; 40 41 class CC_EXPORT Picture 42 : public base::RefCountedThreadSafe<Picture> { 43 public: 44 typedef std::pair<int, int> PixelRefMapKey; 45 typedef std::vector<SkPixelRef*> PixelRefs; 46 typedef base::hash_map<PixelRefMapKey, PixelRefs> PixelRefMap; 47 48 enum RecordingMode { 49 RECORD_NORMALLY, 50 RECORD_WITH_SK_NULL_CANVAS, 51 RECORD_WITH_PAINTING_DISABLED, 52 RECORD_WITH_SKRECORD, 53 RECORDING_MODE_COUNT, // Must be the last entry. 54 }; 55 56 static scoped_refptr<Picture> Create( 57 const gfx::Rect& layer_rect, 58 ContentLayerClient* client, 59 const SkTileGridFactory::TileGridInfo& tile_grid_info, 60 bool gather_pixels_refs, 61 RecordingMode recording_mode); 62 static scoped_refptr<Picture> CreateFromValue(const base::Value* value); 63 static scoped_refptr<Picture> CreateFromSkpValue(const base::Value* value); 64 LayerRect()65 gfx::Rect LayerRect() const { return layer_rect_; } 66 67 // Has Record() been called yet? HasRecording()68 bool HasRecording() const { return picture_.get() != NULL; } 69 70 bool IsSuitableForGpuRasterization() const; 71 int ApproximateOpCount() const; 72 73 bool HasText() const; 74 75 // Apply this scale and raster the negated region into the canvas. 76 // |negated_content_region| specifies the region to be clipped out of the 77 // raster operation, i.e., the parts of the canvas which will not get drawn 78 // to. 79 int Raster(SkCanvas* canvas, 80 SkDrawPictureCallback* callback, 81 const Region& negated_content_region, 82 float contents_scale) const; 83 84 // Draw the picture directly into the given canvas, without applying any 85 // clip/scale/layer transformations. 86 void Replay(SkCanvas* canvas); 87 88 scoped_ptr<base::Value> AsValue() const; 89 90 // This iterator imprecisely returns the set of pixel refs that are needed to 91 // raster this layer rect from this picture. Internally, pixel refs are 92 // clumped into tile grid buckets, so there may be false positives. 93 class CC_EXPORT PixelRefIterator { 94 public: 95 PixelRefIterator(); 96 PixelRefIterator(const gfx::Rect& layer_rect, const Picture* picture); 97 ~PixelRefIterator(); 98 99 SkPixelRef* operator->() const { 100 DCHECK_LT(current_index_, current_pixel_refs_->size()); 101 return (*current_pixel_refs_)[current_index_]; 102 } 103 104 SkPixelRef* operator*() const { 105 DCHECK_LT(current_index_, current_pixel_refs_->size()); 106 return (*current_pixel_refs_)[current_index_]; 107 } 108 109 PixelRefIterator& operator++(); 110 operator bool() const { 111 return current_index_ < current_pixel_refs_->size(); 112 } 113 114 private: 115 static base::LazyInstance<PixelRefs> empty_pixel_refs_; 116 const Picture* picture_; 117 const PixelRefs* current_pixel_refs_; 118 unsigned current_index_; 119 120 gfx::Point min_point_; 121 gfx::Point max_point_; 122 int current_x_; 123 int current_y_; 124 }; 125 126 void EmitTraceSnapshot() const; 127 void EmitTraceSnapshotAlias(Picture* original) const; 128 WillPlayBackBitmaps()129 bool WillPlayBackBitmaps() const { return picture_->willPlayBackBitmaps(); } 130 131 private: 132 explicit Picture(const gfx::Rect& layer_rect); 133 // This constructor assumes SkPicture is already ref'd and transfers 134 // ownership to this picture. 135 Picture(const skia::RefPtr<SkPicture>&, 136 const gfx::Rect& layer_rect, 137 const PixelRefMap& pixel_refs); 138 // This constructor will call AdoptRef on the SkPicture. 139 Picture(SkPicture*, const gfx::Rect& layer_rect); 140 ~Picture(); 141 142 // Record a paint operation. To be able to safely use this SkPicture for 143 // playback on a different thread this can only be called once. 144 void Record(ContentLayerClient* client, 145 const SkTileGridFactory::TileGridInfo& tile_grid_info, 146 RecordingMode recording_mode); 147 148 // Gather pixel refs from recording. 149 void GatherPixelRefs(const SkTileGridFactory::TileGridInfo& tile_grid_info); 150 151 gfx::Rect layer_rect_; 152 skia::RefPtr<SkPicture> picture_; 153 scoped_ptr<const EXPERIMENTAL::SkPlayback> playback_; 154 155 PixelRefMap pixel_refs_; 156 gfx::Point min_pixel_cell_; 157 gfx::Point max_pixel_cell_; 158 gfx::Size cell_size_; 159 160 scoped_refptr<base::debug::ConvertableToTraceFormat> 161 AsTraceableRasterData(float scale) const; 162 scoped_refptr<base::debug::ConvertableToTraceFormat> 163 AsTraceableRecordData() const; 164 165 friend class base::RefCountedThreadSafe<Picture>; 166 friend class PixelRefIterator; 167 DISALLOW_COPY_AND_ASSIGN(Picture); 168 }; 169 170 } // namespace cc 171 172 #endif // CC_RESOURCES_PICTURE_H_ 173