Merge "[Release] Webkit2-efl-123997_0.11.75" into tizen_2.2
[framework/web/webkit-efl.git] / Source / WebKit2 / WebProcess / WebPage / UpdateAtlas.cpp
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 Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 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  Library General Public License for more details.
13
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB.  If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21 #include "UpdateAtlas.h"
22
23 #if USE(UI_SIDE_COMPOSITING)
24
25 #include "GraphicsContext.h"
26 #include "IntRect.h"
27 #include <wtf/MathExtras.h>
28 using namespace WebCore;
29
30 namespace WebKit {
31
32 UpdateAtlas::UpdateAtlas(int dimension, ShareableBitmap::Flags flags)
33     : m_flags(flags)
34     , m_inactivityInSeconds(0)
35     , m_using(true)
36 {
37     m_surface = ShareableSurface::create(IntSize(dimension, dimension), flags, ShareableSurface::SupportsGraphicsSurface);
38 }
39
40 static int nextPowerOfTwo(int number)
41 {
42     // This is a fast trick to get nextPowerOfTwo for an integer.
43     --number;
44     number |= number >> 1;
45     number |= number >> 2;
46     number |= number >> 4;
47     number |= number >> 8;
48     number |= number >> 16;
49     number++;
50     return number;
51 }
52
53 void UpdateAtlas::buildLayoutIfNeeded()
54 {
55     if (!m_layout.isEmpty())
56         return;
57
58     static const int MinTileSize = 32;
59     static const int MaxTileSize = 512;
60
61     // Divide our square to square power-of-two boxes.
62     for (int cursor = 0; cursor < size().width(); ) {
63         int remainder = size().width() - cursor;
64         int dimension = std::min(remainder, std::min(MaxTileSize, std::max(MinTileSize, nextPowerOfTwo(remainder / 2))));
65         cursor += dimension;
66         m_layout.append(dimension);
67     }
68
69     m_bufferStates.resize(m_layout.size() * m_layout.size());
70     size_t size = m_bufferStates.size();
71     for (size_t i = 0; i < size; ++i)
72         m_bufferStates[i] = Available;
73 }
74
75 int UpdateAtlas::findAvailableIndex(const WebCore::IntSize& size)
76 {
77     int dimension = m_layout.size();
78     int stride = dimension;
79     int requiredDimension = std::max(size.width(), size.height());
80
81     // Begin from the smallest buffer, until we reach the smallest available buffer that's big enough to contain our rect.
82     for (int i = m_bufferStates.size() - 1; i >= 0; i -= (dimension + 1), --stride) {
83         // Need a bigger buffer.
84         if (m_layout[i / dimension] < requiredDimension)
85             continue;
86
87         // Check all buffers of current size, to find an available one.
88         for (int offset = 0; offset < stride; ++offset) {
89             int index = i - offset;
90             if (m_bufferStates[index] == Available)
91                 return index;
92         }
93     }
94
95     return -1;
96 }
97
98 void UpdateAtlas::didSwapBuffers()
99 {
100     buildLayoutIfNeeded();
101     size_t size = m_bufferStates.size();
102     for (size_t i = 0; i < size; ++i)
103         m_bufferStates[i] = Available;
104     m_using = false;
105 }
106
107 PassOwnPtr<GraphicsContext> UpdateAtlas::beginPaintingOnAvailableBuffer(ShareableSurface::Handle& handle, const WebCore::IntSize& size, IntPoint& offset)
108 {
109     m_inactivityInSeconds = 0;
110     m_using = true;
111     buildLayoutIfNeeded();
112     int index = findAvailableIndex(size);
113
114     // No available buffer was found, returning null.
115     if (index < 0)
116         return PassOwnPtr<GraphicsContext>();
117
118     if (!m_surface->createHandle(handle))
119         return PassOwnPtr<WebCore::GraphicsContext>();
120
121     // FIXME: Use tri-state buffers, to allow faster updates.
122     m_bufferStates[index] = Taken;
123     offset = offsetForIndex(index);
124     IntRect rect(IntPoint::zero(), size);
125     OwnPtr<GraphicsContext> graphicsContext = m_surface->createGraphicsContext(IntRect(offset, size));
126
127     if (flags() & ShareableBitmap::SupportsAlpha) {
128         graphicsContext->setCompositeOperation(CompositeCopy);
129 #if !ENABLE(TIZEN_WEBKIT2_TILED_AC)
130         graphicsContext->fillRect(rect, Color::transparent, ColorSpaceDeviceRGB);
131 #else
132         graphicsContext->clearRect(rect);
133 #endif
134         graphicsContext->setCompositeOperation(CompositeSourceOver);
135     }
136
137     return graphicsContext.release();
138 }
139
140 IntPoint UpdateAtlas::offsetForIndex(int index) const
141 {
142     IntPoint coord(index % m_layout.size(), index / m_layout.size());
143     int x = 0;
144     int y = 0;
145     for (int i = 0; i < coord.x(); ++i)
146         x += m_layout[i];
147     for (int i = 0; i < coord.y(); ++i)
148         y += m_layout[i];
149
150     return IntPoint(x, y);
151 }
152
153 }
154 #endif