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