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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
315 continue; | 310 continue; |
316 IntRect bound = m_tiler->tileRect(tile); | 311 IntRect bound = m_tiler->tileRect(tile); |
317 bound.intersect(contentRect); | 312 bound.intersect(contentRect); |
318 tile->dirtyRect.unite(bound); | 313 tile->dirtyRect.unite(bound); |
319 } | 314 } |
320 } | 315 } |
321 | 316 |
322 // Returns true if tile is dirty and only part of it needs to be updated. | 317 // Returns true if tile is dirty and only part of it needs to be updated. |
323 bool TiledLayerChromium::tileOnlyNeedsPartialUpdate(UpdatableTile* tile) | 318 bool TiledLayerChromium::tileOnlyNeedsPartialUpdate(UpdatableTile* tile) |
324 { | 319 { |
325 return !tile->dirtyRect.contains(m_tiler->tileRect(tile)); | 320 return !tile->updateRect.contains(m_tiler->tileRect(tile)) && tile->managedT exture()->haveBackingTexture(); |
326 } | 321 } |
327 | 322 |
328 // 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. | |
330 bool TiledLayerChromium::tileNeedsBufferedUpdate(UpdatableTile* tile) | |
331 { | |
332 if (!tile->managedTexture()->haveBackingTexture()) | |
333 return false; | |
334 | |
335 if (!tile->isDirty()) | |
336 return false; | |
337 | |
338 if (!tile->isInUseOnImpl) | |
339 return false; | |
340 | |
341 return true; | |
342 } | |
343 | |
344 | |
345 bool TiledLayerChromium::updateTiles(int left, int top, int right, int bottom, C CTextureUpdateQueue& queue, const CCOcclusionTracker* occlusion, CCRenderingStat s& stats, bool& didPaint) | 323 bool TiledLayerChromium::updateTiles(int left, int top, int right, int bottom, C CTextureUpdateQueue& queue, const CCOcclusionTracker* occlusion, CCRenderingStat s& stats, bool& didPaint) |
346 { | 324 { |
347 didPaint = false; | 325 didPaint = false; |
348 createTextureUpdaterIfNeeded(); | 326 createTextureUpdaterIfNeeded(); |
349 | 327 |
350 bool ignoreOcclusions = !occlusion; | 328 bool ignoreOcclusions = !occlusion; |
351 if (!haveTexturesForTiles(left, top, right, bottom, ignoreOcclusions)) { | 329 if (!haveTexturesForTiles(left, top, right, bottom, ignoreOcclusions)) { |
danakj
2012/10/17 23:39:44
I see. This will make it dirty now.
| |
352 m_failedUpdate = true; | 330 m_failedUpdate = true; |
353 return false; | 331 return false; |
354 } | 332 } |
355 | 333 |
356 IntRect paintRect = markTilesForUpdate(left, top, right, bottom, ignoreOcclu sions); | 334 IntRect paintRect = markTilesForUpdate(left, top, right, bottom, ignoreOcclu sions); |
357 | 335 |
358 if (occlusion) | 336 if (occlusion) |
359 occlusion->overdrawMetrics().didPaint(paintRect); | 337 occlusion->overdrawMetrics().didPaint(paintRect); |
360 | 338 |
361 if (paintRect.isEmpty()) | 339 if (paintRect.isEmpty()) |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
471 if (!tile) | 449 if (!tile) |
472 continue; | 450 continue; |
473 | 451 |
474 IntRect tileRect = m_tiler->tileBounds(i, j); | 452 IntRect tileRect = m_tiler->tileBounds(i, j); |
475 | 453 |
476 // Use updateRect as the above loop copied the dirty rect for this f rame to updateRect. | 454 // Use updateRect as the above loop copied the dirty rect for this f rame to updateRect. |
477 const IntRect& dirtyRect = tile->updateRect; | 455 const IntRect& dirtyRect = tile->updateRect; |
478 if (dirtyRect.isEmpty()) | 456 if (dirtyRect.isEmpty()) |
479 continue; | 457 continue; |
480 | 458 |
459 // FIXME: Decide if partial update should be allowed based on cost | |
460 // of update. https://bugs.webkit.org/show_bug.cgi?id=77376 | |
461 if (layerTreeHost() && layerTreeHost()->bufferedUpdates()) { | |
462 // If we get a partial update, we use the same texture, otherwis e return | |
463 // the current texture backing, so we don't update visible textu res non-atomically. | |
464 // If the current backing is in-use, it won't be deleted until a fter the commit | |
465 // as the texture manager will not allow deletion or recycling | |
466 // of in-use textures. | |
467 if (tileOnlyNeedsPartialUpdate(tile) && layerTreeHost()->request PartialTextureUpdate()) | |
468 tile->partialUpdate = true; | |
469 else | |
470 tile->managedTexture()->returnBackingTexture(); | |
471 } | |
472 | |
481 // Save what was painted opaque in the tile. Keep the old area if th e paint didn't touch it, and didn't paint some | 473 // Save what was painted opaque in the tile. Keep the old area if th e paint didn't touch it, and didn't paint some |
482 // other part of the tile opaque. | 474 // other part of the tile opaque. |
483 IntRect tilePaintedRect = intersection(tileRect, paintRect); | 475 IntRect tilePaintedRect = intersection(tileRect, paintRect); |
484 IntRect tilePaintedOpaqueRect = intersection(tileRect, paintedOpaque Rect); | 476 IntRect tilePaintedOpaqueRect = intersection(tileRect, paintedOpaque Rect); |
485 if (!tilePaintedRect.isEmpty()) { | 477 if (!tilePaintedRect.isEmpty()) { |
486 IntRect paintInsideTileOpaqueRect = intersection(tile->opaqueRec t(), tilePaintedRect); | 478 IntRect paintInsideTileOpaqueRect = intersection(tile->opaqueRec t(), tilePaintedRect); |
487 bool paintInsideTileOpaqueRectIsNonOpaque = !tilePaintedOpaqueRe ct.contains(paintInsideTileOpaqueRect); | 479 bool paintInsideTileOpaqueRectIsNonOpaque = !tilePaintedOpaqueRe ct.contains(paintInsideTileOpaqueRect); |
488 bool opaquePaintNotInsideTileOpaqueRect = !tilePaintedOpaqueRect .isEmpty() && !tile->opaqueRect().contains(tilePaintedOpaqueRect); | 480 bool opaquePaintNotInsideTileOpaqueRect = !tilePaintedOpaqueRect .isEmpty() && !tile->opaqueRect().contains(tilePaintedOpaqueRect); |
489 | 481 |
490 if (paintInsideTileOpaqueRectIsNonOpaque || opaquePaintNotInside TileOpaqueRect) | 482 if (paintInsideTileOpaqueRectIsNonOpaque || opaquePaintNotInside TileOpaqueRect) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
570 resetUpdateState(); | 562 resetUpdateState(); |
571 | 563 |
572 if (m_tiler->hasEmptyBounds()) | 564 if (m_tiler->hasEmptyBounds()) |
573 return; | 565 return; |
574 | 566 |
575 bool drawsToRoot = !renderTarget()->parent(); | 567 bool drawsToRoot = !renderTarget()->parent(); |
576 bool smallAnimatedLayer = isSmallAnimatedLayer(this); | 568 bool smallAnimatedLayer = isSmallAnimatedLayer(this); |
577 | 569 |
578 // Minimally create the tiles in the desired pre-paint rect. | 570 // Minimally create the tiles in the desired pre-paint rect. |
579 IntRect createTilesRect = idlePaintRect(); | 571 IntRect createTilesRect = idlePaintRect(); |
572 if (smallAnimatedLayer) | |
573 createTilesRect = IntRect(IntPoint::zero(), contentBounds()); | |
580 if (!createTilesRect.isEmpty()) { | 574 if (!createTilesRect.isEmpty()) { |
581 int left, top, right, bottom; | 575 int left, top, right, bottom; |
582 m_tiler->contentRectToTileIndices(createTilesRect, left, top, right, bot tom); | 576 m_tiler->contentRectToTileIndices(createTilesRect, left, top, right, bot tom); |
583 for (int j = top; j <= bottom; ++j) { | 577 for (int j = top; j <= bottom; ++j) { |
584 for (int i = left; i <= right; ++i) { | 578 for (int i = left; i <= right; ++i) { |
585 if (!tileAt(i, j)) | 579 if (!tileAt(i, j)) |
586 createTile(i, j); | 580 createTile(i, j); |
587 } | 581 } |
588 } | 582 } |
589 } | 583 } |
590 | 584 |
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; | |
danakj
2012/10/17 23:19:37
who's doing this now?
epenner
2012/10/17 23:33:14
Throwing the texture away will make it dirty.... B
| |
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. | 585 // 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) { | 586 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); | 587 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); |
636 // FIXME: This should not ever be null. | 588 // FIXME: This should not ever be null. |
637 if (!tile) | 589 if (!tile) |
638 continue; | 590 continue; |
639 IntRect tileRect = m_tiler->tileRect(tile); | 591 IntRect tileRect = m_tiler->tileRect(tile); |
640 setPriorityForTexture(visibleContentRect(), tileRect, drawsToRoot, small AnimatedLayer, tile->managedTexture()); | 592 setPriorityForTexture(visibleContentRect(), tileRect, drawsToRoot, small AnimatedLayer, tile->managedTexture()); |
641 } | 593 } |
642 } | 594 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
779 IntRect prepaintRect = visibleContentRect(); | 731 IntRect prepaintRect = visibleContentRect(); |
780 prepaintRect.inflateX(m_tiler->tileSize().width()); | 732 prepaintRect.inflateX(m_tiler->tileSize().width()); |
781 prepaintRect.inflateY(m_tiler->tileSize().height() * 2); | 733 prepaintRect.inflateY(m_tiler->tileSize().height() * 2); |
782 IntRect contentRect(IntPoint::zero(), contentBounds()); | 734 IntRect contentRect(IntPoint::zero(), contentBounds()); |
783 prepaintRect.intersect(contentRect); | 735 prepaintRect.intersect(contentRect); |
784 | 736 |
785 return prepaintRect; | 737 return prepaintRect; |
786 } | 738 } |
787 | 739 |
788 } | 740 } |
OLD | NEW |