Home | History | Annotate | Download | only in trees
      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_TREES_OCCLUSION_TRACKER_H_
      6 #define CC_TREES_OCCLUSION_TRACKER_H_
      7 
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "cc/base/cc_export.h"
     12 #include "cc/base/region.h"
     13 #include "cc/layers/layer_iterator.h"
     14 #include "ui/gfx/rect.h"
     15 
     16 namespace cc {
     17 class OverdrawMetrics;
     18 class LayerImpl;
     19 class RenderSurfaceImpl;
     20 class Layer;
     21 class RenderSurface;
     22 
     23 // This class is used to track occlusion of layers while traversing them in a
     24 // front-to-back order. As each layer is visited, one of the methods in this
     25 // class is called to notify it about the current target surface. Then,
     26 // occlusion in the content space of the current layer may be queried, via
     27 // methods such as Occluded() and UnoccludedContentRect(). If the current layer
     28 // owns a RenderSurfaceImpl, then occlusion on that RenderSurfaceImpl may also
     29 // be queried via surfaceOccluded() and surfaceUnoccludedContentRect(). Finally,
     30 // once finished with the layer, occlusion behind the layer should be marked by
     31 // calling MarkOccludedBehindLayer().
     32 template <typename LayerType, typename RenderSurfaceType>
     33 class CC_EXPORT OcclusionTrackerBase {
     34  public:
     35   OcclusionTrackerBase(gfx::Rect screen_space_clip_rect,
     36                        bool record_metrics_for_frame);
     37   ~OcclusionTrackerBase();
     38 
     39   // Called at the beginning of each step in the LayerIterator's front-to-back
     40   // traversal. If |prevent_occlusion| is true, the layer will be considered
     41   // unoccluded.
     42   void EnterLayer(const LayerIteratorPosition<LayerType>& layer_iterator,
     43                   bool prevent_occlusion);
     44   // Called at the end of each step in the LayerIterator's front-to-back
     45   // traversal.
     46   void LeaveLayer(const LayerIteratorPosition<LayerType>& layer_iterator);
     47 
     48   // Returns true if the given rect in content space for a layer is fully
     49   // occluded in either screen space or the layer's target surface.
     50   // |render_target| is the contributing layer's render target, and
     51   // |draw_transform|, |transformsToTargetKnown| and |clippedRectInTarget| are
     52   // relative to that.
     53   bool Occluded(const LayerType* render_target,
     54                 gfx::Rect content_rect,
     55                 const gfx::Transform& draw_transform,
     56                 bool impl_draw_transform_is_unknown,
     57                 bool is_clipped,
     58                 gfx::Rect clip_rect_in_target,
     59                 bool* has_occlusion_from_outside_target_surface) const;
     60 
     61   // Gives an unoccluded sub-rect of |content_rect| in the content space of a
     62   // layer. Used when considering occlusion for a layer that paints/draws
     63   // something. |render_target| is the contributing layer's render target, and
     64   // |draw_transform|, |transformsToTargetKnown| and |clippedRectInTarget| are
     65   // relative to that.
     66   gfx::Rect UnoccludedContentRect(
     67       const LayerType* render_target,
     68       gfx::Rect content_rect,
     69       const gfx::Transform& draw_transform,
     70       bool impl_draw_transform_is_unknown,
     71       bool is_clipped,
     72       gfx::Rect clip_rect_in_target,
     73       bool* has_occlusion_from_outside_target_surface) const;
     74 
     75   // Gives an unoccluded sub-rect of |content_rect| in the content space of the
     76   // render_target owned by the layer. Used when considering occlusion for a
     77   // contributing surface that is rendering into another target.
     78   gfx::Rect UnoccludedContributingSurfaceContentRect(
     79       const LayerType* layer,
     80       bool for_replica,
     81       gfx::Rect content_rect,
     82       bool* has_occlusion_from_outside_target_surface) const;
     83 
     84   // Report operations for recording overdraw metrics.
     85   OverdrawMetrics* overdraw_metrics() const {
     86     return overdraw_metrics_.get();
     87   }
     88 
     89   // Gives the region of the screen that is not occluded by something opaque.
     90   Region ComputeVisibleRegionInScreen() const {
     91     DCHECK(!stack_.back().target->parent());
     92     return SubtractRegions(screen_space_clip_rect_,
     93                            stack_.back().occlusion_from_inside_target);
     94   }
     95 
     96   void set_minimum_tracking_size(gfx::Size size) {
     97     minimum_tracking_size_ = size;
     98   }
     99 
    100   // The following is used for visualization purposes.
    101   void set_occluding_screen_space_rects_container(
    102       std::vector<gfx::Rect>* rects) {
    103     occluding_screen_space_rects_ = rects;
    104   }
    105   void set_non_occluding_screen_space_rects_container(
    106       std::vector<gfx::Rect>* rects) {
    107     non_occluding_screen_space_rects_ = rects;
    108   }
    109 
    110  protected:
    111   struct StackObject {
    112     StackObject() : target(0) {}
    113     explicit StackObject(const LayerType* target) : target(target) {}
    114     const LayerType* target;
    115     Region occlusion_from_outside_target;
    116     Region occlusion_from_inside_target;
    117   };
    118 
    119   // The stack holds occluded regions for subtrees in the
    120   // RenderSurfaceImpl-Layer tree, so that when we leave a subtree we may apply
    121   // a mask to it, but not to the parts outside the subtree.
    122   // - The first time we see a new subtree under a target, we add that target to
    123   // the top of the stack. This can happen as a layer representing itself, or as
    124   // a target surface.
    125   // - When we visit a target surface, we apply its mask to its subtree, which
    126   // is at the top of the stack.
    127   // - When we visit a layer representing itself, we add its occlusion to the
    128   // current subtree, which is at the top of the stack.
    129   // - When we visit a layer representing a contributing surface, the current
    130   // target will never be the top of the stack since we just came from the
    131   // contributing surface.
    132   // We merge the occlusion at the top of the stack with the new current
    133   // subtree. This new target is pushed onto the stack if not already there.
    134   std::vector<StackObject> stack_;
    135 
    136  private:
    137   // Called when visiting a layer representing itself. If the target was not
    138   // already current, then this indicates we have entered a new surface subtree.
    139   void EnterRenderTarget(const LayerType* new_target);
    140 
    141   // Called when visiting a layer representing a target surface. This indicates
    142   // we have visited all the layers within the surface, and we may perform any
    143   // surface-wide operations.
    144   void FinishedRenderTarget(const LayerType* finished_target);
    145 
    146   // Called when visiting a layer representing a contributing surface. This
    147   // indicates that we are leaving our current surface, and entering the new
    148   // one. We then perform any operations required for merging results from the
    149   // child subtree into its parent.
    150   void LeaveToRenderTarget(const LayerType* new_target);
    151 
    152   // Add the layer's occlusion to the tracked state.
    153   void MarkOccludedBehindLayer(const LayerType* layer);
    154 
    155   gfx::Rect screen_space_clip_rect_;
    156   scoped_ptr<class OverdrawMetrics> overdraw_metrics_;
    157   gfx::Size minimum_tracking_size_;
    158   bool prevent_occlusion_;
    159 
    160   // This is used for visualizing the occlusion tracking process.
    161   std::vector<gfx::Rect>* occluding_screen_space_rects_;
    162   std::vector<gfx::Rect>* non_occluding_screen_space_rects_;
    163 
    164   DISALLOW_COPY_AND_ASSIGN(OcclusionTrackerBase);
    165 };
    166 
    167 typedef OcclusionTrackerBase<Layer, RenderSurface> OcclusionTracker;
    168 typedef OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl> OcclusionTrackerImpl;
    169 #if !defined(COMPILER_MSVC)
    170 extern template class OcclusionTrackerBase<Layer, RenderSurface>;
    171 extern template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>;
    172 #endif
    173 
    174 }  // namespace cc
    175 
    176 #endif  // CC_TREES_OCCLUSION_TRACKER_H_
    177