OLD | NEW |
---|---|
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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 "cc/tiled_layer.h" | 7 #include "cc/tiled_layer.h" |
8 | 8 |
9 #include "CCLayerImpl.h" | 9 #include "CCLayerImpl.h" |
10 #include "CCLayerTreeHost.h" | 10 #include "CCLayerTreeHost.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 validForFrame = true; | 51 validForFrame = true; |
52 updateRect = dirtyRect; | 52 updateRect = dirtyRect; |
53 dirtyRect = IntRect(); | 53 dirtyRect = IntRect(); |
54 } | 54 } |
55 | 55 |
56 IntRect dirtyRect; | 56 IntRect dirtyRect; |
57 IntRect updateRect; | 57 IntRect updateRect; |
58 bool partialUpdate; | 58 bool partialUpdate; |
59 bool validForFrame; | 59 bool validForFrame; |
60 bool occluded; | 60 bool occluded; |
61 bool isInUseOnImpl; | |
62 | 61 |
63 private: | 62 private: |
64 explicit UpdatableTile(scoped_ptr<LayerTextureUpdater::Texture> texture) | 63 explicit UpdatableTile(scoped_ptr<LayerTextureUpdater::Texture> texture) |
65 : partialUpdate(false) | 64 : partialUpdate(false) |
66 , validForFrame(false) | 65 , validForFrame(false) |
67 , occluded(false) | 66 , occluded(false) |
68 , isInUseOnImpl(false) | |
69 , m_texture(texture.Pass()) | 67 , m_texture(texture.Pass()) |
70 { | 68 { |
71 } | 69 } |
72 | 70 |
73 scoped_ptr<LayerTextureUpdater::Texture> m_texture; | 71 scoped_ptr<LayerTextureUpdater::Texture> m_texture; |
74 | 72 |
75 DISALLOW_COPY_AND_ASSIGN(UpdatableTile); | 73 DISALLOW_COPY_AND_ASSIGN(UpdatableTile); |
76 }; | 74 }; |
77 | 75 |
78 TiledLayerChromium::TiledLayerChromium() | 76 TiledLayerChromium::TiledLayerChromium() |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 Vector<UpdatableTile*> invalidTiles; | 199 Vector<UpdatableTile*> invalidTiles; |
202 | 200 |
203 for (CCLayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begi n(); iter != m_tiler->tiles().end(); ++iter) { | 201 for (CCLayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begi n(); iter != m_tiler->tiles().end(); ++iter) { |
204 int i = iter->first.first; | 202 int i = iter->first.first; |
205 int j = iter->first.second; | 203 int j = iter->first.second; |
206 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); | 204 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); |
207 // FIXME: This should not ever be null. | 205 // FIXME: This should not ever be null. |
208 if (!tile) | 206 if (!tile) |
209 continue; | 207 continue; |
210 | 208 |
211 tile->isInUseOnImpl = false; | |
212 | |
213 if (!tile->managedTexture()->haveBackingTexture()) { | 209 if (!tile->managedTexture()->haveBackingTexture()) { |
214 // Evicted tiles get deleted from both layers | 210 // Evicted tiles get deleted from both layers |
215 invalidTiles.append(tile); | 211 invalidTiles.append(tile); |
216 continue; | 212 continue; |
217 } | 213 } |
218 | 214 |
219 if (!tile->validForFrame) { | 215 if (!tile->validForFrame) { |
220 // Invalidated tiles are set so they can get different debug colors. | 216 // Invalidated tiles are set so they can get different debug colors. |
221 tiledLayer->pushInvalidTile(i, j); | 217 tiledLayer->pushInvalidTile(i, j); |
222 continue; | 218 continue; |
223 } | 219 } |
224 | 220 |
225 tiledLayer->pushTileProperties(i, j, tile->managedTexture()->resourceId( ), tile->opaqueRect()); | 221 tiledLayer->pushTileProperties(i, j, tile->managedTexture()->resourceId( ), tile->opaqueRect()); |
226 tile->isInUseOnImpl = true; | |
227 } | 222 } |
228 for (Vector<UpdatableTile*>::const_iterator iter = invalidTiles.begin(); ite r != invalidTiles.end(); ++iter) | 223 for (Vector<UpdatableTile*>::const_iterator iter = invalidTiles.begin(); ite r != invalidTiles.end(); ++iter) |
229 m_tiler->takeTile((*iter)->i(), (*iter)->j()); | 224 m_tiler->takeTile((*iter)->i(), (*iter)->j()); |
230 } | 225 } |
231 | 226 |
232 CCPrioritizedTextureManager* TiledLayerChromium::textureManager() const | 227 CCPrioritizedTextureManager* TiledLayerChromium::textureManager() const |
233 { | 228 { |
234 if (!layerTreeHost()) | 229 if (!layerTreeHost()) |
235 return 0; | 230 return 0; |
236 return layerTreeHost()->contentsTextureManager(); | 231 return layerTreeHost()->contentsTextureManager(); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 // Dirty tiles with valid textures needs buffered update to guarantee that | 323 // Dirty tiles with valid textures needs buffered update to guarantee that |
329 // we don't modify textures currently used for drawing by the impl thread. | 324 // we don't modify textures currently used for drawing by the impl thread. |
330 bool TiledLayerChromium::tileNeedsBufferedUpdate(UpdatableTile* tile) | 325 bool TiledLayerChromium::tileNeedsBufferedUpdate(UpdatableTile* tile) |
331 { | 326 { |
332 if (!tile->managedTexture()->haveBackingTexture()) | 327 if (!tile->managedTexture()->haveBackingTexture()) |
333 return false; | 328 return false; |
334 | 329 |
335 if (!tile->isDirty()) | 330 if (!tile->isDirty()) |
336 return false; | 331 return false; |
337 | 332 |
338 if (!tile->isInUseOnImpl) | |
339 return false; | |
340 | |
341 return true; | 333 return true; |
342 } | 334 } |
343 | 335 |
344 | |
345 bool TiledLayerChromium::updateTiles(int left, int top, int right, int bottom, C CTextureUpdateQueue& queue, const CCOcclusionTracker* occlusion, CCRenderingStat s& stats, bool& didPaint) | 336 bool TiledLayerChromium::updateTiles(int left, int top, int right, int bottom, C CTextureUpdateQueue& queue, const CCOcclusionTracker* occlusion, CCRenderingStat s& stats, bool& didPaint) |
346 { | 337 { |
347 didPaint = false; | 338 didPaint = false; |
348 createTextureUpdaterIfNeeded(); | 339 createTextureUpdaterIfNeeded(); |
349 | 340 |
350 bool ignoreOcclusions = !occlusion; | 341 bool ignoreOcclusions = !occlusion; |
351 if (!haveTexturesForTiles(left, top, right, bottom, ignoreOcclusions)) { | 342 if (!haveTexturesForTiles(left, top, right, bottom, ignoreOcclusions)) { |
352 m_failedUpdate = true; | 343 m_failedUpdate = true; |
353 return false; | 344 return false; |
354 } | 345 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
390 occludedTileCount++; | 381 occludedTileCount++; |
391 } else { | 382 } else { |
392 succeeded &= tile->managedTexture()->requestLate(); | 383 succeeded &= tile->managedTexture()->requestLate(); |
393 } | 384 } |
394 } | 385 } |
395 } | 386 } |
396 | 387 |
397 if (!succeeded) | 388 if (!succeeded) |
398 return; | 389 return; |
399 | 390 |
400 // FIXME: Remove the loop and just pass the count! | 391 occlusion->overdrawMetrics().didCullTilesForUpload(occludedTileCount); |
danakj
2012/10/18 03:03:42
Nice, thanks for this :)
| |
401 for (int i = 0; i < occludedTileCount; i++) | |
402 occlusion->overdrawMetrics().didCullTileForUpload(); | |
403 } | 392 } |
404 | 393 |
405 bool TiledLayerChromium::haveTexturesForTiles(int left, int top, int right, int bottom, bool ignoreOcclusions) | 394 bool TiledLayerChromium::haveTexturesForTiles(int left, int top, int right, int bottom, bool ignoreOcclusions) const |
406 { | 395 { |
407 for (int j = top; j <= bottom; ++j) { | 396 for (int j = top; j <= bottom; ++j) { |
408 for (int i = left; i <= right; ++i) { | 397 for (int i = left; i <= right; ++i) { |
409 UpdatableTile* tile = tileAt(i, j); | 398 UpdatableTile* tile = tileAt(i, j); |
410 ASSERT(tile); // Did setTexturePriorites get skipped? | 399 ASSERT(tile); // Did setTexturePriorites get skipped? |
411 // FIXME: This should not ever be null. | 400 // FIXME: This should not ever be null. |
412 if (!tile) | 401 if (!tile) |
413 continue; | 402 continue; |
414 | 403 |
415 // Ensure the entire tile is dirty if we don't have the texture. | |
416 if (!tile->managedTexture()->haveBackingTexture()) | |
417 tile->dirtyRect = m_tiler->tileRect(tile); | |
418 | |
419 // If using occlusion and the visible region of the tile is occluded , | 404 // If using occlusion and the visible region of the tile is occluded , |
420 // don't reserve a texture or update the tile. | 405 // don't reserve a texture or update the tile. |
421 if (tile->occluded && !ignoreOcclusions) | 406 if (tile->occluded && !ignoreOcclusions) |
422 continue; | 407 continue; |
423 | 408 |
424 if (!tile->managedTexture()->canAcquireBackingTexture()) | 409 if (!tile->managedTexture()->canAcquireBackingTexture()) |
425 return false; | 410 return false; |
426 } | 411 } |
427 } | 412 } |
428 return true; | 413 return true; |
429 } | 414 } |
430 | 415 |
431 IntRect TiledLayerChromium::markTilesForUpdate(int left, int top, int right, int bottom, bool ignoreOcclusions) | 416 IntRect TiledLayerChromium::markTilesForUpdate(int left, int top, int right, int bottom, bool ignoreOcclusions) |
432 { | 417 { |
433 IntRect paintRect; | 418 IntRect paintRect; |
434 for (int j = top; j <= bottom; ++j) { | 419 for (int j = top; j <= bottom; ++j) { |
435 for (int i = left; i <= right; ++i) { | 420 for (int i = left; i <= right; ++i) { |
436 UpdatableTile* tile = tileAt(i, j); | 421 UpdatableTile* tile = tileAt(i, j); |
437 ASSERT(tile); // Did setTexturePriorites get skipped? | 422 ASSERT(tile); // Did setTexturePriorites get skipped? |
438 // FIXME: This should not ever be null. | 423 // FIXME: This should not ever be null. |
439 if (!tile) | 424 if (!tile) |
440 continue; | 425 continue; |
441 if (tile->occluded && !ignoreOcclusions) | 426 if (tile->occluded && !ignoreOcclusions) |
442 continue; | 427 continue; |
428 // FIXME: Decide if partial update should be allowed based on cost | |
429 // of update. https://bugs.webkit.org/show_bug.cgi?id=77376 | |
430 if (layerTreeHost() && layerTreeHost()->bufferedUpdates() && tileNee dsBufferedUpdate(tile)) { | |
431 // If we get a partial update, we use the same texture, otherwis e return the | |
432 // current texture backing, so we don't update visible textures non-atomically. | |
433 // If the current backing is in-use, it won't be deleted until a fter the commit | |
434 // as the texture manager will not allow deletion or recycling o f in-use textures. | |
435 if (tileOnlyNeedsPartialUpdate(tile) && layerTreeHost()->request PartialTextureUpdate()) | |
436 tile->partialUpdate = true; | |
437 else | |
438 tile->managedTexture()->returnBackingTexture(); | |
439 } | |
440 // Ensure the entire tile is dirty if we don't have the texture. | |
441 if (!tile->managedTexture()->haveBackingTexture()) | |
442 tile->dirtyRect = m_tiler->tileRect(tile); | |
443 | |
443 paintRect.unite(tile->dirtyRect); | 444 paintRect.unite(tile->dirtyRect); |
444 tile->markForUpdate(); | 445 tile->markForUpdate(); |
445 } | 446 } |
446 } | 447 } |
447 return paintRect; | 448 return paintRect; |
448 } | 449 } |
449 | 450 |
450 void TiledLayerChromium::updateTileTextures(const IntRect& paintRect, int left, int top, int right, int bottom, CCTextureUpdateQueue& queue, const CCOcclusionTr acker* occlusion, CCRenderingStats& stats) | 451 void TiledLayerChromium::updateTileTextures(const IntRect& paintRect, int left, int top, int right, int bottom, CCTextureUpdateQueue& queue, const CCOcclusionTr acker* occlusion, CCRenderingStats& stats) |
451 { | 452 { |
452 // The updateRect should be in layer space. So we have to convert the paintR ect from content space to layer space. | 453 // The updateRect should be in layer space. So we have to convert the paintR ect from content space to layer space. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
570 resetUpdateState(); | 571 resetUpdateState(); |
571 | 572 |
572 if (m_tiler->hasEmptyBounds()) | 573 if (m_tiler->hasEmptyBounds()) |
573 return; | 574 return; |
574 | 575 |
575 bool drawsToRoot = !renderTarget()->parent(); | 576 bool drawsToRoot = !renderTarget()->parent(); |
576 bool smallAnimatedLayer = isSmallAnimatedLayer(this); | 577 bool smallAnimatedLayer = isSmallAnimatedLayer(this); |
577 | 578 |
578 // Minimally create the tiles in the desired pre-paint rect. | 579 // Minimally create the tiles in the desired pre-paint rect. |
579 IntRect createTilesRect = idlePaintRect(); | 580 IntRect createTilesRect = idlePaintRect(); |
581 if (smallAnimatedLayer) | |
582 createTilesRect = IntRect(IntPoint::zero(), contentBounds()); | |
580 if (!createTilesRect.isEmpty()) { | 583 if (!createTilesRect.isEmpty()) { |
581 int left, top, right, bottom; | 584 int left, top, right, bottom; |
582 m_tiler->contentRectToTileIndices(createTilesRect, left, top, right, bot tom); | 585 m_tiler->contentRectToTileIndices(createTilesRect, left, top, right, bot tom); |
583 for (int j = top; j <= bottom; ++j) { | 586 for (int j = top; j <= bottom; ++j) { |
584 for (int i = left; i <= right; ++i) { | 587 for (int i = left; i <= right; ++i) { |
585 if (!tileAt(i, j)) | 588 if (!tileAt(i, j)) |
586 createTile(i, j); | 589 createTile(i, j); |
587 } | 590 } |
588 } | 591 } |
589 } | 592 } |
590 | 593 |
591 // Also, minimally create all tiles for small animated layers and also | |
592 // double-buffer them since we have limited their size to be reasonable. | |
593 IntRect doubleBufferedRect = visibleContentRect(); | |
594 if (smallAnimatedLayer) | |
595 doubleBufferedRect = IntRect(IntPoint::zero(), contentBounds()); | |
596 | |
597 // Create additional textures for double-buffered updates when needed. | |
598 // These textures must stay alive while the updated textures are incremental ly | |
599 // uploaded, swapped atomically via pushProperties, and finally deleted | |
600 // after the commit is complete, after which they can be recycled. | |
601 if (!doubleBufferedRect.isEmpty()) { | |
602 int left, top, right, bottom; | |
603 m_tiler->contentRectToTileIndices(doubleBufferedRect, left, top, right, bottom); | |
604 for (int j = top; j <= bottom; ++j) { | |
605 for (int i = left; i <= right; ++i) { | |
606 UpdatableTile* tile = tileAt(i, j); | |
607 if (!tile) | |
608 tile = createTile(i, j); | |
609 // We need an additional texture if the tile needs a buffered-up date and it's not a partial update. | |
610 // FIXME: Decide if partial update should be allowed based on co st | |
611 // of update. https://bugs.webkit.org/show_bug.cgi?id=77376 | |
612 if (!layerTreeHost() || !layerTreeHost()->bufferedUpdates() || ! tileNeedsBufferedUpdate(tile)) | |
613 continue; | |
614 if (tileOnlyNeedsPartialUpdate(tile) && layerTreeHost()->request PartialTextureUpdate()) { | |
615 tile->partialUpdate = true; | |
616 continue; | |
617 } | |
618 | |
619 IntRect tileRect = m_tiler->tileRect(tile); | |
620 tile->dirtyRect = tileRect; | |
621 LayerTextureUpdater::Texture* backBuffer = tile->texture(); | |
622 setPriorityForTexture(visibleContentRect(), tile->dirtyRect, dra wsToRoot, smallAnimatedLayer, backBuffer->texture()); | |
623 scoped_ptr<CCPrioritizedTexture> frontBuffer = CCPrioritizedText ure::create(backBuffer->texture()->textureManager(), | |
624 backBuffer->texture()->size(), | |
625 backBuffer->texture()->format()); | |
626 // Swap backBuffer into frontBuffer and add it to delete after c ommit queue. | |
627 backBuffer->swapTextureWith(frontBuffer); | |
628 layerTreeHost()->deleteTextureAfterCommit(frontBuffer.Pass()); | |
629 } | |
630 } | |
631 } | |
632 | |
633 // Now update priorities on all tiles we have in the layer, no matter where they are. | 594 // Now update priorities on all tiles we have in the layer, no matter where they are. |
634 for (CCLayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begi n(); iter != m_tiler->tiles().end(); ++iter) { | 595 for (CCLayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begi n(); iter != m_tiler->tiles().end(); ++iter) { |
635 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); | 596 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); |
636 // FIXME: This should not ever be null. | 597 // FIXME: This should not ever be null. |
637 if (!tile) | 598 if (!tile) |
638 continue; | 599 continue; |
639 IntRect tileRect = m_tiler->tileRect(tile); | 600 IntRect tileRect = m_tiler->tileRect(tile); |
640 setPriorityForTexture(visibleContentRect(), tileRect, drawsToRoot, small AnimatedLayer, tile->managedTexture()); | 601 setPriorityForTexture(visibleContentRect(), tileRect, drawsToRoot, small AnimatedLayer, tile->managedTexture()); |
641 } | 602 } |
642 } | 603 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
779 IntRect prepaintRect = visibleContentRect(); | 740 IntRect prepaintRect = visibleContentRect(); |
780 prepaintRect.inflateX(m_tiler->tileSize().width()); | 741 prepaintRect.inflateX(m_tiler->tileSize().width()); |
781 prepaintRect.inflateY(m_tiler->tileSize().height() * 2); | 742 prepaintRect.inflateY(m_tiler->tileSize().height() * 2); |
782 IntRect contentRect(IntPoint::zero(), contentBounds()); | 743 IntRect contentRect(IntPoint::zero(), contentBounds()); |
783 prepaintRect.intersect(contentRect); | 744 prepaintRect.intersect(contentRect); |
784 | 745 |
785 return prepaintRect; | 746 return prepaintRect; |
786 } | 747 } |
787 | 748 |
788 } | 749 } |
OLD | NEW |