Changeset 109273 in webkit
- Timestamp:
- Feb 29, 2012 3:10:06 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r109271 r109273 1 2012-02-29 Beth Dakin <bdakin@apple.com> 2 3 https://bugs.webkit.org/show_bug.cgi?id=79705 4 didNewFirstVisuallyNonEmptyLayout should be enhanced to look at size instead 5 of a raw tally 6 -and corresponding- 7 <rdar://problem/10821314> 8 9 Reviewed by Dave Hyatt. 10 11 Instead of firing didNewFirstVisuallyNonEmptyLayout() when a raw tally of 12 relevant painted objects has reached a port-defined threshold, this patch 13 looks at the size of those objects with respect to the view area. The patch 14 also looks at relevant objects that cannot yet be fully painted, such as 15 incrementally loading images. 16 17 We no longer need a HashSet for the relevant painted objects since Region can 18 do all of the heavy lifting. We now have a Region for the painted and 19 unpainted regions. We do need a HashSet for the unpainted objects though, 20 because we need to know if a painted object needs to be subtracted from the 21 unpainted region before being added to the painted region. 22 * page/Page.cpp: 23 (WebCore): 24 (WebCore::Page::isCountingRelevantRepaintedObjects): 25 (WebCore::Page::startCountingRelevantRepaintedObjects): 26 (WebCore::Page::resetRelevantPaintedObjectCounter): 27 (WebCore::Page::addRelevantRepaintedObject): 28 (WebCore::Page::addRelevantUnpaintedObject): 29 * page/Page.h: 30 (Page): 31 32 New function on Region iterates through the rects and calculates the total 33 area. 34 * platform/graphics/Region.cpp: 35 (WebCore::Region::totalArea): 36 (WebCore): 37 * platform/graphics/Region.h: 38 (Region): 39 40 Remove code from these classes since they are not actually relevant objects. 41 * rendering/InlineBox.cpp: 42 (WebCore::InlineBox::paint): 43 * rendering/RenderRegion.cpp: 44 (WebCore::RenderRegion::paintReplaced): 45 * rendering/RenderReplaced.cpp: 46 (WebCore::RenderReplaced::paint): 47 48 All of these other callers send a rect that actually represents their size 49 (usually the visualOverflowRect) instead of the paintInfo's paintRect, and 50 they call addRelevantUnpaintedObject when appropriate. 51 * rendering/InlineTextBox.cpp: 52 (WebCore::InlineTextBox::paint): 53 * rendering/RenderEmbeddedObject.cpp: 54 (WebCore::RenderEmbeddedObject::paint): 55 (WebCore::RenderEmbeddedObject::paintReplaced): 56 * rendering/RenderHTMLCanvas.cpp: 57 (WebCore::RenderHTMLCanvas::paintReplaced): 58 * rendering/RenderImage.cpp: 59 (WebCore::RenderImage::paintReplaced): 60 * rendering/RenderVideo.cpp: 61 (WebCore::RenderVideo::paintReplaced): 62 * rendering/svg/RenderSVGRoot.cpp: 63 (WebCore::RenderSVGRoot::paintReplaced): 64 1 65 2012-02-29 Joshua Bell <jsbell@chromium.org> 2 66 -
trunk/Source/WebCore/page/Page.cpp
r108958 r109273 1010 1010 #endif 1011 1011 1012 // FIXME: gPaintedObjectCounterThreshold is no longer used for calculating relevant repainted areas, 1013 // and it should be removed. For the time being, it is useful because it allows us to avoid doing 1014 // any of this work for ports that don't make sure of didNewFirstVisuallyNonEmptyLayout. We should 1015 // remove this when we resolve <rdar://problem/10791680> Need to merge didFirstVisuallyNonEmptyLayout 1016 // and didNewFirstVisuallyNonEmptyLayout 1012 1017 static uint64_t gPaintedObjectCounterThreshold = 0; 1013 1018 1019 // These are magical constants that might be tweaked over time. 1020 static double gMinimumPaintedAreaRatio = 0.1; 1021 static double gMaximumUnpaintedAreaRatio = 0.1; 1022 1014 1023 void Page::setRelevantRepaintedObjectsCounterThreshold(uint64_t threshold) 1015 1024 { … … 1017 1026 } 1018 1027 1028 bool Page::isCountingRelevantRepaintedObjects() const 1029 { 1030 return m_isCountingRelevantRepaintedObjects && gPaintedObjectCounterThreshold > 0; 1031 } 1032 1019 1033 void Page::startCountingRelevantRepaintedObjects() 1020 1034 { 1021 1035 m_isCountingRelevantRepaintedObjects = true; 1022 1036 1023 // Clear the HashSet in case we didn't hit the threshold last time. 1024 m_relevantPaintedRenderObjects.clear(); 1037 // Reset everything in case we didn't hit the threshold last time. 1038 resetRelevantPaintedObjectCounter(); 1039 } 1040 1041 void Page::resetRelevantPaintedObjectCounter() 1042 { 1043 m_relevantUnpaintedRenderObjects.clear(); 1044 m_relevantPaintedRegion = Region(); 1045 m_relevantUnpaintedRegion = Region(); 1025 1046 } 1026 1047 1027 1048 void Page::addRelevantRepaintedObject(RenderObject* object, const IntRect& objectPaintRect) 1028 1049 { 1029 if (!m_isCountingRelevantRepaintedObjects) 1030 return; 1031 1032 // We don't need to do anything if there is no counter threshold. 1033 if (!gPaintedObjectCounterThreshold) 1050 if (!isCountingRelevantRepaintedObjects()) 1034 1051 return; 1035 1052 … … 1040 1057 } 1041 1058 1042 m_relevantPaintedRenderObjects.add(object); 1043 1044 if (m_relevantPaintedRenderObjects.size() == static_cast<int>(gPaintedObjectCounterThreshold)) { 1059 // If this object was previously counted as an unpainted object, remove it from that HashSet 1060 // and corresponding Region. FIXME: This doesn't do the right thing if the objects overlap. 1061 if (m_relevantUnpaintedRenderObjects.contains(object)) { 1062 m_relevantUnpaintedRenderObjects.remove(object); 1063 m_relevantUnpaintedRegion.subtract(objectPaintRect); 1064 } 1065 1066 m_relevantPaintedRegion.unite(objectPaintRect); 1067 1068 RenderView* view = object->view(); 1069 if (!view) 1070 return; 1071 1072 float viewArea = view->viewRect().width() * view->viewRect().height(); 1073 float ratioOfViewThatIsPainted = m_relevantPaintedRegion.totalArea() / viewArea; 1074 float ratioOfViewThatIsUnpainted = m_relevantUnpaintedRegion.totalArea() / viewArea; 1075 1076 if (ratioOfViewThatIsPainted > gMinimumPaintedAreaRatio && ratioOfViewThatIsUnpainted < gMaximumUnpaintedAreaRatio) { 1045 1077 m_isCountingRelevantRepaintedObjects = false; 1046 m_relevantPaintedRenderObjects.clear();1078 resetRelevantPaintedObjectCounter(); 1047 1079 if (Frame* frame = mainFrame()) 1048 1080 frame->loader()->didNewFirstVisuallyNonEmptyLayout(); 1049 1081 } 1082 } 1083 1084 void Page::addRelevantUnpaintedObject(RenderObject* object, const IntRect& objectPaintRect) 1085 { 1086 if (!isCountingRelevantRepaintedObjects()) 1087 return; 1088 1089 // The objects are only relevant if they are being painted within the viewRect(). 1090 if (RenderView* view = object->view()) { 1091 if (!objectPaintRect.intersects(pixelSnappedIntRect(view->viewRect()))) 1092 return; 1093 } 1094 1095 m_relevantUnpaintedRenderObjects.add(object); 1096 m_relevantUnpaintedRegion.unite(objectPaintRect); 1050 1097 } 1051 1098 -
trunk/Source/WebCore/page/Page.h
r108958 r109273 28 28 #include "PlatformScreen.h" 29 29 #include "PlatformString.h" 30 #include "Region.h" 30 31 #include "Supplementable.h" 31 32 #include "ViewportArguments.h" … … 321 322 PlatformDisplayID displayID() const { return m_displayID; } 322 323 324 bool isCountingRelevantRepaintedObjects() const; 323 325 void setRelevantRepaintedObjectsCounterThreshold(uint64_t); 324 326 void startCountingRelevantRepaintedObjects(); 327 void resetRelevantPaintedObjectCounter(); 325 328 void addRelevantRepaintedObject(RenderObject*, const IntRect& objectPaintRect); 329 void addRelevantUnpaintedObject(RenderObject*, const IntRect& objectPaintRect); 326 330 327 331 private: … … 419 423 PlatformDisplayID m_displayID; 420 424 421 HashSet<RenderObject*> m_relevantPaintedRenderObjects; 425 HashSet<RenderObject*> m_relevantUnpaintedRenderObjects; 426 Region m_relevantPaintedRegion; 427 Region m_relevantUnpaintedRegion; 422 428 bool m_isCountingRelevantRepaintedObjects; 423 429 }; -
trunk/Source/WebCore/platform/graphics/Region.cpp
r108433 r109273 78 78 } 79 79 80 unsigned Region::totalArea() const 81 { 82 Vector<IntRect> rects = this->rects(); 83 size_t size = rects.size(); 84 unsigned totalArea = 0; 85 86 for (size_t i = 0; i < size; ++i) { 87 IntRect rect = rects[i]; 88 totalArea += (rect.width() * rect.height()); 89 } 90 91 return totalArea; 92 } 93 80 94 Region::Shape::Shape() 81 95 { -
trunk/Source/WebCore/platform/graphics/Region.h
r107013 r109273 52 52 53 53 bool contains(const IntPoint&) const; 54 55 unsigned totalArea() const; 54 56 55 57 #ifndef NDEBUG -
trunk/Source/WebCore/rendering/InlineBox.cpp
r106492 r109273 214 214 return; 215 215 216 if (Frame* frame = renderer()->frame()) {217 if (Page* page = frame->page())218 page->addRelevantRepaintedObject(renderer(), paintInfo.rect);219 }220 221 216 LayoutPoint childPoint = paintOffset; 222 217 if (parent()->renderer()->style()->isFlippedBlocksWritingMode()) // Faster than calling containingBlock(). -
trunk/Source/WebCore/rendering/InlineTextBox.cpp
r106492 r109273 498 498 499 499 if (Frame* frame = renderer()->frame()) { 500 if (Page* page = frame->page()) 501 page->addRelevantRepaintedObject(renderer(), paintInfo.rect); 500 if (Page* page = frame->page()) { 501 // FIXME: Right now, InlineTextBoxes never call addRelevantUnpaintedObject() even though they might 502 // legitimately be unpainted if they are waiting on a slow-loading web font. We should fix that, and 503 // when we do, we will have to account for the fact the InlineTextBoxes do not always have unique 504 // renderers and Page currently relies on each unpainted object having a unique renderer. 505 if (paintInfo.phase == PaintPhaseForeground) 506 page->addRelevantRepaintedObject(renderer(), IntRect(adjustedPaintOffset.x(), adjustedPaintOffset.y(), logicalWidth(), logicalHeight())); 507 } 502 508 } 503 509 -
trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp
r107296 r109273 140 140 void RenderEmbeddedObject::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 141 141 { 142 Page* page = 0; 143 if (Frame* frame = this->frame()) 144 page = frame->page(); 145 142 146 if (pluginCrashedOrWasMissing()) { 147 if (page && paintInfo.phase == PaintPhaseForeground) 148 page->addRelevantUnpaintedObject(this, visualOverflowRect()); 143 149 RenderReplaced::paint(paintInfo, paintOffset); 144 150 return; 145 151 } 146 152 153 if (page && paintInfo.phase == PaintPhaseForeground) 154 page->addRelevantRepaintedObject(this, visualOverflowRect()); 155 147 156 RenderPart::paint(paintInfo, paintOffset); 148 157 } … … 168 177 if (!getReplacementTextGeometry(paintOffset, contentRect, path, replacementTextRect, font, run, textWidth)) 169 178 return; 170 171 if (Frame* frame = this->frame()) {172 if (Page* page = frame->page())173 page->addRelevantRepaintedObject(this, paintInfo.rect);174 }175 179 176 180 GraphicsContextStateSaver stateSaver(*context); -
trunk/Source/WebCore/rendering/RenderHTMLCanvas.cpp
r106492 r109273 59 59 void RenderHTMLCanvas::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 60 60 { 61 LayoutRect rect = contentBoxRect(); 62 rect.moveBy(paintOffset); 63 61 64 if (Frame* frame = this->frame()) { 62 if (Page* page = frame->page()) 63 page->addRelevantRepaintedObject(this, paintInfo.rect); 65 if (Page* page = frame->page()) { 66 if (paintInfo.phase == PaintPhaseForeground) 67 page->addRelevantRepaintedObject(this, rect); 68 } 64 69 } 65 70 66 LayoutRect rect = contentBoxRect();67 rect.moveBy(paintOffset);68 71 bool useLowQualityScale = style()->imageRendering() == ImageRenderingOptimizeContrast; 69 72 static_cast<HTMLCanvasElement*>(node())->paint(paintInfo.context, rect, useLowQualityScale); -
trunk/Source/WebCore/rendering/RenderImage.cpp
r107461 r109273 265 265 GraphicsContext* context = paintInfo.context; 266 266 267 Page* page = 0; 268 if (Frame* frame = this->frame()) 269 page = frame->page(); 270 267 271 if (!m_imageResource->hasImage() || m_imageResource->errorOccurred()) { 268 272 if (paintInfo.phase == PaintPhaseSelection) 269 273 return; 274 275 if (page && paintInfo.phase == PaintPhaseForeground) 276 page->addRelevantUnpaintedObject(this, visualOverflowRect()); 270 277 271 278 if (cWidth > 2 && cHeight > 2) { … … 326 333 } else if (m_imageResource->hasImage() && cWidth > 0 && cHeight > 0) { 327 334 RefPtr<Image> img = m_imageResource->image(cWidth, cHeight); 328 if (!img || img->isNull()) 335 if (!img || img->isNull()) { 336 if (page && paintInfo.phase == PaintPhaseForeground) 337 page->addRelevantUnpaintedObject(this, visualOverflowRect()); 329 338 return; 330 331 if (Frame* frame = this->frame()) { 332 if (Page* page = frame->page()) 333 page->addRelevantRepaintedObject(this, paintInfo.rect); 339 } 340 341 if (page && paintInfo.phase == PaintPhaseForeground) { 342 // For now, count images as unpainted if they are still progressively loading. We may want 343 // to refine this in the future to account for the portion of the image that has painted. 344 if (cachedImage()->isLoading()) 345 page->addRelevantUnpaintedObject(this, visualOverflowRect()); 346 else 347 page->addRelevantRepaintedObject(this, visualOverflowRect()); 334 348 } 335 349 -
trunk/Source/WebCore/rendering/RenderRegion.cpp
r108952 r109273 140 140 return; 141 141 142 if (Frame* frame = this->frame()) {143 if (Page* page = frame->page())144 page->addRelevantRepaintedObject(this, paintInfo.rect);145 }146 147 142 setRegionBoxesRegionStyle(); 148 143 m_flowThread->paintIntoRegion(paintInfo, this, LayoutPoint(paintOffset.x() + borderLeft() + paddingLeft(), paintOffset.y() + borderTop() + paddingTop())); -
trunk/Source/WebCore/rendering/RenderReplaced.cpp
r109246 r109273 138 138 } 139 139 140 if (Frame* frame = this->frame()) {141 if (Page* page = frame->page())142 page->addRelevantRepaintedObject(this, paintInfo.rect);143 }144 145 140 bool completelyClippedOut = false; 146 141 if (style()->hasBorderRadius()) { -
trunk/Source/WebCore/rendering/RenderVideo.cpp
r106492 r109273 199 199 bool displayingPoster = videoElement()->shouldDisplayPosterImage(); 200 200 201 Page* page = 0; 202 if (Frame* frame = this->frame()) 203 page = frame->page(); 204 201 205 if (!displayingPoster) { 202 if (!mediaPlayer) 206 if (!mediaPlayer) { 207 if (page && paintInfo.phase == PaintPhaseForeground) 208 page->addRelevantUnpaintedObject(this, visualOverflowRect()); 203 209 return; 210 } 204 211 updatePlayer(); 205 212 } 206 213 207 214 LayoutRect rect = videoBox(); 208 if (rect.isEmpty()) 209 return; 215 if (rect.isEmpty()) { 216 if (page && paintInfo.phase == PaintPhaseForeground) 217 page->addRelevantUnpaintedObject(this, visualOverflowRect()); 218 return; 219 } 210 220 rect.moveBy(paintOffset); 211 221 212 if (Frame* frame = this->frame()) { 213 if (Page* page = frame->page()) 214 page->addRelevantRepaintedObject(this, paintInfo.rect); 215 } 222 if (page && paintInfo.phase == PaintPhaseForeground) 223 page->addRelevantRepaintedObject(this, visualOverflowRect()); 216 224 217 225 if (displayingPoster) -
trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
r109104 r109273 250 250 return; 251 251 252 Page* page = 0; 253 if (Frame* frame = this->frame()) 254 page = frame->page(); 255 252 256 // Don't paint if we don't have kids, except if we have filters we should paint those. 253 257 if (!firstChild()) { 254 258 SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this); 255 if (!resources || !resources->filter()) 259 if (!resources || !resources->filter()) { 260 if (page && paintInfo.phase == PaintPhaseForeground) 261 page->addRelevantUnpaintedObject(this, visualOverflowRect()); 256 262 return; 257 } 258 259 if (Frame* frame = this->frame()) { 260 if (Page* page = frame->page()) 261 page->addRelevantRepaintedObject(this, paintInfo.rect); 262 } 263 } 264 } 265 266 if (page && paintInfo.phase == PaintPhaseForeground) 267 page->addRelevantRepaintedObject(this, visualOverflowRect()); 263 268 264 269 // Make a copy of the PaintInfo because applyTransform will modify the damage rect.
Note: See TracChangeset
for help on using the changeset viewer.