SurfaceBacking.cpp revision e080317b90534632e8be18dc8d5e9a51554b444a
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#define LOG_TAG "SurfaceBacking" 27#define LOG_NDEBUG 1 28 29#include "config.h" 30#include "SurfaceBacking.h" 31 32#include "AndroidLog.h" 33#include "Color.h" 34#include "GLWebViewState.h" 35#include "LayerAndroid.h" 36 37#define LOW_RES_PREFETCH_SCALE_MODIFIER 0.3f 38 39namespace WebCore { 40 41SurfaceBacking::SurfaceBacking(bool isBaseSurface) 42{ 43 m_frontTileGrid = new TileGrid(isBaseSurface); 44 m_backTileGrid = new TileGrid(isBaseSurface); 45 m_lowResTileGrid = new TileGrid(isBaseSurface); 46 m_scale = -1; 47 m_futureScale = -1; 48 m_zooming = false; 49} 50 51SurfaceBacking::~SurfaceBacking() 52{ 53 delete m_frontTileGrid; 54 delete m_backTileGrid; 55 delete m_lowResTileGrid; 56} 57 58void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom, 59 const IntRect& prepareArea, const IntRect& unclippedArea, 60 TilePainter* painter, bool aggressiveRendering) 61{ 62 float scale = state->scale(); 63 if (scale > 1 && !allowZoom) 64 scale = 1; 65 66 if (m_scale == -1) { 67 m_scale = scale; 68 m_futureScale = scale; 69 } 70 71 if (m_futureScale != scale) { 72 m_futureScale = scale; 73 m_zoomUpdateTime = WTF::currentTime() + SurfaceBacking::s_zoomUpdateDelay; 74 m_zooming = true; 75 76 // release back TileGrid's TileTextures, so they can be reused immediately 77 m_backTileGrid->discardTextures(); 78 } 79 80 int prepareRegionFlags = TileGrid::StandardRegion; 81 if (aggressiveRendering) 82 prepareRegionFlags |= TileGrid::ExpandedRegion; 83 84 ALOGV("Prepare SurfBack %p, scale %.2f, m_scale %.2f, futScale: %.2f, zooming: %d, f %p, b %p", 85 this, scale, m_scale, m_futureScale, m_zooming, 86 m_frontTileGrid, m_backTileGrid); 87 88 if (m_zooming && (m_zoomUpdateTime < WTF::currentTime())) { 89 // prepare the visible portions of the back tile grid at the futureScale 90 m_backTileGrid->prepareGL(state, m_futureScale, 91 prepareArea, unclippedArea, painter, 92 TileGrid::StandardRegion, false); 93 94 if (m_backTileGrid->isReady()) { 95 // zooming completed, swap the TileGrids and new front tiles 96 swapTileGrids(); 97 98 m_frontTileGrid->swapTiles(); 99 m_backTileGrid->discardTextures(); 100 m_lowResTileGrid->discardTextures(); 101 102 m_scale = m_futureScale; 103 m_zooming = false; 104 105 // clear the StandardRegion flag, to prevent preparing it twice - 106 // the new frontTileGrid has already had its StandardRegion prepared 107 prepareRegionFlags &= ~TileGrid::StandardRegion; 108 } 109 } 110 111 if (!m_zooming) { 112 if (prepareRegionFlags) { 113 // if the front grid hasn't already prepared, or needs to prepare 114 // expanded bounds do so now 115 m_frontTileGrid->prepareGL(state, m_scale, 116 prepareArea, unclippedArea, painter, prepareRegionFlags, false); 117 } 118 if (aggressiveRendering) { 119 // prepare low res content 120 float lowResPrefetchScale = m_scale * LOW_RES_PREFETCH_SCALE_MODIFIER; 121 m_lowResTileGrid->prepareGL(state, lowResPrefetchScale, 122 prepareArea, unclippedArea, painter, 123 TileGrid::StandardRegion | TileGrid::ExpandedRegion, true); 124 m_lowResTileGrid->swapTiles(); 125 } 126 } 127} 128 129void SurfaceBacking::drawGL(const IntRect& visibleArea, float opacity, 130 const TransformationMatrix* transform, 131 bool aggressiveRendering, const Color* background) 132{ 133 // draw low res prefetch page if zooming or front texture missing content 134 if (aggressiveRendering && isMissingContent()) 135 m_lowResTileGrid->drawGL(visibleArea, opacity, transform); 136 137 m_frontTileGrid->drawGL(visibleArea, opacity, transform, background); 138} 139 140void SurfaceBacking::markAsDirty(const SkRegion& dirtyArea) 141{ 142 m_backTileGrid->markAsDirty(dirtyArea); 143 m_frontTileGrid->markAsDirty(dirtyArea); 144 m_lowResTileGrid->markAsDirty(dirtyArea); 145} 146 147void SurfaceBacking::swapTiles() 148{ 149 m_backTileGrid->swapTiles(); 150 m_frontTileGrid->swapTiles(); 151 m_lowResTileGrid->swapTiles(); 152} 153 154void SurfaceBacking::computeTexturesAmount(TexturesResult* result, LayerAndroid* layer) 155{ 156 // TODO: shouldn't use layer, as this SB may paint multiple layers 157 if (!layer) 158 return; 159 160 IntRect unclippedArea = layer->unclippedArea(); 161 IntRect clippedVisibleArea = layer->visibleArea(); 162 163 // get two numbers here: 164 // - textures needed for a clipped area 165 // - textures needed for an un-clipped area 166 TileGrid* tileGrid = m_zooming ? m_backTileGrid : m_frontTileGrid; 167 int nbTexturesUnclipped = tileGrid->nbTextures(unclippedArea, m_scale); 168 int nbTexturesClipped = tileGrid->nbTextures(clippedVisibleArea, m_scale); 169 170 // Set kFixedLayers level 171 if (layer->isPositionFixed()) 172 result->fixed += nbTexturesClipped; 173 174 // Set kScrollableAndFixedLayers level 175 if (layer->contentIsScrollable() 176 || layer->isPositionFixed()) 177 result->scrollable += nbTexturesClipped; 178 179 // Set kClippedTextures level 180 result->clipped += nbTexturesClipped; 181 182 // Set kAllTextures level 183 if (layer->contentIsScrollable()) 184 result->full += nbTexturesClipped; 185 else 186 result->full += nbTexturesUnclipped; 187} 188 189void SurfaceBacking::swapTileGrids() 190{ 191 TileGrid* temp = m_frontTileGrid; 192 m_frontTileGrid = m_backTileGrid; 193 m_backTileGrid = temp; 194} 195 196} // namespace WebCore 197