| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2013 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 "cc/resources/picture_pile_base.h" |  | 
| 6 |  | 
| 7 #include <algorithm> |  | 
| 8 #include <set> |  | 
| 9 #include <vector> |  | 
| 10 |  | 
| 11 #include "base/debug/trace_event_argument.h" |  | 
| 12 #include "base/logging.h" |  | 
| 13 #include "base/values.h" |  | 
| 14 #include "cc/debug/traced_value.h" |  | 
| 15 #include "third_party/skia/include/core/SkColor.h" |  | 
| 16 #include "ui/gfx/geometry/rect_conversions.h" |  | 
| 17 |  | 
| 18 namespace { |  | 
| 19 // Dimensions of the tiles in this picture pile as well as the dimensions of |  | 
| 20 // the base picture in each tile. |  | 
| 21 const int kBasePictureSize = 512; |  | 
| 22 const int kTileGridBorderPixels = 1; |  | 
| 23 #ifdef NDEBUG |  | 
| 24 const bool kDefaultClearCanvasSetting = false; |  | 
| 25 #else |  | 
| 26 const bool kDefaultClearCanvasSetting = true; |  | 
| 27 #endif |  | 
| 28 |  | 
| 29 // Invalidation frequency settings. kInvalidationFrequencyThreshold is a value |  | 
| 30 // between 0 and 1 meaning invalidation frequency between 0% and 100% that |  | 
| 31 // indicates when to stop invalidating offscreen regions. |  | 
| 32 // kFrequentInvalidationDistanceThreshold defines what it means to be |  | 
| 33 // "offscreen" in terms of distance to visible in css pixels. |  | 
| 34 const float kInvalidationFrequencyThreshold = 0.75f; |  | 
| 35 const int kFrequentInvalidationDistanceThreshold = 512; |  | 
| 36 |  | 
| 37 }  // namespace |  | 
| 38 |  | 
| 39 namespace cc { |  | 
| 40 |  | 
| 41 PicturePileBase::PicturePileBase() |  | 
| 42     : min_contents_scale_(0), |  | 
| 43       background_color_(SkColorSetARGBInline(0, 0, 0, 0)), |  | 
| 44       slow_down_raster_scale_factor_for_debug_(0), |  | 
| 45       contents_opaque_(false), |  | 
| 46       contents_fill_bounds_completely_(false), |  | 
| 47       show_debug_picture_borders_(false), |  | 
| 48       clear_canvas_with_debug_color_(kDefaultClearCanvasSetting), |  | 
| 49       has_any_recordings_(false), |  | 
| 50       is_mask_(false), |  | 
| 51       is_solid_color_(false), |  | 
| 52       solid_color_(SK_ColorTRANSPARENT) { |  | 
| 53   tiling_.SetMaxTextureSize(gfx::Size(kBasePictureSize, kBasePictureSize)); |  | 
| 54   tile_grid_info_.fTileInterval.setEmpty(); |  | 
| 55   tile_grid_info_.fMargin.setEmpty(); |  | 
| 56   tile_grid_info_.fOffset.setZero(); |  | 
| 57 } |  | 
| 58 |  | 
| 59 PicturePileBase::PicturePileBase(const PicturePileBase* other) |  | 
| 60     : picture_map_(other->picture_map_), |  | 
| 61       tiling_(other->tiling_), |  | 
| 62       recorded_viewport_(other->recorded_viewport_), |  | 
| 63       min_contents_scale_(other->min_contents_scale_), |  | 
| 64       tile_grid_info_(other->tile_grid_info_), |  | 
| 65       background_color_(other->background_color_), |  | 
| 66       slow_down_raster_scale_factor_for_debug_( |  | 
| 67           other->slow_down_raster_scale_factor_for_debug_), |  | 
| 68       contents_opaque_(other->contents_opaque_), |  | 
| 69       contents_fill_bounds_completely_(other->contents_fill_bounds_completely_), |  | 
| 70       show_debug_picture_borders_(other->show_debug_picture_borders_), |  | 
| 71       clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), |  | 
| 72       has_any_recordings_(other->has_any_recordings_), |  | 
| 73       is_mask_(other->is_mask_), |  | 
| 74       is_solid_color_(other->is_solid_color_), |  | 
| 75       solid_color_(other->solid_color_) { |  | 
| 76 } |  | 
| 77 |  | 
| 78 PicturePileBase::~PicturePileBase() { |  | 
| 79 } |  | 
| 80 |  | 
| 81 void PicturePileBase::SetMinContentsScale(float min_contents_scale) { |  | 
| 82   DCHECK(min_contents_scale); |  | 
| 83   if (min_contents_scale_ == min_contents_scale) |  | 
| 84     return; |  | 
| 85 |  | 
| 86   // Picture contents are played back scaled. When the final contents scale is |  | 
| 87   // less than 1 (i.e. low res), then multiple recorded pixels will be used |  | 
| 88   // to raster one final pixel.  To avoid splitting a final pixel across |  | 
| 89   // pictures (which would result in incorrect rasterization due to blending), a |  | 
| 90   // buffer margin is added so that any picture can be snapped to integral |  | 
| 91   // final pixels. |  | 
| 92   // |  | 
| 93   // For example, if a 1/4 contents scale is used, then that would be 3 buffer |  | 
| 94   // pixels, since that's the minimum number of pixels to add so that resulting |  | 
| 95   // content can be snapped to a four pixel aligned grid. |  | 
| 96   int buffer_pixels = static_cast<int>(ceil(1 / min_contents_scale) - 1); |  | 
| 97   buffer_pixels = std::max(0, buffer_pixels); |  | 
| 98   SetBufferPixels(buffer_pixels); |  | 
| 99   min_contents_scale_ = min_contents_scale; |  | 
| 100 } |  | 
| 101 |  | 
| 102 // static |  | 
| 103 void PicturePileBase::ComputeTileGridInfo( |  | 
| 104     const gfx::Size& tile_grid_size, |  | 
| 105     SkTileGridFactory::TileGridInfo* info) { |  | 
| 106   DCHECK(info); |  | 
| 107   info->fTileInterval.set(tile_grid_size.width() - 2 * kTileGridBorderPixels, |  | 
| 108                           tile_grid_size.height() - 2 * kTileGridBorderPixels); |  | 
| 109   DCHECK_GT(info->fTileInterval.width(), 0); |  | 
| 110   DCHECK_GT(info->fTileInterval.height(), 0); |  | 
| 111   info->fMargin.set(kTileGridBorderPixels, kTileGridBorderPixels); |  | 
| 112   // Offset the tile grid coordinate space to take into account the fact |  | 
| 113   // that the top-most and left-most tiles do not have top and left borders |  | 
| 114   // respectively. |  | 
| 115   info->fOffset.set(-kTileGridBorderPixels, -kTileGridBorderPixels); |  | 
| 116 } |  | 
| 117 |  | 
| 118 void PicturePileBase::SetTileGridSize(const gfx::Size& tile_grid_size) { |  | 
| 119   ComputeTileGridInfo(tile_grid_size, &tile_grid_info_); |  | 
| 120 } |  | 
| 121 |  | 
| 122 void PicturePileBase::SetBufferPixels(int new_buffer_pixels) { |  | 
| 123   if (new_buffer_pixels == buffer_pixels()) |  | 
| 124     return; |  | 
| 125 |  | 
| 126   Clear(); |  | 
| 127   tiling_.SetBorderTexels(new_buffer_pixels); |  | 
| 128 } |  | 
| 129 |  | 
| 130 void PicturePileBase::Clear() { |  | 
| 131   picture_map_.clear(); |  | 
| 132   recorded_viewport_ = gfx::Rect(); |  | 
| 133   has_any_recordings_ = false; |  | 
| 134   is_solid_color_ = false; |  | 
| 135 } |  | 
| 136 |  | 
| 137 bool PicturePileBase::HasRecordingAt(int x, int y) { |  | 
| 138   PictureMap::const_iterator found = picture_map_.find(PictureMapKey(x, y)); |  | 
| 139   if (found == picture_map_.end()) |  | 
| 140     return false; |  | 
| 141   return !!found->second.GetPicture(); |  | 
| 142 } |  | 
| 143 |  | 
| 144 gfx::Rect PicturePileBase::PaddedRect(const PictureMapKey& key) const { |  | 
| 145   gfx::Rect tile = tiling_.TileBounds(key.first, key.second); |  | 
| 146   return PadRect(tile); |  | 
| 147 } |  | 
| 148 |  | 
| 149 gfx::Rect PicturePileBase::PadRect(const gfx::Rect& rect) const { |  | 
| 150   gfx::Rect padded_rect = rect; |  | 
| 151   padded_rect.Inset( |  | 
| 152       -buffer_pixels(), -buffer_pixels(), -buffer_pixels(), -buffer_pixels()); |  | 
| 153   return padded_rect; |  | 
| 154 } |  | 
| 155 |  | 
| 156 PicturePileBase::PictureInfo::PictureInfo() : last_frame_number_(0) {} |  | 
| 157 |  | 
| 158 PicturePileBase::PictureInfo::~PictureInfo() {} |  | 
| 159 |  | 
| 160 void PicturePileBase::PictureInfo::AdvanceInvalidationHistory( |  | 
| 161     int frame_number) { |  | 
| 162   DCHECK_GE(frame_number, last_frame_number_); |  | 
| 163   if (frame_number == last_frame_number_) |  | 
| 164     return; |  | 
| 165 |  | 
| 166   invalidation_history_ <<= (frame_number - last_frame_number_); |  | 
| 167   last_frame_number_ = frame_number; |  | 
| 168 } |  | 
| 169 |  | 
| 170 bool PicturePileBase::PictureInfo::Invalidate(int frame_number) { |  | 
| 171   AdvanceInvalidationHistory(frame_number); |  | 
| 172   invalidation_history_.set(0); |  | 
| 173 |  | 
| 174   bool did_invalidate = !!picture_.get(); |  | 
| 175   picture_ = NULL; |  | 
| 176   return did_invalidate; |  | 
| 177 } |  | 
| 178 |  | 
| 179 bool PicturePileBase::PictureInfo::NeedsRecording(int frame_number, |  | 
| 180                                                   int distance_to_visible) { |  | 
| 181   AdvanceInvalidationHistory(frame_number); |  | 
| 182 |  | 
| 183   // We only need recording if we don't have a picture. Furthermore, we only |  | 
| 184   // need a recording if we're within frequent invalidation distance threshold |  | 
| 185   // or the invalidation is not frequent enough (below invalidation frequency |  | 
| 186   // threshold). |  | 
| 187   return !picture_.get() && |  | 
| 188          ((distance_to_visible <= kFrequentInvalidationDistanceThreshold) || |  | 
| 189           (GetInvalidationFrequency() < kInvalidationFrequencyThreshold)); |  | 
| 190 } |  | 
| 191 |  | 
| 192 void PicturePileBase::PictureInfo::SetPicture(scoped_refptr<Picture> picture) { |  | 
| 193   picture_ = picture; |  | 
| 194 } |  | 
| 195 |  | 
| 196 const Picture* PicturePileBase::PictureInfo::GetPicture() const { |  | 
| 197   return picture_.get(); |  | 
| 198 } |  | 
| 199 |  | 
| 200 float PicturePileBase::PictureInfo::GetInvalidationFrequency() const { |  | 
| 201   return invalidation_history_.count() / |  | 
| 202          static_cast<float>(INVALIDATION_FRAMES_TRACKED); |  | 
| 203 } |  | 
| 204 |  | 
| 205 }  // namespace cc |  | 
| OLD | NEW | 
|---|