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