1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef PingPongRegion_h__
8 #define PingPongRegion_h__
9 
10 /* This class uses a pair of regions and swaps between them while
11  * accumulating to avoid the heap allocations associated with
12  * modifying a region in place.
13  *
14  * It is sizeof(T)*2 + sizeof(T*) and can use end up using
15  * approximately double the amount of memory as using single
16  * region so use it sparingly.
17  */
18 
19 template <typename T>
20 class PingPongRegion {
21   typedef typename T::RectType RectType;
22 
23  public:
PingPongRegion()24   PingPongRegion() { rgn = &rgn1; }
25 
SubOut(const RectType & aOther)26   void SubOut(const RectType& aOther) {
27     T* nextRgn = nextRegion();
28     nextRgn->Sub(*rgn, aOther);
29     rgn = nextRgn;
30   }
31 
OrWith(const RectType & aOther)32   void OrWith(const RectType& aOther) {
33     T* nextRgn = nextRegion();
34     nextRgn->Or(*rgn, aOther);
35     rgn = nextRgn;
36   }
37 
Region()38   T& Region() { return *rgn; }
39 
40  private:
nextRegion()41   T* nextRegion() {
42     if (rgn == &rgn1) {
43       return &rgn2;
44     } else {
45       return &rgn1;
46     }
47   }
48 
49   T* rgn;
50   T rgn1;
51   T rgn2;
52 };
53 
54 #endif
55