, m_latestPictureInval(0)
, m_prepare(false)
, m_isPrefetchPage(false)
+ , m_willDraw(false)
{
m_baseTiles = new BaseTile[TilesManager::getMaxTextureAllocation() + 1];
#ifdef DEBUG_COUNT
void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds)
{
- if (y < 0)
- return;
-
for (int i = 0; i < tilesInRow; i++) {
int x = firstTileX;
else
x += i;
- if (x < 0)
- continue;
-
BaseTile* currentTile = 0;
BaseTile* availableTile = 0;
for (int j = 0; j < m_baseTileSize; j++) {
int nbTilesWidth = tileBounds.width();
int nbTilesHeight = tileBounds.height();
- int lastTileX = tileBounds.fRight - 1;
- int lastTileY = tileBounds.fBottom - 1;
-
// Expand number of tiles to allow tiles outside of viewport to be prepared for
// smoother scrolling.
int nTilesToPrepare = nbTilesWidth * nbTilesHeight;
int expandY = m_glWebViewState->expandedTileBoundsY();
firstTileX -= expandX;
- lastTileX += expandX;
nbTilesWidth += expandX * 2;
firstTileY -= expandY;
- lastTileY += expandY;
nbTilesHeight += expandY * 2;
}
- m_expandedTileBounds.fLeft = firstTileX;
- m_expandedTileBounds.fTop = firstTileY;
- m_expandedTileBounds.fRight = lastTileX;
- m_expandedTileBounds.fBottom = lastTileY;
+ // crop the prepared region to the contents of the base layer
+ float maxWidthTiles = m_glWebViewState->baseContentWidth() * m_scale / TilesManager::tileWidth();
+ float maxHeightTiles = m_glWebViewState->baseContentHeight() * m_scale / TilesManager::tileHeight();
+
+ // adjust perimeter to not go outside base content bounds
+ if (firstTileX < 0) {
+ nbTilesWidth += firstTileX;
+ firstTileX = 0;
+ }
+ if (firstTileY < 0) {
+ nbTilesHeight += firstTileY;
+ firstTileY = 0;
+ }
+ nbTilesWidth = std::min(nbTilesWidth, static_cast<int>(ceilf(maxWidthTiles)) - firstTileX);
+ nbTilesHeight = std::min(nbTilesHeight, static_cast<int>(ceilf(maxHeightTiles)) - firstTileY);
// check against corrupted scale values giving bad height/width (use float to avoid overflow)
float numTiles = static_cast<float>(nbTilesHeight) * static_cast<float>(nbTilesWidth);
m_prepare = true;
}
-bool TiledPage::swapBuffersIfReady(const SkIRect& tileBounds, float scale, SwapMethod swap)
+bool TiledPage::hasMissingContent(const SkIRect& tileBounds)
+{
+ int neededTiles = tileBounds.width() * tileBounds.height();
+ for (int j = 0; j < m_baseTileSize; j++) {
+ BaseTile& tile = m_baseTiles[j];
+ if (tileBounds.contains(tile.x(), tile.y())) {
+ if (tile.frontTexture())
+ neededTiles--;
+ }
+ }
+ return neededTiles > 0;
+}
+
+bool TiledPage::isReady(const SkIRect& tileBounds)
+{
+ int neededTiles = tileBounds.width() * tileBounds.height();
+ XLOG("tiled page %p needs %d ready tiles", this, neededTiles);
+ for (int j = 0; j < m_baseTileSize; j++) {
+ BaseTile& tile = m_baseTiles[j];
+ if (tileBounds.contains(tile.x(), tile.y())) {
+ if (tile.isTileReady())
+ neededTiles--;
+ }
+ }
+ XLOG("tiled page %p still needs %d ready tiles", this, neededTiles);
+ return neededTiles == 0;
+}
+
+bool TiledPage::swapBuffersIfReady(const SkIRect& tileBounds, float scale)
{
if (!m_glWebViewState)
return false;
int swaps = 0;
bool fullSwap = true;
- if (swap == SwapWholePage) {
- for (int x = tileBounds.fLeft; x < tileBounds.fRight; x++) {
- for (int y = tileBounds.fTop; y < tileBounds.fBottom; y++) {
- BaseTile* t = getBaseTile(x, y);
- if (!t || !t->isTileReady())
- return false;
- }
- }
- } else { // SwapWhateveryIsReady
- for (int x = tileBounds.fLeft; x < tileBounds.fRight; x++) {
- for (int y = tileBounds.fTop; y < tileBounds.fBottom; y++) {
- BaseTile* t = getBaseTile(x, y);
- if (!t || !t->isTileReady())
- fullSwap = false;
- }
+ for (int x = tileBounds.fLeft; x < tileBounds.fRight; x++) {
+ for (int y = tileBounds.fTop; y < tileBounds.fBottom; y++) {
+ BaseTile* t = getBaseTile(x, y);
+ if (!t || !t->isTileReady())
+ fullSwap = false;
}
}
swaps++;
}
- XLOG("%p %s swapped %d textures, returning true",
- this, (swap == SwapWholePage) ? "whole page" : "greedy swap", swaps);
+ XLOG("%p greedy swapped %d textures, returning true", this, swaps);
return fullSwap;
}
+void TiledPage::prepareForDrawGL(float transparency, const SkIRect& tileBounds)
+{
+ m_willDraw = true;
+ m_transparency = transparency;
+ m_tileBounds = tileBounds;
+}
-void TiledPage::draw(float transparency, const SkIRect& tileBounds)
+void TiledPage::drawGL()
{
- if (!m_glWebViewState)
+ if (!m_glWebViewState || m_transparency == 0 || !m_willDraw)
return;
const float tileWidth = TilesManager::tileWidth() * m_invScale;
const float tileHeight = TilesManager::tileHeight() * m_invScale;
- SkIRect actualTileBounds = tileBounds;
- actualTileBounds.fTop -= m_glWebViewState->expandedTileBoundsY();
- actualTileBounds.fBottom += m_glWebViewState->expandedTileBoundsY();
- actualTileBounds.fLeft -= m_glWebViewState->expandedTileBoundsX();
- actualTileBounds.fRight += m_glWebViewState->expandedTileBoundsX();
-
- actualTileBounds.fTop = std::max(0, actualTileBounds.fTop);
- actualTileBounds.fLeft = std::max(0, actualTileBounds.fLeft);
-
for (int j = 0; j < m_baseTileSize; j++) {
BaseTile& tile = m_baseTiles[j];
- bool tileInView = actualTileBounds.contains(tile.x(), tile.y());
+ bool tileInView = m_tileBounds.contains(tile.x(), tile.y());
if (tileInView) {
SkRect rect;
rect.fLeft = tile.x() * tileWidth;
rect.fRight = rect.fLeft + tileWidth;
rect.fBottom = rect.fTop + tileHeight;
- tile.draw(transparency, rect, m_scale);
+ tile.draw(m_transparency, rect, m_scale);
}
TilesManager::instance()->getProfiler()->nextTile(tile, m_invScale, tileInView);
}
+ m_willDraw = false; // don't redraw until re-prepared
}
bool TiledPage::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed)
{
- // TODO: consider other flags so the pre-rendered tiles aren't so ugly
- static SkPaintFlagsDrawFilter prefetchFilter(SkPaint::kAllFlags, 0);
+ static SkPaintFlagsDrawFilter prefetchFilter(SkPaint::kAllFlags,
+ SkPaint::kAntiAlias_Flag);
if (!m_glWebViewState)
return false;
return true;
}
-void TiledPage::paintExtra(SkCanvas* canvas)
-{
-}
-
TiledPage* TiledPage::sibling()
{
if (!m_glWebViewState)