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
26594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#define LOG_TAG "TileGrid"
27d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#define LOG_NDEBUG 1
28d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik
293c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include "config.h"
30594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "TileGrid.h"
313c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
32d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#include "AndroidLog.h"
33a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu#include "DrawQuadData.h"
34594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "GLWebViewState.h"
353c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include "PaintTileOperation.h"
36594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "Tile.h"
37e859a34171f2a36877d95197d118d962078f8aa0John Reck#include "TileTexture.h"
38d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#include "TilesManager.h"
393c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
403c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard#include <wtf/CurrentTime.h>
413c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
42c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik#define EXPANDED_BOUNDS_INFLATE 1
43c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik#define EXPANDED_PREFETCH_BOUNDS_Y_INFLATE 1
44c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik
453c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roardnamespace WebCore {
463c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
47594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikTileGrid::TileGrid(bool isBaseSurface)
48594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    : m_prevTileY(0)
49594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    , m_scale(1)
50594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    , m_isBaseSurface(isBaseSurface)
51dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik{
52594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    m_dirtyRegion.setEmpty();
53dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik#ifdef DEBUG_COUNT
54594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    ClassTracker::instance()->increment("TileGrid");
55594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#endif
56594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik}
57594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik
58594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikTileGrid::~TileGrid()
59594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik{
60594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#ifdef DEBUG_COUNT
61594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    ClassTracker::instance()->decrement("TileGrid");
62dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik#endif
63dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik    removeTiles();
64dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik}
65dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik
66594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool TileGrid::isReady()
67dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik{
68f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    bool tilesAllReady = true;
69f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    bool tilesVisible = false;
70f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    for (unsigned int i = 0; i < m_tiles.size(); i++) {
71594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik        Tile* tile = m_tiles[i];
725997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard        if (tile->isTileVisible(m_area)) {
73f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard            tilesVisible = true;
745997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard            if (!tile->isTileReady()) {
755997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard                tilesAllReady = false;
765997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard                break;
775997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard            }
785997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard        }
79f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    }
80f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    // For now, if no textures are available, consider ourselves as ready
81f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    // in order to unblock the zooming process.
82f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    // FIXME: have a better system -- maybe keeping the last scale factor
83f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    // able to fully render everything
84ceac2217dad840ce8d690923219b51787083bb44Chris Craik    ALOGV("TG %p, ready %d, visible %d, texturesRemain %d",
85d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          this, tilesAllReady, tilesVisible,
86d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          TilesManager::instance()->layerTexturesRemain());
87dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik
88f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    return !TilesManager::instance()->layerTexturesRemain()
899bcbd1be99f8033fe90e903b41a29a24dbf3616dChris Craik            || !tilesVisible || tilesAllReady;
90f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard}
91f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard
92594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool TileGrid::isMissingContent()
93c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik{
94c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik    for (unsigned int i = 0; i < m_tiles.size(); i++)
95c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        if (m_tiles[i]->isTileVisible(m_area) && !m_tiles[i]->frontTexture())
96c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik            return true;
97c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik    return false;
98c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik}
99c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik
100377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roardbool TileGrid::swapTiles()
101dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik{
102dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik    int swaps = 0;
103dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik    for (unsigned int i = 0; i < m_tiles.size(); i++)
104dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik        if (m_tiles[i]->swapTexturesIfNeeded())
105dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik            swaps++;
106ceac2217dad840ce8d690923219b51787083bb44Chris Craik    ALOGV("TG %p swapping, swaps = %d", this, swaps);
107377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard    return swaps != 0;
108dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik}
109dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik
110594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikIntRect TileGrid::computeTilesArea(const IntRect& contentArea, float scale)
1113c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{
1125997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard    IntRect computedArea;
113bfe61b92a059634950caed7cf9a65492cf2da8a0Chris Craik    IntRect area(contentArea.x() * scale,
114bfe61b92a059634950caed7cf9a65492cf2da8a0Chris Craik                 contentArea.y() * scale,
115bfe61b92a059634950caed7cf9a65492cf2da8a0Chris Craik                 ceilf(contentArea.width() * scale),
116bfe61b92a059634950caed7cf9a65492cf2da8a0Chris Craik                 ceilf(contentArea.height() * scale));
1173c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
118e859a34171f2a36877d95197d118d962078f8aa0John Reck    ALOGV("TG prepare, scale %f, area %d x %d", scale, area.width(), area.height());
119dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik
1203c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    if (area.width() == 0 && area.height() == 0) {
1215997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard        computedArea.setWidth(0);
1225997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard        computedArea.setHeight(0);
1235997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard        return computedArea;
1243c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    }
1253c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
126c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik    int tileWidth = TilesManager::tileWidth();
127c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik    int tileHeight = TilesManager::tileHeight();
1283c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
1295997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard    computedArea.setX(area.x() / tileWidth);
1305997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard    computedArea.setY(area.y() / tileHeight);
13129c97ede6da941582b98f709215c48f88b5850a6Nicolas Roard    float right = (area.x() + area.width()) / (float) tileWidth;
13229c97ede6da941582b98f709215c48f88b5850a6Nicolas Roard    float bottom = (area.y() + area.height()) / (float) tileHeight;
1335997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard    computedArea.setWidth(ceilf(right) - computedArea.x());
1345997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard    computedArea.setHeight(ceilf(bottom) - computedArea.y());
1355997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard    return computedArea;
1365997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard}
13729c97ede6da941582b98f709215c48f88b5850a6Nicolas Roard
138594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid TileGrid::prepareGL(GLWebViewState* state, float scale,
1399e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu                         const IntRect& prepareArea, const IntRect& fullContentArea,
140e859a34171f2a36877d95197d118d962078f8aa0John Reck                         TilePainter* painter, int regionFlags, bool isLowResPrefetch,
141e859a34171f2a36877d95197d118d962078f8aa0John Reck                         bool updateWithBlit)
1425997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard{
143dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik    // first, how many tiles do we need
144bfe61b92a059634950caed7cf9a65492cf2da8a0Chris Craik    m_area = computeTilesArea(prepareArea, scale);
1455997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard    if (m_area.isEmpty())
1465997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard        return;
1475997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard
148594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    ALOGV("prepare TileGrid %p with scale %.2f, prepareArea "
149d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles",
150d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          this, scale,
151d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          prepareArea.x(), prepareArea.y(),
152d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          prepareArea.width(), prepareArea.height(),
153d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          m_area.x(), m_area.y(),
154d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          m_area.width(), m_area.height());
1557c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
1563c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    bool goingDown = m_prevTileY < m_area.y();
1573c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    m_prevTileY = m_area.y();
1583c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
15977a63f12c44ce6ef9e69cb9a2e104fc625d96cacChris Craik    TilesManager* tilesManager = TilesManager::instance();
160f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    if (scale != m_scale)
16177a63f12c44ce6ef9e69cb9a2e104fc625d96cacChris Craik        tilesManager->removeOperationsForFilter(new ScaleFilter(painter, m_scale));
1623c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
163f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    m_scale = scale;
1643c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
165e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik    // apply dirty region to affected tiles
166e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik    if (!m_dirtyRegion.isEmpty()) {
167d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik        for (unsigned int i = 0; i < m_tiles.size(); i++)
168f7ad77dc2a981834d664fd24022c3dfade69c8aaChris Craik            m_tiles[i]->markAsDirty(m_dirtyRegion);
169885e650b12d781be054b31ae6221925a0184dc33Chris Craik
170885e650b12d781be054b31ae6221925a0184dc33Chris Craik        // log inval region for the base surface
17177a63f12c44ce6ef9e69cb9a2e104fc625d96cacChris Craik        if (m_isBaseSurface && tilesManager->getProfiler()->enabled()) {
172885e650b12d781be054b31ae6221925a0184dc33Chris Craik            SkRegion::Iterator iterator(m_dirtyRegion);
173885e650b12d781be054b31ae6221925a0184dc33Chris Craik            while (!iterator.done()) {
174885e650b12d781be054b31ae6221925a0184dc33Chris Craik                SkIRect r = iterator.rect();
17577a63f12c44ce6ef9e69cb9a2e104fc625d96cacChris Craik                tilesManager->getProfiler()->nextInval(r, scale);
176885e650b12d781be054b31ae6221925a0184dc33Chris Craik                iterator.next();
177885e650b12d781be054b31ae6221925a0184dc33Chris Craik            }
178885e650b12d781be054b31ae6221925a0184dc33Chris Craik        }
179d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik        m_dirtyRegion.setEmpty();
180e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik    }
181e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik
182e080317b90534632e8be18dc8d5e9a51554b444aChris Craik    if (regionFlags & StandardRegion) {
183e080317b90534632e8be18dc8d5e9a51554b444aChris Craik        for (int i = 0; i < m_area.width(); i++) {
184e080317b90534632e8be18dc8d5e9a51554b444aChris Craik            if (goingDown) {
185e080317b90534632e8be18dc8d5e9a51554b444aChris Craik                for (int j = 0; j < m_area.height(); j++)
186e080317b90534632e8be18dc8d5e9a51554b444aChris Craik                    prepareTile(m_area.x() + i, m_area.y() + j,
187e859a34171f2a36877d95197d118d962078f8aa0John Reck                                painter, state, isLowResPrefetch, false, updateWithBlit);
188e080317b90534632e8be18dc8d5e9a51554b444aChris Craik            } else {
189e080317b90534632e8be18dc8d5e9a51554b444aChris Craik                for (int j = m_area.height() - 1; j >= 0; j--)
190e080317b90534632e8be18dc8d5e9a51554b444aChris Craik                    prepareTile(m_area.x() + i, m_area.y() + j,
191e859a34171f2a36877d95197d118d962078f8aa0John Reck                                painter, state, isLowResPrefetch, false, updateWithBlit);
192e080317b90534632e8be18dc8d5e9a51554b444aChris Craik            }
1933c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        }
1943c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    }
195c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik
196e080317b90534632e8be18dc8d5e9a51554b444aChris Craik    if (regionFlags & ExpandedRegion) {
1979e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu        IntRect fullArea = computeTilesArea(fullContentArea, scale);
198c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        IntRect expandedArea = m_area;
199ca1e910446353672503d5251c28cc7384018932aChris Craik
20077a63f12c44ce6ef9e69cb9a2e104fc625d96cacChris Craik        // on systems reporting highEndGfx=true and useMinimalMemory not set, use expanded bounds
20177a63f12c44ce6ef9e69cb9a2e104fc625d96cacChris Craik        if (tilesManager->highEndGfx() && !tilesManager->useMinimalMemory())
202ca1e910446353672503d5251c28cc7384018932aChris Craik            expandedArea.inflate(EXPANDED_BOUNDS_INFLATE);
203c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik
204c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        if (isLowResPrefetch)
205ca1e910446353672503d5251c28cc7384018932aChris Craik            expandedArea.inflateY(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE);
206c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik
207c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        // clip painting area to content
208c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        expandedArea.intersect(fullArea);
209c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik
210c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        for (int i = expandedArea.x(); i < expandedArea.maxX(); i++)
211c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik            for (int j = expandedArea.y(); j < expandedArea.maxY(); j++)
212c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik                if (!m_area.contains(i, j))
213e859a34171f2a36877d95197d118d962078f8aa0John Reck                    prepareTile(i, j, painter, state, isLowResPrefetch, true, updateWithBlit);
214c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik    }
2153c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard}
2163c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
217594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid TileGrid::markAsDirty(const SkRegion& invalRegion)
218fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard{
219ceac2217dad840ce8d690923219b51787083bb44Chris Craik    ALOGV("TG %p markAsDirty, current region empty %d, new empty %d",
220d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty());
221dfd2fb1ed3c17d0cbb4af895f74704c22130587fChris Craik    m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op);
222fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard}
223fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
224594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid TileGrid::prepareTile(int x, int y, TilePainter* painter,
225e859a34171f2a36877d95197d118d962078f8aa0John Reck                           GLWebViewState* state, bool isLowResPrefetch,
226e859a34171f2a36877d95197d118d962078f8aa0John Reck                           bool isExpandPrefetch, bool shouldTryUpdateWithBlit)
2273c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{
228594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    Tile* tile = getTile(x, y);
2293c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    if (!tile) {
230885e650b12d781be054b31ae6221925a0184dc33Chris Craik        bool isLayerTile = !m_isBaseSurface;
231594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik        tile = new Tile(isLayerTile);
2323c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        m_tiles.append(tile);
2333c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    }
2343c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
235d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik    ALOGV("preparing tile %p at %d, %d, painter is %p", tile, x, y, painter);
236c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik
237c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik    tile->setContents(x, y, m_scale, isExpandPrefetch);
2383c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
239e859a34171f2a36877d95197d118d962078f8aa0John Reck    if (shouldTryUpdateWithBlit && tryBlitFromContents(tile, painter))
240e859a34171f2a36877d95197d118d962078f8aa0John Reck        return;
241e859a34171f2a36877d95197d118d962078f8aa0John Reck
2428ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (tile->isDirty() || !tile->frontTexture())
2438ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        tile->reserveTexture();
24454e75f0875a8376c1119b019431921bc58295b79Nicolas Roard
245425ef23631e3468c61a5740dd4e4bae3052cec48Chris Craik    if (tile->backTexture() && tile->isDirty()) {
246425ef23631e3468c61a5740dd4e4bae3052cec48Chris Craik        TilesManager* tilesManager = TilesManager::instance();
247425ef23631e3468c61a5740dd4e4bae3052cec48Chris Craik
248425ef23631e3468c61a5740dd4e4bae3052cec48Chris Craik        // if a scheduled repaint is still outstanding, update it with the new painter
249425ef23631e3468c61a5740dd4e4bae3052cec48Chris Craik        if (tile->isRepaintPending() && tilesManager->tryUpdateOperationWithPainter(tile, painter))
250425ef23631e3468c61a5740dd4e4bae3052cec48Chris Craik            return;
251425ef23631e3468c61a5740dd4e4bae3052cec48Chris Craik
25255ff9f5ac537f2b11ae997f1029bdccb87008825Chris Craik        ALOGV("painting TG %p's tile %d %d for LG %p, scale %f", this, x, y, painter, m_scale);
253c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        PaintTileOperation *operation = new PaintTileOperation(tile, painter,
254c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik                                                               state, isLowResPrefetch);
255425ef23631e3468c61a5740dd4e4bae3052cec48Chris Craik        tilesManager->scheduleOperation(operation);
2563c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    }
2573c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard}
2583c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
259e859a34171f2a36877d95197d118d962078f8aa0John Reckbool TileGrid::tryBlitFromContents(Tile* tile, TilePainter* painter)
260e859a34171f2a36877d95197d118d962078f8aa0John Reck{
261e859a34171f2a36877d95197d118d962078f8aa0John Reck    return tile->frontTexture()
262e859a34171f2a36877d95197d118d962078f8aa0John Reck           && !tile->frontTexture()->isPureColor()
263e859a34171f2a36877d95197d118d962078f8aa0John Reck           && tile->frontTexture()->m_ownTextureId
264e859a34171f2a36877d95197d118d962078f8aa0John Reck           && !tile->isRepaintPending()
265e859a34171f2a36877d95197d118d962078f8aa0John Reck           && painter->blitFromContents(tile);
266e859a34171f2a36877d95197d118d962078f8aa0John Reck}
267e859a34171f2a36877d95197d118d962078f8aa0John Reck
268594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikTile* TileGrid::getTile(int x, int y)
2693c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{
2703c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    for (unsigned int i = 0; i <m_tiles.size(); i++) {
271594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik        Tile* tile = m_tiles[i];
2723c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        if (tile->x() == x && tile->y() == y)
2733c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard            return tile;
2743c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    }
2753c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    return 0;
2763c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard}
2773c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
278750f81c3eb609bfd132182bbbb9b467455175498Teng-Hui Zhuunsigned int TileGrid::getImageTextureId()
279750f81c3eb609bfd132182bbbb9b467455175498Teng-Hui Zhu{
280750f81c3eb609bfd132182bbbb9b467455175498Teng-Hui Zhu    if (m_tiles.size() == 1) {
281750f81c3eb609bfd132182bbbb9b467455175498Teng-Hui Zhu        if (m_tiles[0]->frontTexture())
282750f81c3eb609bfd132182bbbb9b467455175498Teng-Hui Zhu            return m_tiles[0]->frontTexture()->m_ownTextureId;
283750f81c3eb609bfd132182bbbb9b467455175498Teng-Hui Zhu    }
284750f81c3eb609bfd132182bbbb9b467455175498Teng-Hui Zhu    return 0;
285750f81c3eb609bfd132182bbbb9b467455175498Teng-Hui Zhu}
286750f81c3eb609bfd132182bbbb9b467455175498Teng-Hui Zhu
287bfd7e70d96a769e5d62fb5c9148b5c810a8bef65Chris Craikint TileGrid::nbTextures(const IntRect& area, float scale)
2885997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard{
289429351139cee4eb681000434a73fabc3450a1f1dChris Craik    IntRect tileBounds = computeTilesArea(area, scale);
290429351139cee4eb681000434a73fabc3450a1f1dChris Craik    int numberTextures = tileBounds.width() * tileBounds.height();
291429351139cee4eb681000434a73fabc3450a1f1dChris Craik
292429351139cee4eb681000434a73fabc3450a1f1dChris Craik    // add the number of dirty tiles in the bounds, as they take up double
293429351139cee4eb681000434a73fabc3450a1f1dChris Craik    // textures for double buffering
294429351139cee4eb681000434a73fabc3450a1f1dChris Craik    for (unsigned int i = 0; i <m_tiles.size(); i++) {
295594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik        Tile* tile = m_tiles[i];
296429351139cee4eb681000434a73fabc3450a1f1dChris Craik        if (tile->isDirty()
297429351139cee4eb681000434a73fabc3450a1f1dChris Craik                && tile->x() >= tileBounds.x() && tile->x() <= tileBounds.maxX()
298429351139cee4eb681000434a73fabc3450a1f1dChris Craik                && tile->y() >= tileBounds.y() && tile->y() <= tileBounds.maxY())
299429351139cee4eb681000434a73fabc3450a1f1dChris Craik            numberTextures++;
300429351139cee4eb681000434a73fabc3450a1f1dChris Craik    }
301429351139cee4eb681000434a73fabc3450a1f1dChris Craik    return numberTextures;
3025997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard}
3035997528e55d0dc6734718bde61faa8513b1dd54fNicolas Roard
3049e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhuvoid TileGrid::drawGL(const IntRect& visibleContentArea, float opacity,
30572ae6b87e6a35b6bea03035afa3fe21284033444Chris Craik                      const TransformationMatrix* transform,
30672ae6b87e6a35b6bea03035afa3fe21284033444Chris Craik                      const Color* background)
3073c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{
3089e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu    m_area = computeTilesArea(visibleContentArea, m_scale);
3093c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    if (m_area.width() == 0 || m_area.height() == 0)
310bf9aa54ac784685db3d2cd8c0d616b25b289c09eTeng-Hui Zhu        return;
3113c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
312868c42d56aae84ed4cd33f9de0d93132e1483ddcTeng-Hui Zhu    float invScale = 1.0 / m_scale;
313afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    const float tileWidth = TilesManager::tileWidth() * invScale;
314afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    const float tileHeight = TilesManager::tileHeight() * invScale;
315e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik
316d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik    int drawn = 0;
317afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu
318afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    SkRegion missingRegion;
319a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu    bool semiOpaqueBaseSurface =
320afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        background ? (background->hasAlpha() && background->alpha() > 0) : false;
321a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu    if (semiOpaqueBaseSurface) {
322afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        SkIRect totalArea = SkIRect::MakeXYWH(m_area.x(), m_area.y(),
323afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                                              m_area.width(), m_area.height());
324afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        missingRegion = SkRegion(totalArea);
325afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    }
326afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu
3273efc67e0caf0b63fe0350d6896d2cbc08661f5d7Teng-Hui Zhu    bool usePointSampling =
3283efc67e0caf0b63fe0350d6896d2cbc08661f5d7Teng-Hui Zhu        TilesManager::instance()->shader()->usePointSampling(m_scale, transform);
3293efc67e0caf0b63fe0350d6896d2cbc08661f5d7Teng-Hui Zhu
3309e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu    float minTileX =  visibleContentArea.x() / tileWidth;
3319e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu    float minTileY =  visibleContentArea.y() / tileWidth;
3329e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu    float maxTileWidth = visibleContentArea.maxX() / tileWidth;
3339e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu    float maxTileHeight = visibleContentArea.maxY() / tileWidth;
334485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu    ALOGV("minTileX, minTileY, maxTileWidth, maxTileHeight %f, %f, %f %f",
335485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu          minTileX, minTileY, maxTileWidth, maxTileHeight);
336e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik    for (unsigned int i = 0; i < m_tiles.size(); i++) {
337594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik        Tile* tile = m_tiles[i];
338e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik
339885e650b12d781be054b31ae6221925a0184dc33Chris Craik        bool tileInView = tile->isTileVisible(m_area);
340885e650b12d781be054b31ae6221925a0184dc33Chris Craik        if (tileInView) {
3413c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard            SkRect rect;
3423c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard            rect.fLeft = tile->x() * tileWidth;
3433c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard            rect.fTop = tile->y() * tileHeight;
3443c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard            rect.fRight = rect.fLeft + tileWidth;
3453c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard            rect.fBottom = rect.fTop + tileHeight;
346d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik            ALOGV("tile %p (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d",
347d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik                  tile, tile->isLayerTile(), tile->x(), tile->y(),
348d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik                  tile->scale(), m_scale, tile->isTileReady(), tile->isDirty());
349afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu
350a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu            bool forceBaseBlending = background ? background->hasAlpha() : false;
35132ce41e0241790f20e63cafea4d3c1db87423eecChris Craik
352485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu            float left = std::max(minTileX - tile->x(), 0.0f);
353485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu            float top = std::max(minTileY - tile->y(), 0.0f);
354485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu            float right = std::min(maxTileWidth - tile->x(), 1.0f);
355485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu            float bottom = std::min(maxTileHeight - tile->y(), 1.0f);
356485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu            if (left > 1.0f || top > 1.0f || right < 0.0f || bottom < 0.0f) {
357485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu                ALOGE("Unexpected portion:left, top, right, bottom %f %f %f %f",
358485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu                      left, top, right, bottom);
359485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu                left = 0.0f;
360485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu                top = 0.0f;
361485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu                right = 1.0f;
362485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu                bottom = 1.0f;
363485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu            }
364485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu            FloatRect fillPortion(left, top, right - left, bottom - top);
365485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu
366a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu            bool success = tile->drawGL(opacity, rect, m_scale, transform,
36732ce41e0241790f20e63cafea4d3c1db87423eecChris Craik                                        forceBaseBlending, usePointSampling, fillPortion);
368a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu            if (semiOpaqueBaseSurface && success) {
369afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                // Cut the successful drawn tile area from the missing region.
370afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                missingRegion.op(SkIRect::MakeXYWH(tile->x(), tile->y(), 1, 1),
371afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                                 SkRegion::kDifference_Op);
372afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu            }
373d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik            if (tile->frontTexture())
374d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik                drawn++;
3753c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        }
376885e650b12d781be054b31ae6221925a0184dc33Chris Craik
37772ae6b87e6a35b6bea03035afa3fe21284033444Chris Craik        // log tile information for base, high res tiles
37872ae6b87e6a35b6bea03035afa3fe21284033444Chris Craik        if (m_isBaseSurface && background)
379afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu            TilesManager::instance()->getProfiler()->nextTile(tile, invScale, tileInView);
3803c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    }
381afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu
382afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    // Draw missing Regions with blend turned on
383a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu    if (semiOpaqueBaseSurface)
384afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        drawMissingRegion(missingRegion, opacity, background);
385afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu
386ceac2217dad840ce8d690923219b51787083bb44Chris Craik    ALOGV("TG %p drew %d tiles, scale %f",
387bf9aa54ac784685db3d2cd8c0d616b25b289c09eTeng-Hui Zhu          this, drawn, m_scale);
3883c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard}
3893c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
390594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid TileGrid::drawMissingRegion(const SkRegion& region, float opacity,
391afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                                     const Color* background)
392afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu{
393afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    SkRegion::Iterator iterator(region);
394afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    const float tileWidth = TilesManager::tileWidth() / m_scale;
395afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    const float tileHeight = TilesManager::tileHeight() / m_scale;
396afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    while (!iterator.done()) {
397afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        SkIRect r = iterator.rect();
398afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        SkRect rect;
399afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        rect.fLeft = r.x() * tileWidth;
400afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        rect.fTop =  r.y() * tileHeight;
401afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        rect.fRight = rect.fLeft + tileWidth * r.width();
402afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        rect.fBottom = rect.fTop + tileHeight * r.height();
403afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        ALOGV("draw tile x y, %d %d (%d %d) opacity %f", r.x(), r.y(),
404afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu              r.width(), r.height(), opacity);
405afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        // Skia is using pre-multiplied color.
406afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        Color postAlpha = Color(background->red() * background->alpha() / 255,
407afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                                background->green() * background->alpha() / 255,
408afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                                background->blue() * background->alpha() / 255,
409afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                                background->alpha() );
410a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu
411a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu        PureColorQuadData backGroundData(postAlpha, BaseQuad, 0, &rect, opacity);
412a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu        TilesManager::instance()->shader()->drawQuad(&backGroundData);
413afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        iterator.next();
414afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    }
415afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu}
416afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu
417594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid TileGrid::removeTiles()
4183c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard{
4197ebd389d0f7a0e47fe731e1d024753bce0f0614dChris Craik    for (unsigned int i = 0; i < m_tiles.size(); i++) {
4207ebd389d0f7a0e47fe731e1d024753bce0f0614dChris Craik        delete m_tiles[i];
4217ebd389d0f7a0e47fe731e1d024753bce0f0614dChris Craik    }
422f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    m_tiles.clear();
423f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard}
424f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard
425594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid TileGrid::discardTextures()
426f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard{
427ceac2217dad840ce8d690923219b51787083bb44Chris Craik    ALOGV("TG %p discarding textures", this);
428f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard    for (unsigned int i = 0; i < m_tiles.size(); i++)
429f65ed48034d37597dc4b191a79781ae49d2cfc99Nicolas Roard        m_tiles[i]->discardTextures();
4303c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard}
4313c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
4323c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard} // namespace WebCore
433