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

Side by Side Diff: cc/occlusion_tracker.cc

Issue 11189043: cc: Rename cc classes and members to match filenames (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
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 6
7 #include "CCOcclusionTracker.h" 7 #include "CCOcclusionTracker.h"
8 8
9 #include "CCLayerImpl.h" 9 #include "CCLayerImpl.h"
10 #include "CCMathUtil.h" 10 #include "CCMathUtil.h"
11 #include "CCOverdrawMetrics.h" 11 #include "CCOverdrawMetrics.h"
12 #include "cc/layer.h" 12 #include "cc/layer.h"
13 #include <algorithm> 13 #include <algorithm>
14 14
15 using namespace std; 15 using namespace std;
16 using WebKit::WebTransformationMatrix; 16 using WebKit::WebTransformationMatrix;
17 17
18 namespace cc { 18 namespace cc {
19 19
20 template<typename LayerType, typename RenderSurfaceType> 20 template<typename LayerType, typename RenderSurfaceType>
21 CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::CCOcclusionTrackerBase(Int Rect rootTargetRect, bool recordMetricsForFrame) 21 OcclusionTrackerBase<LayerType, RenderSurfaceType>::OcclusionTrackerBase(IntRect rootTargetRect, bool recordMetricsForFrame)
22 : m_rootTargetRect(rootTargetRect) 22 : m_rootTargetRect(rootTargetRect)
23 , m_overdrawMetrics(CCOverdrawMetrics::create(recordMetricsForFrame)) 23 , m_overdrawMetrics(OverdrawMetrics::create(recordMetricsForFrame))
24 , m_occludingScreenSpaceRects(0) 24 , m_occludingScreenSpaceRects(0)
25 { 25 {
26 } 26 }
27 27
28 template<typename LayerType, typename RenderSurfaceType> 28 template<typename LayerType, typename RenderSurfaceType>
29 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::enterLayer(const CCLa yerIteratorPosition<LayerType>& layerIterator) 29 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::enterLayer(const LayerI teratorPosition<LayerType>& layerIterator)
30 { 30 {
31 LayerType* renderTarget = layerIterator.targetRenderSurfaceLayer; 31 LayerType* renderTarget = layerIterator.targetRenderSurfaceLayer;
32 32
33 if (layerIterator.representsItself) 33 if (layerIterator.representsItself)
34 enterRenderTarget(renderTarget); 34 enterRenderTarget(renderTarget);
35 else if (layerIterator.representsTargetRenderSurface) 35 else if (layerIterator.representsTargetRenderSurface)
36 finishedRenderTarget(renderTarget); 36 finishedRenderTarget(renderTarget);
37 } 37 }
38 38
39 template<typename LayerType, typename RenderSurfaceType> 39 template<typename LayerType, typename RenderSurfaceType>
40 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveLayer(const CCLa yerIteratorPosition<LayerType>& layerIterator) 40 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveLayer(const LayerI teratorPosition<LayerType>& layerIterator)
41 { 41 {
42 LayerType* renderTarget = layerIterator.targetRenderSurfaceLayer; 42 LayerType* renderTarget = layerIterator.targetRenderSurfaceLayer;
43 43
44 if (layerIterator.representsItself) 44 if (layerIterator.representsItself)
45 markOccludedBehindLayer(layerIterator.currentLayer); 45 markOccludedBehindLayer(layerIterator.currentLayer);
46 else if (layerIterator.representsContributingRenderSurface) 46 else if (layerIterator.representsContributingRenderSurface)
47 leaveToRenderTarget(renderTarget); 47 leaveToRenderTarget(renderTarget);
48 } 48 }
49 49
50 template<typename LayerType, typename RenderSurfaceType> 50 template<typename LayerType, typename RenderSurfaceType>
51 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::enterRenderTarget(con st LayerType* newTarget) 51 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::enterRenderTarget(const LayerType* newTarget)
52 { 52 {
53 if (!m_stack.isEmpty() && m_stack.last().target == newTarget) 53 if (!m_stack.isEmpty() && m_stack.last().target == newTarget)
54 return; 54 return;
55 55
56 const LayerType* oldTarget = m_stack.isEmpty() ? 0 : m_stack.last().target; 56 const LayerType* oldTarget = m_stack.isEmpty() ? 0 : m_stack.last().target;
57 const RenderSurfaceType* oldAncestorThatMovesPixels = !oldTarget ? 0 : oldTa rget->renderSurface()->nearestAncestorThatMovesPixels(); 57 const RenderSurfaceType* oldAncestorThatMovesPixels = !oldTarget ? 0 : oldTa rget->renderSurface()->nearestAncestorThatMovesPixels();
58 const RenderSurfaceType* newAncestorThatMovesPixels = newTarget->renderSurfa ce()->nearestAncestorThatMovesPixels(); 58 const RenderSurfaceType* newAncestorThatMovesPixels = newTarget->renderSurfa ce()->nearestAncestorThatMovesPixels();
59 59
60 m_stack.append(StackObject(newTarget)); 60 m_stack.append(StackObject(newTarget));
61 61
62 // We copy the screen occlusion into the new RenderSurface subtree, but we n ever copy in the 62 // We copy the screen occlusion into the new RenderSurfaceImpl subtree, but we never copy in the
63 // target occlusion, since we are looking at a new RenderSurface target. 63 // target occlusion, since we are looking at a new RenderSurfaceImpl target.
64 64
65 // If we are entering a subtree that is going to move pixels around, then th e occlusion we've computed 65 // If we are entering a subtree that is going to move pixels around, then th e occlusion we've computed
66 // so far won't apply to the pixels we're drawing here in the same way. We d iscard the occlusion thus 66 // so far won't apply to the pixels we're drawing here in the same way. We d iscard the occlusion thus
67 // far to be safe, and ensure we don't cull any pixels that are moved such t hat they become visible. 67 // far to be safe, and ensure we don't cull any pixels that are moved such t hat they become visible.
68 bool enteringSubtreeThatMovesPixels = newAncestorThatMovesPixels && newAnces torThatMovesPixels != oldAncestorThatMovesPixels; 68 bool enteringSubtreeThatMovesPixels = newAncestorThatMovesPixels && newAnces torThatMovesPixels != oldAncestorThatMovesPixels;
69 69
70 bool copyScreenOcclusionForward = m_stack.size() > 1 && !enteringSubtreeThat MovesPixels; 70 bool copyScreenOcclusionForward = m_stack.size() > 1 && !enteringSubtreeThat MovesPixels;
71 if (copyScreenOcclusionForward) { 71 if (copyScreenOcclusionForward) {
72 int lastIndex = m_stack.size() - 1; 72 int lastIndex = m_stack.size() - 1;
73 m_stack[lastIndex].occlusionInScreen = m_stack[lastIndex - 1].occlusionI nScreen; 73 m_stack[lastIndex].occlusionInScreen = m_stack[lastIndex - 1].occlusionI nScreen;
74 } 74 }
75 } 75 }
76 76
77 static inline bool layerOpacityKnown(const LayerChromium* layer) { return !layer ->drawOpacityIsAnimating(); } 77 static inline bool layerOpacityKnown(const Layer* layer) { return !layer->drawOp acityIsAnimating(); }
78 static inline bool layerOpacityKnown(const CCLayerImpl*) { return true; } 78 static inline bool layerOpacityKnown(const LayerImpl*) { return true; }
79 static inline bool layerTransformsToTargetKnown(const LayerChromium* layer) { re turn !layer->drawTransformIsAnimating(); } 79 static inline bool layerTransformsToTargetKnown(const Layer* layer) { return !la yer->drawTransformIsAnimating(); }
80 static inline bool layerTransformsToTargetKnown(const CCLayerImpl*) { return tru e; } 80 static inline bool layerTransformsToTargetKnown(const LayerImpl*) { return true; }
81 static inline bool layerTransformsToScreenKnown(const LayerChromium* layer) { re turn !layer->screenSpaceTransformIsAnimating(); } 81 static inline bool layerTransformsToScreenKnown(const Layer* layer) { return !la yer->screenSpaceTransformIsAnimating(); }
82 static inline bool layerTransformsToScreenKnown(const CCLayerImpl*) { return tru e; } 82 static inline bool layerTransformsToScreenKnown(const LayerImpl*) { return true; }
83 83
84 static inline bool surfaceOpacityKnown(const RenderSurfaceChromium* surface) { r eturn !surface->drawOpacityIsAnimating(); } 84 static inline bool surfaceOpacityKnown(const RenderSurface* surface) { return !s urface->drawOpacityIsAnimating(); }
85 static inline bool surfaceOpacityKnown(const CCRenderSurface*) { return true; } 85 static inline bool surfaceOpacityKnown(const RenderSurfaceImpl*) { return true; }
86 static inline bool surfaceTransformsToTargetKnown(const RenderSurfaceChromium* s urface) { return !surface->targetSurfaceTransformsAreAnimating(); } 86 static inline bool surfaceTransformsToTargetKnown(const RenderSurface* surface) { return !surface->targetSurfaceTransformsAreAnimating(); }
87 static inline bool surfaceTransformsToTargetKnown(const CCRenderSurface*) { retu rn true; } 87 static inline bool surfaceTransformsToTargetKnown(const RenderSurfaceImpl*) { re turn true; }
88 static inline bool surfaceTransformsToScreenKnown(const RenderSurfaceChromium* s urface) { return !surface->screenSpaceTransformsAreAnimating(); } 88 static inline bool surfaceTransformsToScreenKnown(const RenderSurface* surface) { return !surface->screenSpaceTransformsAreAnimating(); }
89 static inline bool surfaceTransformsToScreenKnown(const CCRenderSurface*) { retu rn true; } 89 static inline bool surfaceTransformsToScreenKnown(const RenderSurfaceImpl*) { re turn true; }
90 90
91 static inline bool layerIsInUnsorted3dRenderingContext(const LayerChromium* laye r) { return layer->parent() && layer->parent()->preserves3D(); } 91 static inline bool layerIsInUnsorted3dRenderingContext(const Layer* layer) { ret urn layer->parent() && layer->parent()->preserves3D(); }
92 static inline bool layerIsInUnsorted3dRenderingContext(const CCLayerImpl*) { ret urn false; } 92 static inline bool layerIsInUnsorted3dRenderingContext(const LayerImpl*) { retur n false; }
93 93
94 template<typename LayerType, typename RenderSurfaceType> 94 template<typename LayerType, typename RenderSurfaceType>
95 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::finishedRenderTarget( const LayerType* finishedTarget) 95 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::finishedRenderTarget(co nst LayerType* finishedTarget)
96 { 96 {
97 // Make sure we know about the target surface. 97 // Make sure we know about the target surface.
98 enterRenderTarget(finishedTarget); 98 enterRenderTarget(finishedTarget);
99 99
100 RenderSurfaceType* surface = finishedTarget->renderSurface(); 100 RenderSurfaceType* surface = finishedTarget->renderSurface();
101 101
102 // 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. 102 // 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.
103 if (finishedTarget->maskLayer() || !surfaceOpacityKnown(surface) || surface- >drawOpacity() < 1 || finishedTarget->filters().hasFilterThatAffectsOpacity()) { 103 if (finishedTarget->maskLayer() || !surfaceOpacityKnown(surface) || surface- >drawOpacity() < 1 || finishedTarget->filters().hasFilterThatAffectsOpacity()) {
104 m_stack.last().occlusionInScreen = Region(); 104 m_stack.last().occlusionInScreen = Region();
105 m_stack.last().occlusionInTarget = Region(); 105 m_stack.last().occlusionInTarget = Region();
106 } else { 106 } else {
107 if (!surfaceTransformsToTargetKnown(surface)) 107 if (!surfaceTransformsToTargetKnown(surface))
108 m_stack.last().occlusionInTarget = Region(); 108 m_stack.last().occlusionInTarget = Region();
109 if (!surfaceTransformsToScreenKnown(surface)) 109 if (!surfaceTransformsToScreenKnown(surface))
110 m_stack.last().occlusionInScreen = Region(); 110 m_stack.last().occlusionInScreen = Region();
111 } 111 }
112 } 112 }
113 113
114 template<typename RenderSurfaceType> 114 template<typename RenderSurfaceType>
115 static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surfa ce, const Region& region, const WebTransformationMatrix& transform) 115 static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surfa ce, const Region& region, const WebTransformationMatrix& transform)
116 { 116 {
117 // Verify that rects within the |surface| will remain rects in its target su rface after applying |transform|. If this is true, then 117 // Verify that rects within the |surface| will remain rects in its target su rface after applying |transform|. If this is true, then
118 // apply |transform| to each rect within |region| in order to transform the entire Region. 118 // apply |transform| to each rect within |region| in order to transform the entire Region.
119 119
120 bool clipped; 120 bool clipped;
121 FloatQuad transformedBoundsQuad = CCMathUtil::mapQuad(transform, FloatQuad(r egion.bounds()), clipped); 121 FloatQuad transformedBoundsQuad = MathUtil::mapQuad(transform, FloatQuad(reg ion.bounds()), clipped);
122 // FIXME: Find a rect interior to each transformed quad. 122 // FIXME: Find a rect interior to each transformed quad.
123 if (clipped || !transformedBoundsQuad.isRectilinear()) 123 if (clipped || !transformedBoundsQuad.isRectilinear())
124 return Region(); 124 return Region();
125 125
126 Region transformedRegion; 126 Region transformedRegion;
127 127
128 Vector<WebCore::IntRect> rects = region.rects(); 128 Vector<WebCore::IntRect> rects = region.rects();
129 for (size_t i = 0; i < rects.size(); ++i) { 129 for (size_t i = 0; i < rects.size(); ++i) {
130 // We've already checked for clipping in the mapQuad call above, these c alls should not clip anything further. 130 // We've already checked for clipping in the mapQuad call above, these c alls should not clip anything further.
131 IntRect transformedRect = enclosedIntRect(CCMathUtil::mapClippedRect(tra nsform, FloatRect(rects[i]))); 131 IntRect transformedRect = enclosedIntRect(MathUtil::mapClippedRect(trans form, FloatRect(rects[i])));
132 if (!surface->clipRect().isEmpty()) 132 if (!surface->clipRect().isEmpty())
133 transformedRect.intersect(surface->clipRect()); 133 transformedRect.intersect(surface->clipRect());
134 transformedRegion.unite(transformedRect); 134 transformedRegion.unite(transformedRect);
135 } 135 }
136 return transformedRegion; 136 return transformedRegion;
137 } 137 }
138 138
139 static inline void reduceOcclusion(const IntRect& affectedArea, const IntRect& e xpandedPixel, Region& occlusion) 139 static inline void reduceOcclusion(const IntRect& affectedArea, const IntRect& e xpandedPixel, Region& occlusion)
140 { 140 {
141 if (affectedArea.isEmpty()) 141 if (affectedArea.isEmpty())
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 occlusion.unite(occlusionRect); 173 occlusion.unite(occlusionRect);
174 } 174 }
175 } 175 }
176 176
177 template<typename LayerType> 177 template<typename LayerType>
178 static void reduceOcclusionBelowSurface(LayerType* contributingLayer, const IntR ect& surfaceRect, const WebTransformationMatrix& surfaceTransform, LayerType* re nderTarget, Region& occlusionInTarget, Region& occlusionInScreen) 178 static void reduceOcclusionBelowSurface(LayerType* contributingLayer, const IntR ect& surfaceRect, const WebTransformationMatrix& surfaceTransform, LayerType* re nderTarget, Region& occlusionInTarget, Region& occlusionInScreen)
179 { 179 {
180 if (surfaceRect.isEmpty()) 180 if (surfaceRect.isEmpty())
181 return; 181 return;
182 182
183 IntRect boundsInTarget = enclosingIntRect(CCMathUtil::mapClippedRect(surface Transform, FloatRect(surfaceRect))); 183 IntRect boundsInTarget = enclosingIntRect(MathUtil::mapClippedRect(surfaceTr ansform, FloatRect(surfaceRect)));
184 if (!contributingLayer->renderSurface()->clipRect().isEmpty()) 184 if (!contributingLayer->renderSurface()->clipRect().isEmpty())
185 boundsInTarget.intersect(contributingLayer->renderSurface()->clipRect()) ; 185 boundsInTarget.intersect(contributingLayer->renderSurface()->clipRect()) ;
186 186
187 int outsetTop, outsetRight, outsetBottom, outsetLeft; 187 int outsetTop, outsetRight, outsetBottom, outsetLeft;
188 contributingLayer->backgroundFilters().getOutsets(outsetTop, outsetRight, ou tsetBottom, outsetLeft); 188 contributingLayer->backgroundFilters().getOutsets(outsetTop, outsetRight, ou tsetBottom, outsetLeft);
189 189
190 // The filter can move pixels from outside of the clip, so allow affectedAre a to expand outside the clip. 190 // The filter can move pixels from outside of the clip, so allow affectedAre a to expand outside the clip.
191 boundsInTarget.move(-outsetLeft, -outsetTop); 191 boundsInTarget.move(-outsetLeft, -outsetTop);
192 boundsInTarget.expand(outsetLeft + outsetRight, outsetTop + outsetBottom); 192 boundsInTarget.expand(outsetLeft + outsetRight, outsetTop + outsetBottom);
193 193
194 IntRect boundsInScreen = enclosingIntRect(CCMathUtil::mapClippedRect(renderT arget->renderSurface()->screenSpaceTransform(), FloatRect(boundsInTarget))); 194 IntRect boundsInScreen = enclosingIntRect(MathUtil::mapClippedRect(renderTar get->renderSurface()->screenSpaceTransform(), FloatRect(boundsInTarget)));
195 195
196 IntRect filterOutsetsInTarget(-outsetLeft, -outsetTop, outsetLeft + outsetRi ght, outsetTop + outsetBottom); 196 IntRect filterOutsetsInTarget(-outsetLeft, -outsetTop, outsetLeft + outsetRi ght, outsetTop + outsetBottom);
197 IntRect filterOutsetsInScreen = enclosingIntRect(CCMathUtil::mapClippedRect( renderTarget->renderSurface()->screenSpaceTransform(), FloatRect(filterOutsetsIn Target))); 197 IntRect filterOutsetsInScreen = enclosingIntRect(MathUtil::mapClippedRect(re nderTarget->renderSurface()->screenSpaceTransform(), FloatRect(filterOutsetsInTa rget)));
198 198
199 reduceOcclusion(boundsInTarget, filterOutsetsInTarget, occlusionInTarget); 199 reduceOcclusion(boundsInTarget, filterOutsetsInTarget, occlusionInTarget);
200 reduceOcclusion(boundsInScreen, filterOutsetsInScreen, occlusionInScreen); 200 reduceOcclusion(boundsInScreen, filterOutsetsInScreen, occlusionInScreen);
201 } 201 }
202 202
203 template<typename LayerType, typename RenderSurfaceType> 203 template<typename LayerType, typename RenderSurfaceType>
204 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToRenderTarget(c onst LayerType* newTarget) 204 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToRenderTarget(con st LayerType* newTarget)
205 { 205 {
206 int lastIndex = m_stack.size() - 1; 206 int lastIndex = m_stack.size() - 1;
207 bool surfaceWillBeAtTopAfterPop = m_stack.size() > 1 && m_stack[lastIndex - 1].target == newTarget; 207 bool surfaceWillBeAtTopAfterPop = m_stack.size() > 1 && m_stack[lastIndex - 1].target == newTarget;
208 208
209 // We merge the screen occlusion from the current RenderSurface subtree out to its parent target RenderSurface. 209 // We merge the screen occlusion from the current RenderSurfaceImpl subtree out to its parent target RenderSurfaceImpl.
210 // The target occlusion can be merged out as well but needs to be transforme d to the new target. 210 // The target occlusion can be merged out as well but needs to be transforme d to the new target.
211 211
212 const LayerType* oldTarget = m_stack[lastIndex].target; 212 const LayerType* oldTarget = m_stack[lastIndex].target;
213 const RenderSurfaceType* oldSurface = oldTarget->renderSurface(); 213 const RenderSurfaceType* oldSurface = oldTarget->renderSurface();
214 Region oldTargetOcclusionInNewTarget = transformSurfaceOpaqueRegion<RenderSu rfaceType>(oldSurface, m_stack[lastIndex].occlusionInTarget, oldSurface->drawTra nsform()); 214 Region oldTargetOcclusionInNewTarget = transformSurfaceOpaqueRegion<RenderSu rfaceType>(oldSurface, m_stack[lastIndex].occlusionInTarget, oldSurface->drawTra nsform());
215 if (oldTarget->hasReplica() && !oldTarget->replicaHasMask()) 215 if (oldTarget->hasReplica() && !oldTarget->replicaHasMask())
216 oldTargetOcclusionInNewTarget.unite(transformSurfaceOpaqueRegion<RenderS urfaceType>(oldSurface, m_stack[lastIndex].occlusionInTarget, oldSurface->replic aDrawTransform())); 216 oldTargetOcclusionInNewTarget.unite(transformSurfaceOpaqueRegion<RenderS urfaceType>(oldSurface, m_stack[lastIndex].occlusionInTarget, oldSurface->replic aDrawTransform()));
217 217
218 IntRect unoccludedSurfaceRect; 218 IntRect unoccludedSurfaceRect;
219 IntRect unoccludedReplicaRect; 219 IntRect unoccludedReplicaRect;
(...skipping 21 matching lines...) Expand all
241 } 241 }
242 } 242 }
243 243
244 // FIXME: Remove usePaintTracking when paint tracking is on for paint culling. 244 // FIXME: Remove usePaintTracking when paint tracking is on for paint culling.
245 template<typename LayerType> 245 template<typename LayerType>
246 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) 246 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)
247 { 247 {
248 ASSERT(layer->visibleContentRect().contains(opaqueContents.bounds())); 248 ASSERT(layer->visibleContentRect().contains(opaqueContents.bounds()));
249 249
250 bool clipped; 250 bool clipped;
251 FloatQuad visibleTransformedQuad = CCMathUtil::mapQuad(transform, FloatQuad( layer->visibleContentRect()), clipped); 251 FloatQuad visibleTransformedQuad = MathUtil::mapQuad(transform, FloatQuad(la yer->visibleContentRect()), clipped);
252 // FIXME: Find a rect interior to each transformed quad. 252 // FIXME: Find a rect interior to each transformed quad.
253 if (clipped || !visibleTransformedQuad.isRectilinear()) 253 if (clipped || !visibleTransformedQuad.isRectilinear())
254 return; 254 return;
255 255
256 Vector<WebCore::IntRect> contentRects = opaqueContents.rects(); 256 Vector<WebCore::IntRect> contentRects = opaqueContents.rects();
257 for (size_t i = 0; i < contentRects.size(); ++i) { 257 for (size_t i = 0; i < contentRects.size(); ++i) {
258 // We've already checked for clipping in the mapQuad call above, these c alls should not clip anything further. 258 // We've already checked for clipping in the mapQuad call above, these c alls should not clip anything further.
259 IntRect transformedRect = enclosedIntRect(CCMathUtil::mapClippedRect(tra nsform, FloatRect(contentRects[i]))); 259 IntRect transformedRect = enclosedIntRect(MathUtil::mapClippedRect(trans form, FloatRect(contentRects[i])));
260 transformedRect.intersect(clipRectInTarget); 260 transformedRect.intersect(clipRectInTarget);
261 if (transformedRect.width() >= minimumTrackingSize.width() || transforme dRect.height() >= minimumTrackingSize.height()) { 261 if (transformedRect.width() >= minimumTrackingSize.width() || transforme dRect.height() >= minimumTrackingSize.height()) {
262 if (occludingScreenSpaceRects) 262 if (occludingScreenSpaceRects)
263 occludingScreenSpaceRects->append(transformedRect); 263 occludingScreenSpaceRects->append(transformedRect);
264 region.unite(transformedRect); 264 region.unite(transformedRect);
265 } 265 }
266 } 266 }
267 } 267 }
268 268
269 template<typename LayerType, typename RenderSurfaceType> 269 template<typename LayerType, typename RenderSurfaceType>
270 void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay er(const LayerType* layer) 270 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLayer (const LayerType* layer)
271 { 271 {
272 ASSERT(!m_stack.isEmpty()); 272 ASSERT(!m_stack.isEmpty());
273 ASSERT(layer->renderTarget() == m_stack.last().target); 273 ASSERT(layer->renderTarget() == m_stack.last().target);
274 if (m_stack.isEmpty()) 274 if (m_stack.isEmpty())
275 return; 275 return;
276 276
277 if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1) 277 if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1)
278 return; 278 return;
279 279
280 if (layerIsInUnsorted3dRenderingContext(layer)) 280 if (layerIsInUnsorted3dRenderingContext(layer))
281 return; 281 return;
282 282
283 Region opaqueContents = layer->visibleContentOpaqueRegion(); 283 Region opaqueContents = layer->visibleContentOpaqueRegion();
284 if (opaqueContents.isEmpty()) 284 if (opaqueContents.isEmpty())
285 return; 285 return;
286 286
287 IntRect clipRectInTarget = layerClipRectInTarget(layer); 287 IntRect clipRectInTarget = layerClipRectInTarget(layer);
288 if (layerTransformsToTargetKnown(layer)) 288 if (layerTransformsToTargetKnown(layer))
289 addOcclusionBehindLayer<LayerType>(m_stack.last().occlusionInTarget, lay er, layer->drawTransform(), opaqueContents, clipRectInTarget, m_minimumTrackingS ize, 0); 289 addOcclusionBehindLayer<LayerType>(m_stack.last().occlusionInTarget, lay er, layer->drawTransform(), opaqueContents, clipRectInTarget, m_minimumTrackingS ize, 0);
290 290
291 // 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 291 // 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
292 // remain rectilinear, then we don't add any occlusion in screen space. 292 // remain rectilinear, then we don't add any occlusion in screen space.
293 293
294 if (layerTransformsToScreenKnown(layer)) { 294 if (layerTransformsToScreenKnown(layer)) {
295 WebTransformationMatrix targetToScreenTransform = m_stack.last().target- >renderSurface()->screenSpaceTransform(); 295 WebTransformationMatrix targetToScreenTransform = m_stack.last().target- >renderSurface()->screenSpaceTransform();
296 bool clipped; 296 bool clipped;
297 FloatQuad clipQuadInScreen = CCMathUtil::mapQuad(targetToScreenTransform , FloatQuad(FloatRect(clipRectInTarget)), clipped); 297 FloatQuad clipQuadInScreen = MathUtil::mapQuad(targetToScreenTransform, FloatQuad(FloatRect(clipRectInTarget)), clipped);
298 // FIXME: Find a rect interior to the transformed clip quad. 298 // FIXME: Find a rect interior to the transformed clip quad.
299 if (clipped || !clipQuadInScreen.isRectilinear()) 299 if (clipped || !clipQuadInScreen.isRectilinear())
300 return; 300 return;
301 IntRect clipRectInScreen = intersection(m_rootTargetRect, enclosedIntRec t(clipQuadInScreen.boundingBox())); 301 IntRect clipRectInScreen = intersection(m_rootTargetRect, enclosedIntRec t(clipQuadInScreen.boundingBox()));
302 addOcclusionBehindLayer<LayerType>(m_stack.last().occlusionInScreen, lay er, layer->screenSpaceTransform(), opaqueContents, clipRectInScreen, m_minimumTr ackingSize, m_occludingScreenSpaceRects); 302 addOcclusionBehindLayer<LayerType>(m_stack.last().occlusionInScreen, lay er, layer->screenSpaceTransform(), opaqueContents, clipRectInScreen, m_minimumTr ackingSize, m_occludingScreenSpaceRects);
303 } 303 }
304 } 304 }
305 305
306 static inline bool testContentRectOccluded(const IntRect& contentRect, const Web TransformationMatrix& contentSpaceTransform, const IntRect& clipRectInTarget, co nst Region& occlusion) 306 static inline bool testContentRectOccluded(const IntRect& contentRect, const Web TransformationMatrix& contentSpaceTransform, const IntRect& clipRectInTarget, co nst Region& occlusion)
307 { 307 {
308 FloatRect transformedRect = CCMathUtil::mapClippedRect(contentSpaceTransform , FloatRect(contentRect)); 308 FloatRect transformedRect = MathUtil::mapClippedRect(contentSpaceTransform, FloatRect(contentRect));
309 // Take the enclosingIntRect, as we want to include partial pixels in the te st. 309 // Take the enclosingIntRect, as we want to include partial pixels in the te st.
310 IntRect targetRect = intersection(enclosingIntRect(transformedRect), clipRec tInTarget); 310 IntRect targetRect = intersection(enclosingIntRect(transformedRect), clipRec tInTarget);
311 return targetRect.isEmpty() || occlusion.contains(targetRect); 311 return targetRect.isEmpty() || occlusion.contains(targetRect);
312 } 312 }
313 313
314 template<typename LayerType, typename RenderSurfaceType> 314 template<typename LayerType, typename RenderSurfaceType>
315 bool CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerT ype* layer, const IntRect& contentRect, bool* hasOcclusionFromOutsideTargetSurfa ce) const 315 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerTyp e* layer, const IntRect& contentRect, bool* hasOcclusionFromOutsideTargetSurface ) const
316 { 316 {
317 if (hasOcclusionFromOutsideTargetSurface) 317 if (hasOcclusionFromOutsideTargetSurface)
318 *hasOcclusionFromOutsideTargetSurface = false; 318 *hasOcclusionFromOutsideTargetSurface = false;
319 319
320 ASSERT(!m_stack.isEmpty()); 320 ASSERT(!m_stack.isEmpty());
321 if (m_stack.isEmpty()) 321 if (m_stack.isEmpty())
322 return false; 322 return false;
323 if (contentRect.isEmpty()) 323 if (contentRect.isEmpty())
324 return true; 324 return true;
325 325
(...skipping 19 matching lines...) Expand all
345 rectRegion.subtract(region); 345 rectRegion.subtract(region);
346 return rectRegion.bounds(); 346 return rectRegion.bounds();
347 } 347 }
348 348
349 static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, c onst WebTransformationMatrix& contentSpaceTransform, const IntRect& clipRectInTa rget, const Region& occlusion) 349 static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, c onst WebTransformationMatrix& contentSpaceTransform, const IntRect& clipRectInTa rget, const Region& occlusion)
350 { 350 {
351 if (!contentSpaceTransform.isInvertible()) 351 if (!contentSpaceTransform.isInvertible())
352 return contentRect; 352 return contentRect;
353 353
354 // Take the enclosingIntRect at each step, as we want to contain any unocclu ded partial pixels in the resulting IntRect. 354 // Take the enclosingIntRect at each step, as we want to contain any unocclu ded partial pixels in the resulting IntRect.
355 FloatRect transformedRect = CCMathUtil::mapClippedRect(contentSpaceTransform , FloatRect(contentRect)); 355 FloatRect transformedRect = MathUtil::mapClippedRect(contentSpaceTransform, FloatRect(contentRect));
356 IntRect shrunkRect = rectSubtractRegion(intersection(enclosingIntRect(transf ormedRect), clipRectInTarget), occlusion); 356 IntRect shrunkRect = rectSubtractRegion(intersection(enclosingIntRect(transf ormedRect), clipRectInTarget), occlusion);
357 IntRect unoccludedRect = enclosingIntRect(CCMathUtil::projectClippedRect(con tentSpaceTransform.inverse(), FloatRect(shrunkRect))); 357 IntRect unoccludedRect = enclosingIntRect(MathUtil::projectClippedRect(conte ntSpaceTransform.inverse(), FloatRect(shrunkRect)));
358 // 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. 358 // 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.
359 return intersection(unoccludedRect, contentRect); 359 return intersection(unoccludedRect, contentRect);
360 } 360 }
361 361
362 template<typename LayerType, typename RenderSurfaceType> 362 template<typename LayerType, typename RenderSurfaceType>
363 IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR ect(const LayerType* layer, const IntRect& contentRect, bool* hasOcclusionFromOu tsideTargetSurface) const 363 IntRect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentRec t(const LayerType* layer, const IntRect& contentRect, bool* hasOcclusionFromOuts ideTargetSurface) const
364 { 364 {
365 ASSERT(!m_stack.isEmpty()); 365 ASSERT(!m_stack.isEmpty());
366 if (m_stack.isEmpty()) 366 if (m_stack.isEmpty())
367 return contentRect; 367 return contentRect;
368 if (contentRect.isEmpty()) 368 if (contentRect.isEmpty())
369 return contentRect; 369 return contentRect;
370 370
371 ASSERT(layer->renderTarget() == m_stack.last().target); 371 ASSERT(layer->renderTarget() == m_stack.last().target);
372 372
373 // We want to return a rect that contains all the visible parts of |contentR ect| in both screen space and in the target surface. 373 // We want to return a rect that contains all the visible parts of |contentR ect| in both screen space and in the target surface.
374 // So we find the visible parts of |contentRect| in each space, and take the intersection. 374 // So we find the visible parts of |contentRect| in each space, and take the intersection.
375 375
376 IntRect unoccludedInScreen = contentRect; 376 IntRect unoccludedInScreen = contentRect;
377 if (layerTransformsToScreenKnown(layer)) 377 if (layerTransformsToScreenKnown(layer))
378 unoccludedInScreen = computeUnoccludedContentRect(contentRect, layer->sc reenSpaceTransform(), m_rootTargetRect, m_stack.last().occlusionInScreen); 378 unoccludedInScreen = computeUnoccludedContentRect(contentRect, layer->sc reenSpaceTransform(), m_rootTargetRect, m_stack.last().occlusionInScreen);
379 379
380 IntRect unoccludedInTarget = contentRect; 380 IntRect unoccludedInTarget = contentRect;
381 if (layerTransformsToTargetKnown(layer)) 381 if (layerTransformsToTargetKnown(layer))
382 unoccludedInTarget = computeUnoccludedContentRect(contentRect, layer->dr awTransform(), layerClipRectInTarget(layer), m_stack.last().occlusionInTarget); 382 unoccludedInTarget = computeUnoccludedContentRect(contentRect, layer->dr awTransform(), layerClipRectInTarget(layer), m_stack.last().occlusionInTarget);
383 383
384 if (hasOcclusionFromOutsideTargetSurface) 384 if (hasOcclusionFromOutsideTargetSurface)
385 *hasOcclusionFromOutsideTargetSurface = (intersection(unoccludedInScreen , unoccludedInTarget) != unoccludedInTarget); 385 *hasOcclusionFromOutsideTargetSurface = (intersection(unoccludedInScreen , unoccludedInTarget) != unoccludedInTarget);
386 386
387 return intersection(unoccludedInScreen, unoccludedInTarget); 387 return intersection(unoccludedInScreen, unoccludedInTarget);
388 } 388 }
389 389
390 template<typename LayerType, typename RenderSurfaceType> 390 template<typename LayerType, typename RenderSurfaceType>
391 IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContribu tingSurfaceContentRect(const LayerType* layer, bool forReplica, const IntRect& c ontentRect, bool* hasOcclusionFromOutsideTargetSurface) const 391 IntRect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContributi ngSurfaceContentRect(const LayerType* layer, bool forReplica, const IntRect& con tentRect, bool* hasOcclusionFromOutsideTargetSurface) const
392 { 392 {
393 ASSERT(!m_stack.isEmpty()); 393 ASSERT(!m_stack.isEmpty());
394 // The layer is a contributing renderTarget so it should have a surface. 394 // The layer is a contributing renderTarget so it should have a surface.
395 ASSERT(layer->renderSurface()); 395 ASSERT(layer->renderSurface());
396 // The layer is a contributing renderTarget so its target should be itself. 396 // The layer is a contributing renderTarget so its target should be itself.
397 ASSERT(layer->renderTarget() == layer); 397 ASSERT(layer->renderTarget() == layer);
398 // The layer should not be the root, else what is is contributing to? 398 // The layer should not be the root, else what is is contributing to?
399 ASSERT(layer->parent()); 399 ASSERT(layer->parent());
400 // This should be called while the layer is still considered the current tar get in the occlusion tracker. 400 // This should be called while the layer is still considered the current tar get in the occlusion tracker.
401 ASSERT(layer == m_stack.last().target); 401 ASSERT(layer == m_stack.last().target);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 unoccludedInTarget = computeUnoccludedContentRect(contentRect, trans formToTarget, surfaceClipRect, Region()); 436 unoccludedInTarget = computeUnoccludedContentRect(contentRect, trans formToTarget, surfaceClipRect, Region());
437 } 437 }
438 438
439 if (hasOcclusionFromOutsideTargetSurface) 439 if (hasOcclusionFromOutsideTargetSurface)
440 *hasOcclusionFromOutsideTargetSurface = (intersection(unoccludedInScreen , unoccludedInTarget) != unoccludedInTarget); 440 *hasOcclusionFromOutsideTargetSurface = (intersection(unoccludedInScreen , unoccludedInTarget) != unoccludedInTarget);
441 441
442 return intersection(unoccludedInScreen, unoccludedInTarget); 442 return intersection(unoccludedInScreen, unoccludedInTarget);
443 } 443 }
444 444
445 template<typename LayerType, typename RenderSurfaceType> 445 template<typename LayerType, typename RenderSurfaceType>
446 IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerClipRectInTar get(const LayerType* layer) const 446 IntRect OcclusionTrackerBase<LayerType, RenderSurfaceType>::layerClipRectInTarge t(const LayerType* layer) const
447 { 447 {
448 // FIXME: we could remove this helper function, but unit tests currently ove rride this 448 // FIXME: we could remove this helper function, but unit tests currently ove rride this
449 // function, and they need to be verified/adjusted before this can be removed. 449 // function, and they need to be verified/adjusted before this can be removed.
450 return layer->drawableContentRect(); 450 return layer->drawableContentRect();
451 } 451 }
452 452
453 // Declare the possible functions here for the linker. 453 // Declare the possible functions here for the linker.
454 template CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::CCOcclusi onTrackerBase(IntRect rootTargetRect, bool recordMetricsForFrame); 454 template OcclusionTrackerBase<Layer, RenderSurface>::OcclusionTrackerBase(IntRec t rootTargetRect, bool recordMetricsForFrame);
455 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::ente rLayer(const CCLayerIteratorPosition<LayerChromium>&); 455 template void OcclusionTrackerBase<Layer, RenderSurface>::enterLayer(const Layer IteratorPosition<Layer>&);
456 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::leav eLayer(const CCLayerIteratorPosition<LayerChromium>&); 456 template void OcclusionTrackerBase<Layer, RenderSurface>::leaveLayer(const Layer IteratorPosition<Layer>&);
457 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::ente rRenderTarget(const LayerChromium* newTarget); 457 template void OcclusionTrackerBase<Layer, RenderSurface>::enterRenderTarget(cons t Layer* newTarget);
458 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::fini shedRenderTarget(const LayerChromium* finishedTarget); 458 template void OcclusionTrackerBase<Layer, RenderSurface>::finishedRenderTarget(c onst Layer* finishedTarget);
459 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::leav eToRenderTarget(const LayerChromium* newTarget); 459 template void OcclusionTrackerBase<Layer, RenderSurface>::leaveToRenderTarget(co nst Layer* newTarget);
460 template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::mark OccludedBehindLayer(const LayerChromium*); 460 template void OcclusionTrackerBase<Layer, RenderSurface>::markOccludedBehindLaye r(const Layer*);
461 template bool CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::occl uded(const LayerChromium*, const IntRect& contentRect, bool* hasOcclusionFromOut sideTargetSurface) const; 461 template bool OcclusionTrackerBase<Layer, RenderSurface>::occluded(const Layer*, const IntRect& contentRect, bool* hasOcclusionFromOutsideTargetSurface) const;
462 template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::u noccludedContentRect(const LayerChromium*, const IntRect& contentRect, bool* has OcclusionFromOutsideTargetSurface) const; 462 template IntRect OcclusionTrackerBase<Layer, RenderSurface>::unoccludedContentRe ct(const Layer*, const IntRect& contentRect, bool* hasOcclusionFromOutsideTarget Surface) const;
463 template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::u noccludedContributingSurfaceContentRect(const LayerChromium*, bool forReplica, c onst IntRect& contentRect, bool* hasOcclusionFromOutsideTargetSurface) const; 463 template IntRect OcclusionTrackerBase<Layer, RenderSurface>::unoccludedContribut ingSurfaceContentRect(const Layer*, bool forReplica, const IntRect& contentRect, bool* hasOcclusionFromOutsideTargetSurface) const;
464 template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::l ayerClipRectInTarget(const LayerChromium*) const; 464 template IntRect OcclusionTrackerBase<Layer, RenderSurface>::layerClipRectInTarg et(const Layer*) const;
465 465
466 template CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::CCOcclusionTracke rBase(IntRect rootTargetRect, bool recordMetricsForFrame); 466 template OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::OcclusionTrackerBas e(IntRect rootTargetRect, bool recordMetricsForFrame);
467 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::enterLayer(c onst CCLayerIteratorPosition<CCLayerImpl>&); 467 template void OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::enterLayer(con st LayerIteratorPosition<LayerImpl>&);
468 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::leaveLayer(c onst CCLayerIteratorPosition<CCLayerImpl>&); 468 template void OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::leaveLayer(con st LayerIteratorPosition<LayerImpl>&);
469 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::enterRenderT arget(const CCLayerImpl* newTarget); 469 template void OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::enterRenderTar get(const LayerImpl* newTarget);
470 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::finishedRend erTarget(const CCLayerImpl* finishedTarget); 470 template void OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::finishedRender Target(const LayerImpl* finishedTarget);
471 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::leaveToRende rTarget(const CCLayerImpl* newTarget); 471 template void OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::leaveToRenderT arget(const LayerImpl* newTarget);
472 template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::markOccluded BehindLayer(const CCLayerImpl*); 472 template void OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::markOccludedBe hindLayer(const LayerImpl*);
473 template bool CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::occluded(con st CCLayerImpl*, const IntRect& contentRect, bool* hasOcclusionFromOutsideTarget Surface) const; 473 template bool OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::occluded(const LayerImpl*, const IntRect& contentRect, bool* hasOcclusionFromOutsideTargetSurf ace) const;
474 template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unocclude dContentRect(const CCLayerImpl*, const IntRect& contentRect, bool* hasOcclusionF romOutsideTargetSurface) const; 474 template IntRect OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::unoccludedC ontentRect(const LayerImpl*, const IntRect& contentRect, bool* hasOcclusionFromO utsideTargetSurface) const;
475 template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unocclude dContributingSurfaceContentRect(const CCLayerImpl*, bool forReplica, const IntRe ct& contentRect, bool* hasOcclusionFromOutsideTargetSurface) const; 475 template IntRect OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::unoccludedC ontributingSurfaceContentRect(const LayerImpl*, bool forReplica, const IntRect& contentRect, bool* hasOcclusionFromOutsideTargetSurface) const;
476 template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::layerClip RectInTarget(const CCLayerImpl*) const; 476 template IntRect OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>::layerClipRe ctInTarget(const LayerImpl*) const;
477 477
478 478
479 } // namespace cc 479 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698