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

Side by Side Diff: cc/occlusion_tracker.cc

Issue 11308153: Migrate most of cc/ from WebKit::WebTransformationMatrix to gfx::Transform (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased to tip of tree and addressed feedback Created 8 years, 1 month 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 "cc/occlusion_tracker.h" 5 #include "cc/occlusion_tracker.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "cc/layer.h" 9 #include "cc/layer.h"
10 #include "cc/layer_impl.h" 10 #include "cc/layer_impl.h"
11 #include "cc/math_util.h" 11 #include "cc/math_util.h"
12 #include "cc/overdraw_metrics.h" 12 #include "cc/overdraw_metrics.h"
13 #include "ui/gfx/quad_f.h" 13 #include "ui/gfx/quad_f.h"
14 #include "ui/gfx/rect_conversions.h" 14 #include "ui/gfx/rect_conversions.h"
15 15
16 using namespace std; 16 using namespace std;
17 using WebKit::WebTransformationMatrix; 17 using gfx::Transform;
18 18
19 namespace cc { 19 namespace cc {
20 20
21 template<typename LayerType, typename RenderSurfaceType> 21 template<typename LayerType, typename RenderSurfaceType>
22 OcclusionTrackerBase<LayerType, RenderSurfaceType>::OcclusionTrackerBase(gfx::Re ct rootTargetRect, bool recordMetricsForFrame) 22 OcclusionTrackerBase<LayerType, RenderSurfaceType>::OcclusionTrackerBase(gfx::Re ct rootTargetRect, bool recordMetricsForFrame)
23 : m_rootTargetRect(rootTargetRect) 23 : m_rootTargetRect(rootTargetRect)
24 , m_overdrawMetrics(OverdrawMetrics::create(recordMetricsForFrame)) 24 , m_overdrawMetrics(OverdrawMetrics::create(recordMetricsForFrame))
25 , m_occludingScreenSpaceRects(0) 25 , m_occludingScreenSpaceRects(0)
26 , m_nonOccludingScreenSpaceRects(0) 26 , m_nonOccludingScreenSpaceRects(0)
27 { 27 {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 m_stack.back().occlusionInTarget.Clear(); 114 m_stack.back().occlusionInTarget.Clear();
115 } else { 115 } else {
116 if (!surfaceTransformsToTargetKnown(surface)) 116 if (!surfaceTransformsToTargetKnown(surface))
117 m_stack.back().occlusionInTarget.Clear(); 117 m_stack.back().occlusionInTarget.Clear();
118 if (!surfaceTransformsToScreenKnown(surface)) 118 if (!surfaceTransformsToScreenKnown(surface))
119 m_stack.back().occlusionInScreen.Clear(); 119 m_stack.back().occlusionInScreen.Clear();
120 } 120 }
121 } 121 }
122 122
123 template<typename RenderSurfaceType> 123 template<typename RenderSurfaceType>
124 static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surfa ce, const Region& region, const WebTransformationMatrix& transform) 124 static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surfa ce, const Region& region, const Transform& transform)
125 { 125 {
126 // Verify that rects within the |surface| will remain rects in its target su rface after applying |transform|. If this is true, then 126 // Verify that rects within the |surface| will remain rects in its target su rface after applying |transform|. If this is true, then
127 // apply |transform| to each rect within |region| in order to transform the entire Region. 127 // apply |transform| to each rect within |region| in order to transform the entire Region.
128 128
129 bool clipped; 129 bool clipped;
130 gfx::QuadF transformedBoundsQuad = MathUtil::mapQuad(transform, gfx::QuadF(r egion.bounds()), clipped); 130 gfx::QuadF transformedBoundsQuad = MathUtil::mapQuad(transform, gfx::QuadF(r egion.bounds()), clipped);
131 // FIXME: Find a rect interior to each transformed quad. 131 // FIXME: Find a rect interior to each transformed quad.
132 if (clipped || !transformedBoundsQuad.IsRectilinear()) 132 if (clipped || !transformedBoundsQuad.IsRectilinear())
133 return Region(); 133 return Region();
134 134
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 int shrinkRight = occlusionRect.right() == affectedArea.right() ? 0 : -e xpandedPixel.x(); 175 int shrinkRight = occlusionRect.right() == affectedArea.right() ? 0 : -e xpandedPixel.x();
176 int shrinkBottom = occlusionRect.bottom() == affectedArea.bottom() ? 0 : -expandedPixel.y(); 176 int shrinkBottom = occlusionRect.bottom() == affectedArea.bottom() ? 0 : -expandedPixel.y();
177 177
178 occlusionRect.Inset(shrinkLeft, shrinkTop, shrinkRight, shrinkBottom); 178 occlusionRect.Inset(shrinkLeft, shrinkTop, shrinkRight, shrinkBottom);
179 179
180 occlusion.Union(occlusionRect); 180 occlusion.Union(occlusionRect);
181 } 181 }
182 } 182 }
183 183
184 template<typename LayerType> 184 template<typename LayerType>
185 static void reduceOcclusionBelowSurface(LayerType* contributingLayer, const gfx: :Rect& surfaceRect, const WebTransformationMatrix& surfaceTransform, LayerType* renderTarget, Region& occlusionInTarget, Region& occlusionInScreen) 185 static void reduceOcclusionBelowSurface(LayerType* contributingLayer, const gfx: :Rect& surfaceRect, const Transform& surfaceTransform, LayerType* renderTarget, Region& occlusionInTarget, Region& occlusionInScreen)
186 { 186 {
187 if (surfaceRect.IsEmpty()) 187 if (surfaceRect.IsEmpty())
188 return; 188 return;
189 189
190 gfx::Rect boundsInTarget = gfx::ToEnclosingRect(MathUtil::mapClippedRect(sur faceTransform, gfx::RectF(surfaceRect))); 190 gfx::Rect boundsInTarget = gfx::ToEnclosingRect(MathUtil::mapClippedRect(sur faceTransform, gfx::RectF(surfaceRect)));
191 if (!contributingLayer->renderSurface()->clipRect().IsEmpty()) 191 if (!contributingLayer->renderSurface()->clipRect().IsEmpty())
192 boundsInTarget.Intersect(contributingLayer->renderSurface()->clipRect()) ; 192 boundsInTarget.Intersect(contributingLayer->renderSurface()->clipRect()) ;
193 193
194 int outsetTop, outsetRight, outsetBottom, outsetLeft; 194 int outsetTop, outsetRight, outsetBottom, outsetLeft;
195 contributingLayer->backgroundFilters().getOutsets(outsetTop, outsetRight, ou tsetBottom, outsetLeft); 195 contributingLayer->backgroundFilters().getOutsets(outsetTop, outsetRight, ou tsetBottom, outsetLeft);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 242
243 if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) { 243 if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) {
244 reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface ->drawTransform(), newTarget, m_stack.back().occlusionInTarget, m_stack.back().o cclusionInScreen); 244 reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface ->drawTransform(), newTarget, m_stack.back().occlusionInTarget, m_stack.back().o cclusionInScreen);
245 if (oldTarget->hasReplica()) 245 if (oldTarget->hasReplica())
246 reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSur face->replicaDrawTransform(), newTarget, m_stack.back().occlusionInTarget, m_sta ck.back().occlusionInScreen); 246 reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSur face->replicaDrawTransform(), newTarget, m_stack.back().occlusionInTarget, m_sta ck.back().occlusionInScreen);
247 } 247 }
248 } 248 }
249 249
250 // FIXME: Remove usePaintTracking when paint tracking is on for paint culling. 250 // FIXME: Remove usePaintTracking when paint tracking is on for paint culling.
251 template<typename LayerType> 251 template<typename LayerType>
252 static inline void addOcclusionBehindLayer(Region& region, const LayerType* laye r, const WebTransformationMatrix& transform, const Region& opaqueContents, const gfx::Rect& clipRectInTarget, const gfx::Size& minimumTrackingSize, std::vector< gfx::Rect>* occludingScreenSpaceRects, std::vector<gfx::Rect>* nonOccludingScree nSpaceRects) 252 static inline void addOcclusionBehindLayer(Region& region, const LayerType* laye r, const Transform& transform, const Region& opaqueContents, const gfx::Rect& cl ipRectInTarget, const gfx::Size& minimumTrackingSize, std::vector<gfx::Rect>* oc cludingScreenSpaceRects, std::vector<gfx::Rect>* nonOccludingScreenSpaceRects)
253 { 253 {
254 DCHECK(layer->visibleContentRect().Contains(opaqueContents.bounds())); 254 DCHECK(layer->visibleContentRect().Contains(opaqueContents.bounds()));
255 255
256 bool clipped; 256 bool clipped;
257 gfx::QuadF visibleTransformedQuad = MathUtil::mapQuad(transform, gfx::QuadF( layer->visibleContentRect()), clipped); 257 gfx::QuadF visibleTransformedQuad = MathUtil::mapQuad(transform, gfx::QuadF( layer->visibleContentRect()), clipped);
258 // FIXME: Find a rect interior to each transformed quad. 258 // FIXME: Find a rect interior to each transformed quad.
259 if (clipped || !visibleTransformedQuad.IsRectilinear()) 259 if (clipped || !visibleTransformedQuad.IsRectilinear())
260 return; 260 return;
261 261
262 for (Region::Iterator opaqueContentRects(opaqueContents); opaqueContentRects .has_rect(); opaqueContentRects.next()) { 262 for (Region::Iterator opaqueContentRects(opaqueContents); opaqueContentRects .has_rect(); opaqueContentRects.next()) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 return; 302 return;
303 303
304 gfx::Rect clipRectInTarget = layerClipRectInTarget(layer); 304 gfx::Rect clipRectInTarget = layerClipRectInTarget(layer);
305 if (layerTransformsToTargetKnown(layer)) 305 if (layerTransformsToTargetKnown(layer))
306 addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInTarget, lay er, layer->drawTransform(), opaqueContents, clipRectInTarget, m_minimumTrackingS ize, 0, 0); 306 addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInTarget, lay er, layer->drawTransform(), opaqueContents, clipRectInTarget, m_minimumTrackingS ize, 0, 0);
307 307
308 // 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 308 // 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
309 // remain rectilinear, then we don't add any occlusion in screen space. 309 // remain rectilinear, then we don't add any occlusion in screen space.
310 310
311 if (layerTransformsToScreenKnown(layer)) { 311 if (layerTransformsToScreenKnown(layer)) {
312 WebTransformationMatrix targetToScreenTransform = m_stack.back().target- >renderSurface()->screenSpaceTransform(); 312 Transform targetToScreenTransform = m_stack.back().target->renderSurface ()->screenSpaceTransform();
313 bool clipped; 313 bool clipped;
314 gfx::QuadF clipQuadInScreen = MathUtil::mapQuad(targetToScreenTransform, gfx::QuadF(clipRectInTarget), clipped); 314 gfx::QuadF clipQuadInScreen = MathUtil::mapQuad(targetToScreenTransform, gfx::QuadF(clipRectInTarget), clipped);
315 // FIXME: Find a rect interior to the transformed clip quad. 315 // FIXME: Find a rect interior to the transformed clip quad.
316 if (clipped || !clipQuadInScreen.IsRectilinear()) 316 if (clipped || !clipQuadInScreen.IsRectilinear())
317 return; 317 return;
318 gfx::Rect clipRectInScreen = gfx::IntersectRects(m_rootTargetRect, gfx:: ToEnclosedRect(clipQuadInScreen.BoundingBox())); 318 gfx::Rect clipRectInScreen = gfx::IntersectRects(m_rootTargetRect, gfx:: ToEnclosedRect(clipQuadInScreen.BoundingBox()));
319 addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInScreen, lay er, layer->screenSpaceTransform(), opaqueContents, clipRectInScreen, m_minimumTr ackingSize, m_occludingScreenSpaceRects, m_nonOccludingScreenSpaceRects); 319 addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInScreen, lay er, layer->screenSpaceTransform(), opaqueContents, clipRectInScreen, m_minimumTr ackingSize, m_occludingScreenSpaceRects, m_nonOccludingScreenSpaceRects);
320 } 320 }
321 } 321 }
322 322
323 static inline bool testContentRectOccluded(const gfx::Rect& contentRect, const W ebTransformationMatrix& contentSpaceTransform, const gfx::Rect& clipRectInTarget , const Region& occlusion) 323 static inline bool testContentRectOccluded(const gfx::Rect& contentRect, const T ransform& contentSpaceTransform, const gfx::Rect& clipRectInTarget, const Region & occlusion)
324 { 324 {
325 gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform, gfx::RectF(contentRect)); 325 gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform, gfx::RectF(contentRect));
326 // Take the gfx::ToEnclosingRect, as we want to include partial pixels in th e test. 326 // Take the gfx::ToEnclosingRect, as we want to include partial pixels in th e test.
327 gfx::Rect targetRect = gfx::IntersectRects(gfx::ToEnclosingRect(transformedR ect), clipRectInTarget); 327 gfx::Rect targetRect = gfx::IntersectRects(gfx::ToEnclosingRect(transformedR ect), clipRectInTarget);
328 return occlusion.Contains(targetRect); 328 return occlusion.Contains(targetRect);
329 } 329 }
330 330
331 template<typename LayerType, typename RenderSurfaceType> 331 template<typename LayerType, typename RenderSurfaceType>
332 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerTyp e* renderTarget, const gfx::Rect& contentRect, const WebKit::WebTransformationMa trix& drawTransform, bool implDrawTransformIsUnknown, const gfx::Rect& clippedRe ctInTarget, bool* hasOcclusionFromOutsideTargetSurface) const 332 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerTyp e* renderTarget, const gfx::Rect& contentRect, const gfx::Transform& drawTransfo rm, bool implDrawTransformIsUnknown, const gfx::Rect& clippedRectInTarget, bool* hasOcclusionFromOutsideTargetSurface) const
333 { 333 {
334 if (hasOcclusionFromOutsideTargetSurface) 334 if (hasOcclusionFromOutsideTargetSurface)
335 *hasOcclusionFromOutsideTargetSurface = false; 335 *hasOcclusionFromOutsideTargetSurface = false;
336 336
337 DCHECK(!m_stack.empty()); 337 DCHECK(!m_stack.empty());
338 if (m_stack.empty()) 338 if (m_stack.empty())
339 return false; 339 return false;
340 if (contentRect.IsEmpty()) 340 if (contentRect.IsEmpty())
341 return true; 341 return true;
342 342
(...skipping 18 matching lines...) Expand all
361 static inline gfx::Rect rectSubtractRegion(const gfx::Rect& rect, const Region& region) 361 static inline gfx::Rect rectSubtractRegion(const gfx::Rect& rect, const Region& region)
362 { 362 {
363 if (region.IsEmpty()) 363 if (region.IsEmpty())
364 return rect; 364 return rect;
365 365
366 Region rectRegion(rect); 366 Region rectRegion(rect);
367 rectRegion.Subtract(region); 367 rectRegion.Subtract(region);
368 return rectRegion.bounds(); 368 return rectRegion.bounds();
369 } 369 }
370 370
371 static inline gfx::Rect computeUnoccludedContentRect(const gfx::Rect& contentRec t, const WebTransformationMatrix& contentSpaceTransform, const gfx::Rect& clipRe ctInTarget, const Region& occlusion) 371 static inline gfx::Rect computeUnoccludedContentRect(const gfx::Rect& contentRec t, const Transform& contentSpaceTransform, const gfx::Rect& clipRectInTarget, co nst Region& occlusion)
372 { 372 {
373 if (!contentSpaceTransform.isInvertible()) 373 if (!contentSpaceTransform.IsInvertible())
374 return contentRect; 374 return contentRect;
375 375
376 // Take the ToEnclosingRect at each step, as we want to contain any unocclud ed partial pixels in the resulting Rect. 376 // Take the ToEnclosingRect at each step, as we want to contain any unocclud ed partial pixels in the resulting Rect.
377 gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform, gfx::RectF(contentRect)); 377 gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform, gfx::RectF(contentRect));
378 gfx::Rect shrunkRect = rectSubtractRegion(gfx::IntersectRects(gfx::ToEnclosi ngRect(transformedRect), clipRectInTarget), occlusion); 378 gfx::Rect shrunkRect = rectSubtractRegion(gfx::IntersectRects(gfx::ToEnclosi ngRect(transformedRect), clipRectInTarget), occlusion);
379 gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect (contentSpaceTransform.inverse(), gfx::RectF(shrunkRect))); 379 gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect (MathUtil::inverse(contentSpaceTransform), gfx::RectF(shrunkRect)));
380 // 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. 380 // 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.
381 return gfx::IntersectRects(unoccludedRect, contentRect); 381 return gfx::IntersectRects(unoccludedRect, contentRect);
382 } 382 }
383 383
384 template<typename LayerType, typename RenderSurfaceType> 384 template<typename LayerType, typename RenderSurfaceType>
385 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR ect(const LayerType* renderTarget, const gfx::Rect& contentRect, const WebKit::W ebTransformationMatrix& drawTransform, bool implDrawTransformIsUnknown, const gf x::Rect& clippedRectInTarget, bool* hasOcclusionFromOutsideTargetSurface) const 385 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR ect(const LayerType* renderTarget, const gfx::Rect& contentRect, const gfx::Tran sform& drawTransform, bool implDrawTransformIsUnknown, const gfx::Rect& clippedR ectInTarget, bool* hasOcclusionFromOutsideTargetSurface) const
386 { 386 {
387 DCHECK(!m_stack.empty()); 387 DCHECK(!m_stack.empty());
388 if (m_stack.empty()) 388 if (m_stack.empty())
389 return contentRect; 389 return contentRect;
390 if (contentRect.IsEmpty()) 390 if (contentRect.IsEmpty())
391 return contentRect; 391 return contentRect;
392 392
393 DCHECK(renderTarget->renderTarget() == renderTarget); 393 DCHECK(renderTarget->renderTarget() == renderTarget);
394 DCHECK(renderTarget->renderSurface()); 394 DCHECK(renderTarget->renderSurface());
395 DCHECK(renderTarget == m_stack.back().target); 395 DCHECK(renderTarget == m_stack.back().target);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 gfx::Rect surfaceClipRect = surface->clipRect(); 432 gfx::Rect surfaceClipRect = surface->clipRect();
433 if (surfaceClipRect.IsEmpty()) { 433 if (surfaceClipRect.IsEmpty()) {
434 const LayerType* contributingSurfaceRenderTarget = layer->parent()->rend erTarget(); 434 const LayerType* contributingSurfaceRenderTarget = layer->parent()->rend erTarget();
435 surfaceClipRect = gfx::IntersectRects(contributingSurfaceRenderTarget->r enderSurface()->contentRect(), gfx::ToEnclosingRect(surface->drawableContentRect ())); 435 surfaceClipRect = gfx::IntersectRects(contributingSurfaceRenderTarget->r enderSurface()->contentRect(), gfx::ToEnclosingRect(surface->drawableContentRect ()));
436 } 436 }
437 437
438 // 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 438 // 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
439 // found just below the top of the stack (if it exists). 439 // found just below the top of the stack (if it exists).
440 bool hasOcclusion = m_stack.size() > 1; 440 bool hasOcclusion = m_stack.size() > 1;
441 441
442 const WebTransformationMatrix& transformToScreen = forReplica ? surface->rep licaScreenSpaceTransform() : surface->screenSpaceTransform(); 442 const Transform& transformToScreen = forReplica ? surface->replicaScreenSpac eTransform() : surface->screenSpaceTransform();
443 const WebTransformationMatrix& transformToTarget = forReplica ? surface->rep licaDrawTransform() : surface->drawTransform(); 443 const Transform& transformToTarget = forReplica ? surface->replicaDrawTransf orm() : surface->drawTransform();
444 444
445 gfx::Rect unoccludedInScreen = contentRect; 445 gfx::Rect unoccludedInScreen = contentRect;
446 if (surfaceTransformsToScreenKnown(surface)) { 446 if (surfaceTransformsToScreenKnown(surface)) {
447 if (hasOcclusion) { 447 if (hasOcclusion) {
448 const StackObject& secondLast = m_stack[m_stack.size() - 2]; 448 const StackObject& secondLast = m_stack[m_stack.size() - 2];
449 unoccludedInScreen = computeUnoccludedContentRect(contentRect, trans formToScreen, m_rootTargetRect, secondLast.occlusionInScreen); 449 unoccludedInScreen = computeUnoccludedContentRect(contentRect, trans formToScreen, m_rootTargetRect, secondLast.occlusionInScreen);
450 } else 450 } else
451 unoccludedInScreen = computeUnoccludedContentRect(contentRect, trans formToScreen, m_rootTargetRect, Region()); 451 unoccludedInScreen = computeUnoccludedContentRect(contentRect, trans formToScreen, m_rootTargetRect, Region());
452 } 452 }
453 453
(...skipping 18 matching lines...) Expand all
472 // FIXME: we could remove this helper function, but unit tests currently ove rride this 472 // FIXME: we could remove this helper function, but unit tests currently ove rride this
473 // function, and they need to be verified/adjusted before this can be removed. 473 // function, and they need to be verified/adjusted before this can be removed.
474 return layer->drawableContentRect(); 474 return layer->drawableContentRect();
475 } 475 }
476 476
477 // Instantiate (and export) templates here for the linker. 477 // Instantiate (and export) templates here for the linker.
478 template class OcclusionTrackerBase<Layer, RenderSurface>; 478 template class OcclusionTrackerBase<Layer, RenderSurface>;
479 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; 479 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>;
480 480
481 } // namespace cc 481 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698