// Copyright 2012 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_OCCLUSION_TRACKER_H_
#define CC_TREES_OCCLUSION_TRACKER_H_

#include <vector>

#include "base/macros.h"
#include "cc/base/simple_enclosed_region.h"
#include "cc/cc_export.h"
#include "cc/layers/effect_tree_layer_list_iterator.h"
#include "cc/trees/occlusion.h"
#include "ui/gfx/geometry/rect.h"

namespace cc {
class LayerImpl;
class Region;
class RenderSurfaceImpl;

// This class is used to track occlusion of layers while traversing them in a
// front-to-back order. As each layer is visited, one of the methods in this
// class is called to notify it about the current target surface. Then,
// occlusion in the content space of the current layer may be queried, via
// Occlusion from GetCurrentOcclusionForLayer(). If the current layer owns a
// RenderSurfaceImpl, then occlusion on that RenderSurfaceImpl may also be
// queried via surfaceOccluded() and surfaceUnoccludedContentRect(). Finally,
// once finished with the layer, occlusion behind the layer should be marked by
// calling MarkOccludedBehindLayer().
class CC_EXPORT OcclusionTracker {
 public:
  explicit OcclusionTracker(const gfx::Rect& screen_space_clip_rect);
  ~OcclusionTracker();

  // Return an occlusion that retains the current state of the tracker
  // and can be used outside of a layer walk to check occlusion.
  Occlusion GetCurrentOcclusionForLayer(
      const gfx::Transform& draw_transform) const;
  Occlusion GetCurrentOcclusionForContributingSurface(
      const gfx::Transform& draw_transform) const;

  const RenderSurfaceImpl* OcclusionSurfaceForContributingSurface() const;
  // Called at the beginning of each step in EffectTreeLayerListIterator's
  // front-to-back traversal.
  void EnterLayer(const EffectTreeLayerListIterator::Position& iterator);
  // Called at the end of each step in EffectTreeLayerListIterator's
  // front-to-back traversal.
  void LeaveLayer(const EffectTreeLayerListIterator::Position& iterator);

  // Gives the region of the screen that is not occluded by something opaque.
  Region ComputeVisibleRegionInScreen(const LayerTreeImpl* layer_tree) const;

  void set_minimum_tracking_size(const gfx::Size& size) {
    minimum_tracking_size_ = size;
  }

 protected:
  struct StackObject {
    StackObject() : target(0) {}
    explicit StackObject(const RenderSurfaceImpl* target) : target(target) {}
    const RenderSurfaceImpl* target;
    SimpleEnclosedRegion occlusion_from_outside_target;
    SimpleEnclosedRegion occlusion_from_inside_target;
  };

  // The stack holds occluded regions for subtrees in the
  // RenderSurfaceImpl-Layer tree, so that when we leave a subtree we may apply
  // a mask to it, but not to the parts outside the subtree.
  // - The first time we see a new subtree under a target, we add that target to
  // the top of the stack. This can happen as a layer representing itself, or as
  // a target surface.
  // - When we visit a target surface, we apply its mask to its subtree, which
  // is at the top of the stack.
  // - When we visit a layer representing itself, we add its occlusion to the
  // current subtree, which is at the top of the stack.
  // - When we visit a layer representing a contributing surface, the current
  // target will never be the top of the stack since we just came from the
  // contributing surface.
  // We merge the occlusion at the top of the stack with the new current
  // subtree. This new target is pushed onto the stack if not already there.
  std::vector<StackObject> stack_;

 private:
  // Called when visiting a layer. If the target was not already current, then
  // this indicates we have entered a new surface subtree.
  void EnterRenderTarget(const RenderSurfaceImpl* new_target_surface);

  // Called when visiting a target surface. This indicates we have visited all
  // the layers within the surface, and we may perform any surface-wide
  // operations.
  void FinishedRenderTarget(const RenderSurfaceImpl* finished_target_surface);

  // Called when visiting a contributing surface. This indicates that we are
  // leaving our current surface, and entering the new one. We then perform any
  // operations required for merging results from the child subtree into its
  // parent.
  void LeaveToRenderTarget(const RenderSurfaceImpl* new_target_surface);

  // Add the layer's occlusion to the tracked state.
  void MarkOccludedBehindLayer(const LayerImpl* layer);

  gfx::Rect screen_space_clip_rect_;
  gfx::Size minimum_tracking_size_;

  DISALLOW_COPY_AND_ASSIGN(OcclusionTracker);
};

}  // namespace cc

#endif  // CC_TREES_OCCLUSION_TRACKER_H_
