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 bool SurfaceCollection::drawGL(const SkRect& visibleContentRect) 99 { 100 TRACE_METHOD(); 101 #ifdef DEBUG_COUNT 102 ClassTracker::instance()->show(); 103 #endif 104 105 updateLayerPositions(visibleContentRect); 106 bool layerTilesDisabled = m_compositedRoot->state()->isSingleSurfaceRenderingMode(); 107 108 return m_compositedRoot->drawTreeSurfacesGL(); 109 } 110 111 Color SurfaceCollection::getBackgroundColor() 112 { 113 return static_cast<BaseLayerAndroid*>(m_compositedRoot)->getBackgroundColor(); 114 } 115 116 void SurfaceCollection::swapTiles() 117 { 118 bool calculateFrameworkInvals = !m_compositedRoot->state()->inUnclippedDraw(); 119 120 TRACE_METHOD(); 121 for (unsigned int i = 0; i < m_surfaces.size(); i++) 122 m_surfaces[i]->swapTiles(calculateFrameworkInvals); 123 } 124 125 void SurfaceCollection::addFrameworkInvals() 126 { 127 for (unsigned int i = 0; i < m_surfaces.size(); i++) 128 m_surfaces[i]->addFrameworkInvals(); 129 } 130 131 bool SurfaceCollection::isReady() 132 { 133 // Override layer readiness check for single surface mode 134 if (m_compositedRoot->state()->isSingleSurfaceRenderingMode()) 135 return m_surfaces[0]->isReady(); 136 137 for (unsigned int i = 0; i < m_surfaces.size(); i++) { 138 if (!m_surfaces[i]->isReady()) { 139 ALOGV("layer surface %p isn't ready", m_surfaces[i]); 140 return false; 141 } 142 } 143 return true; 144 } 145 146 bool SurfaceCollection::isMissingBackgroundContent() 147 { 148 // return true when the first surface is missing content (indicating the 149 // entire viewport isn't covered) 150 return m_surfaces[0]->isMissingContent(); 151 } 152 153 void SurfaceCollection::removePainterOperations() 154 { 155 for (unsigned int i = 0; i < m_surfaces.size(); i++) 156 TilesManager::instance()->removeOperationsForFilter(new TilePainterFilter(m_surfaces[i])); 157 } 158 159 void SurfaceCollection::computeTexturesAmount(TexturesResult* result) 160 { 161 for (unsigned int i = 0; i < m_surfaces.size(); i++) 162 m_surfaces[i]->computeTexturesAmount(result); 163 } 164 165 //////////////////////////////////////////////////////////////////////////////// 166 // RECURSIVE ANIMATION / INVALS / LAYERS // 167 //////////////////////////////////////////////////////////////////////////////// 168 169 void SurfaceCollection::setIsPainting(SurfaceCollection* drawingSurface) 170 { 171 if (!drawingSurface) 172 return; 173 174 for (unsigned int i = 0; i < m_surfaces.size(); i++) { 175 Surface* newSurface = m_surfaces[i]; 176 if (!newSurface->needsTexture()) 177 continue; 178 179 for (unsigned int j = 0; j < drawingSurface->m_surfaces.size(); j++) { 180 Surface* oldSurface = drawingSurface->m_surfaces[j]; 181 if (newSurface->tryUpdateSurface(oldSurface)) 182 break; 183 } 184 } 185 } 186 187 void SurfaceCollection::setIsDrawing() 188 { 189 m_compositedRoot->initAnimations(); 190 } 191 192 void SurfaceCollection::mergeInvalsInto(SurfaceCollection* replacementSurface) 193 { 194 m_compositedRoot->mergeInvalsInto(replacementSurface->m_compositedRoot); 195 } 196 197 bool SurfaceCollection::evaluateAnimations(double currentTime) 198 { 199 return m_compositedRoot->evaluateAnimations(currentTime); 200 } 201 202 bool SurfaceCollection::hasCompositedLayers() 203 { 204 return m_compositedRoot->countChildren(); 205 } 206 207 bool SurfaceCollection::hasCompositedAnimations() 208 { 209 return m_compositedRoot->hasAnimations(); 210 } 211 212 void SurfaceCollection::updateScrollableLayer(int layerId, int x, int y) 213 { 214 LayerAndroid* layer = m_compositedRoot->findById(layerId); 215 if (layer && layer->contentIsScrollable()) 216 static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y); 217 } 218 219 void SurfaceCollection::updateLayerPositions(const SkRect& visibleContentRect) 220 { 221 m_compositedRoot->updatePositionsRecursive(visibleContentRect); 222 223 #ifdef DEBUG 224 m_compositedRoot->showLayer(0); 225 ALOGV("We have %d layers, %d textured", 226 m_compositedRoot->nbLayers(), 227 m_compositedRoot->nbTexturedLayers()); 228 #endif 229 } 230 231 int SurfaceCollection::backedSize() 232 { 233 int count = 0; 234 for (unsigned int i = 0; i < m_surfaces.size(); i++) { 235 if (m_surfaces[i]->needsTexture()) 236 count++; 237 } 238 return count; 239 } 240 241 } // namespace WebCore 242