// Copyright (c) 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 PPAPI_UTILITY_GRAPHICS_PAINT_AGGREGATOR_H_
#define PPAPI_UTILITY_GRAPHICS_PAINT_AGGREGATOR_H_

#include <stddef.h>
#include <vector>

#include "ppapi/cpp/point.h"
#include "ppapi/cpp/rect.h"

/// @file
/// This file defines the API to aggregate multiple invalidation and scroll
/// commands to produce a scroll and repaint sequence.
namespace pp {

/// This class is responsible for aggregating multiple invalidation and scroll
/// commands to produce a scroll and repaint sequence. You can use this manually
/// to track your updates, but most applications will use the PaintManager to
/// additionally handle the necessary callbacks on top of the PaintAggregator
/// functionality.
///
/// Refer to <code>http://code.google.com/p/ppapi/wiki/2DPaintingModel</code>
/// for further information.
class PaintAggregator {
 public:
  struct PaintUpdate {
    /// Default constructor for creating an is_null() <code>PaintUpdate</code>
    /// object.
    PaintUpdate();

    /// Destructor.
    ~PaintUpdate();

    /// True if there is a scroll applied. This indicates that the scroll delta
    /// and scroll_rect are nonzero (just as a convenience).
    bool has_scroll;

    /// The amount to scroll by. Either the X or Y may be nonzero to indicate a
    /// scroll in that direction, but there will never be a scroll in both
    /// directions at the same time (this will be converted to a paint of the
    /// region instead).
    ///
    /// If there is no scroll, this will be (0, 0).
    Point scroll_delta;

    /// The rectangle that should be scrolled by the scroll_delta. If there is
    /// no scroll, this will be (0, 0, 0, 0). We only track one scroll command
    /// at once. If there are multiple ones, they will be converted to
    /// invalidates.
    Rect scroll_rect;

    /// A list of all the individual dirty rectangles. This is an aggregated
    /// list of all invalidate calls. Different rectangles may be unified to
    /// produce a minimal list with no overlap that is more efficient to paint.
    /// This list also contains the region exposed by any scroll command.
    std::vector<Rect> paint_rects;

    /// The union of all paint_rects.
    Rect paint_bounds;
  };

  /// Default constructor.
  PaintAggregator();

  /// Setter function setting the max ratio of paint rect area to scroll rect
  /// area that we will tolerate before downgrading the scroll into a repaint.
  ///
  /// If the combined area of paint rects contained within the scroll
  /// rect grows too large, then we might as well just treat
  /// the scroll rect as a paint rect.
  ///
  /// @param[in] area The max ratio of paint rect area to scroll rect area that
  /// we will tolerate before downgrading the scroll into a repaint.
  void set_max_redundant_paint_to_scroll_area(float area) {
    max_redundant_paint_to_scroll_area_ = area;
  }

  /// Setter function for setting the maximum number of paint rects. If we
  /// exceed this limit, then we'll start combining paint rects (see
  /// CombinePaintRects). This limiting can be important since there is
  /// typically some overhead in deciding what to paint. If your module is fast
  /// at doing these computations, raise this threshold, if your module is
  /// slow, lower it (probably requires some tuning to find the right value).
  ///
  /// @param[in] max_rects The maximum number of paint rects.
  void set_max_paint_rects(size_t max_rects) {
    max_paint_rects_ = max_rects;
  }

  /// This function determines if there is a pending update. There is a
  /// PendingUpdate if InvalidateRect or ScrollRect were called and
  /// ClearPendingUpdate was not called.
  ///
  /// @return true if there is a pending update, otherwise false.
  bool HasPendingUpdate() const;

  /// This function clears a pending update.
  void ClearPendingUpdate();

  /// This function gets a pending update.
  ///
  /// @return A PaintUpdate containing the pending update.
  PaintUpdate GetPendingUpdate() const;

  /// This function invalidates the rect so it will be repainted.
  ///
  /// @param[in] rect A rect to be repainted.
  void InvalidateRect(const Rect& rect);

  /// This function adds a pending scroll update.
  ///
  /// @param[in] clip_rect The rect to scroll.
  /// @param[in] amount A Point amount to scroll <code>rect</code>.
  void ScrollRect(const Rect& clip_rect, const Point& amount);

 private:
  // This structure is an internal version of PaintUpdate. It's different in
  // two respects:
  //
  //  - The scroll damange (area exposed by the scroll operation, if any) is
  //    maintained separately from the dirty rects generated by calling
  //    InvalidateRect. We need to know this distinction for some operations.
  //
  //  - The paint bounds union is computed on the fly so we don't have to keep
  //    a rectangle up-to-date as we do different operations.
  class InternalPaintUpdate {
   public:
    InternalPaintUpdate();
    ~InternalPaintUpdate();

    // Computes the rect damaged by scrolling within |scroll_rect| by
    // |scroll_delta|. This rect must be repainted. It is not included in
    // paint_rects or in the rect returned by GetPaintBounds.
    Rect GetScrollDamage() const;

    // Returns the smallest rect containing all paint rects, not including the
    // scroll damage rect.
    Rect GetPaintBounds() const;

    Point scroll_delta;
    Rect scroll_rect;

    // Does not include the scroll damage rect.
    std::vector<Rect> paint_rects;
  };

  Rect ScrollPaintRect(const Rect& paint_rect, const Point& amount) const;
  bool ShouldInvalidateScrollRect(const Rect& rect) const;
  void InvalidateScrollRect();
  void CombinePaintRects();

  InternalPaintUpdate update_;

  // If the combined area of paint rects contained within the scroll rect grows
  // too large, then we might as well just treat the scroll rect as a paint
  // rect. This constant sets the max ratio of paint rect area to scroll rect
  // area that we will tolerate before downgrading the scroll into a repaint.
  float max_redundant_paint_to_scroll_area_;

  // The maximum number of paint rects. If we exceed this limit, then we'll
  // start combining paint rects (see CombinePaintRects). This limiting can be
  // important since there is typically some overhead in deciding what to
  // paint. If your plugin is fast at doing these computations, raise this
  // threshold, if your plugin is slow, lower it (probably requires some
  // tuning to find the right value).
  size_t max_paint_rects_;
};

}  // namespace pp

#endif  // PPAPI_UTILITY_PAINT_AGGREGATOR_H_
