| // Copyright 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CC_TREES_DAMAGE_TRACKER_H_ |
| #define CC_TREES_DAMAGE_TRACKER_H_ |
| |
| #include <memory> |
| #include <vector> |
| |
| #include "base/macros.h" |
| #include "cc/cc_export.h" |
| #include "cc/layers/layer_collections.h" |
| #include "ui/gfx/geometry/rect.h" |
| |
| namespace gfx { |
| class Rect; |
| } |
| |
| namespace cc { |
| |
| class FilterOperations; |
| class LayerImpl; |
| class LayerTreeImpl; |
| class RenderSurfaceImpl; |
| |
| // Computes the region where pixels have actually changed on a |
| // RenderSurfaceImpl. This region is used to scissor what is actually drawn to |
| // the screen to save GPU computation and bandwidth. |
| class CC_EXPORT DamageTracker { |
| public: |
| static std::unique_ptr<DamageTracker> Create(); |
| ~DamageTracker(); |
| |
| static void UpdateDamageTracking( |
| LayerTreeImpl* layer_tree_impl, |
| const RenderSurfaceList& render_surface_list); |
| |
| void DidDrawDamagedArea() { |
| current_damage_ = DamageAccumulator(); |
| has_damage_from_contributing_content_ = false; |
| } |
| void AddDamageNextUpdate(const gfx::Rect& dmg) { current_damage_.Union(dmg); } |
| |
| bool GetDamageRectIfValid(gfx::Rect* rect); |
| |
| bool has_damage_from_contributing_content() const { |
| return has_damage_from_contributing_content_; |
| } |
| |
| private: |
| DamageTracker(); |
| |
| class DamageAccumulator { |
| public: |
| template <typename Type> |
| void Union(const Type& rect) { |
| if (!is_valid_rect_) |
| return; |
| if (rect.IsEmpty()) |
| return; |
| if (IsEmpty()) { |
| x_ = rect.x(); |
| y_ = rect.y(); |
| right_ = rect.right(); |
| bottom_ = rect.bottom(); |
| return; |
| } |
| |
| x_ = std::min(x_, rect.x()); |
| y_ = std::min(y_, rect.y()); |
| right_ = std::max(right_, rect.right()); |
| bottom_ = std::max(bottom_, rect.bottom()); |
| } |
| |
| int x() const { return x_; } |
| int y() const { return y_; } |
| int right() const { return right_; } |
| int bottom() const { return bottom_; } |
| bool IsEmpty() const { return x_ == right_ || y_ == bottom_; } |
| |
| bool GetAsRect(gfx::Rect* rect); |
| |
| private: |
| bool is_valid_rect_ = true; |
| int x_ = 0; |
| int y_ = 0; |
| int right_ = 0; |
| int bottom_ = 0; |
| }; |
| |
| DamageAccumulator TrackDamageFromSurfaceMask( |
| LayerImpl* target_surface_mask_layer); |
| DamageAccumulator TrackDamageFromLeftoverRects(); |
| |
| // These helper functions are used only during UpdateDamageTracking(). |
| void PrepareForUpdate(); |
| void AccumulateDamageFromLayer(LayerImpl* layer); |
| void AccumulateDamageFromRenderSurface(RenderSurfaceImpl* render_surface); |
| void ComputeSurfaceDamage(RenderSurfaceImpl* render_surface); |
| void ExpandDamageInsideRectWithFilters(const gfx::Rect& pre_filter_rect, |
| const FilterOperations& filters); |
| |
| struct LayerRectMapData { |
| LayerRectMapData() : layer_id_(0), mailboxId_(0) {} |
| explicit LayerRectMapData(int layer_id) |
| : layer_id_(layer_id), mailboxId_(0) {} |
| void Update(const gfx::Rect& rect, unsigned int mailboxId) { |
| mailboxId_ = mailboxId; |
| rect_ = rect; |
| } |
| |
| bool operator<(const LayerRectMapData& other) const { |
| return layer_id_ < other.layer_id_; |
| } |
| |
| int layer_id_; |
| unsigned int mailboxId_; |
| gfx::Rect rect_; |
| }; |
| |
| struct SurfaceRectMapData { |
| SurfaceRectMapData() : surface_id_(0), mailboxId_(0) {} |
| explicit SurfaceRectMapData(uint64_t surface_id) |
| : surface_id_(surface_id), mailboxId_(0) {} |
| void Update(const gfx::Rect& rect, unsigned int mailboxId) { |
| mailboxId_ = mailboxId; |
| rect_ = rect; |
| } |
| |
| bool operator<(const SurfaceRectMapData& other) const { |
| return surface_id_ < other.surface_id_; |
| } |
| |
| uint64_t surface_id_; |
| unsigned int mailboxId_; |
| gfx::Rect rect_; |
| }; |
| typedef std::vector<LayerRectMapData> SortedRectMapForLayers; |
| typedef std::vector<SurfaceRectMapData> SortedRectMapForSurfaces; |
| |
| LayerRectMapData& RectDataForLayer(int layer_id, bool* layer_is_new); |
| SurfaceRectMapData& RectDataForSurface(uint64_t surface_id, |
| bool* layer_is_new); |
| |
| SortedRectMapForLayers rect_history_for_layers_; |
| SortedRectMapForSurfaces rect_history_for_surfaces_; |
| |
| unsigned int mailboxId_; |
| DamageAccumulator current_damage_; |
| // Damage from contributing render surface and layer |
| bool has_damage_from_contributing_content_; |
| |
| // Damage accumulated since the last call to PrepareForUpdate(). |
| DamageAccumulator damage_for_this_update_; |
| |
| DISALLOW_COPY_AND_ASSIGN(DamageTracker); |
| }; |
| |
| } // namespace cc |
| |
| #endif // CC_TREES_DAMAGE_TRACKER_H_ |