| // 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_ |