OSDN Git Service

Merge "Support registering page swap callback, content inval"
[android-x86/external-webkit.git] / Source / WebCore / platform / graphics / android / TiledTexture.cpp
1 /*
2  * Copyright 2011, The Android Open Source Project
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
24  */
25
26 #include "config.h"
27 #include "TiledTexture.h"
28
29 #include "TilesManager.h"
30 #include "TilesTracker.h"
31
32 #include "PaintedSurface.h"
33 #include "PaintTileOperation.h"
34 #include "SkCanvas.h"
35
36 #ifdef DEBUG
37
38 #include <cutils/log.h>
39 #include <wtf/CurrentTime.h>
40 #include <wtf/text/CString.h>
41
42 #undef XLOG
43 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TiledTexture", __VA_ARGS__)
44
45 #else
46
47 #undef XLOG
48 #define XLOG(...)
49
50 #endif // DEBUG
51
52 namespace WebCore {
53
54 void TiledTexture::prepare(GLWebViewState* state, bool repaint)
55 {
56     if (!m_surface)
57         return;
58
59     // first, how many tiles do we need
60     IntRect visibleArea = m_surface->visibleArea();
61     IntRect area(visibleArea.x() * m_surface->scale(),
62                  visibleArea.y() * m_surface->scale(),
63                  visibleArea.width() * m_surface->scale(),
64                  visibleArea.height() * m_surface->scale());
65
66     for (unsigned int i = 0; i < m_tiles.size(); i++) {
67         BaseTile* tile = m_tiles[i];
68         tile->setUsedLevel(-1);
69     }
70
71     if (area.width() == 0 && area.height() == 0) {
72         m_area.setWidth(0);
73         m_area.setHeight(0);
74         return;
75     }
76
77     int tileWidth = TilesManager::instance()->layerTileWidth();
78     int tileHeight = TilesManager::instance()->layerTileHeight();
79
80     m_area.setX(area.x() / tileWidth);
81     m_area.setY(area.y() / tileHeight);
82     m_area.setWidth(area.width() / tileWidth);
83     m_area.setHeight(area.height() / tileHeight);
84
85     if (m_area.width() * tileWidth < area.width())
86         m_area.setWidth(m_area.width() + 1);
87     if (m_area.height() * tileHeight < area.height())
88         m_area.setHeight(m_area.height() + 1);
89
90     XLOG("for TiledTexture %x, we have a visible area of %d x %d, corresponding to %d x %d tiles",
91          this, visibleArea.width(), visibleArea.height(),
92          m_area.width(), m_area.height());
93
94     bool goingDown = m_prevTileY < m_area.y();
95     m_prevTileY = m_area.y();
96
97     if (m_surface->scale() != m_prevScale)
98         TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(m_surface->scale()));
99
100     m_prevScale = m_surface->scale();
101
102     for (int i = 0; i < m_area.width(); i++) {
103         if (goingDown) {
104             for (int j = 0; j < m_area.height(); j++) {
105                 prepareTile(repaint, m_area.x() + i, m_area.y() + j);
106             }
107         } else {
108             for (int j = m_area.height() - 1; j >= 0; j--) {
109                 prepareTile(repaint, m_area.x() + i, m_area.y() + j);
110             }
111         }
112     }
113 }
114
115 void TiledTexture::prepareTile(bool repaint, int x, int y)
116 {
117     BaseTile* tile = getTile(x, y);
118     if (!tile) {
119         tile = new BaseTile(true);
120         m_tiles.append(tile);
121     }
122     tile->reserveTexture();
123     if (!tile->texture())
124         return;
125
126     tile->setContents(this, x, y, m_surface->scale());
127     tile->setUsedLevel(0);
128
129     bool schedule = false;
130     if (repaint)
131         tile->fullInval();
132     if (!tile->isTileReady())
133         schedule = true;
134     if (repaint || tile->isDirty())
135         schedule = true;
136
137     if (schedule && !tile->isRepaintPending()) {
138         PaintTileOperation *operation = new PaintTileOperation(tile);
139         TilesManager::instance()->scheduleOperation(operation);
140     }
141 }
142
143 BaseTile* TiledTexture::getTile(int x, int y)
144 {
145     for (unsigned int i = 0; i <m_tiles.size(); i++) {
146         BaseTile* tile = m_tiles[i];
147         if (tile->x() == x && tile->y() == y)
148             return tile;
149     }
150     return 0;
151 }
152
153 bool TiledTexture::draw()
154 {
155 #ifdef DEBUG
156     TilesManager::instance()->getTilesTracker()->trackLayer();
157 #endif
158
159     bool askRedraw = false;
160     if (m_area.width() == 0 || m_area.height() == 0)
161         return askRedraw;
162
163 #ifdef DEBUG
164     TilesManager::instance()->getTilesTracker()->trackVisibleLayer();
165 #endif
166
167     float m_invScale = 1 / m_surface->scale();
168     const float tileWidth = TilesManager::layerTileWidth() * m_invScale;
169     const float tileHeight = TilesManager::layerTileHeight() * m_invScale;
170     XLOG("draw tile %x, tiles %d", this, m_tiles.size());
171     for (unsigned int i = 0; i <m_tiles.size(); i++) {
172         BaseTile* tile = m_tiles[i];
173         if (tile->x() >= m_area.x()
174             && tile->x() < m_area.x() + m_area.width()
175             && tile->y() >= m_area.y()
176             && tile->y() < m_area.y() + m_area.height()) {
177             SkRect rect;
178             rect.fLeft = tile->x() * tileWidth;
179             rect.fTop = tile->y() * tileHeight;
180             rect.fRight = rect.fLeft + tileWidth;
181             rect.fBottom = rect.fTop + tileHeight;
182             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());
183             askRedraw |= !tile->isTileReady();
184             tile->draw(m_surface->opacity(), rect, m_surface->scale());
185 #ifdef DEBUG
186             TilesManager::instance()->getTilesTracker()->track(tile->isTileReady(), tile->texture());
187 #endif
188         }
189     }
190     return askRedraw;
191 }
192
193 bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed)
194 {
195     if (!m_surface)
196         return false;
197
198     XLOG("painting scheduled tile(%x : %d, %d, %.2f, %x) for %x",
199          tile, tile->x(), tile->y(), tile->scale(), tile->painter(), this);
200     return m_surface->paint(tile, canvas, pictureUsed);
201 }
202
203 void TiledTexture::paintExtra(SkCanvas* canvas)
204 {
205     m_surface->paintExtra(canvas);
206 }
207
208 const TransformationMatrix* TiledTexture::transform()
209 {
210     return m_surface->transform();
211 }
212
213 void TiledTexture::removeTiles()
214 {
215     TilesManager::instance()->removeOperationsForPainter(this, true);
216     for (unsigned int i = 0; i < m_tiles.size(); i++) {
217         delete m_tiles[i];
218     }
219 }
220
221 bool TiledTexture::owns(BaseTileTexture* texture)
222 {
223     for (unsigned int i = 0; i < m_tiles.size(); i++) {
224         BaseTile* tile = m_tiles[i];
225         if (tile->texture() == texture)
226             return true;
227     }
228     return false;
229 }
230
231 } // namespace WebCore