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