Chromium Code Reviews| 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 |