2 * Copyright 2011, The Android Open Source Project
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "TiledTexture.h"
29 #include "TilesManager.h"
30 #include "TilesTracker.h"
32 #include "PaintedSurface.h"
33 #include "PaintTileOperation.h"
38 #include <cutils/log.h>
39 #include <wtf/CurrentTime.h>
40 #include <wtf/text/CString.h>
43 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TiledTexture", __VA_ARGS__)
54 void TiledTexture::prepare(GLWebViewState* state, bool repaint)
59 if (!m_surface->layer())
62 // first, how many tiles do we need
63 IntRect visibleArea = m_surface->visibleArea();
64 IntRect area(visibleArea.x() * m_surface->scale(),
65 visibleArea.y() * m_surface->scale(),
66 visibleArea.width() * m_surface->scale(),
67 visibleArea.height() * m_surface->scale());
69 for (unsigned int i = 0; i < m_tiles.size(); i++) {
70 BaseTile* tile = m_tiles[i];
71 tile->setUsedLevel(-1);
74 if (area.width() == 0 && area.height() == 0) {
80 int tileWidth = TilesManager::instance()->layerTileWidth();
81 int tileHeight = TilesManager::instance()->layerTileHeight();
83 m_area.setX(area.x() / tileWidth);
84 m_area.setY(area.y() / tileHeight);
85 m_area.setWidth(area.width() / tileWidth);
86 m_area.setHeight(area.height() / tileHeight);
88 if (m_area.width() * tileWidth < area.width())
89 m_area.setWidth(m_area.width() + 1);
90 if (m_area.height() * tileHeight < area.height())
91 m_area.setHeight(m_area.height() + 1);
93 XLOG("for TiledTexture %x, we have a visible area of %d x %d, corresponding to %d x %d tiles",
94 this, visibleArea.width(), visibleArea.height(),
95 m_area.width(), m_area.height());
97 bool goingDown = m_prevTileY < m_area.y();
98 m_prevTileY = m_area.y();
100 if (m_surface->scale() != m_prevScale)
101 TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(m_surface->scale()));
103 m_prevScale = m_surface->scale();
105 for (int i = 0; i < m_area.width(); i++) {
107 for (int j = 0; j < m_area.height(); j++) {
108 prepareTile(repaint, m_area.x() + i, m_area.y() + j);
111 for (int j = m_area.height() - 1; j >= 0; j--) {
112 prepareTile(repaint, m_area.x() + i, m_area.y() + j);
118 void TiledTexture::prepareTile(bool repaint, int x, int y)
120 BaseTile* tile = getTile(x, y);
122 tile = new BaseTile(true);
123 m_tiles.append(tile);
125 tile->reserveTexture();
126 if (!tile->texture())
129 tile->setContents(this, x, y, m_surface->scale());
130 tile->setUsedLevel(0);
132 bool schedule = false;
135 if (!tile->isTileReady())
137 if (repaint || tile->isDirty())
140 LayerAndroid* layer = m_surface->layer();
141 if (schedule && layer && !tile->isRepaintPending()) {
142 PaintTileOperation *operation = new PaintTileOperation(tile, layer);
143 TilesManager::instance()->scheduleOperation(operation);
147 BaseTile* TiledTexture::getTile(int x, int y)
149 for (unsigned int i = 0; i <m_tiles.size(); i++) {
150 BaseTile* tile = m_tiles[i];
151 if (tile->x() == x && tile->y() == y)
157 bool TiledTexture::draw()
160 TilesManager::instance()->getTilesTracker()->trackLayer();
163 bool askRedraw = false;
164 if (m_area.width() == 0 || m_area.height() == 0)
168 TilesManager::instance()->getTilesTracker()->trackVisibleLayer();
171 float m_invScale = 1 / m_surface->scale();
172 const float tileWidth = TilesManager::layerTileWidth() * m_invScale;
173 const float tileHeight = TilesManager::layerTileHeight() * m_invScale;
174 XLOG("draw tile %x, tiles %d", this, m_tiles.size());
175 for (unsigned int i = 0; i <m_tiles.size(); i++) {
176 BaseTile* tile = m_tiles[i];
177 if (tile->x() >= m_area.x()
178 && tile->x() < m_area.x() + m_area.width()
179 && tile->y() >= m_area.y()
180 && tile->y() < m_area.y() + m_area.height()) {
182 rect.fLeft = tile->x() * tileWidth;
183 rect.fTop = tile->y() * tileHeight;
184 rect.fRight = rect.fLeft + tileWidth;
185 rect.fBottom = rect.fTop + tileHeight;
186 XLOG(" - [%d], { painter %x vs %x }, tile %x %d,%d at scale %.2f [ready: %d]", i, this, tile->painter(), tile, tile->x(), tile->y(), tile->scale(), tile->isTileReady());
187 askRedraw |= !tile->isTileReady();
188 tile->draw(m_surface->opacity(), rect, m_surface->scale());
190 TilesManager::instance()->getTilesTracker()->track(tile->isTileReady(), tile->texture());
197 bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed)
202 XLOG("painting scheduled tile(%x : %d, %d, %.2f, %x) for %x",
203 tile, tile->x(), tile->y(), tile->scale(), tile->painter(), this);
204 return m_surface->paint(tile, canvas, pictureUsed);
207 void TiledTexture::paintExtra(SkCanvas* canvas)
209 m_surface->paintExtra(canvas);
212 const TransformationMatrix* TiledTexture::transform()
214 return m_surface->transform();
217 void TiledTexture::beginPaint()
220 m_surface->beginPaint();
223 void TiledTexture::endPaint()
226 m_surface->endPaint();
229 void TiledTexture::removeTiles()
231 TilesManager::instance()->removeOperationsForPainter(this, true);
232 for (unsigned int i = 0; i < m_tiles.size(); i++) {
237 bool TiledTexture::owns(BaseTileTexture* texture)
239 for (unsigned int i = 0; i < m_tiles.size(); i++) {
240 BaseTile* tile = m_tiles[i];
241 if (tile->texture() == texture)
247 } // namespace WebCore