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

Side by Side Diff: cc/tiled_layer.cc

Issue 11264056: cc: Use gfx:: Geometry types for positions, bounds, and related things. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ScaleAsVector 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
« no previous file with comments | « cc/tiled_layer.h ('k') | cc/tiled_layer_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "Region.h" 9 #include "Region.h"
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
11 #include "cc/geometry.h"
11 #include "cc/layer_impl.h" 12 #include "cc/layer_impl.h"
12 #include "cc/layer_tree_host.h" 13 #include "cc/layer_tree_host.h"
13 #include "cc/overdraw_metrics.h" 14 #include "cc/overdraw_metrics.h"
14 #include "cc/tiled_layer_impl.h" 15 #include "cc/tiled_layer_impl.h"
15 #include "third_party/khronos/GLES2/gl2.h" 16 #include "third_party/khronos/GLES2/gl2.h"
17 #include "ui/gfx/rect_conversions.h"
16 18
17 using namespace std; 19 using namespace std;
18 using WebKit::WebTransformationMatrix; 20 using WebKit::WebTransformationMatrix;
19 21
20 namespace cc { 22 namespace cc {
21 23
22 // Maximum predictive expansion of the visible area. 24 // Maximum predictive expansion of the visible area.
23 static const int maxPredictiveTilesCount = 2; 25 static const int maxPredictiveTilesCount = 2;
24 26
25 // Number of rows/columns of tiles to pre-paint. 27 // Number of rows/columns of tiles to pre-paint.
26 // We should increase these further as all textures are 28 // We should increase these further as all textures are
27 // prioritized and we insure performance doesn't suffer. 29 // prioritized and we insure performance doesn't suffer.
28 static const int prepaintRows = 4; 30 static const int prepaintRows = 4;
29 static const int prepaintColumns = 2; 31 static const int prepaintColumns = 2;
30 32
31 33
32 class UpdatableTile : public LayerTilingData::Tile { 34 class UpdatableTile : public LayerTilingData::Tile {
33 public: 35 public:
34 static scoped_ptr<UpdatableTile> create(scoped_ptr<LayerUpdater::Resource> u pdaterResource) 36 static scoped_ptr<UpdatableTile> create(scoped_ptr<LayerUpdater::Resource> u pdaterResource)
35 { 37 {
36 return make_scoped_ptr(new UpdatableTile(updaterResource.Pass())); 38 return make_scoped_ptr(new UpdatableTile(updaterResource.Pass()));
37 } 39 }
38 40
39 LayerUpdater::Resource* updaterResource() { return m_updaterResource.get(); } 41 LayerUpdater::Resource* updaterResource() { return m_updaterResource.get(); }
40 PrioritizedTexture* managedTexture() { return m_updaterResource->texture(); } 42 PrioritizedTexture* managedTexture() { return m_updaterResource->texture(); }
41 43
42 bool isDirty() const { return !dirtyRect.isEmpty(); } 44 bool isDirty() const { return !dirtyRect.IsEmpty(); }
43 45
44 // Reset update state for the current frame. This should occur before painti ng 46 // Reset update state for the current frame. This should occur before painti ng
45 // for all layers. Since painting one layer can invalidate another layer 47 // for all layers. Since painting one layer can invalidate another layer
46 // after it has already painted, mark all non-dirty tiles as valid before pa inting 48 // after it has already painted, mark all non-dirty tiles as valid before pa inting
47 // such that invalidations during painting won't prevent them from being pus hed. 49 // such that invalidations during painting won't prevent them from being pus hed.
48 void resetUpdateState() 50 void resetUpdateState()
49 { 51 {
50 updateRect = IntRect(); 52 updateRect = gfx::Rect();
51 occluded = false; 53 occluded = false;
52 partialUpdate = false; 54 partialUpdate = false;
53 validForFrame = !isDirty(); 55 validForFrame = !isDirty();
54 } 56 }
55 57
56 // This promises to update the tile and therefore also guarantees the tile 58 // This promises to update the tile and therefore also guarantees the tile
57 // will be valid for this frame. dirtyRect is copied into updateRect so 59 // will be valid for this frame. dirtyRect is copied into updateRect so
58 // we can continue to track re-entrant invalidations that occur during paint ing. 60 // we can continue to track re-entrant invalidations that occur during paint ing.
59 void markForUpdate() 61 void markForUpdate()
60 { 62 {
61 validForFrame = true; 63 validForFrame = true;
62 updateRect = dirtyRect; 64 updateRect = dirtyRect;
63 dirtyRect = IntRect(); 65 dirtyRect = gfx::Rect();
64 } 66 }
65 67
66 IntRect dirtyRect; 68 gfx::Rect dirtyRect;
67 IntRect updateRect; 69 gfx::Rect updateRect;
68 bool partialUpdate; 70 bool partialUpdate;
69 bool validForFrame; 71 bool validForFrame;
70 bool occluded; 72 bool occluded;
71 73
72 private: 74 private:
73 explicit UpdatableTile(scoped_ptr<LayerUpdater::Resource> updaterResource) 75 explicit UpdatableTile(scoped_ptr<LayerUpdater::Resource> updaterResource)
74 : partialUpdate(false) 76 : partialUpdate(false)
75 , validForFrame(false) 77 , validForFrame(false)
76 , occluded(false) 78 , occluded(false)
77 , m_updaterResource(updaterResource.Pass()) 79 , m_updaterResource(updaterResource.Pass())
78 { 80 {
79 } 81 }
80 82
81 scoped_ptr<LayerUpdater::Resource> m_updaterResource; 83 scoped_ptr<LayerUpdater::Resource> m_updaterResource;
82 84
83 DISALLOW_COPY_AND_ASSIGN(UpdatableTile); 85 DISALLOW_COPY_AND_ASSIGN(UpdatableTile);
84 }; 86 };
85 87
86 TiledLayer::TiledLayer() 88 TiledLayer::TiledLayer()
87 : ContentsScalingLayer() 89 : ContentsScalingLayer()
88 , m_textureFormat(GL_INVALID_ENUM) 90 , m_textureFormat(GL_INVALID_ENUM)
89 , m_skipsDraw(false) 91 , m_skipsDraw(false)
90 , m_failedUpdate(false) 92 , m_failedUpdate(false)
91 , m_tilingOption(AutoTile) 93 , m_tilingOption(AutoTile)
92 { 94 {
93 m_tiler = LayerTilingData::create(IntSize(), LayerTilingData::HasBorderTexel s); 95 m_tiler = LayerTilingData::create(gfx::Size(), LayerTilingData::HasBorderTex els);
94 } 96 }
95 97
96 TiledLayer::~TiledLayer() 98 TiledLayer::~TiledLayer()
97 { 99 {
98 } 100 }
99 101
100 scoped_ptr<LayerImpl> TiledLayer::createLayerImpl() 102 scoped_ptr<LayerImpl> TiledLayer::createLayerImpl()
101 { 103 {
102 return TiledLayerImpl::create(id()).PassAs<LayerImpl>(); 104 return TiledLayerImpl::create(id()).PassAs<LayerImpl>();
103 } 105 }
104 106
105 void TiledLayer::updateTileSizeAndTilingOption() 107 void TiledLayer::updateTileSizeAndTilingOption()
106 { 108 {
107 DCHECK(layerTreeHost()); 109 DCHECK(layerTreeHost());
108 110
109 const IntSize& defaultTileSize = layerTreeHost()->settings().defaultTileSize ; 111 gfx::Size defaultTileSize = layerTreeHost()->settings().defaultTileSize;
110 const IntSize& maxUntiledLayerSize = layerTreeHost()->settings().maxUntiledL ayerSize; 112 gfx::Size maxUntiledLayerSize = layerTreeHost()->settings().maxUntiledLayerS ize;
111 int layerWidth = contentBounds().width(); 113 int layerWidth = contentBounds().width();
112 int layerHeight = contentBounds().height(); 114 int layerHeight = contentBounds().height();
113 115
114 const IntSize tileSize(min(defaultTileSize.width(), layerWidth), min(default TileSize.height(), layerHeight)); 116 gfx::Size tileSize(min(defaultTileSize.width(), layerWidth), min(defaultTile Size.height(), layerHeight));
115 117
116 // Tile if both dimensions large, or any one dimension large and the other 118 // Tile if both dimensions large, or any one dimension large and the other
117 // extends into a second tile but the total layer area isn't larger than tha t 119 // extends into a second tile but the total layer area isn't larger than tha t
118 // of the largest possible untiled layer. This heuristic allows for long ski nny layers 120 // of the largest possible untiled layer. This heuristic allows for long ski nny layers
119 // (e.g. scrollbars) that are Nx1 tiles to minimize wasted texture space but still avoids 121 // (e.g. scrollbars) that are Nx1 tiles to minimize wasted texture space but still avoids
120 // creating very large tiles. 122 // creating very large tiles.
121 const bool anyDimensionLarge = layerWidth > maxUntiledLayerSize.width() || l ayerHeight > maxUntiledLayerSize.height(); 123 bool anyDimensionLarge = layerWidth > maxUntiledLayerSize.width() || layerHe ight > maxUntiledLayerSize.height();
122 const bool anyDimensionOneTile = (layerWidth <= defaultTileSize.width() || l ayerHeight <= defaultTileSize.height()) 124 bool anyDimensionOneTile = (layerWidth <= defaultTileSize.width() || layerHe ight <= defaultTileSize.height())
123 && (layerWidth * layerHeight) <= (maxUntil edLayerSize.width() * maxUntiledLayerSize.height()); 125 && (layerWidth * layerHeight) <= (maxUntil edLayerSize.width() * maxUntiledLayerSize.height());
124 const bool autoTiled = anyDimensionLarge && !anyDimensionOneTile; 126 bool autoTiled = anyDimensionLarge && !anyDimensionOneTile;
125 127
126 bool isTiled; 128 bool isTiled;
127 if (m_tilingOption == AlwaysTile) 129 if (m_tilingOption == AlwaysTile)
128 isTiled = true; 130 isTiled = true;
129 else if (m_tilingOption == NeverTile) 131 else if (m_tilingOption == NeverTile)
130 isTiled = false; 132 isTiled = false;
131 else 133 else
132 isTiled = autoTiled; 134 isTiled = autoTiled;
133 135
134 IntSize requestedSize = isTiled ? tileSize : contentBounds(); 136 gfx::Size requestedSize = isTiled ? tileSize : contentBounds();
135 const int maxSize = layerTreeHost()->rendererCapabilities().maxTextureSize; 137 const int maxSize = layerTreeHost()->rendererCapabilities().maxTextureSize;
136 IntSize clampedSize = requestedSize.shrunkTo(IntSize(maxSize, maxSize)); 138 gfx::Size clampedSize = ClampSizeFromAbove(requestedSize, gfx::Size(maxSize, maxSize));
137 setTileSize(clampedSize); 139 setTileSize(clampedSize);
138 } 140 }
139 141
140 void TiledLayer::updateBounds() 142 void TiledLayer::updateBounds()
141 { 143 {
142 IntSize oldBounds = m_tiler->bounds(); 144 gfx::Size oldBounds = m_tiler->bounds();
143 IntSize newBounds = contentBounds(); 145 gfx::Size newBounds = contentBounds();
144 if (oldBounds == newBounds) 146 if (oldBounds == newBounds)
145 return; 147 return;
146 m_tiler->setBounds(newBounds); 148 m_tiler->setBounds(newBounds);
147 149
148 // Invalidate any areas that the new bounds exposes. 150 // Invalidate any areas that the new bounds exposes.
149 Region oldRegion(IntRect(IntPoint(), oldBounds)); 151 Region oldRegion = IntRect(IntPoint(), cc::IntSize(oldBounds));
150 Region newRegion(IntRect(IntPoint(), newBounds)); 152 Region newRegion = IntRect(IntPoint(), cc::IntSize(newBounds));
151 newRegion.subtract(oldRegion); 153 newRegion.subtract(oldRegion);
152 Vector<WebCore::IntRect> rects = newRegion.rects(); 154 Vector<WebCore::IntRect> rects = newRegion.rects();
153 for (size_t i = 0; i < rects.size(); ++i) 155 for (size_t i = 0; i < rects.size(); ++i)
154 invalidateContentRect(rects[i]); 156 invalidateContentRect(cc::IntRect(rects[i]));
155 } 157 }
156 158
157 void TiledLayer::setTileSize(const IntSize& size) 159 void TiledLayer::setTileSize(const gfx::Size& size)
158 { 160 {
159 m_tiler->setTileSize(size); 161 m_tiler->setTileSize(size);
160 } 162 }
161 163
162 void TiledLayer::setBorderTexelOption(LayerTilingData::BorderTexelOption borderT exelOption) 164 void TiledLayer::setBorderTexelOption(LayerTilingData::BorderTexelOption borderT exelOption)
163 { 165 {
164 m_tiler->setBorderTexelOption(borderTexelOption); 166 m_tiler->setBorderTexelOption(borderTexelOption);
165 } 167 }
166 168
167 bool TiledLayer::drawsContent() const 169 bool TiledLayer::drawsContent() const
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 264
263 // Temporary diagnostic crash. 265 // Temporary diagnostic crash.
264 if (!addedTile) 266 if (!addedTile)
265 CRASH(); 267 CRASH();
266 if (!tileAt(i, j)) 268 if (!tileAt(i, j))
267 CRASH(); 269 CRASH();
268 270
269 return addedTile; 271 return addedTile;
270 } 272 }
271 273
272 void TiledLayer::setNeedsDisplayRect(const FloatRect& dirtyRect) 274 void TiledLayer::setNeedsDisplayRect(const gfx::RectF& dirtyRect)
273 { 275 {
274 invalidateContentRect(layerRectToContentRect(dirtyRect)); 276 invalidateContentRect(layerRectToContentRect(dirtyRect));
275 ContentsScalingLayer::setNeedsDisplayRect(dirtyRect); 277 ContentsScalingLayer::setNeedsDisplayRect(dirtyRect);
276 } 278 }
277 279
278 void TiledLayer::setUseLCDText(bool useLCDText) 280 void TiledLayer::setUseLCDText(bool useLCDText)
279 { 281 {
280 ContentsScalingLayer::setUseLCDText(useLCDText); 282 ContentsScalingLayer::setUseLCDText(useLCDText);
281 283
282 LayerTilingData::BorderTexelOption borderTexelOption; 284 LayerTilingData::BorderTexelOption borderTexelOption;
283 #if OS(ANDROID) 285 #if OS(ANDROID)
284 // Always want border texels and GL_LINEAR due to pinch zoom. 286 // Always want border texels and GL_LINEAR due to pinch zoom.
285 borderTexelOption = LayerTilingData::HasBorderTexels; 287 borderTexelOption = LayerTilingData::HasBorderTexels;
286 #else 288 #else
287 borderTexelOption = useLCDText ? LayerTilingData::NoBorderTexels : LayerTili ngData::HasBorderTexels; 289 borderTexelOption = useLCDText ? LayerTilingData::NoBorderTexels : LayerTili ngData::HasBorderTexels;
288 #endif 290 #endif
289 setBorderTexelOption(borderTexelOption); 291 setBorderTexelOption(borderTexelOption);
290 } 292 }
291 293
292 void TiledLayer::invalidateContentRect(const IntRect& contentRect) 294 void TiledLayer::invalidateContentRect(const gfx::Rect& contentRect)
293 { 295 {
294 updateBounds(); 296 updateBounds();
295 if (m_tiler->isEmpty() || contentRect.isEmpty() || m_skipsDraw) 297 if (m_tiler->isEmpty() || contentRect.IsEmpty() || m_skipsDraw)
296 return; 298 return;
297 299
298 for (LayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin( ); iter != m_tiler->tiles().end(); ++iter) { 300 for (LayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin( ); iter != m_tiler->tiles().end(); ++iter) {
299 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); 301 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
300 DCHECK(tile); 302 DCHECK(tile);
301 // FIXME: This should not ever be null. 303 // FIXME: This should not ever be null.
302 if (!tile) 304 if (!tile)
303 continue; 305 continue;
304 IntRect bound = m_tiler->tileRect(tile); 306 gfx::Rect bound = m_tiler->tileRect(tile);
305 bound.intersect(contentRect); 307 bound.Intersect(contentRect);
306 tile->dirtyRect.unite(bound); 308 tile->dirtyRect.Union(bound);
307 } 309 }
308 } 310 }
309 311
310 // Returns true if tile is dirty and only part of it needs to be updated. 312 // Returns true if tile is dirty and only part of it needs to be updated.
311 bool TiledLayer::tileOnlyNeedsPartialUpdate(UpdatableTile* tile) 313 bool TiledLayer::tileOnlyNeedsPartialUpdate(UpdatableTile* tile)
312 { 314 {
313 return !tile->dirtyRect.contains(m_tiler->tileRect(tile)) && tile->managedTe xture()->haveBackingTexture(); 315 return !tile->dirtyRect.Contains(m_tiler->tileRect(tile)) && tile->managedTe xture()->haveBackingTexture();
314 } 316 }
315 317
316 bool TiledLayer::updateTiles(int left, int top, int right, int bottom, ResourceU pdateQueue& queue, const OcclusionTracker* occlusion, RenderingStats& stats, boo l& didPaint) 318 bool TiledLayer::updateTiles(int left, int top, int right, int bottom, ResourceU pdateQueue& queue, const OcclusionTracker* occlusion, RenderingStats& stats, boo l& didPaint)
317 { 319 {
318 didPaint = false; 320 didPaint = false;
319 createUpdaterIfNeeded(); 321 createUpdaterIfNeeded();
320 322
321 bool ignoreOcclusions = !occlusion; 323 bool ignoreOcclusions = !occlusion;
322 if (!haveTexturesForTiles(left, top, right, bottom, ignoreOcclusions)) { 324 if (!haveTexturesForTiles(left, top, right, bottom, ignoreOcclusions)) {
323 m_failedUpdate = true; 325 m_failedUpdate = true;
324 return false; 326 return false;
325 } 327 }
326 328
327 IntRect paintRect = markTilesForUpdate(left, top, right, bottom, ignoreOcclu sions); 329 gfx::Rect paintRect = markTilesForUpdate(left, top, right, bottom, ignoreOcc lusions);
328 330
329 if (occlusion) 331 if (occlusion)
330 occlusion->overdrawMetrics().didPaint(paintRect); 332 occlusion->overdrawMetrics().didPaint(cc::IntRect(paintRect));
331 333
332 if (paintRect.isEmpty()) 334 if (paintRect.IsEmpty())
333 return true; 335 return true;
334 336
335 didPaint = true; 337 didPaint = true;
336 updateTileTextures(paintRect, left, top, right, bottom, queue, occlusion, st ats); 338 updateTileTextures(paintRect, left, top, right, bottom, queue, occlusion, st ats);
337 return true; 339 return true;
338 } 340 }
339 341
340 void TiledLayer::markOcclusionsAndRequestTextures(int left, int top, int right, int bottom, const OcclusionTracker* occlusion) 342 void TiledLayer::markOcclusionsAndRequestTextures(int left, int top, int right, int bottom, const OcclusionTracker* occlusion)
341 { 343 {
342 // There is some difficult dependancies between occlusions, recording occlus ion metrics 344 // There is some difficult dependancies between occlusions, recording occlus ion metrics
343 // and requesting memory so those are encapsulated in this function: 345 // and requesting memory so those are encapsulated in this function:
344 // - We only want to call requestLate on unoccluded textures (to preserve 346 // - We only want to call requestLate on unoccluded textures (to preserve
345 // memory for other layers when near OOM). 347 // memory for other layers when near OOM).
346 // - We only want to record occlusion metrics if all memory requests succeed . 348 // - We only want to record occlusion metrics if all memory requests succeed .
347 349
348 int occludedTileCount = 0; 350 int occludedTileCount = 0;
349 bool succeeded = true; 351 bool succeeded = true;
350 for (int j = top; j <= bottom; ++j) { 352 for (int j = top; j <= bottom; ++j) {
351 for (int i = left; i <= right; ++i) { 353 for (int i = left; i <= right; ++i) {
352 UpdatableTile* tile = tileAt(i, j); 354 UpdatableTile* tile = tileAt(i, j);
353 DCHECK(tile); // Did setTexturePriorities get skipped? 355 DCHECK(tile); // Did setTexturePriorities get skipped?
354 // FIXME: This should not ever be null. 356 // FIXME: This should not ever be null.
355 if (!tile) 357 if (!tile)
356 continue; 358 continue;
357 DCHECK(!tile->occluded); // Did resetUpdateState get skipped? Are we doing more than one occlusion pass? 359 DCHECK(!tile->occluded); // Did resetUpdateState get skipped? Are we doing more than one occlusion pass?
358 IntRect visibleTileRect = intersection(m_tiler->tileBounds(i, j), vi sibleContentRect()); 360 gfx::Rect visibleTileRect = gfx::IntersectRects(m_tiler->tileBounds( i, j), visibleContentRect());
359 if (occlusion && occlusion->occluded(renderTarget(), visibleTileRect , drawTransform(), drawTransformIsAnimating(), drawableContentRect())) { 361 if (occlusion && occlusion->occluded(renderTarget(), visibleTileRect , drawTransform(), drawTransformIsAnimating(), drawableContentRect())) {
360 tile->occluded = true; 362 tile->occluded = true;
361 occludedTileCount++; 363 occludedTileCount++;
362 } else { 364 } else {
363 succeeded &= tile->managedTexture()->requestLate(); 365 succeeded &= tile->managedTexture()->requestLate();
364 } 366 }
365 } 367 }
366 } 368 }
367 369
368 if (!succeeded) 370 if (!succeeded)
(...skipping 21 matching lines...) Expand all
390 if (tile->occluded && !ignoreOcclusions) 392 if (tile->occluded && !ignoreOcclusions)
391 continue; 393 continue;
392 394
393 if (!tile->managedTexture()->canAcquireBackingTexture()) 395 if (!tile->managedTexture()->canAcquireBackingTexture())
394 return false; 396 return false;
395 } 397 }
396 } 398 }
397 return true; 399 return true;
398 } 400 }
399 401
400 IntRect TiledLayer::markTilesForUpdate(int left, int top, int right, int bottom, bool ignoreOcclusions) 402 gfx::Rect TiledLayer::markTilesForUpdate(int left, int top, int right, int botto m, bool ignoreOcclusions)
401 { 403 {
402 IntRect paintRect; 404 gfx::Rect paintRect;
403 for (int j = top; j <= bottom; ++j) { 405 for (int j = top; j <= bottom; ++j) {
404 for (int i = left; i <= right; ++i) { 406 for (int i = left; i <= right; ++i) {
405 UpdatableTile* tile = tileAt(i, j); 407 UpdatableTile* tile = tileAt(i, j);
406 DCHECK(tile); // Did setTexturePriorites get skipped? 408 DCHECK(tile); // Did setTexturePriorites get skipped?
407 // FIXME: This should not ever be null. 409 // FIXME: This should not ever be null.
408 if (!tile) 410 if (!tile)
409 continue; 411 continue;
410 if (tile->occluded && !ignoreOcclusions) 412 if (tile->occluded && !ignoreOcclusions)
411 continue; 413 continue;
412 // FIXME: Decide if partial update should be allowed based on cost 414 // FIXME: Decide if partial update should be allowed based on cost
413 // of update. https://bugs.webkit.org/show_bug.cgi?id=77376 415 // of update. https://bugs.webkit.org/show_bug.cgi?id=77376
414 if (tile->isDirty() && layerTreeHost() && layerTreeHost()->bufferedU pdates()) { 416 if (tile->isDirty() && layerTreeHost() && layerTreeHost()->bufferedU pdates()) {
415 // If we get a partial update, we use the same texture, otherwis e return the 417 // If we get a partial update, we use the same texture, otherwis e return the
416 // current texture backing, so we don't update visible textures non-atomically. 418 // current texture backing, so we don't update visible textures non-atomically.
417 // If the current backing is in-use, it won't be deleted until a fter the commit 419 // If the current backing is in-use, it won't be deleted until a fter the commit
418 // as the texture manager will not allow deletion or recycling o f in-use textures. 420 // as the texture manager will not allow deletion or recycling o f in-use textures.
419 if (tileOnlyNeedsPartialUpdate(tile) && layerTreeHost()->request PartialTextureUpdate()) 421 if (tileOnlyNeedsPartialUpdate(tile) && layerTreeHost()->request PartialTextureUpdate())
420 tile->partialUpdate = true; 422 tile->partialUpdate = true;
421 else { 423 else {
422 tile->dirtyRect = m_tiler->tileRect(tile); 424 tile->dirtyRect = m_tiler->tileRect(tile);
423 tile->managedTexture()->returnBackingTexture(); 425 tile->managedTexture()->returnBackingTexture();
424 } 426 }
425 } 427 }
426 428
427 paintRect.unite(tile->dirtyRect); 429 paintRect.Union(tile->dirtyRect);
428 tile->markForUpdate(); 430 tile->markForUpdate();
429 } 431 }
430 } 432 }
431 return paintRect; 433 return paintRect;
432 } 434 }
433 435
434 void TiledLayer::updateTileTextures(const IntRect& paintRect, int left, int top, int right, int bottom, ResourceUpdateQueue& queue, const OcclusionTracker* occl usion, RenderingStats& stats) 436 void TiledLayer::updateTileTextures(const gfx::Rect& paintRect, int left, int to p, int right, int bottom, ResourceUpdateQueue& queue, const OcclusionTracker* oc clusion, RenderingStats& stats)
435 { 437 {
436 // The updateRect should be in layer space. So we have to convert the paintR ect from content space to layer space. 438 // The updateRect should be in layer space. So we have to convert the paintR ect from content space to layer space.
437 m_updateRect = FloatRect(paintRect);
438 float widthScale = bounds().width() / static_cast<float>(contentBounds().wid th()); 439 float widthScale = bounds().width() / static_cast<float>(contentBounds().wid th());
439 float heightScale = bounds().height() / static_cast<float>(contentBounds().h eight()); 440 float heightScale = bounds().height() / static_cast<float>(contentBounds().h eight());
440 m_updateRect.scale(widthScale, heightScale); 441 m_updateRect = gfx::ScaleRect(paintRect, widthScale, heightScale);
441 442
442 // Calling prepareToUpdate() calls into WebKit to paint, which may have the side 443 // Calling prepareToUpdate() calls into WebKit to paint, which may have the side
443 // effect of disabling compositing, which causes our reference to the textur e updater to be deleted. 444 // effect of disabling compositing, which causes our reference to the textur e updater to be deleted.
444 // However, we can't free the memory backing the SkCanvas until the paint fi nishes, 445 // However, we can't free the memory backing the SkCanvas until the paint fi nishes,
445 // so we grab a local reference here to hold the updater alive until the pai nt completes. 446 // so we grab a local reference here to hold the updater alive until the pai nt completes.
446 scoped_refptr<LayerUpdater> protector(updater()); 447 scoped_refptr<LayerUpdater> protector(updater());
447 gfx::Rect paintedOpaqueRect; 448 gfx::Rect paintedOpaqueRect;
448 updater()->prepareToUpdate(paintRect, m_tiler->tileSize(), 1 / widthScale, 1 / heightScale, paintedOpaqueRect, stats); 449 updater()->prepareToUpdate(paintRect, m_tiler->tileSize(), 1 / widthScale, 1 / heightScale, paintedOpaqueRect, stats);
449 450
450 for (int j = top; j <= bottom; ++j) { 451 for (int j = top; j <= bottom; ++j) {
451 for (int i = left; i <= right; ++i) { 452 for (int i = left; i <= right; ++i) {
452 UpdatableTile* tile = tileAt(i, j); 453 UpdatableTile* tile = tileAt(i, j);
453 DCHECK(tile); // Did setTexturePriorites get skipped? 454 DCHECK(tile); // Did setTexturePriorites get skipped?
454 // FIXME: This should not ever be null. 455 // FIXME: This should not ever be null.
455 if (!tile) 456 if (!tile)
456 continue; 457 continue;
457 458
458 IntRect tileRect = m_tiler->tileBounds(i, j); 459 gfx::Rect tileRect = m_tiler->tileBounds(i, j);
459 460
460 // Use updateRect as the above loop copied the dirty rect for this f rame to updateRect. 461 // Use updateRect as the above loop copied the dirty rect for this f rame to updateRect.
461 const IntRect& dirtyRect = tile->updateRect; 462 const gfx::Rect& dirtyRect = tile->updateRect;
462 if (dirtyRect.isEmpty()) 463 if (dirtyRect.IsEmpty())
463 continue; 464 continue;
464 465
465 // 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 466 // 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
466 // other part of the tile opaque. 467 // other part of the tile opaque.
467 IntRect tilePaintedRect = intersection(tileRect, paintRect); 468 gfx::Rect tilePaintedRect = gfx::IntersectRects(tileRect, paintRect) ;
468 IntRect tilePaintedOpaqueRect = intersection(tileRect, cc::IntRect(p aintedOpaqueRect)); 469 gfx::Rect tilePaintedOpaqueRect = gfx::IntersectRects(tileRect, pain tedOpaqueRect);
469 if (!tilePaintedRect.isEmpty()) { 470 if (!tilePaintedRect.IsEmpty()) {
470 IntRect paintInsideTileOpaqueRect = intersection(tile->opaqueRec t(), tilePaintedRect); 471 gfx::Rect paintInsideTileOpaqueRect = gfx::IntersectRects(tile-> opaqueRect(), tilePaintedRect);
471 bool paintInsideTileOpaqueRectIsNonOpaque = !tilePaintedOpaqueRe ct.contains(paintInsideTileOpaqueRect); 472 bool paintInsideTileOpaqueRectIsNonOpaque = !tilePaintedOpaqueRe ct.Contains(paintInsideTileOpaqueRect);
472 bool opaquePaintNotInsideTileOpaqueRect = !tilePaintedOpaqueRect .isEmpty() && !tile->opaqueRect().contains(tilePaintedOpaqueRect); 473 bool opaquePaintNotInsideTileOpaqueRect = !tilePaintedOpaqueRect .IsEmpty() && !tile->opaqueRect().Contains(tilePaintedOpaqueRect);
473 474
474 if (paintInsideTileOpaqueRectIsNonOpaque || opaquePaintNotInside TileOpaqueRect) 475 if (paintInsideTileOpaqueRectIsNonOpaque || opaquePaintNotInside TileOpaqueRect)
475 tile->setOpaqueRect(tilePaintedOpaqueRect); 476 tile->setOpaqueRect(tilePaintedOpaqueRect);
476 } 477 }
477 478
478 // sourceRect starts as a full-sized tile with border texels include d. 479 // sourceRect starts as a full-sized tile with border texels include d.
479 IntRect sourceRect = m_tiler->tileRect(tile); 480 gfx::Rect sourceRect = m_tiler->tileRect(tile);
480 sourceRect.intersect(dirtyRect); 481 sourceRect.Intersect(dirtyRect);
481 // Paint rect not guaranteed to line up on tile boundaries, so 482 // Paint rect not guaranteed to line up on tile boundaries, so
482 // make sure that sourceRect doesn't extend outside of it. 483 // make sure that sourceRect doesn't extend outside of it.
483 sourceRect.intersect(paintRect); 484 sourceRect.Intersect(paintRect);
484 485
485 tile->updateRect = sourceRect; 486 tile->updateRect = sourceRect;
486 487
487 if (sourceRect.isEmpty()) 488 if (sourceRect.IsEmpty())
488 continue; 489 continue;
489 490
490 const IntPoint anchor = m_tiler->tileRect(tile).location(); 491 const gfx::Point anchor = m_tiler->tileRect(tile).origin();
491 492
492 // Calculate tile-space rectangle to upload into. 493 // Calculate tile-space rectangle to upload into.
493 gfx::Vector2d destOffset(sourceRect.x() - anchor.x(), sourceRect.y() - anchor.y()); 494 gfx::Vector2d destOffset = sourceRect.origin() - anchor;
494 if (destOffset.x() < 0) 495 if (destOffset.x() < 0)
495 CRASH(); 496 CRASH();
496 if (destOffset.y() < 0) 497 if (destOffset.y() < 0)
497 CRASH(); 498 CRASH();
498 499
499 // Offset from paint rectangle to this tile's dirty rectangle. 500 // Offset from paint rectangle to this tile's dirty rectangle.
500 gfx::Vector2d paintOffset(sourceRect.x() - paintRect.x(), sourceRect .y() - paintRect.y()); 501 gfx::Vector2d paintOffset = sourceRect.origin() - paintRect.origin() ;
501 if (paintOffset.x() < 0) 502 if (paintOffset.x() < 0)
502 CRASH(); 503 CRASH();
503 if (paintOffset.y() < 0) 504 if (paintOffset.y() < 0)
504 CRASH(); 505 CRASH();
505 if (paintOffset.x() + sourceRect.width() > paintRect.width()) 506 if (paintOffset.x() + sourceRect.width() > paintRect.width())
506 CRASH(); 507 CRASH();
507 if (paintOffset.y() + sourceRect.height() > paintRect.height()) 508 if (paintOffset.y() + sourceRect.height() > paintRect.height())
508 CRASH(); 509 CRASH();
509 510
510 tile->updaterResource()->update(queue, sourceRect, destOffset, tile- >partialUpdate, stats); 511 tile->updaterResource()->update(queue, sourceRect, destOffset, tile- >partialUpdate, stats);
511 if (occlusion) 512 if (occlusion)
512 occlusion->overdrawMetrics().didUpload(WebTransformationMatrix() , sourceRect, tile->opaqueRect()); 513 occlusion->overdrawMetrics().didUpload(WebTransformationMatrix() , cc::IntRect(sourceRect), cc::IntRect(tile->opaqueRect()));
513 514
514 } 515 }
515 } 516 }
516 } 517 }
517 518
518 namespace { 519 namespace {
519 // This picks a small animated layer to be anything less than one viewport. This 520 // This picks a small animated layer to be anything less than one viewport. This
520 // is specifically for page transitions which are viewport-sized layers. The ext ra 521 // is specifically for page transitions which are viewport-sized layers. The ext ra
521 // 64 pixels is due to these layers being slightly larger than the viewport in s ome cases. 522 // 64 pixels is due to these layers being slightly larger than the viewport in s ome cases.
522 bool isSmallAnimatedLayer(TiledLayer* layer) 523 bool isSmallAnimatedLayer(TiledLayer* layer)
523 { 524 {
524 if (!layer->drawTransformIsAnimating() && !layer->screenSpaceTransformIsAnim ating()) 525 if (!layer->drawTransformIsAnimating() && !layer->screenSpaceTransformIsAnim ating())
525 return false; 526 return false;
526 IntSize viewportSize = layer->layerTreeHost() ? layer->layerTreeHost()->devi ceViewportSize() : IntSize(); 527 gfx::Size viewportSize = layer->layerTreeHost() ? layer->layerTreeHost()->de viceViewportSize() : gfx::Size();
527 IntRect contentRect(IntPoint::zero(), layer->contentBounds()); 528 gfx::Rect contentRect(gfx::Point(), layer->contentBounds());
528 return contentRect.width() <= viewportSize.width() + 64 529 return contentRect.width() <= viewportSize.width() + 64
529 && contentRect.height() <= viewportSize.height() + 64; 530 && contentRect.height() <= viewportSize.height() + 64;
530 } 531 }
531 532
532 // FIXME: Remove this and make this based on distance once distance can be calcu lated 533 // FIXME: Remove this and make this based on distance once distance can be calcu lated
533 // for offscreen layers. For now, prioritize all small animated layers after 512 534 // for offscreen layers. For now, prioritize all small animated layers after 512
534 // pixels of pre-painting. 535 // pixels of pre-painting.
535 void setPriorityForTexture(const IntRect& visibleRect, 536 void setPriorityForTexture(const gfx::Rect& visibleRect,
536 const IntRect& tileRect, 537 const gfx::Rect& tileRect,
537 bool drawsToRoot, 538 bool drawsToRoot,
538 bool isSmallAnimatedLayer, 539 bool isSmallAnimatedLayer,
539 PrioritizedTexture* texture) 540 PrioritizedTexture* texture)
540 { 541 {
541 int priority = PriorityCalculator::lowestPriority(); 542 int priority = PriorityCalculator::lowestPriority();
542 if (!visibleRect.isEmpty()) 543 if (!visibleRect.IsEmpty())
543 priority = PriorityCalculator::priorityFromDistance(visibleRect, tileRec t, drawsToRoot); 544 priority = PriorityCalculator::priorityFromDistance(visibleRect, tileRec t, drawsToRoot);
544 if (isSmallAnimatedLayer) 545 if (isSmallAnimatedLayer)
545 priority = PriorityCalculator::maxPriority(priority, PriorityCalculator: :smallAnimatedLayerMinPriority()); 546 priority = PriorityCalculator::maxPriority(priority, PriorityCalculator: :smallAnimatedLayerMinPriority());
546 if (priority != PriorityCalculator::lowestPriority()) 547 if (priority != PriorityCalculator::lowestPriority())
547 texture->setRequestPriority(priority); 548 texture->setRequestPriority(priority);
548 } 549 }
549 } 550 }
550 551
551 void TiledLayer::setTexturePriorities(const PriorityCalculator& priorityCalc) 552 void TiledLayer::setTexturePriorities(const PriorityCalculator& priorityCalc)
552 { 553 {
553 updateBounds(); 554 updateBounds();
554 resetUpdateState(); 555 resetUpdateState();
555 updateScrollPrediction(); 556 updateScrollPrediction();
556 557
557 if (m_tiler->hasEmptyBounds()) 558 if (m_tiler->hasEmptyBounds())
558 return; 559 return;
559 560
560 bool drawsToRoot = !renderTarget()->parent(); 561 bool drawsToRoot = !renderTarget()->parent();
561 bool smallAnimatedLayer = isSmallAnimatedLayer(this); 562 bool smallAnimatedLayer = isSmallAnimatedLayer(this);
562 563
563 // Minimally create the tiles in the desired pre-paint rect. 564 // Minimally create the tiles in the desired pre-paint rect.
564 IntRect createTilesRect = idlePaintRect(); 565 gfx::Rect createTilesRect = idlePaintRect();
565 if (smallAnimatedLayer) 566 if (smallAnimatedLayer)
566 createTilesRect = IntRect(IntPoint::zero(), contentBounds()); 567 createTilesRect = gfx::Rect(gfx::Point(), contentBounds());
567 if (!createTilesRect.isEmpty()) { 568 if (!createTilesRect.IsEmpty()) {
568 int left, top, right, bottom; 569 int left, top, right, bottom;
569 m_tiler->contentRectToTileIndices(createTilesRect, left, top, right, bot tom); 570 m_tiler->contentRectToTileIndices(createTilesRect, left, top, right, bot tom);
570 for (int j = top; j <= bottom; ++j) { 571 for (int j = top; j <= bottom; ++j) {
571 for (int i = left; i <= right; ++i) { 572 for (int i = left; i <= right; ++i) {
572 if (!tileAt(i, j)) 573 if (!tileAt(i, j))
573 createTile(i, j); 574 createTile(i, j);
574 } 575 }
575 } 576 }
576 } 577 }
577 578
578 // Now update priorities on all tiles we have in the layer, no matter where they are. 579 // Now update priorities on all tiles we have in the layer, no matter where they are.
579 for (LayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin( ); iter != m_tiler->tiles().end(); ++iter) { 580 for (LayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin( ); iter != m_tiler->tiles().end(); ++iter) {
580 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); 581 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
581 // FIXME: This should not ever be null. 582 // FIXME: This should not ever be null.
582 if (!tile) 583 if (!tile)
583 continue; 584 continue;
584 IntRect tileRect = m_tiler->tileRect(tile); 585 gfx::Rect tileRect = m_tiler->tileRect(tile);
585 setPriorityForTexture(m_predictedVisibleRect, tileRect, drawsToRoot, sma llAnimatedLayer, tile->managedTexture()); 586 setPriorityForTexture(m_predictedVisibleRect, tileRect, drawsToRoot, sma llAnimatedLayer, tile->managedTexture());
586 } 587 }
587 } 588 }
588 589
589 Region TiledLayer::visibleContentOpaqueRegion() const 590 Region TiledLayer::visibleContentOpaqueRegion() const
590 { 591 {
591 if (m_skipsDraw) 592 if (m_skipsDraw)
592 return Region(); 593 return Region();
593 if (contentsOpaque()) 594 if (contentsOpaque())
594 return visibleContentRect(); 595 return cc::IntRect(visibleContentRect());
595 return m_tiler->opaqueRegionInContentRect(visibleContentRect()); 596 return m_tiler->opaqueRegionInContentRect(visibleContentRect());
596 } 597 }
597 598
598 void TiledLayer::resetUpdateState() 599 void TiledLayer::resetUpdateState()
599 { 600 {
600 m_skipsDraw = false; 601 m_skipsDraw = false;
601 m_failedUpdate = false; 602 m_failedUpdate = false;
602 603
603 LayerTilingData::TileMap::const_iterator end = m_tiler->tiles().end(); 604 LayerTilingData::TileMap::const_iterator end = m_tiler->tiles().end();
604 for (LayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin( ); iter != end; ++iter) { 605 for (LayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin( ); iter != end; ++iter) {
605 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); 606 UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
606 // FIXME: This should not ever be null. 607 // FIXME: This should not ever be null.
607 if (!tile) 608 if (!tile)
608 continue; 609 continue;
609 tile->resetUpdateState(); 610 tile->resetUpdateState();
610 } 611 }
611 } 612 }
612 613
613 namespace { 614 namespace {
614 IntRect expandRectByDelta(IntRect rect, IntSize delta) { 615 gfx::Rect expandRectByDelta(gfx::Rect rect, gfx::Vector2d delta) {
615 int width = rect.width() + abs(delta.width()); 616 int width = rect.width() + abs(delta.x());
616 int height = rect.height() + abs(delta.height()); 617 int height = rect.height() + abs(delta.y());
617 int x = rect.x() + ((delta.width() < 0) ? delta.width() : 0); 618 int x = rect.x() + ((delta.x() < 0) ? delta.x() : 0);
618 int y = rect.y() + ((delta.height() < 0) ? delta.height() : 0); 619 int y = rect.y() + ((delta.y() < 0) ? delta.y() : 0);
619 return IntRect(x, y, width, height); 620 return gfx::Rect(x, y, width, height);
620 } 621 }
621 } 622 }
622 623
623 void TiledLayer::updateScrollPrediction() 624 void TiledLayer::updateScrollPrediction()
624 { 625 {
625 // This scroll prediction is very primitive and should be replaced by a 626 // This scroll prediction is very primitive and should be replaced by a
626 // a recursive calculation on all layers which uses actual scroll/animation 627 // a recursive calculation on all layers which uses actual scroll/animation
627 // velocities. To insure this doesn't miss-predict, we only use it to predic t 628 // velocities. To insure this doesn't miss-predict, we only use it to predic t
628 // the visibleRect if: 629 // the visibleRect if:
629 // - contentBounds() hasn't changed. 630 // - contentBounds() hasn't changed.
630 // - visibleRect.size() hasn't changed. 631 // - visibleRect.size() hasn't changed.
631 // These two conditions prevent rotations, scales, pinch-zooms etc. where 632 // These two conditions prevent rotations, scales, pinch-zooms etc. where
632 // the prediction would be incorrect. 633 // the prediction would be incorrect.
633 IntSize delta = visibleContentRect().center() - m_previousVisibleRect.center (); 634 gfx::Vector2d delta = visibleContentRect().CenterPoint() - m_previousVisible Rect.CenterPoint();
634 m_predictedScroll = -delta; 635 m_predictedScroll = -delta;
635 m_predictedVisibleRect = visibleContentRect(); 636 m_predictedVisibleRect = visibleContentRect();
636 if (m_previousContentBounds == contentBounds() && m_previousVisibleRect.size () == visibleContentRect().size()) { 637 if (m_previousContentBounds == contentBounds() && m_previousVisibleRect.size () == visibleContentRect().size()) {
637 // Only expand the visible rect in the major scroll direction, to preven t 638 // Only expand the visible rect in the major scroll direction, to preven t
638 // massive paints due to diagonal scrolls. 639 // massive paints due to diagonal scrolls.
639 IntSize majorScrollDelta = (abs(delta.width()) > abs(delta.height())) ? IntSize(delta.width(), 0) : IntSize(0, delta.height()); 640 gfx::Vector2d majorScrollDelta = (abs(delta.x()) > abs(delta.y())) ? gfx ::Vector2d(delta.x(), 0) : gfx::Vector2d(0, delta.y());
640 m_predictedVisibleRect = expandRectByDelta(visibleContentRect(), majorSc rollDelta); 641 m_predictedVisibleRect = expandRectByDelta(visibleContentRect(), majorSc rollDelta);
641 642
642 // Bound the prediction to prevent unbounded paints, and clamp to conten t bounds. 643 // Bound the prediction to prevent unbounded paints, and clamp to conten t bounds.
643 IntRect bound = visibleContentRect(); 644 gfx::Rect bound = visibleContentRect();
644 bound.inflateX(m_tiler->tileSize().width() * maxPredictiveTilesCount); 645 bound.Inset(-m_tiler->tileSize().width() * maxPredictiveTilesCount,
645 bound.inflateY(m_tiler->tileSize().height() * maxPredictiveTilesCount); 646 -m_tiler->tileSize().height() * maxPredictiveTilesCount);
646 bound.intersect(IntRect(IntPoint::zero(), contentBounds())); 647 bound.Intersect(gfx::Rect(gfx::Point(), contentBounds()));
647 m_predictedVisibleRect.intersect(bound); 648 m_predictedVisibleRect.Intersect(bound);
648 } 649 }
649 m_previousContentBounds = contentBounds(); 650 m_previousContentBounds = contentBounds();
650 m_previousVisibleRect = visibleContentRect(); 651 m_previousVisibleRect = visibleContentRect();
651 } 652 }
652 653
653 void TiledLayer::update(ResourceUpdateQueue& queue, const OcclusionTracker* occl usion, RenderingStats& stats) 654 void TiledLayer::update(ResourceUpdateQueue& queue, const OcclusionTracker* occl usion, RenderingStats& stats)
654 { 655 {
655 DCHECK(!m_skipsDraw && !m_failedUpdate); // Did resetUpdateState get skipped ? 656 DCHECK(!m_skipsDraw && !m_failedUpdate); // Did resetUpdateState get skipped ?
656 updateBounds(); 657 updateBounds();
657 if (m_tiler->hasEmptyBounds() || !drawsContent()) 658 if (m_tiler->hasEmptyBounds() || !drawsContent())
658 return; 659 return;
659 660
660 bool didPaint = false; 661 bool didPaint = false;
661 662
662 // Animation pre-paint. If the layer is small, try to paint it all 663 // Animation pre-paint. If the layer is small, try to paint it all
663 // immediately whether or not it is occluded, to avoid paint/upload 664 // immediately whether or not it is occluded, to avoid paint/upload
664 // hiccups while it is animating. 665 // hiccups while it is animating.
665 if (isSmallAnimatedLayer(this)) { 666 if (isSmallAnimatedLayer(this)) {
666 int left, top, right, bottom; 667 int left, top, right, bottom;
667 m_tiler->contentRectToTileIndices(IntRect(IntPoint::zero(), contentBound s()), left, top, right, bottom); 668 m_tiler->contentRectToTileIndices(gfx::Rect(gfx::Point(), contentBounds( )), left, top, right, bottom);
668 updateTiles(left, top, right, bottom, queue, 0, stats, didPaint); 669 updateTiles(left, top, right, bottom, queue, 0, stats, didPaint);
669 if (didPaint) 670 if (didPaint)
670 return; 671 return;
671 // This was an attempt to paint the entire layer so if we fail it's okay , 672 // This was an attempt to paint the entire layer so if we fail it's okay ,
672 // just fallback on painting visible etc. below. 673 // just fallback on painting visible etc. below.
673 m_failedUpdate = false; 674 m_failedUpdate = false;
674 } 675 }
675 676
676 if (m_predictedVisibleRect.isEmpty()) 677 if (m_predictedVisibleRect.IsEmpty())
677 return; 678 return;
678 679
679 // Visible painting. First occlude visible tiles and paint the non-occluded tiles. 680 // Visible painting. First occlude visible tiles and paint the non-occluded tiles.
680 int left, top, right, bottom; 681 int left, top, right, bottom;
681 m_tiler->contentRectToTileIndices(m_predictedVisibleRect, left, top, right, bottom); 682 m_tiler->contentRectToTileIndices(m_predictedVisibleRect, left, top, right, bottom);
682 markOcclusionsAndRequestTextures(left, top, right, bottom, occlusion); 683 markOcclusionsAndRequestTextures(left, top, right, bottom, occlusion);
683 m_skipsDraw = !updateTiles(left, top, right, bottom, queue, occlusion, stats , didPaint); 684 m_skipsDraw = !updateTiles(left, top, right, bottom, queue, occlusion, stats , didPaint);
684 if (m_skipsDraw) 685 if (m_skipsDraw)
685 m_tiler->reset(); 686 m_tiler->reset();
686 if (m_skipsDraw || didPaint) 687 if (m_skipsDraw || didPaint)
687 return; 688 return;
688 689
689 // If we have already painting everything visible. Do some pre-painting whil e idle. 690 // If we have already painting everything visible. Do some pre-painting whil e idle.
690 IntRect idlePaintContentRect = idlePaintRect(); 691 gfx::Rect idlePaintContentRect = idlePaintRect();
691 if (idlePaintContentRect.isEmpty()) 692 if (idlePaintContentRect.IsEmpty())
692 return; 693 return;
693 694
694 // Prepaint anything that was occluded but inside the layer's visible region . 695 // Prepaint anything that was occluded but inside the layer's visible region .
695 if (!updateTiles(left, top, right, bottom, queue, 0, stats, didPaint) || did Paint) 696 if (!updateTiles(left, top, right, bottom, queue, 0, stats, didPaint) || did Paint)
696 return; 697 return;
697 698
698 int prepaintLeft, prepaintTop, prepaintRight, prepaintBottom; 699 int prepaintLeft, prepaintTop, prepaintRight, prepaintBottom;
699 m_tiler->contentRectToTileIndices(idlePaintContentRect, prepaintLeft, prepai ntTop, prepaintRight, prepaintBottom); 700 m_tiler->contentRectToTileIndices(idlePaintContentRect, prepaintLeft, prepai ntTop, prepaintRight, prepaintBottom);
700 701
701 // Then expand outwards one row/column at a time until we find a dirty row/c olumn 702 // Then expand outwards one row/column at a time until we find a dirty row/c olumn
702 // to update. Increment along the major and minor scroll directions first. 703 // to update. Increment along the major and minor scroll directions first.
703 IntSize delta = -m_predictedScroll; 704 gfx::Vector2d delta = -m_predictedScroll;
704 delta = IntSize(delta.width() == 0 ? 1 : delta.width(), 705 delta = gfx::Vector2d(delta.x() == 0 ? 1 : delta.x(),
705 delta.height() == 0 ? 1 : delta.height()); 706 delta.y() == 0 ? 1 : delta.y());
706 IntSize majorDelta = (abs(delta.width()) > abs(delta.height())) ? IntSize(d elta.width(), 0) : IntSize(0, delta.height()); 707 gfx::Vector2d majorDelta = (abs(delta.x()) > abs(delta.y())) ? gfx::Vector2 d(delta.x(), 0) : gfx::Vector2d(0, delta.y());
707 IntSize minorDelta = (abs(delta.width()) <= abs(delta.height())) ? IntSize(d elta.width(), 0) : IntSize(0, delta.height()); 708 gfx::Vector2d minorDelta = (abs(delta.x()) <= abs(delta.y())) ? gfx::Vector2 d(delta.x(), 0) : gfx::Vector2d(0, delta.y());
708 IntSize deltas[4] = {majorDelta, minorDelta, -majorDelta, -minorDelta}; 709 gfx::Vector2d deltas[4] = {majorDelta, minorDelta, -majorDelta, -minorDelta} ;
709 for(int i = 0; i < 4; i++) { 710 for(int i = 0; i < 4; i++) {
710 if (deltas[i].height() > 0) { 711 if (deltas[i].y() > 0) {
711 while (bottom < prepaintBottom) { 712 while (bottom < prepaintBottom) {
712 ++bottom; 713 ++bottom;
713 if (!updateTiles(left, bottom, right, bottom, queue, 0, stats, d idPaint) || didPaint) 714 if (!updateTiles(left, bottom, right, bottom, queue, 0, stats, d idPaint) || didPaint)
714 return; 715 return;
715 } 716 }
716 } 717 }
717 if (deltas[i].height() < 0) { 718 if (deltas[i].y() < 0) {
718 while (top > prepaintTop) { 719 while (top > prepaintTop) {
719 --top; 720 --top;
720 if (!updateTiles(left, top, right, top, queue, 0, stats, didPain t) || didPaint) 721 if (!updateTiles(left, top, right, top, queue, 0, stats, didPain t) || didPaint)
721 return; 722 return;
722 } 723 }
723 } 724 }
724 if (deltas[i].width() < 0) { 725 if (deltas[i].x() < 0) {
725 while (left > prepaintLeft) { 726 while (left > prepaintLeft) {
726 --left; 727 --left;
727 if (!updateTiles(left, top, left, bottom, queue, 0, stats, didPa int) || didPaint) 728 if (!updateTiles(left, top, left, bottom, queue, 0, stats, didPa int) || didPaint)
728 return; 729 return;
729 } 730 }
730 } 731 }
731 if (deltas[i].width() > 0) { 732 if (deltas[i].x() > 0) {
732 while (right < prepaintRight) { 733 while (right < prepaintRight) {
733 ++right; 734 ++right;
734 if (!updateTiles(right, top, right, bottom, queue, 0, stats, did Paint) || didPaint) 735 if (!updateTiles(right, top, right, bottom, queue, 0, stats, did Paint) || didPaint)
735 return; 736 return;
736 } 737 }
737 } 738 }
738 } 739 }
739 } 740 }
740 741
741 bool TiledLayer::needsIdlePaint() 742 bool TiledLayer::needsIdlePaint()
742 { 743 {
743 // Don't trigger more paints if we failed (as we'll just fail again). 744 // Don't trigger more paints if we failed (as we'll just fail again).
744 if (m_failedUpdate || visibleContentRect().isEmpty() || m_tiler->hasEmptyBou nds() || !drawsContent()) 745 if (m_failedUpdate || visibleContentRect().IsEmpty() || m_tiler->hasEmptyBou nds() || !drawsContent())
745 return false; 746 return false;
746 747
747 IntRect idlePaintContentRect = idlePaintRect(); 748 gfx::Rect idlePaintContentRect = idlePaintRect();
748 if (idlePaintContentRect.isEmpty()) 749 if (idlePaintContentRect.IsEmpty())
749 return false; 750 return false;
750 751
751 int left, top, right, bottom; 752 int left, top, right, bottom;
752 m_tiler->contentRectToTileIndices(idlePaintContentRect, left, top, right, bo ttom); 753 m_tiler->contentRectToTileIndices(idlePaintContentRect, left, top, right, bo ttom);
753 754
754 for (int j = top; j <= bottom; ++j) { 755 for (int j = top; j <= bottom; ++j) {
755 for (int i = left; i <= right; ++i) { 756 for (int i = left; i <= right; ++i) {
756 UpdatableTile* tile = tileAt(i, j); 757 UpdatableTile* tile = tileAt(i, j);
757 DCHECK(tile); // Did setTexturePriorities get skipped? 758 DCHECK(tile); // Did setTexturePriorities get skipped?
758 if (!tile) 759 if (!tile)
759 continue; 760 continue;
760 761
761 bool updated = !tile->updateRect.isEmpty(); 762 bool updated = !tile->updateRect.IsEmpty();
762 bool canAcquire = tile->managedTexture()->canAcquireBackingTexture() ; 763 bool canAcquire = tile->managedTexture()->canAcquireBackingTexture() ;
763 bool dirty = tile->isDirty() || !tile->managedTexture()->haveBacking Texture(); 764 bool dirty = tile->isDirty() || !tile->managedTexture()->haveBacking Texture();
764 if (!updated && canAcquire && dirty) 765 if (!updated && canAcquire && dirty)
765 return true; 766 return true;
766 } 767 }
767 } 768 }
768 return false; 769 return false;
769 } 770 }
770 771
771 IntRect TiledLayer::idlePaintRect() 772 gfx::Rect TiledLayer::idlePaintRect()
772 { 773 {
773 // Don't inflate an empty rect. 774 // Don't inflate an empty rect.
774 if (visibleContentRect().isEmpty()) 775 if (visibleContentRect().IsEmpty())
775 return IntRect(); 776 return gfx::Rect();
776 777
777 IntRect prepaintRect = visibleContentRect(); 778 gfx::Rect prepaintRect = visibleContentRect();
778 prepaintRect.inflateX(m_tiler->tileSize().width() * prepaintColumns); 779 prepaintRect.Inset(-m_tiler->tileSize().width() * prepaintColumns,
779 prepaintRect.inflateY(m_tiler->tileSize().height() * prepaintRows); 780 -m_tiler->tileSize().height() * prepaintRows);
780 IntRect contentRect(IntPoint::zero(), contentBounds()); 781 gfx::Rect contentRect(gfx::Point(), contentBounds());
781 prepaintRect.intersect(contentRect); 782 prepaintRect.Intersect(contentRect);
782 783
783 return prepaintRect; 784 return prepaintRect;
784 } 785 }
785 786
786 } 787 }
OLDNEW
« no previous file with comments | « cc/tiled_layer.h ('k') | cc/tiled_layer_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698