1 /* 2 * Copyright 2012, 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 "SurfaceCollection" 27 #define LOG_NDEBUG 1 28 29 #include "config.h" 30 #include "SurfaceCollection.h" 31 32 #include "AndroidLog.h" 33 #include "BaseLayerAndroid.h" 34 #include "ClassTracker.h" 35 #include "GLWebViewState.h" 36 #include "PaintTileOperation.h" 37 #include "Surface.h" 38 #include "ScrollableLayerAndroid.h" 39 #include "TilesManager.h" 40 41 namespace WebCore { 42 43 //////////////////////////////////////////////////////////////////////////////// 44 // TILED PAINTING / SURFACES // 45 //////////////////////////////////////////////////////////////////////////////// 46 47 SurfaceCollection::SurfaceCollection(BaseLayerAndroid* layer) 48 : m_compositedRoot(layer) 49 { 50 // layer must be non-null. 51 SkSafeRef(m_compositedRoot); 52 53 // calculate draw transforms and z values 54 SkRect visibleRect = SkRect::MakeLTRB(0, 0, 1, 1); 55 m_compositedRoot->updatePositionsRecursive(visibleRect); 56 57 // allocate surfaces for layers, merging where possible 58 ALOGV("new tree, allocating surfaces for tree %p", m_baseLayer); 59 60 LayerMergeState layerMergeState(&m_surfaces); 61 m_compositedRoot->assignSurfaces(&layerMergeState); 62 63 // set the layersurfaces' update count, to be drawn on painted tiles 64 unsigned int updateCount = TilesManager::instance()->incWebkitContentUpdates(); 65 for (unsigned int i = 0; i < m_surfaces.size(); i++) 66 m_surfaces[i]->setUpdateCount(updateCount); 67 68 #ifdef DEBUG_COUNT 69 ClassTracker::instance()->increment("SurfaceCollection"); 70 #endif 71 } 72 73 SurfaceCollection::~SurfaceCollection() 74 { 75 SkSafeUnref(m_compositedRoot); 76 for (unsigned int i = 0; i < m_surfaces.size(); i++) 77 SkSafeUnref(m_surfaces[i]); 78 m_surfaces.clear(); 79 80 #ifdef DEBUG_COUNT 81 ClassTracker::instance()->decrement("SurfaceCollection"); 82 #endif 83 } 84 85 void SurfaceCollection::prepareGL(const SkRect& visibleContentRect, bool tryToFastBlit) 86 { 87 TRACE_METHOD(); 88 updateLayerPositions(visibleContentRect); 89 bool layerTilesDisabled = m_compositedRoot->state()->isSingleSurfaceRenderingMode(); 90 if (!layerTilesDisabled) { 91 for (unsigned int i = 0; tryToFastBlit && i < m_surfaces.size(); i++) 92 tryToFastBlit &= m_surfaces[i]->canUpdateWithBlit(); 93 } 94 for (unsigned int i = 0; i < m_surfaces.size(); i++) 95 m_surfaces[i]->prepareGL(layerTilesDisabled, tryToFastBlit); 96 } 97 98 static inline bool compareSurfaceZ(const Surface* a, const Surface* b) 99 { 100 const LayerAndroid* la = a->getFirstLayer(); 101 const LayerAndroid* lb = b->getFirstLayer(); 102 103 // swap drawing order if zValue suggests it AND the layers are in the same stacking context 104 return (la->zValue() > lb->zValue()) && (la->getParent() == lb->getParent()); 105 } 106 107 bool SurfaceCollection::drawGL(const SkRect& visibleContentRect) 108 { 109 TRACE_METHOD(); 110 #ifdef DEBUG_COUNT 111 ClassTracker::instance()->show(); 112 #endif 113 114 bool needsRedraw = false; 115 updateLayerPositions(visibleContentRect); 116 bool layerTilesDisabled = m_compositedRoot->state()->isSingleSurfaceRenderingMode(); 117 118 // create a duplicate vector of surfaces, sorted by z value 119 Vector <Surface*> surfaces; 120 for (unsigned int i = 0; i < m_surfaces.size(); i++) 121 surfaces.append(m_surfaces[i]); 122 std::stable_sort(surfaces.begin()+1, surfaces.end(), compareSurfaceZ); 123 124 // draw the sorted vector 125 for (unsigned int i = 0; i < m_surfaces.size(); i++) 126 needsRedraw |= surfaces[i]->drawGL(layerTilesDisabled); 127 128 return needsRedraw; 129 } 130 131 Color SurfaceCollection::getBackgroundColor() 132 { 133 return static_cast<BaseLayerAndroid*>(m_compositedRoot)->getBackgroundColor(); 134 } 135 136 void SurfaceCollection::swapTiles() 137 { 138 bool calculateFrameworkInvals = !m_compositedRoot->state()->inUnclippedDraw(); 139 140 TRACE_METHOD(); 141 for (unsigned int i = 0; i < m_surfaces.size(); i++) 142 m_surfaces[i]->swapTiles(calculateFrameworkInvals); 143 } 144 145 void SurfaceCollection::addFrameworkInvals() 146 { 147 for (unsigned int i = 0; i < m_surfaces.size(); i++) 148 m_surfaces[i]->addFrameworkInvals(); 149 } 150 151 bool SurfaceCollection::isReady() 152 { 153 // Override layer readiness check for single surface mode 154 if (m_compositedRoot->state()->isSingleSurfaceRenderingMode()) 155 return m_surfaces[0]->isReady(); 156 157 for (unsigned int i = 0; i < m_surfaces.size(); i++) { 158 if (!m_surfaces[i]->isReady()) { 159 ALOGV("layer surface %p isn't ready", m_surfaces[i]); 160 return false; 161 } 162 } 163 return true; 164 } 165 166 bool SurfaceCollection::isMissingBackgroundContent() 167 { 168 // return true when the first surface is missing content (indicating the 169 // entire viewport isn't covered) 170 return m_surfaces[0]->isMissingContent(); 171 } 172 173 void SurfaceCollection::removePainterOperations() 174 { 175 for (unsigned int i = 0; i < m_surfaces.size(); i++) 176 TilesManager::instance()->removeOperationsForFilter(new TilePainterFilter(m_surfaces[i])); 177 } 178 179 void SurfaceCollection::computeTexturesAmount(TexturesResult* result) 180 { 181 for (unsigned int i = 0; i < m_surfaces.size(); i++) 182 m_surfaces[i]->computeTexturesAmount(result); 183 } 184 185 //////////////////////////////////////////////////////////////////////////////// 186 // RECURSIVE ANIMATION / INVALS / LAYERS // 187 //////////////////////////////////////////////////////////////////////////////// 188 189 void SurfaceCollection::setIsPainting(SurfaceCollection* drawingSurface) 190 { 191 if (!drawingSurface) 192 return; 193 194 for (unsigned int i = 0; i < m_surfaces.size(); i++) { 195 Surface* newSurface = m_surfaces[i]; 196 if (!newSurface->needsTexture()) 197 continue; 198 199 for (unsigned int j = 0; j < drawingSurface->m_surfaces.size(); j++) { 200 Surface* oldSurface = drawingSurface->m_surfaces[j]; 201 if (newSurface->tryUpdateSurface(oldSurface)) 202 break; 203 } 204 } 205 } 206 207 void SurfaceCollection::setIsDrawing() 208 { 209 m_compositedRoot->initAnimations(); 210 } 211 212 void SurfaceCollection::mergeInvalsInto(SurfaceCollection* replacementSurface) 213 { 214 m_compositedRoot->mergeInvalsInto(replacementSurface->m_compositedRoot); 215 } 216 217 bool SurfaceCollection::evaluateAnimations(double currentTime) 218 { 219 return m_compositedRoot->evaluateAnimations(currentTime); 220 } 221 222 bool SurfaceCollection::hasCompositedLayers() 223 { 224 return m_compositedRoot->countChildren(); 225 } 226 227 bool SurfaceCollection::hasCompositedAnimations() 228 { 229 return m_compositedRoot->hasAnimations(); 230 } 231 232 void SurfaceCollection::updateScrollableLayer(int layerId, int x, int y) 233 { 234 LayerAndroid* layer = m_compositedRoot->findById(layerId); 235 if (layer && layer->contentIsScrollable()) 236 static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y); 237 } 238 239 void SurfaceCollection::updateLayerPositions(const SkRect& visibleContentRect) 240 { 241 m_compositedRoot->updatePositionsRecursive(visibleContentRect); 242 243 #ifdef DEBUG 244 m_compositedRoot->showLayer(0); 245 ALOGV("We have %d layers, %d textured", 246 m_compositedRoot->nbLayers(), 247 m_compositedRoot->nbTexturedLayers()); 248 #endif 249 } 250 251 int SurfaceCollection::backedSize() 252 { 253 int count = 0; 254 for (unsigned int i = 0; i < m_surfaces.size(); i++) { 255 if (m_surfaces[i]->needsTexture()) 256 count++; 257 } 258 return count; 259 } 260 261 } // namespace WebCore 262