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