void GLWebViewState::setVisibleContentRect(const SkRect& visibleContentRect, float scale) { // allocate max possible number of tiles visible with this visibleContentRect / expandedTileBounds const float invTileContentWidth = scale / TilesManager::tileWidth(); const float invTileContentHeight = scale / TilesManager::tileHeight(); int viewMaxTileX = static_cast<int>(ceilf((visibleContentRect.width()-1) * invTileContentWidth)) + 1; int viewMaxTileY = static_cast<int>(ceilf((visibleContentRect.height()-1) * invTileContentHeight)) + 1; TilesManager* tilesManager = TilesManager::instance(); int maxTextureCount = viewMaxTileX * viewMaxTileY * (tilesManager->highEndGfx() ? 4 : 2); tilesManager->setCurrentTextureCount(maxTextureCount); // TODO: investigate whether we can move this return earlier. if ((m_visibleContentRect == visibleContentRect) && (m_scale == scale)) { // everything below will stay the same, early return. m_isVisibleContentRectScrolling = false; return; } m_scale = scale; m_goingDown = m_visibleContentRect.fTop - visibleContentRect.fTop <= 0; m_goingLeft = m_visibleContentRect.fLeft - visibleContentRect.fLeft >= 0; // detect visibleContentRect scrolling from short programmatic scrolls/jumps m_isVisibleContentRectScrolling = m_visibleContentRect != visibleContentRect && SkRect::Intersects(m_visibleContentRect, visibleContentRect); m_visibleContentRect = visibleContentRect; ALOGV("New visibleContentRect %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f )", m_visibleContentRect.fLeft, m_visibleContentRect.fTop, m_visibleContentRect.fRight, m_visibleContentRect.fBottom, m_visibleContentRect.width(), m_visibleContentRect.height(), scale); }
void TileGrid::prepareGL(GLWebViewState* state, float scale, const IntRect& prepareArea, const IntRect& fullContentArea, TilePainter* painter, int regionFlags, bool isLowResPrefetch, bool updateWithBlit) { // first, how many tiles do we need m_area = computeTilesArea(prepareArea, scale); if (m_area.isEmpty()) return; ALOGV("prepare TileGrid %p with scale %.2f, prepareArea " " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles", this, scale, prepareArea.x(), prepareArea.y(), prepareArea.width(), prepareArea.height(), m_area.x(), m_area.y(), m_area.width(), m_area.height()); bool goingDown = m_prevTileY < m_area.y(); m_prevTileY = m_area.y(); TilesManager* tilesManager = TilesManager::instance(); if (scale != m_scale) tilesManager->removeOperationsForFilter(new ScaleFilter(painter, m_scale)); m_scale = scale; // apply dirty region to affected tiles if (!m_dirtyRegion.isEmpty()) { for (unsigned int i = 0; i < m_tiles.size(); i++) m_tiles[i]->markAsDirty(m_dirtyRegion); // log inval region for the base surface if (m_isBaseSurface && tilesManager->getProfiler()->enabled()) { SkRegion::Iterator iterator(m_dirtyRegion); while (!iterator.done()) { SkIRect r = iterator.rect(); tilesManager->getProfiler()->nextInval(r, scale); iterator.next(); } } m_dirtyRegion.setEmpty(); } if (regionFlags & StandardRegion) { for (int i = 0; i < m_area.width(); i++) { if (goingDown) { for (int j = 0; j < m_area.height(); j++) prepareTile(m_area.x() + i, m_area.y() + j, painter, state, isLowResPrefetch, false, updateWithBlit); } else { for (int j = m_area.height() - 1; j >= 0; j--) prepareTile(m_area.x() + i, m_area.y() + j, painter, state, isLowResPrefetch, false, updateWithBlit); } } } if (regionFlags & ExpandedRegion) { IntRect fullArea = computeTilesArea(fullContentArea, scale); IntRect expandedArea = m_area; // on systems reporting highEndGfx=true and useMinimalMemory not set, use expanded bounds if (tilesManager->highEndGfx() && !tilesManager->useMinimalMemory()) expandedArea.inflate(EXPANDED_BOUNDS_INFLATE); if (isLowResPrefetch) expandedArea.inflateY(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE); // clip painting area to content expandedArea.intersect(fullArea); for (int i = expandedArea.x(); i < expandedArea.maxX(); i++) for (int j = expandedArea.y(); j < expandedArea.maxY(); j++) if (!m_area.contains(i, j)) prepareTile(i, j, painter, state, isLowResPrefetch, true, updateWithBlit); } }