2 Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
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.
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.
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.
22 #if USE(ACCELERATED_COMPOSITING)
23 #include "TextureMapperBackingStore.h"
25 #include "GraphicsLayer.h"
26 #include "ImageBuffer.h"
27 #include "TextureMapper.h"
29 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
30 #include "GraphicsSurface.h"
31 #include "TextureMapperGL.h"
36 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
37 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
38 void TextureMapperSurfaceBackingStore::setGraphicsSurface(PlatformBufferHandle graphicsSurfaceToken, const IntSize& surfaceSize, PlatformBufferHandle frontBuffer, int flags)
40 void TextureMapperSurfaceBackingStore::setGraphicsSurface(uint64_t graphicsSurfaceToken, const IntSize& surfaceSize, uint32_t frontBuffer)
43 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
44 if (graphicsSurfaceToken != m_graphicsSurfaceToken || m_graphicsSurfaceSize != surfaceSize) {
46 if (graphicsSurfaceToken != m_graphicsSurfaceToken) {
48 GraphicsSurface::Flags surfaceFlags = GraphicsSurface::SupportsTextureTarget
49 | GraphicsSurface::SupportsSharing;
50 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
51 setSurface(GraphicsSurface::create(surfaceSize, surfaceFlags, graphicsSurfaceToken, flags));
53 setSurface(GraphicsSurface::create(surfaceSize, surfaceFlags, graphicsSurfaceToken));
55 m_graphicsSurfaceSize = surfaceSize;
58 RefPtr<WebCore::GraphicsSurface> surface = graphicsSurface();
59 if (surface && surface->frontBuffer() != frontBuffer)
60 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
61 surface->swapBuffers(frontBuffer);
63 surface->swapBuffers();
67 PassRefPtr<BitmapTexture> TextureMapperSurfaceBackingStore::texture() const
69 // FIXME: Instead of just returning an empty texture, we should wrap the texture contents into a BitmapTexture.
70 RefPtr<BitmapTexture> emptyTexture;
74 void TextureMapperSurfaceBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
76 if (m_graphicsSurface)
77 m_graphicsSurface->paintToTextureMapper(textureMapper, targetRect, transform, opacity);
80 void TextureMapperSurfaceBackingStore::setSurface(PassRefPtr<GraphicsSurface> surface)
83 m_graphicsSurface = surface;
84 m_graphicsSurfaceToken = m_graphicsSurface->exportToken();
86 m_graphicsSurface = RefPtr<GraphicsSurface>();
87 m_graphicsSurfaceToken = 0;
92 void TextureMapperTile::updateContents(TextureMapper* textureMapper, Image* image, const IntRect& dirtyRect)
94 IntRect targetRect = enclosingIntRect(m_rect);
95 targetRect.intersect(dirtyRect);
96 if (targetRect.isEmpty())
98 IntPoint sourceOffset = targetRect.location();
100 // Normalize sourceRect to the buffer's coordinates.
101 sourceOffset.move(-dirtyRect.x(), -dirtyRect.y());
103 // Normalize targetRect to the texture's coordinates.
104 targetRect.move(-m_rect.x(), -m_rect.y());
106 m_texture = textureMapper->createTexture();
107 m_texture->reset(targetRect.size(), image->currentFrameHasAlpha() ? BitmapTexture::SupportsAlpha : 0);
110 m_texture->updateContents(image, targetRect, sourceOffset);
113 void TextureMapperTile::paint(TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, const unsigned exposedEdges)
116 textureMapper->drawTexture(*texture().get(), rect(), transform, opacity, exposedEdges);
119 TextureMapperTiledBackingStore::TextureMapperTiledBackingStore()
120 : m_drawsDebugBorders(false)
124 void TextureMapperTiledBackingStore::updateContentsFromImageIfNeeded(TextureMapper* textureMapper)
129 updateContents(textureMapper, m_image.get());
133 unsigned TextureMapperBackingStore::calculateExposedTileEdges(const FloatRect& totalRect, const FloatRect& tileRect)
135 unsigned exposedEdges = TextureMapper::NoEdges;
137 exposedEdges |= TextureMapper::LeftEdge;
139 exposedEdges |= TextureMapper::TopEdge;
140 if (tileRect.width() + tileRect.x() >= totalRect.width())
141 exposedEdges |= TextureMapper::RightEdge;
142 if (tileRect.height() + tileRect.y() >= totalRect.height())
143 exposedEdges |= TextureMapper::BottomEdge;
147 void TextureMapperTiledBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
149 updateContentsFromImageIfNeeded(textureMapper);
150 TransformationMatrix adjustedTransform = transform;
151 adjustedTransform.multiply(TransformationMatrix::rectToRect(rect(), targetRect));
152 for (size_t i = 0; i < m_tiles.size(); ++i) {
153 m_tiles[i].paint(textureMapper, adjustedTransform, opacity, calculateExposedTileEdges(rect(), m_tiles[i].rect()));
154 if (m_drawsDebugBorders)
155 textureMapper->drawBorder(m_debugBorderColor, m_debugBorderWidth, m_tiles[i].rect(), adjustedTransform);
159 void TextureMapperTiledBackingStore::createOrDestroyTilesIfNeeded(const FloatSize& size, const IntSize& tileSize, bool hasAlpha)
166 Vector<FloatRect> tileRectsToAdd;
167 Vector<int> tileIndicesToRemove;
168 static const size_t TileEraseThreshold = 6;
170 // This method recycles tiles. We check which tiles we need to add, which to remove, and use as many
171 // removable tiles as replacement for new tiles when possible.
172 for (float y = 0; y < m_size.height(); y += tileSize.height()) {
173 for (float x = 0; x < m_size.width(); x += tileSize.width()) {
174 FloatRect tileRect(x, y, tileSize.width(), tileSize.height());
175 tileRect.intersect(rect());
176 tileRectsToAdd.append(tileRect);
180 // Check which tiles need to be removed, and which already exist.
181 for (int i = m_tiles.size() - 1; i >= 0; --i) {
182 FloatRect oldTile = m_tiles[i].rect();
183 bool existsAlready = false;
185 for (int j = tileRectsToAdd.size() - 1; j >= 0; --j) {
186 FloatRect newTile = tileRectsToAdd[j];
187 if (oldTile != newTile)
190 // A tile that we want to add already exists, no need to add or remove it.
191 existsAlready = true;
192 tileRectsToAdd.remove(j);
196 // This tile is not needed.
198 tileIndicesToRemove.append(i);
201 // Recycle removable tiles to be used for newly requested tiles.
202 for (size_t i = 0; i < tileRectsToAdd.size(); ++i) {
203 if (!tileIndicesToRemove.isEmpty()) {
204 // We recycle an existing tile for usage with a new tile rect.
205 TextureMapperTile& tile = m_tiles[tileIndicesToRemove.last()];
206 tileIndicesToRemove.removeLast();
207 tile.setRect(tileRectsToAdd[i]);
210 tile.texture()->reset(enclosingIntRect(tile.rect()).size(), hasAlpha ? BitmapTexture::SupportsAlpha : 0);
214 m_tiles.append(TextureMapperTile(tileRectsToAdd[i]));
217 // Remove unnecessary tiles, if they weren't recycled.
218 // We use a threshold to make sure we don't create/destroy tiles too eagerly.
219 for (size_t i = 0; i < tileIndicesToRemove.size() && m_tiles.size() > TileEraseThreshold; ++i)
220 m_tiles.remove(tileIndicesToRemove[i]);
223 void TextureMapperTiledBackingStore::updateContents(TextureMapper* textureMapper, Image* image, const FloatSize& totalSize, const IntRect& dirtyRect)
225 createOrDestroyTilesIfNeeded(totalSize, textureMapper->maxTextureSize(), image->currentFrameHasAlpha());
226 for (size_t i = 0; i < m_tiles.size(); ++i)
227 m_tiles[i].updateContents(textureMapper, image, dirtyRect);
230 PassRefPtr<BitmapTexture> TextureMapperTiledBackingStore::texture() const
232 for (size_t i = 0; i < m_tiles.size(); ++i) {
233 RefPtr<BitmapTexture> texture = m_tiles[i].texture();
238 return PassRefPtr<BitmapTexture>();
241 void TextureMapperTiledBackingStore::setDebugBorder(const Color& color, float width)
243 m_debugBorderColor = color;
244 m_debugBorderWidth = width;