Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: cc/CCOcclusionTracker.cpp

Issue 11122003: [cc] Rename all cc/ filenames to Chromium style (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/CCOcclusionTracker.h ('k') | cc/CCOverdrawMetrics.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6
7 #if USE(ACCELERATED_COMPOSITING)
8
9 #include "CCOcclusionTracker.h"
10
11 #include "CCLayerImpl.h"
12 #include "CCMathUtil.h"
13 #include "CCOverdrawMetrics.h"
14 #include "LayerChromium.h"
15 #include <algorithm>
16
17 using namespace std;
18 using WebKit::WebTransformationMatrix;
19
20 namespace cc {
21
22 template<typename LayerType, typename RenderSurfaceType>
23 CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::CCOcclusionTrackerBase(Int Rect rootTargetRect, bool recordMetricsForFrame)
24 : m_rootTargetRect(rootTargetRect)
25 , m_overdrawMetrics(CCOverdrawMetrics::create(recordMetricsForFrame))
26 , m_occludingScreenSpaceRects(0)
27 {
28 }
29
30 template<typename LayerType, typename RenderSurfaceType>
31 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::enterLayer(const CCLa yerIteratorPosition<LayerType>& layerIterator)
32 {
33 LayerType* renderTarget = layerIterator.targetRenderSurfaceLayer;
34
35 if (layerIterator.representsItself)
36 enterRenderTarget(renderTarget);
37 else if (layerIterator.representsTargetRenderSurface)
38 finishedRenderTarget(renderTarget);
39 }
40
41 template<typename LayerType, typename RenderSurfaceType>
42 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveLayer(const CCLa yerIteratorPosition<LayerType>& layerIterator)
43 {
44 LayerType* renderTarget = layerIterator.targetRenderSurfaceLayer;
45
46 if (layerIterator.representsItself)
47 markOccludedBehindLayer(layerIterator.currentLayer);
48 else if (layerIterator.representsContributingRenderSurface)
49 leaveToRenderTarget(renderTarget);
50 }
51
52 template<typename LayerType, typename RenderSurfaceType>
53 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::enterRenderTarget(con st LayerType* newTarget)
54 {
55 if (!m_stack.isEmpty() && m_stack.last().target == newTarget)
56 return;
57
58 const LayerType* oldTarget = m_stack.isEmpty() ? 0 : m_stack.last().target;
59 const RenderSurfaceType* oldAncestorThatMovesPixels = !oldTarget ? 0 : oldTa rget->renderSurface()->nearestAncestorThatMovesPixels();
60 const RenderSurfaceType* newAncestorThatMovesPixels = newTarget->renderSurfa ce()->nearestAncestorThatMovesPixels();
61
62 m_stack.append(StackObject(newTarget));
63
64 // We copy the screen occlusion into the new RenderSurface subtree, but we n ever copy in the
65 // target occlusion, since we are looking at a new RenderSurface target.
66
67 // If we are entering a subtree that is going to move pixels around, then th e occlusion we've computed
68 // so far won't apply to the pixels we're drawing here in the same way. We d iscard the occlusion thus
69 // far to be safe, and ensure we don't cull any pixels that are moved such t hat they become visible.
70 bool enteringSubtreeThatMovesPixels = newAncestorThatMovesPixels && newAnces torThatMovesPixels != oldAncestorThatMovesPixels;
71
72 bool copyScreenOcclusionForward = m_stack.size() > 1 && !enteringSubtreeThat MovesPixels;
73 if (copyScreenOcclusionForward) {
74 int lastIndex = m_stack.size() - 1;
75 m_stack[lastIndex].occlusionInScreen = m_stack[lastIndex - 1].occlusionI nScreen;
76 }
77 }
78
79 static inline bool layerOpacityKnown(const LayerChromium* layer) { return !layer ->drawOpacityIsAnimating(); }
80 static inline bool layerOpacityKnown(const CCLayerImpl*) { return true; }
81 static inline bool layerTransformsToTargetKnown(const LayerChromium* layer) { re turn !layer->drawTransformIsAnimating(); }
82 static inline bool layerTransformsToTargetKnown(const CCLayerImpl*) { return tru e; }
83 static inline bool layerTransformsToScreenKnown(const LayerChromium* layer) { re turn !layer->screenSpaceTransformIsAnimating(); }
84 static inline bool layerTransformsToScreenKnown(const CCLayerImpl*) { return tru e; }
85
86 static inline bool surfaceOpacityKnown(const RenderSurfaceChromium* surface) { r eturn !surface->drawOpacityIsAnimating(); }
87 static inline bool surfaceOpacityKnown(const CCRenderSurface*) { return true; }
88 static inline bool surfaceTransformsToTargetKnown(const RenderSurfaceChromium* s urface) { return !surface->targetSurfaceTransformsAreAnimating(); }
89 static inline bool surfaceTransformsToTargetKnown(const CCRenderSurface*) { retu rn true; }
90 static inline bool surfaceTransformsToScreenKnown(const RenderSurfaceChromium* s urface) { return !surface->screenSpaceTransformsAreAnimating(); }
91 static inline bool surfaceTransformsToScreenKnown(const CCRenderSurface*) { retu rn true; }
92
93 static inline bool layerIsInUnsorted3dRenderingContext(const LayerChromium* laye r) { return layer->parent() && layer->parent()->preserves3D(); }
94 static inline bool layerIsInUnsorted3dRenderingContext(const CCLayerImpl*) { ret urn false; }
95
96 template<typename LayerType, typename RenderSurfaceType>
97 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::finishedRenderTarget( const LayerType* finishedTarget)
98 {
99 // Make sure we know about the target surface.
100 enterRenderTarget(finishedTarget);
101
102 RenderSurfaceType* surface = finishedTarget->renderSurface();
103
104 // If the occlusion within the surface can not be applied to things outside of the surface's subtree, then clear the occlusion here so it won't be used.
105 if (finishedTarget->maskLayer() || !surfaceOpacityKnown(surface) || surface- >drawOpacity() < 1 || finishedTarget->filters().hasFilterThatAffectsOpacity()) {
106 m_stack.last().occlusionInScreen = Region();
107 m_stack.last().occlusionInTarget = Region();
108 } else {
109 if (!surfaceTransformsToTargetKnown(surface))
110 m_stack.last().occlusionInTarget = Region();
111 if (!surfaceTransformsToScreenKnown(surface))
112 m_stack.last().occlusionInScreen = Region();
113 }
114 }
115
116 template<typename RenderSurfaceType>
117 static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surfa ce, const Region& region, const WebTransformationMatrix& transform)
118 {
119 // Verify that rects within the |surface| will remain rects in its target su rface after applying |transform|. If this is true, then
120 // apply |transform| to each rect within |region| in order to transform the entire Region.
121
122 bool clipped;
123 FloatQuad transformedBoundsQuad = CCMathUtil::mapQuad(transform, FloatQuad(r egion.bounds()), clipped);
124 // FIXME: Find a rect interior to each transformed quad.
125 if (clipped || !transformedBoundsQuad.isRectilinear())
126 return Region();
127
128 Region transformedRegion;
129
130 Vector<WebCore::IntRect> rects = region.rects();
131 for (size_t i = 0; i < rects.size(); ++i) {
132 // We've already checked for clipping in the mapQuad call above, these c alls should not clip anything further.
133 IntRect transformedRect = enclosedIntRect(CCMathUtil::mapClippedRect(tra nsform, FloatRect(rects[i])));
134 if (!surface->clipRect().isEmpty())
135 transformedRect.intersect(surface->clipRect());
136 transformedRegion.unite(transformedRect);
137 }
138 return transformedRegion;
139 }
140
141 static inline void reduceOcclusion(const IntRect& affectedArea, const IntRect& e xpandedPixel, Region& occlusion)
142 {
143 if (affectedArea.isEmpty())
144 return;
145
146 Region affectedOcclusion = intersect(occlusion, affectedArea);
147 Vector<WebCore::IntRect> affectedOcclusionRects = affectedOcclusion.rects();
148
149 occlusion.subtract(affectedArea);
150 for (size_t j = 0; j < affectedOcclusionRects.size(); ++j) {
151 WebCore::IntRect& occlusionRect = affectedOcclusionRects[j];
152
153 // Shrink the rect by expanding the non-opaque pixels outside the rect.
154
155 // The expandedPixel is the IntRect for a single pixel after being
156 // expanded by filters on the layer. The original pixel would be
157 // IntRect(0, 0, 1, 1), and the expanded pixel is the rect, relative
158 // to this original rect, that the original pixel can influence after
159 // being filtered.
160 // To convert the expandedPixel IntRect back to filter outsets:
161 // x = -leftOutset
162 // width = leftOutset + rightOutset
163 // maxX = x + width = -leftOutset + leftOutset + rightOutset = rightOuts et
164
165 // The leftOutset of the filters moves pixels on the right side of
166 // the occlusionRect into it, shrinking its right edge.
167 int shrinkLeft = occlusionRect.x() == affectedArea.x() ? 0 : expandedPix el.maxX();
168 int shrinkTop = occlusionRect.y() == affectedArea.y() ? 0 : expandedPixe l.maxY();
169 int shrinkRight = occlusionRect.maxX() == affectedArea.maxX() ? 0 : -exp andedPixel.x();
170 int shrinkBottom = occlusionRect.maxY() == affectedArea.maxY() ? 0 : -ex pandedPixel.y();
171
172 occlusionRect.move(shrinkLeft, shrinkTop);
173 occlusionRect.contract(shrinkLeft + shrinkRight, shrinkTop + shrinkBotto m);
174
175 occlusion.unite(occlusionRect);
176 }
177 }
178
179 template<typename LayerType>
180 static void reduceOcclusionBelowSurface(LayerType* contributingLayer, const IntR ect& surfaceRect, const WebTransformationMatrix& surfaceTransform, LayerType* re nderTarget, Region& occlusionInTarget, Region& occlusionInScreen)
181 {
182 if (surfaceRect.isEmpty())
183 return;
184
185 IntRect boundsInTarget = enclosingIntRect(CCMathUtil::mapClippedRect(surface Transform, FloatRect(surfaceRect)));
186 if (!contributingLayer->renderSurface()->clipRect().isEmpty())
187 boundsInTarget.intersect(contributingLayer->renderSurface()->clipRect()) ;
188
189 int outsetTop, outsetRight, outsetBottom, outsetLeft;
190 contributingLayer->backgroundFilters().getOutsets(outsetTop, outsetRight, ou tsetBottom, outsetLeft);
191
192 // The filter can move pixels from outside of the clip, so allow affectedAre a to expand outside the clip.
193 boundsInTarget.move(-outsetLeft, -outsetTop);
194 boundsInTarget.expand(outsetLeft + outsetRight, outsetTop + outsetBottom);
195
196 IntRect boundsInScreen = enclosingIntRect(CCMathUtil::mapClippedRect(renderT arget->renderSurface()->screenSpaceTransform(), FloatRect(boundsInTarget)));
197
198 IntRect filterOutsetsInTarget(-outsetLeft, -outsetTop, outsetLeft + outsetRi ght, outsetTop + outsetBottom);
199 IntRect filterOutsetsInScreen = enclosingIntRect(CCMathUtil::mapClippedRect( renderTarget->renderSurface()->screenSpaceTransform(), FloatRect(filterOutsetsIn Target)));
200
201 reduceOcclusion(boundsInTarget, filterOutsetsInTarget, occlusionInTarget);
202 reduceOcclusion(boundsInScreen, filterOutsetsInScreen, occlusionInScreen);
203 }
204
205 template<typename LayerType, typename RenderSurfaceType>
206 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToRenderTarget(c onst LayerType* newTarget)
207 {
208 int lastIndex = m_stack.size() - 1;
209 bool surfaceWillBeAtTopAfterPop = m_stack.size() > 1 && m_stack[lastIndex - 1].target == newTarget;
210
211 // We merge the screen occlusion from the current RenderSurface subtree out to its parent target RenderSurface.
212 // The target occlusion can be merged out as well but needs to be transforme d to the new target.
213
214 const LayerType* oldTarget = m_stack[lastIndex].target;
215 const RenderSurfaceType* oldSurface = oldTarget->renderSurface();
216 Region oldTargetOcclusionInNewTarget = transformSurfaceOpaqueRegion<RenderSu rfaceType>(oldSurface, m_stack[lastIndex].occlusionInTarget, oldSurface->drawTra nsform());
217 if (oldTarget->hasReplica() && !oldTarget->replicaHasMask())
218 oldTargetOcclusionInNewTarget.unite(transformSurfaceOpaqueRegion<RenderS urfaceType>(oldSurface, m_stack[lastIndex].occlusionInTarget, oldSurface->replic aDrawTransform()));
219
220 IntRect unoccludedSurfaceRect;
221 IntRect unoccludedReplicaRect;
222 if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) {
223 unoccludedSurfaceRect = unoccludedContributingSurfaceContentRect(oldTarg et, false, oldSurface->contentRect());
224 if (oldTarget->hasReplica())
225 unoccludedReplicaRect = unoccludedContributingSurfaceContentRect(old Target, true, oldSurface->contentRect());
226 }
227
228 if (surfaceWillBeAtTopAfterPop) {
229 // Merge the top of the stack down.
230 m_stack[lastIndex - 1].occlusionInScreen.unite(m_stack[lastIndex].occlus ionInScreen);
231 m_stack[lastIndex - 1].occlusionInTarget.unite(oldTargetOcclusionInNewTa rget);
232 m_stack.removeLast();
233 } else {
234 // Replace the top of the stack with the new pushed surface. Copy the oc cluded screen region to the top.
235 m_stack.last().target = newTarget;
236 m_stack.last().occlusionInTarget = oldTargetOcclusionInNewTarget;
237 }
238
239 if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) {
240 reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface ->drawTransform(), newTarget, m_stack.last().occlusionInTarget, m_stack.last().o cclusionInScreen);
241 if (oldTarget->hasReplica())
242 reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSur face->replicaDrawTransform(), newTarget, m_stack.last().occlusionInTarget, m_sta ck.last().occlusionInScreen);
243 }
244 }
245
246 // FIXME: Remove usePaintTracking when paint tracking is on for paint culling.
247 template<typename LayerType>
248 static inline void addOcclusionBehindLayer(Region& region, const LayerType* laye r, const WebTransformationMatrix& transform, const Region& opaqueContents, const IntRect& clipRectInTarget, const IntSize& minimumTrackingSize, Vector<IntRect>* occludingScreenSpaceRects)
249 {
250 ASSERT(layer->visibleContentRect().contains(opaqueContents.bounds()));
251
252 bool clipped;
253 FloatQuad visibleTransformedQuad = CCMathUtil::mapQuad(transform, FloatQuad( layer->visibleContentRect()), clipped);
254 // FIXME: Find a rect interior to each transformed quad.
255 if (clipped || !visibleTransformedQuad.isRectilinear())
256 return;
257
258 Vector<WebCore::IntRect> contentRects = opaqueContents.rects();
259 for (size_t i = 0; i < contentRects.size(); ++i) {
260 // We've already checked for clipping in the mapQuad call above, these c alls should not clip anything further.
261 IntRect transformedRect = enclosedIntRect(CCMathUtil::mapClippedRect(tra nsform, FloatRect(contentRects[i])));
262 transformedRect.intersect(clipRectInTarget);
263 if (transformedRect.width() >= minimumTrackingSize.width() || transforme dRect.height() >= minimumTrackingSize.height()) {
264 if (occludingScreenSpaceRects)
265 occludingScreenSpaceRects->append(transformedRect);
266 region.unite(transformedRect);
267 }
268 }
269 }
270
271 template<typename LayerType, typename RenderSurfaceType>
272 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay er(const LayerType* layer)
273 {
274 ASSERT(!m_stack.isEmpty());
275 ASSERT(layer->renderTarget() == m_stack.last().target);
276 if (m_stack.isEmpty())
277 return;
278
279 if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1)
280 return;
281
282 if (layerIsInUnsorted3dRenderingContext(layer))
283 return;
284
285 Region opaqueContents = layer->visibleContentOpaqueRegion();
286 if (opaqueContents.isEmpty())
287 return;
288
289 IntRect clipRectInTarget = layerClipRectInTarget(layer);
290 if (layerTransformsToTargetKnown(layer))
291 addOcclusionBehindLayer<LayerType>(m_stack.last().occlusionInTarget, lay er, layer->drawTransform(), opaqueContents, clipRectInTarget, m_minimumTrackingS ize, 0);
292
293 // We must clip the occlusion within the layer's clipRectInTarget within scr een space as well. If the clip rect can't be moved to screen space and
294 // remain rectilinear, then we don't add any occlusion in screen space.
295
296 if (layerTransformsToScreenKnown(layer)) {
297 WebTransformationMatrix targetToScreenTransform = m_stack.last().target- >renderSurface()->screenSpaceTransform();
298 bool clipped;
299 FloatQuad clipQuadInScreen = CCMathUtil::mapQuad(targetToScreenTransform , FloatQuad(FloatRect(clipRectInTarget)), clipped);
300 // FIXME: Find a rect interior to the transformed clip quad.
301 if (clipped || !clipQuadInScreen.isRectilinear())
302 return;
303 IntRect clipRectInScreen = intersection(m_rootTargetRect, enclosedIntRec t(clipQuadInScreen.boundingBox()));
304 addOcclusionBehindLayer<LayerType>(m_stack.last().occlusionInScreen, lay er, layer->screenSpaceTransform(), opaqueContents, clipRectInScreen, m_minimumTr ackingSize, m_occludingScreenSpaceRects);
305 }
306 }
307
308 static inline bool testContentRectOccluded(const IntRect& contentRect, const Web TransformationMatrix& contentSpaceTransform, const IntRect& clipRectInTarget, co nst Region& occlusion)
309 {
310 FloatRect transformedRect = CCMathUtil::mapClippedRect(contentSpaceTransform , FloatRect(contentRect));
311 // Take the enclosingIntRect, as we want to include partial pixels in the te st.
312 IntRect targetRect = intersection(enclosingIntRect(transformedRect), clipRec tInTarget);
313 return targetRect.isEmpty() || occlusion.contains(targetRect);
314 }
315
316 template<typename LayerType, typename RenderSurfaceType>
317 bool CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerT ype* layer, const IntRect& contentRect, bool* hasOcclusionFromOutsideTargetSurfa ce) const
318 {
319 if (hasOcclusionFromOutsideTargetSurface)
320 *hasOcclusionFromOutsideTargetSurface = false;
321
322 ASSERT(!m_stack.isEmpty());
323 if (m_stack.isEmpty())
324 return false;
325 if (contentRect.isEmpty())
326 return true;
327
328 ASSERT(layer->renderTarget() == m_stack.last().target);
329
330 if (layerTransformsToTargetKnown(layer) && testContentRectOccluded(contentRe ct, layer->drawTransform(), layerClipRectInTarget(layer), m_stack.last().occlusi onInTarget))
331 return true;
332
333 if (layerTransformsToScreenKnown(layer) && testContentRectOccluded(contentRe ct, layer->screenSpaceTransform(), m_rootTargetRect, m_stack.last().occlusionInS creen)) {
334 if (hasOcclusionFromOutsideTargetSurface)
335 *hasOcclusionFromOutsideTargetSurface = true;
336 return true;
337 }
338
339 return false;
340 }
341
342 // Determines what portion of rect, if any, is unoccluded (not occluded by regio n). If
343 // the resulting unoccluded region is not rectangular, we return a rect containi ng it.
344 static inline IntRect rectSubtractRegion(const IntRect& rect, const Region& regi on)
345 {
346 Region rectRegion(rect);
347 rectRegion.subtract(region);
348 return rectRegion.bounds();
349 }
350
351 static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, c onst WebTransformationMatrix& contentSpaceTransform, const IntRect& clipRectInTa rget, const Region& occlusion)
352 {
353 if (!contentSpaceTransform.isInvertible())
354 return contentRect;
355
356 // Take the enclosingIntRect at each step, as we want to contain any unocclu ded partial pixels in the resulting IntRect.
357 FloatRect transformedRect = CCMathUtil::mapClippedRect(contentSpaceTransform , FloatRect(contentRect));
358 IntRect shrunkRect = rectSubtractRegion(intersection(enclosingIntRect(transf ormedRect), clipRectInTarget), occlusion);
359 IntRect unoccludedRect = enclosingIntRect(CCMathUtil::projectClippedRect(con tentSpaceTransform.inverse(), FloatRect(shrunkRect)));
360 // The rect back in content space is a bounding box and may extend outside o f the original contentRect, so clamp it to the contentRectBounds.
361 return intersection(unoccludedRect, contentRect);
362 }
363
364 template<typename LayerType, typename RenderSurfaceType>
365 IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR ect(const LayerType* layer, const IntRect& contentRect, bool* hasOcclusionFromOu tsideTargetSurface) const
366 {
367 ASSERT(!m_stack.isEmpty());
368 if (m_stack.isEmpty())
369 return contentRect;
370 if (contentRect.isEmpty())
371 return contentRect;
372
373 ASSERT(layer->renderTarget() == m_stack.last().target);
374
375 // We want to return a rect that contains all the visible parts of |contentR ect| in both screen space and in the target surface.
376 // So we find the visible parts of |contentRect| in each space, and take the intersection.
377
378 IntRect unoccludedInScreen = contentRect;
379 if (layerTransformsToScreenKnown(layer))
380 unoccludedInScreen = computeUnoccludedContentRect(contentRect, layer->sc reenSpaceTransform(), m_rootTargetRect, m_stack.last().occlusionInScreen);
381
382 IntRect unoccludedInTarget = contentRect;
383 if (layerTransformsToTargetKnown(layer))
384 unoccludedInTarget = computeUnoccludedContentRect(contentRect, layer->dr awTransform(), layerClipRectInTarget(layer), m_stack.last().occlusionInTarget);
385
386 if (hasOcclusionFromOutsideTargetSurface)
387 *hasOcclusionFromOutsideTargetSurface = (intersection(unoccludedInScreen , unoccludedInTarget) != unoccludedInTarget);
388
389 return intersection(unoccludedInScreen, unoccludedInTarget);
390 }
391
392 template<typename LayerType, typename RenderSurfaceType>
393 IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContribu tingSurfaceContentRect(const LayerType* layer, bool forReplica, const IntRect& c ontentRect, bool* hasOcclusionFromOutsideTargetSurface) const
394 {
395 ASSERT(!m_stack.isEmpty());
396 // The layer is a contributing renderTarget so it should have a surface.
397 ASSERT(layer->renderSurface());
398 // The layer is a contributing renderTarget so its target should be itself.
399 ASSERT(layer->renderTarget() == layer);
400 // The layer should not be the root, else what is is contributing to?
401 ASSERT(layer->parent());
402 // This should be called while the layer is still considered the current tar get in the occlusion tracker.
403 ASSERT(layer == m_stack.last().target);
404
405 if (contentRect.isEmpty())
406 return contentRect;
407
408 RenderSurfaceType* surface = layer->renderSurface();
409
410 IntRect surfaceClipRect = surface->clipRect();
411 if (surfaceClipRect.isEmpty()) {
412 LayerType* contributingSurfaceRenderTarget = layer->parent()->renderTarg et();
413 surfaceClipRect = intersection(contributingSurfaceRenderTarget->renderSu rface()->contentRect(), enclosingIntRect(surface->drawableContentRect()));
414 }
415
416 // A contributing surface doesn't get occluded by things inside its own surf ace, so only things outside the surface can occlude it. That occlusion is
417 // found just below the top of the stack (if it exists).
418 bool hasOcclusion = m_stack.size() > 1;
419
420 const WebTransformationMatrix& transformToScreen = forReplica ? surface->rep licaScreenSpaceTransform() : surface->screenSpaceTransform();
421 const WebTransformationMatrix& transformToTarget = forReplica ? surface->rep licaDrawTransform() : surface->drawTransform();
422
423 IntRect unoccludedInScreen = contentRect;
424 if (surfaceTransformsToScreenKnown(surface)) {
425 if (hasOcclusion) {
426 const StackObject& secondLast = m_stack[m_stack.size() - 2];
427 unoccludedInScreen = computeUnoccludedContentRect(contentRect, trans formToScreen, m_rootTargetRect, secondLast.occlusionInScreen);
428 } else
429 unoccludedInScreen = computeUnoccludedContentRect(contentRect, trans formToScreen, m_rootTargetRect, Region());
430 }
431
432 IntRect unoccludedInTarget = contentRect;
433 if (surfaceTransformsToTargetKnown(surface)) {
434 if (hasOcclusion) {
435 const StackObject& secondLast = m_stack[m_stack.size() - 2];
436 unoccludedInTarget = computeUnoccludedContentRect(contentRect, trans formToTarget, surfaceClipRect, secondLast.occlusionInTarget);
437 } else
438 unoccludedInTarget = computeUnoccludedContentRect(contentRect, trans formToTarget, surfaceClipRect, Region());
439 }
440
441 if (hasOcclusionFromOutsideTargetSurface)
442 *hasOcclusionFromOutsideTargetSurface = (intersection(unoccludedInScreen , unoccludedInTarget) != unoccludedInTarget);
443
444 return intersection(unoccludedInScreen, unoccludedInTarget);
445 }
446
447 template<typename LayerType, typename RenderSurfaceType>
448 IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerClipRectInTar get(const LayerType* layer) const
449 {
450 // FIXME: we could remove this helper function, but unit tests currently ove rride this
451 // function, and they need to be verified/adjusted before this can be removed.
452 return layer->drawableContentRect();
453 }
454
455 // Declare the possible functions here for the linker.
456 template CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::CCOcclusi onTrackerBase(IntRect rootTargetRect, bool recordMetricsForFrame);
457 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::ente rLayer(const CCLayerIteratorPosition<LayerChromium>&);
458 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::leav eLayer(const CCLayerIteratorPosition<LayerChromium>&);
459 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::ente rRenderTarget(const LayerChromium* newTarget);
460 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::fini shedRenderTarget(const LayerChromium* finishedTarget);
461 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::leav eToRenderTarget(const LayerChromium* newTarget);
462 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::mark OccludedBehindLayer(const LayerChromium*);
463 template bool CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::occl uded(const LayerChromium*, const IntRect& contentRect, bool* hasOcclusionFromOut sideTargetSurface) const;
464 template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::u noccludedContentRect(const LayerChromium*, const IntRect& contentRect, bool* has OcclusionFromOutsideTargetSurface) const;
465 template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::u noccludedContributingSurfaceContentRect(const LayerChromium*, bool forReplica, c onst IntRect& contentRect, bool* hasOcclusionFromOutsideTargetSurface) const;
466 template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::l ayerClipRectInTarget(const LayerChromium*) const;
467
468 template CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::CCOcclusionTracke rBase(IntRect rootTargetRect, bool recordMetricsForFrame);
469 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::enterLayer(c onst CCLayerIteratorPosition<CCLayerImpl>&);
470 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::leaveLayer(c onst CCLayerIteratorPosition<CCLayerImpl>&);
471 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::enterRenderT arget(const CCLayerImpl* newTarget);
472 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::finishedRend erTarget(const CCLayerImpl* finishedTarget);
473 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::leaveToRende rTarget(const CCLayerImpl* newTarget);
474 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::markOccluded BehindLayer(const CCLayerImpl*);
475 template bool CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::occluded(con st CCLayerImpl*, const IntRect& contentRect, bool* hasOcclusionFromOutsideTarget Surface) const;
476 template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unocclude dContentRect(const CCLayerImpl*, const IntRect& contentRect, bool* hasOcclusionF romOutsideTargetSurface) const;
477 template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unocclude dContributingSurfaceContentRect(const CCLayerImpl*, bool forReplica, const IntRe ct& contentRect, bool* hasOcclusionFromOutsideTargetSurface) const;
478 template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::layerClip RectInTarget(const CCLayerImpl*) const;
479
480
481 } // namespace cc
482 #endif // USE(ACCELERATED_COMPOSITING)
OLDNEW
« no previous file with comments | « cc/CCOcclusionTracker.h ('k') | cc/CCOverdrawMetrics.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698