13c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard/* 23c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * Copyright 2011, The Android Open Source Project 33c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * 43c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * Redistribution and use in source and binary forms, with or without 53c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * modification, are permitted provided that the following conditions 63c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * are met: 73c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * * Redistributions of source code must retain the above copyright 83c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * notice, this list of conditions and the following disclaimer. 93c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * * Redistributions in binary form must reproduce the above copyright 103c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * notice, this list of conditions and the following disclaimer in the 113c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * documentation and/or other materials provided with the distribution. 123c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * 133c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 143c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 153c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 163c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 173c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 183c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 193c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 203c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 213c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 223c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 233c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 243c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard */ 253c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 263c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include "config.h" 273c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include "TiledTexture.h" 283c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 293c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include "TilesManager.h" 303c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include "TilesTracker.h" 313c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 323c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include "PaintedSurface.h" 333c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include "PaintTileOperation.h" 343c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include "SkCanvas.h" 35dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik#include "SkPicture.h" 363c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 373c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include <cutils/log.h> 383c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include <wtf/CurrentTime.h> 393c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include <wtf/text/CString.h> 403c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 41e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik#undef XLOGC 42e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "TiledTexture", __VA_ARGS__) 43e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik 44e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik#ifdef DEBUG 45e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik 463c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#undef XLOG 473c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TiledTexture", __VA_ARGS__) 483c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 493c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#else 503c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 513c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#undef XLOG 523c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#define XLOG(...) 533c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 543c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#endif // DEBUG 553c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 563c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roardnamespace WebCore { 573c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 58dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris CraikTiledTexture::~TiledTexture() 59dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik{ 60dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik SkSafeUnref(m_paintingPicture); 61dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik#ifdef DEBUG_COUNT 62dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik ClassTracker::instance()->decrement("TiledTexture"); 63dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik#endif 64dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik removeTiles(); 65dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik} 66dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 67dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craikbool TiledTexture::ready() 68dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik{ 69f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard bool tilesAllReady = true; 70f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard bool tilesVisible = false; 71f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard for (unsigned int i = 0; i < m_tiles.size(); i++) { 72f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard BaseTile* tile = m_tiles[i]; 735997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard if (tile->isTileVisible(m_area)) { 74f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard tilesVisible = true; 755997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard if (!tile->isTileReady()) { 765997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard tilesAllReady = false; 775997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard break; 785997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard } 795997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard } 80f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard } 81f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard // For now, if no textures are available, consider ourselves as ready 82f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard // in order to unblock the zooming process. 83f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard // FIXME: have a better system -- maybe keeping the last scale factor 84f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard // able to fully render everything 85dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik XLOG("TT %p, ready %d, visible %d, texturesRemain %d", 86dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik this, tilesAllReady, tilesVisible, 87dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik TilesManager::instance()->layerTexturesRemain()); 88dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 89f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard return !TilesManager::instance()->layerTexturesRemain() 909bcbd1be99f8033fe90e903b41a29a24dbf3616dChris Craik || !tilesVisible || tilesAllReady; 91f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard} 92f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 93dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craikvoid TiledTexture::swapTiles() 94dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik{ 95dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik int swaps = 0; 96dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik for (unsigned int i = 0; i < m_tiles.size(); i++) 97dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik if (m_tiles[i]->swapTexturesIfNeeded()) 98dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik swaps++; 99dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik XLOG("TT %p swapping, swaps = %d", this, swaps); 100dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik} 101dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 1025997528e55d0dc6734718bde61faa8513b1dd54fNicolas RoardIntRect TiledTexture::computeTilesArea(IntRect& visibleArea, float scale) 1033c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{ 1045997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard IntRect computedArea; 105f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard IntRect area(visibleArea.x() * scale, 106f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard visibleArea.y() * scale, 107f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard ceilf(visibleArea.width() * scale), 108f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard ceilf(visibleArea.height() * scale)); 1093c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 110dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik XLOG("TT %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height()); 111dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 1123c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard if (area.width() == 0 && area.height() == 0) { 1135997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard computedArea.setWidth(0); 1145997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard computedArea.setHeight(0); 1155997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard return computedArea; 1163c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 1173c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 1183c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard int tileWidth = TilesManager::instance()->layerTileWidth(); 1193c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard int tileHeight = TilesManager::instance()->layerTileHeight(); 1203c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 1215997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard computedArea.setX(area.x() / tileWidth); 1225997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard computedArea.setY(area.y() / tileHeight); 12329c97ede6da941582b98f709215c48f88b5850a6Nicolas Roard float right = (area.x() + area.width()) / (float) tileWidth; 12429c97ede6da941582b98f709215c48f88b5850a6Nicolas Roard float bottom = (area.y() + area.height()) / (float) tileHeight; 1255997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard computedArea.setWidth(ceilf(right) - computedArea.x()); 1265997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard computedArea.setHeight(ceilf(bottom) - computedArea.y()); 1275997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard return computedArea; 1285997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard} 12929c97ede6da941582b98f709215c48f88b5850a6Nicolas Roard 1305997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roardvoid TiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, 131dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik bool startFastSwap, IntRect& visibleArea) 1325997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard{ 1335997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard if (!m_surface) 1345997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard return; 1355997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard 136dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik // first, how many tiles do we need 137dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik m_area = computeTilesArea(visibleArea, scale); 1385997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard if (m_area.isEmpty()) 1395997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard return; 1405997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard 1415997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard XLOG("for TiledTexture %p, we prepare with scale %.2f, have a visible area of " 1425997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles", 143f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard this, scale, 14429c97ede6da941582b98f709215c48f88b5850a6Nicolas Roard visibleArea.x(), visibleArea.y(), 14529c97ede6da941582b98f709215c48f88b5850a6Nicolas Roard visibleArea.width(), visibleArea.height(), 14629c97ede6da941582b98f709215c48f88b5850a6Nicolas Roard m_area.x(), m_area.y(), 1477c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu m_area.width(), m_area.height()); 1487c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu 1493c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard bool goingDown = m_prevTileY < m_area.y(); 1503c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard m_prevTileY = m_area.y(); 1513c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 152f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard if (scale != m_scale) 153f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(this, scale)); 1543c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 155f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_scale = scale; 1563c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 157e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik // apply dirty region to affected tiles 158e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik if (!m_dirtyRegion.isEmpty()) { 159e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik for (unsigned int i = 0; i < m_tiles.size(); i++) { 160e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik // TODO: don't mark all tiles dirty 161e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik m_tiles[i]->markAsDirty(1, m_dirtyRegion); 162e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik } 163e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik } 164e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik m_dirtyRegion.setEmpty(); 165e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik 1663c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard for (int i = 0; i < m_area.width(); i++) { 1673c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard if (goingDown) { 1683c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard for (int j = 0; j < m_area.height(); j++) { 1693c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard prepareTile(repaint, m_area.x() + i, m_area.y() + j); 1703c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 1713c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } else { 1723c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard for (int j = m_area.height() - 1; j >= 0; j--) { 1733c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard prepareTile(repaint, m_area.x() + i, m_area.y() + j); 1743c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 1753c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 1763c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 1773c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard} 1783c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 179e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craikvoid TiledTexture::update(const SkRegion& invalRegion, SkPicture* picture) 180fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard{ 181dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik XLOG("TT %p update, current region empty %d, new empty %d, painting picture %p", 182dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty(), picture); 183dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op); 184dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 185dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik android::Mutex::Autolock lock(m_paintingPictureSync); 186dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik SkSafeRef(picture); 187dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik SkSafeUnref(m_paintingPicture); 188dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik m_paintingPicture = picture; 189fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard} 190fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard 1913c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roardvoid TiledTexture::prepareTile(bool repaint, int x, int y) 1923c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{ 1933c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard BaseTile* tile = getTile(x, y); 1943c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard if (!tile) { 1953c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard tile = new BaseTile(true); 1963c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard m_tiles.append(tile); 1973c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 1983c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 199dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik XLOG("preparing tile %p at %d, %d, painter is this %p", tile, x, y, this); 200f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard tile->setContents(this, x, y, m_scale); 2013c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 2028ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik // TODO: move below (which is largely the same for layers / tiled page) into 2038ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik // prepare() function 2043c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 2058ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (tile->isDirty() || !tile->frontTexture()) 2068ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik tile->reserveTexture(); 20754e75f0875a8376c1119b019431921bc58295b79Nicolas Roard 208dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik bool hasPicture = m_paintingPicture != 0; // safely read on UI thread, since only UI thread writes 209dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending() && hasPicture) { 21078fdfbadbd9b4ba76a2a021f85b98bc2b098b8eaNicolas Roard PaintTileOperation *operation = new PaintTileOperation(tile, m_surface); 2113c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard TilesManager::instance()->scheduleOperation(operation); 2123c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 2133c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard} 2143c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 2153c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas RoardBaseTile* TiledTexture::getTile(int x, int y) 2163c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{ 2173c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard for (unsigned int i = 0; i <m_tiles.size(); i++) { 2183c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard BaseTile* tile = m_tiles[i]; 2193c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard if (tile->x() == x && tile->y() == y) 2203c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard return tile; 2213c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 2223c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard return 0; 2233c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard} 2243c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 2255997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roardint TiledTexture::nbTextures(IntRect& area, float scale) 2265997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard{ 227429351139cee4eb681000434a73fabc3450a1f1dChris Craik IntRect tileBounds = computeTilesArea(area, scale); 228429351139cee4eb681000434a73fabc3450a1f1dChris Craik int numberTextures = tileBounds.width() * tileBounds.height(); 229429351139cee4eb681000434a73fabc3450a1f1dChris Craik 230429351139cee4eb681000434a73fabc3450a1f1dChris Craik // add the number of dirty tiles in the bounds, as they take up double 231429351139cee4eb681000434a73fabc3450a1f1dChris Craik // textures for double buffering 232429351139cee4eb681000434a73fabc3450a1f1dChris Craik for (unsigned int i = 0; i <m_tiles.size(); i++) { 233429351139cee4eb681000434a73fabc3450a1f1dChris Craik BaseTile* tile = m_tiles[i]; 234429351139cee4eb681000434a73fabc3450a1f1dChris Craik if (tile->isDirty() 235429351139cee4eb681000434a73fabc3450a1f1dChris Craik && tile->x() >= tileBounds.x() && tile->x() <= tileBounds.maxX() 236429351139cee4eb681000434a73fabc3450a1f1dChris Craik && tile->y() >= tileBounds.y() && tile->y() <= tileBounds.maxY()) 237429351139cee4eb681000434a73fabc3450a1f1dChris Craik numberTextures++; 238429351139cee4eb681000434a73fabc3450a1f1dChris Craik } 239429351139cee4eb681000434a73fabc3450a1f1dChris Craik return numberTextures; 2405997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard} 2415997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard 2423c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roardbool TiledTexture::draw() 2433c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{ 24454e75f0875a8376c1119b019431921bc58295b79Nicolas Roard if (!m_surface) 24554e75f0875a8376c1119b019431921bc58295b79Nicolas Roard return true; 24654e75f0875a8376c1119b019431921bc58295b79Nicolas Roard 247dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik XLOG("TT %p draw", this); 248dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 2493c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#ifdef DEBUG 2503c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard TilesManager::instance()->getTilesTracker()->trackLayer(); 2513c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#endif 2523c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 2533c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard if (m_area.width() == 0 || m_area.height() == 0) 254e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik return false; 2553c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 2563c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#ifdef DEBUG 2573c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard TilesManager::instance()->getTilesTracker()->trackVisibleLayer(); 2583c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#endif 2593c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 260f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard float m_invScale = 1 / m_scale; 2613c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard const float tileWidth = TilesManager::layerTileWidth() * m_invScale; 2623c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard const float tileHeight = TilesManager::layerTileHeight() * m_invScale; 263e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik 264e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik bool askRedraw = false; 265e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik for (unsigned int i = 0; i < m_tiles.size(); i++) { 2663c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard BaseTile* tile = m_tiles[i]; 267e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik 268e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik if (tile->isTileVisible(m_area)) { 26993bfc77abb66a95750b747cf5d782c31beadf7cfChris Craik askRedraw |= !tile->isTileReady(); 2703c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard SkRect rect; 2713c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard rect.fLeft = tile->x() * tileWidth; 2723c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard rect.fTop = tile->y() * tileHeight; 2733c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard rect.fRight = rect.fLeft + tileWidth; 2743c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard rect.fBottom = rect.fTop + tileHeight; 27554e75f0875a8376c1119b019431921bc58295b79Nicolas Roard XLOG("- [%d], { painter %x vs %x }, tile %x (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d", 27654e75f0875a8376c1119b019431921bc58295b79Nicolas Roard i, this, tile->painter(), tile, tile->isLayerTile(), tile->x(), tile->y(), 277f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard tile->scale(), m_scale, tile->isTileReady(), tile->isDirty()); 278f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard tile->draw(m_surface->opacity(), rect, m_scale); 2793c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#ifdef DEBUG 2808ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik TilesManager::instance()->getTilesTracker()->track(tile->isTileReady(), tile->backTexture()); 2813c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#endif 2823c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 2833c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 284e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik 285e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik // need to redraw if some visible tile wasn't ready 2863c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard return askRedraw; 2873c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard} 2883c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 2893c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roardbool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) 2903c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{ 291dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik m_paintingPictureSync.lock(); 292dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik SkPicture* picture = m_paintingPicture; 293dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik SkSafeRef(picture); 294dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik m_paintingPictureSync.unlock(); 295dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 296dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik if (!picture) { 297dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik XLOG("TT %p COULDNT PAINT, NO PICTURE", this); 298dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik return false; 299dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik } 300dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 30154e75f0875a8376c1119b019431921bc58295b79Nicolas Roard XLOG("TT %p painting tile %d, %d with picture %p", this, tile->x(), tile->y(), picture); 302dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 303dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik canvas->drawPicture(*picture); 304dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 305dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik SkSafeUnref(picture); 306dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 307dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik return true; 3083c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard} 3093c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 3103c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roardconst TransformationMatrix* TiledTexture::transform() 3113c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{ 31254e75f0875a8376c1119b019431921bc58295b79Nicolas Roard if (!m_surface) 31354e75f0875a8376c1119b019431921bc58295b79Nicolas Roard return 0; 3143c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard return m_surface->transform(); 3153c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard} 3163c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 3173c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roardvoid TiledTexture::removeTiles() 3183c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{ 3193c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard for (unsigned int i = 0; i < m_tiles.size(); i++) { 3203c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard delete m_tiles[i]; 3213c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 322f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_tiles.clear(); 323f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard} 324f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 325f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roardvoid TiledTexture::discardTextures() 326f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard{ 327f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard for (unsigned int i = 0; i < m_tiles.size(); i++) 328f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_tiles[i]->discardTextures(); 3293c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard} 3303c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 3313c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roardbool TiledTexture::owns(BaseTileTexture* texture) 3323c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{ 3333c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard for (unsigned int i = 0; i < m_tiles.size(); i++) { 3343c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard BaseTile* tile = m_tiles[i]; 3358ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (tile->frontTexture() == texture) 3368ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik return true; 3378ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (tile->backTexture() == texture) 3383c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard return true; 3393c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 3403c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard return false; 3413c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard} 3423c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 34354e75f0875a8376c1119b019431921bc58295b79Nicolas RoardDualTiledTexture::DualTiledTexture(SurfacePainter* surface) 344f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard{ 345f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_textureA = new TiledTexture(surface); 346f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_textureB = new TiledTexture(surface); 347f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_frontTexture = m_textureA; 348f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_backTexture = m_textureB; 349f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_scale = -1; 350f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_futureScale = -1; 351f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_zooming = false; 352f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard} 353f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 354f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas RoardDualTiledTexture::~DualTiledTexture() 355f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard{ 356f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard delete m_textureA; 357f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard delete m_textureB; 358f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard} 359f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 360f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roardvoid DualTiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, 361f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard bool startFastSwap, IntRect& visibleArea) 362f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard{ 363f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard // If we are zooming, we will use the previously used area, to prevent the 364f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard // frontTexture to try to allocate more tiles than what it has already 365f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard if (!m_zooming) 366f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_preZoomVisibleArea = visibleArea; 367f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 368f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard if (m_futureScale != scale) { 369f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_futureScale = scale; 370f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_zoomUpdateTime = WTF::currentTime() + DualTiledTexture::s_zoomUpdateDelay; 371f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_zooming = true; 372f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard } 373f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 374dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik XLOG("Preparing DTT %p with scale %.2f, m_scale %.2f, futureScale: %.2f, zooming: %d", 375dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik this, scale, m_scale, m_futureScale, m_zooming); 376f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 377f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard if (m_scale > 0) 378f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_frontTexture->prepare(state, m_scale, repaint, startFastSwap, m_preZoomVisibleArea); 379f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 380f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard // If we had a scheduled update 381f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard if (m_zooming && m_zoomUpdateTime < WTF::currentTime()) { 382f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_backTexture->prepare(state, m_futureScale, repaint, startFastSwap, visibleArea); 383f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard if (m_backTexture->ready()) { 38460082004bd7975748f8b0bee91645de245f1ea94Chris Craik m_backTexture->swapTiles(); 385f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard swap(); 386f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_zooming = false; 387f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard } 388f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard } 389f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard} 390f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 391f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roardvoid DualTiledTexture::swap() 392f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard{ 393f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_frontTexture = m_frontTexture == m_textureA ? m_textureB : m_textureA; 394f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_backTexture = m_backTexture == m_textureA ? m_textureB : m_textureA; 395f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_scale = m_futureScale; 396f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_backTexture->discardTextures(); 397f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard} 398f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 399f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roardbool DualTiledTexture::draw() 400f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard{ 401f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard bool needsRepaint = m_frontTexture->draw(); 402f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard needsRepaint |= m_zooming; 403f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard needsRepaint |= (m_scale <= 0); 404f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard return needsRepaint; 405f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard} 406f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 407f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roardvoid DualTiledTexture::update(const SkRegion& dirtyArea, SkPicture* picture) 408f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard{ 409f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_backTexture->update(dirtyArea, picture); 410f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard m_frontTexture->update(dirtyArea, picture); 411f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard} 412f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 413dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craikvoid DualTiledTexture::swapTiles() 414dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik{ 415dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik m_backTexture->swapTiles(); 416dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik m_frontTexture->swapTiles(); 417dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik} 418dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik 419f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roardbool DualTiledTexture::owns(BaseTileTexture* texture) 420f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard{ 421f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard bool owns = m_textureA->owns(texture); 422f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard owns |= m_textureB->owns(texture); 423f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard return owns; 424f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard} 425f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard 4263c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard} // namespace WebCore 427