[ThreadedCompositor] Scrolling artifacts on accelerated subframes
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / CoordinatedGraphics / AreaAllocator.h
1 /*
2  * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  */
19
20 #ifndef AreaAllocator_h
21 #define AreaAllocator_h
22
23 #if USE(COORDINATED_GRAPHICS)
24
25 #include <WebCore/IntPoint.h>
26 #include <WebCore/IntRect.h>
27 #include <WebCore/IntSize.h>
28
29 namespace WebKit {
30
31 inline int nextPowerOfTwo(int number)
32 {
33     // This is a fast trick to get nextPowerOfTwo for an integer.
34     --number;
35     number |= number >> 1;
36     number |= number >> 2;
37     number |= number >> 4;
38     number |= number >> 8;
39     number |= number >> 16;
40     number++;
41     return number;
42 }
43
44 inline WebCore::IntSize nextPowerOfTwo(const WebCore::IntSize& size)
45 {
46     return WebCore::IntSize(nextPowerOfTwo(size.width()), nextPowerOfTwo(size.height()));
47 }
48
49 class AreaAllocator {
50     WTF_MAKE_FAST_ALLOCATED;
51 public:
52     explicit AreaAllocator(const WebCore::IntSize&);
53     virtual ~AreaAllocator();
54
55     WebCore::IntSize size() const { return m_size; }
56
57     WebCore::IntSize minimumAllocation() const { return m_minAlloc; }
58     void setMinimumAllocation(const WebCore::IntSize& size) { m_minAlloc = size; }
59
60     WebCore::IntSize margin() const { return m_margin; }
61     void setMargin(const WebCore::IntSize &margin) { m_margin = margin; }
62
63     virtual void expand(const WebCore::IntSize&);
64     void expandBy(const WebCore::IntSize&);
65
66     virtual WebCore::IntRect allocate(const WebCore::IntSize&) = 0;
67     virtual void release(const WebCore::IntRect&);
68
69     virtual int overhead() const;
70
71 protected:
72     WebCore::IntSize m_size;
73     WebCore::IntSize m_minAlloc;
74     WebCore::IntSize m_margin;
75
76     WebCore::IntSize roundAllocation(const WebCore::IntSize&) const;
77 };
78
79 class GeneralAreaAllocator final : public AreaAllocator {
80     WTF_MAKE_FAST_ALLOCATED;
81 public:
82     explicit GeneralAreaAllocator(const WebCore::IntSize&);
83     virtual ~GeneralAreaAllocator();
84
85     void expand(const WebCore::IntSize&) override;
86     WebCore::IntRect allocate(const WebCore::IntSize&) override;
87     void release(const WebCore::IntRect&) override;
88     int overhead() const override;
89
90 private:
91     enum Split { SplitOnX, SplitOnY };
92
93     struct Node {
94         WTF_MAKE_FAST_ALLOCATED;
95     public:
96         WebCore::IntRect rect;
97         WebCore::IntSize largestFree;
98         Node* parent { nullptr };
99         Node* left { nullptr };
100         Node* right { nullptr };
101     };
102
103     Node* m_root;
104     int m_nodeCount;
105
106     static void freeNode(Node*);
107     WebCore::IntPoint allocateFromNode(const WebCore::IntSize&, Node*);
108     Node* splitNode(Node*, Split);
109     static void updateLargestFree(Node*);
110 };
111
112 } // namespace WebKit
113
114 #endif // USE(COORDINATED_GRAPHICS)
115 #endif // AreaAllocator_h