1 // Copyright (c) 2011 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 PPAPI_UTILITY_GRAPHICS_PAINT_AGGREGATOR_H_ 6 #define PPAPI_UTILITY_GRAPHICS_PAINT_AGGREGATOR_H_ 7 8 #include <stddef.h> 9 #include <vector> 10 11 #include "ppapi/cpp/point.h" 12 #include "ppapi/cpp/rect.h" 13 14 /// @file 15 /// This file defines the API to aggregate multiple invalidation and scroll 16 /// commands to produce a scroll and repaint sequence. 17 namespace pp { 18 19 /// This class is responsible for aggregating multiple invalidation and scroll 20 /// commands to produce a scroll and repaint sequence. You can use this manually 21 /// to track your updates, but most applications will use the PaintManager to 22 /// additionally handle the necessary callbacks on top of the PaintAggregator 23 /// functionality. 24 /// 25 /// Refer to <code>http://code.google.com/p/ppapi/wiki/2DPaintingModel</code> 26 /// for further information. 27 class PaintAggregator { 28 public: 29 struct PaintUpdate { 30 /// Default constructor for creating an is_null() <code>PaintUpdate</code> 31 /// object. 32 PaintUpdate(); 33 34 /// Destructor. 35 ~PaintUpdate(); 36 37 /// True if there is a scroll applied. This indicates that the scroll delta 38 /// and scroll_rect are nonzero (just as a convenience). 39 bool has_scroll; 40 41 /// The amount to scroll by. Either the X or Y may be nonzero to indicate a 42 /// scroll in that direction, but there will never be a scroll in both 43 /// directions at the same time (this will be converted to a paint of the 44 /// region instead). 45 /// 46 /// If there is no scroll, this will be (0, 0). 47 Point scroll_delta; 48 49 /// The rectangle that should be scrolled by the scroll_delta. If there is 50 /// no scroll, this will be (0, 0, 0, 0). We only track one scroll command 51 /// at once. If there are multiple ones, they will be converted to 52 /// invalidates. 53 Rect scroll_rect; 54 55 /// A list of all the individual dirty rectangles. This is an aggregated 56 /// list of all invalidate calls. Different rectangles may be unified to 57 /// produce a minimal list with no overlap that is more efficient to paint. 58 /// This list also contains the region exposed by any scroll command. 59 std::vector<Rect> paint_rects; 60 61 /// The union of all paint_rects. 62 Rect paint_bounds; 63 }; 64 65 /// Default constructor. 66 PaintAggregator(); 67 68 /// Setter function setting the max ratio of paint rect area to scroll rect 69 /// area that we will tolerate before downgrading the scroll into a repaint. 70 /// 71 /// If the combined area of paint rects contained within the scroll 72 /// rect grows too large, then we might as well just treat 73 /// the scroll rect as a paint rect. 74 /// 75 /// @param[in] area The max ratio of paint rect area to scroll rect area that 76 /// we will tolerate before downgrading the scroll into a repaint. 77 void set_max_redundant_paint_to_scroll_area(float area) { 78 max_redundant_paint_to_scroll_area_ = area; 79 } 80 81 /// Setter function for setting the maximum number of paint rects. If we 82 /// exceed this limit, then we'll start combining paint rects (see 83 /// CombinePaintRects). This limiting can be important since there is 84 /// typically some overhead in deciding what to paint. If your module is fast 85 /// at doing these computations, raise this threshold, if your module is 86 /// slow, lower it (probably requires some tuning to find the right value). 87 /// 88 /// @param[in] max_rects The maximum number of paint rects. 89 void set_max_paint_rects(size_t max_rects) { 90 max_paint_rects_ = max_rects; 91 } 92 93 /// This function determines if there is a pending update. There is a 94 /// PendingUpdate if InvalidateRect or ScrollRect were called and 95 /// ClearPendingUpdate was not called. 96 /// 97 /// @return true if there is a pending update, otherwise false. 98 bool HasPendingUpdate() const; 99 100 /// This function clears a pending update. 101 void ClearPendingUpdate(); 102 103 /// This function gets a pending update. 104 /// 105 /// @return A PaintUpdate containing the pending update. 106 PaintUpdate GetPendingUpdate() const; 107 108 /// This function invalidates the rect so it will be repainted. 109 /// 110 /// @param[in] rect A rect to be repainted. 111 void InvalidateRect(const Rect& rect); 112 113 /// This function adds a pending scroll update. 114 /// 115 /// @param[in] clip_rect The rect to scroll. 116 /// @param[in] amount A Point amount to scroll <code>rect</code>. 117 void ScrollRect(const Rect& clip_rect, const Point& amount); 118 119 private: 120 // This structure is an internal version of PaintUpdate. It's different in 121 // two respects: 122 // 123 // - The scroll damange (area exposed by the scroll operation, if any) is 124 // maintained separately from the dirty rects generated by calling 125 // InvalidateRect. We need to know this distinction for some operations. 126 // 127 // - The paint bounds union is computed on the fly so we don't have to keep 128 // a rectangle up-to-date as we do different operations. 129 class InternalPaintUpdate { 130 public: 131 InternalPaintUpdate(); 132 ~InternalPaintUpdate(); 133 134 // Computes the rect damaged by scrolling within |scroll_rect| by 135 // |scroll_delta|. This rect must be repainted. It is not included in 136 // paint_rects or in the rect returned by GetPaintBounds. 137 Rect GetScrollDamage() const; 138 139 // Returns the smallest rect containing all paint rects, not including the 140 // scroll damage rect. 141 Rect GetPaintBounds() const; 142 143 Point scroll_delta; 144 Rect scroll_rect; 145 146 // Does not include the scroll damage rect. 147 std::vector<Rect> paint_rects; 148 }; 149 150 Rect ScrollPaintRect(const Rect& paint_rect, const Point& amount) const; 151 bool ShouldInvalidateScrollRect(const Rect& rect) const; 152 void InvalidateScrollRect(); 153 void CombinePaintRects(); 154 155 InternalPaintUpdate update_; 156 157 // If the combined area of paint rects contained within the scroll rect grows 158 // too large, then we might as well just treat the scroll rect as a paint 159 // rect. This constant sets the max ratio of paint rect area to scroll rect 160 // area that we will tolerate before downgrading the scroll into a repaint. 161 float max_redundant_paint_to_scroll_area_; 162 163 // The maximum number of paint rects. If we exceed this limit, then we'll 164 // start combining paint rects (see CombinePaintRects). This limiting can be 165 // important since there is typically some overhead in deciding what to 166 // paint. If your plugin is fast at doing these computations, raise this 167 // threshold, if your plugin is slow, lower it (probably requires some 168 // tuning to find the right value). 169 size_t max_paint_rects_; 170 }; 171 172 } // namespace pp 173 174 #endif // PPAPI_UTILITY_PAINT_AGGREGATOR_H_ 175