Add WTF::move()
[WebKit-https.git] / Source / WebCore / platform / graphics / texmap / coordinated / CoordinatedBackingStore.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 "CoordinatedBackingStore.h"
22
23 #if USE(COORDINATED_GRAPHICS)
24 #include "CoordinatedSurface.h"
25 #include "GraphicsLayer.h"
26 #include "TextureMapper.h"
27 #include "TextureMapperGL.h"
28
29 namespace WebCore {
30
31 void CoordinatedBackingStoreTile::swapBuffers(TextureMapper* textureMapper)
32 {
33     if (!m_surface)
34         return;
35
36     FloatRect tileRect(m_tileRect);
37     tileRect.scale(1. / m_scale);
38     bool shouldReset = false;
39     if (tileRect != rect()) {
40         setRect(tileRect);
41         shouldReset = true;
42     }
43     RefPtr<BitmapTexture> texture = this->texture();
44     if (!texture) {
45         texture = textureMapper->createTexture();
46         setTexture(texture.get());
47         shouldReset = true;
48     }
49
50     ASSERT(textureMapper->maxTextureSize().width() >= m_tileRect.size().width());
51     ASSERT(textureMapper->maxTextureSize().height() >= m_tileRect.size().height());
52     if (shouldReset)
53         texture->reset(m_tileRect.size(), m_surface->supportsAlpha());
54
55     m_surface->copyToTexture(texture, m_sourceRect, m_surfaceOffset);
56     m_surface.clear();
57 }
58
59 void CoordinatedBackingStoreTile::setBackBuffer(const IntRect& tileRect, const IntRect& sourceRect, PassRefPtr<CoordinatedSurface> buffer, const IntPoint& offset)
60 {
61     m_sourceRect = sourceRect;
62     m_tileRect = tileRect;
63     m_surfaceOffset = offset;
64     m_surface = buffer;
65 }
66
67 void CoordinatedBackingStore::createTile(uint32_t id, float scale)
68 {
69     m_tiles.add(id, CoordinatedBackingStoreTile(scale));
70     m_scale = scale;
71 }
72
73 void CoordinatedBackingStore::removeTile(uint32_t id)
74 {
75     ASSERT(m_tiles.contains(id));
76     m_tilesToRemove.add(id);
77 }
78
79 void CoordinatedBackingStore::removeAllTiles()
80 {
81     CoordinatedBackingStoreTileMap::iterator end = m_tiles.end();
82     for (CoordinatedBackingStoreTileMap::iterator it = m_tiles.begin(); it != end; ++it)
83         m_tilesToRemove.add(it->key);
84 }
85
86 void CoordinatedBackingStore::updateTile(uint32_t id, const IntRect& sourceRect, const IntRect& tileRect, PassRefPtr<CoordinatedSurface> backBuffer, const IntPoint& offset)
87 {
88     CoordinatedBackingStoreTileMap::iterator it = m_tiles.find(id);
89     ASSERT(it != m_tiles.end());
90     it->value.setBackBuffer(tileRect, sourceRect, backBuffer, offset);
91 }
92
93 PassRefPtr<BitmapTexture> CoordinatedBackingStore::texture() const
94 {
95     CoordinatedBackingStoreTileMap::const_iterator end = m_tiles.end();
96     for (CoordinatedBackingStoreTileMap::const_iterator it = m_tiles.begin(); it != end; ++it) {
97         RefPtr<BitmapTexture> texture = it->value.texture();
98         if (texture)
99             return texture;
100     }
101
102     return PassRefPtr<BitmapTexture>();
103 }
104
105 void CoordinatedBackingStore::setSize(const FloatSize& size)
106 {
107     m_pendingSize = size;
108 }
109
110 void CoordinatedBackingStore::paintTilesToTextureMapper(Vector<TextureMapperTile*>& tiles, TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, const FloatRect& rect)
111 {
112     for (size_t i = 0; i < tiles.size(); ++i)
113         tiles[i]->paint(textureMapper, transform, opacity, calculateExposedTileEdges(rect, tiles[i]->rect()));
114 }
115
116 TransformationMatrix CoordinatedBackingStore::adjustedTransformForRect(const FloatRect& targetRect)
117 {
118     return TransformationMatrix::rectToRect(rect(), targetRect);
119 }
120
121 void CoordinatedBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
122 {
123     if (m_tiles.isEmpty())
124         return;
125     ASSERT(!m_size.isZero());
126
127     Vector<TextureMapperTile*> tilesToPaint;
128     Vector<TextureMapperTile*> previousTilesToPaint;
129
130     // We have to do this every time we paint, in case the opacity has changed.
131     CoordinatedBackingStoreTileMap::iterator end = m_tiles.end();
132     FloatRect coveredRect;
133     for (CoordinatedBackingStoreTileMap::iterator it = m_tiles.begin(); it != end; ++it) {
134         CoordinatedBackingStoreTile& tile = it->value;
135         if (!tile.texture())
136             continue;
137
138         if (tile.scale() == m_scale) {
139             tilesToPaint.append(&tile);
140             coveredRect.unite(tile.rect());
141             continue;
142         }
143
144         // Only show the previous tile if the opacity is high, otherwise effect looks like a bug.
145         // We show the previous-scale tile anyway if it doesn't intersect with any current-scale tile.
146         if (opacity < 0.95 && coveredRect.intersects(tile.rect()))
147             continue;
148
149         previousTilesToPaint.append(&tile);
150     }
151
152     // targetRect is on the contents coordinate system, so we must compare two rects on the contents coordinate system.
153     // See TiledBackingStore.
154     TransformationMatrix adjustedTransform = transform * adjustedTransformForRect(targetRect);
155
156     paintTilesToTextureMapper(previousTilesToPaint, textureMapper, adjustedTransform, opacity, rect());
157     paintTilesToTextureMapper(tilesToPaint, textureMapper, adjustedTransform, opacity, rect());
158 }
159
160 void CoordinatedBackingStore::drawBorder(TextureMapper* textureMapper, const Color& borderColor, float borderWidth, const FloatRect& targetRect, const TransformationMatrix& transform)
161 {
162     TransformationMatrix adjustedTransform = transform * adjustedTransformForRect(targetRect);
163     CoordinatedBackingStoreTileMap::iterator end = m_tiles.end();
164     for (CoordinatedBackingStoreTileMap::iterator it = m_tiles.begin(); it != end; ++it)
165         textureMapper->drawBorder(borderColor, borderWidth, it->value.rect(), adjustedTransform);
166 }
167
168 void CoordinatedBackingStore::drawRepaintCounter(TextureMapper* textureMapper, int repaintCount, const Color& borderColor, const FloatRect& targetRect, const TransformationMatrix& transform)
169 {
170     TransformationMatrix adjustedTransform = transform * adjustedTransformForRect(targetRect);
171     CoordinatedBackingStoreTileMap::iterator end = m_tiles.end();
172     for (CoordinatedBackingStoreTileMap::iterator it = m_tiles.begin(); it != end; ++it)
173         textureMapper->drawNumber(repaintCount, borderColor, it->value.rect().location(), adjustedTransform);
174 }
175
176 void CoordinatedBackingStore::commitTileOperations(TextureMapper* textureMapper)
177 {
178     if (!m_pendingSize.isZero()) {
179         m_size = m_pendingSize;
180         m_pendingSize = FloatSize();
181     }
182
183     HashSet<uint32_t>::iterator tilesToRemoveEnd = m_tilesToRemove.end();
184     for (HashSet<uint32_t>::iterator it = m_tilesToRemove.begin(); it != tilesToRemoveEnd; ++it)
185         m_tiles.remove(*it);
186     m_tilesToRemove.clear();
187
188     CoordinatedBackingStoreTileMap::iterator tilesEnd = m_tiles.end();
189     for (CoordinatedBackingStoreTileMap::iterator it = m_tiles.begin(); it != tilesEnd; ++it)
190         it->value.swapBuffers(textureMapper);
191 }
192
193 } // namespace WebCore
194 #endif // USE(COORDINATED_GRAPHICS)