• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SurfaceCollection(BaseLayerAndroid * layer)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 
~SurfaceCollection()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 
prepareGL(const SkRect & visibleContentRect,bool tryToFastBlit)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 
compareSurfaceZ(const Surface * a,const Surface * b)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 
drawGL(const SkRect & visibleContentRect)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 
getBackgroundColor()131 Color SurfaceCollection::getBackgroundColor()
132 {
133     return static_cast<BaseLayerAndroid*>(m_compositedRoot)->getBackgroundColor();
134 }
135 
swapTiles()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 
addFrameworkInvals()145 void SurfaceCollection::addFrameworkInvals()
146 {
147     for (unsigned int i = 0; i < m_surfaces.size(); i++)
148          m_surfaces[i]->addFrameworkInvals();
149 }
150 
isReady()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 
isMissingBackgroundContent()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 
removePainterOperations()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 
computeTexturesAmount(TexturesResult * result)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 
setIsPainting(SurfaceCollection * drawingSurface)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 
setIsDrawing()207 void SurfaceCollection::setIsDrawing()
208 {
209     m_compositedRoot->initAnimations();
210 }
211 
mergeInvalsInto(SurfaceCollection * replacementSurface)212 void SurfaceCollection::mergeInvalsInto(SurfaceCollection* replacementSurface)
213 {
214     m_compositedRoot->mergeInvalsInto(replacementSurface->m_compositedRoot);
215 }
216 
evaluateAnimations(double currentTime)217 bool SurfaceCollection::evaluateAnimations(double currentTime)
218 {
219     return m_compositedRoot->evaluateAnimations(currentTime);
220 }
221 
hasCompositedLayers()222 bool SurfaceCollection::hasCompositedLayers()
223 {
224     return m_compositedRoot->countChildren();
225 }
226 
hasCompositedAnimations()227 bool SurfaceCollection::hasCompositedAnimations()
228 {
229     return m_compositedRoot->hasAnimations();
230 }
231 
updateScrollableLayer(int layerId,int x,int y)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 
updateLayerPositions(const SkRect & visibleContentRect)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 
backedSize()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