Changeset 80330 in webkit
- Timestamp:
- Mar 3, 2011 11:03:55 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r80328 r80330 1 2011-03-03 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Dimitri Glazkov. 4 5 Refactor createRendererIfNeeded to avoid premature nextRenderer calculation 6 https://bugs.webkit.org/show_bug.cgi?id=55720 7 8 There are two thing going on here: 9 1. Delaying nextRenderer calculation until we actually use it, 10 previously we would always compute nextRenderer (expensive!) 11 even if no renderer insertion was to occur. 12 2. Fix fullscreen elements to be inserted into the right place 13 in the rendering tree. Previously they would always be the last 14 child in their parent's list, even if that wasn't the right place. 15 16 I don't know of any way to trigger the fullscreen bug, 17 but I tested this with peacekeeper and saw no performance change. 18 19 Peacekeeper's domJQueryBasics is now possibly as much as 2% faster 20 but I don't really trust the stability of peacekeeper to begin with. 21 22 This paves the way for further improvement in our nextRenderer calculation. 23 24 * dom/Node.cpp: 25 (WebCore::Node::attach): 26 (WebCore::Node::previousRenderer): 27 (WebCore::Node::nextRenderer): 28 (WebCore::Node::createRendererAndStyle): 29 (WebCore::wrapWithRenderFullScreen): 30 (WebCore::Node::createRendererIfNeeded): 31 * dom/Node.h: 32 1 33 2011-03-03 Ryosuke Niwa <rniwa@webkit.org> 2 34 -
trunk/Source/WebCore/dom/Node.cpp
r79269 r80330 1243 1243 ASSERT(!renderer() || (renderer()->style() && renderer()->parent())); 1244 1244 1245 // FIXME: This is O(N^2) for the innerHTML case, where all children are replaced at once (and not attached). 1245 1246 // If this node got a renderer it may be the previousRenderer() of sibling text nodes and thus affect the 1246 1247 // result of Text::rendererIsNeeded() for those nodes. … … 1286 1287 } 1287 1288 1288 RenderObject * Node::previousRenderer() 1289 { 1290 for (Node *n = previousSibling(); n; n = n->previousSibling()) { 1289 RenderObject* Node::previousRenderer() 1290 { 1291 // FIXME: We should have the same O(N^2) avoidance as nextRenderer does 1292 // however, when I tried adding it, several tests failed. 1293 for (Node* n = previousSibling(); n; n = n->previousSibling()) { 1291 1294 if (n->renderer()) 1292 1295 return n->renderer(); … … 1295 1298 } 1296 1299 1297 RenderObject 1298 { 1299 // Avoid an O(n^2) problem with this function by not checking for nextRenderer() when the parent element hasn't even1300 // beenattached yet.1300 RenderObject* Node::nextRenderer() 1301 { 1302 // Avoid an O(n^2) problem with this function by not checking for 1303 // nextRenderer() when the parent element hasn't attached yet. 1301 1304 if (parentOrHostNode() && !parentOrHostNode()->attached()) 1302 1305 return 0; 1303 1306 1304 for (Node *n = nextSibling(); n; n = n->nextSibling()) {1307 for (Node* n = nextSibling(); n; n = n->nextSibling()) { 1305 1308 if (n->renderer()) 1306 1309 return n->renderer(); … … 1362 1365 } 1363 1366 1367 RenderObject* Node::createRendererAndStyle() 1368 { 1369 ASSERT(!renderer()); 1370 ASSERT(document()->shouldCreateRenderers()); 1371 1372 ContainerNode* parent = parentOrHostNode(); 1373 ASSERT(parent); 1374 RenderObject* parentRenderer = parent->renderer(); 1375 1376 // FIXME: Ignoring canHaveChildren() in a case of isShadowRoot() might be wrong. 1377 // See https://bugs.webkit.org/show_bug.cgi?id=52423 1378 if (!parentRenderer || (!parentRenderer->canHaveChildren() && !isShadowRoot()) || !parent->childShouldCreateRenderer(this)) 1379 return 0; 1380 1381 RefPtr<RenderStyle> style = styleForRenderer(); 1382 if (!rendererIsNeeded(style.get())) 1383 return 0; 1384 1385 RenderObject* newRenderer = createRenderer(document()->renderArena(), style.get()); 1386 if (!newRenderer) 1387 return 0; 1388 1389 if (!parentRenderer->isChildAllowed(newRenderer, style.get())) { 1390 newRenderer->destroy(); 1391 return 0; 1392 } 1393 setRenderer(newRenderer); 1394 newRenderer->setAnimatableStyle(style.release()); // setAnimatableStyle() can depend on renderer() already being set. 1395 return newRenderer; 1396 } 1397 1398 #if ENABLE(FULLSCREEN_API) 1399 static RenderFullScreen* wrapWithRenderFullScreen(RenderObject* object, Document* document) 1400 { 1401 RenderFullScreen* fullscreenRenderer = new (document->renderArena()) RenderFullScreen(document); 1402 fullscreenRenderer->setStyle(RenderFullScreen::createFullScreenStyle()); 1403 // It's possible that we failed to create the new render and end up wrapping nothing. 1404 // We'll end up displaying a black screen, but Jer says this is expected. 1405 if (object) 1406 fullscreenRenderer->addChild(object); 1407 document->setFullScreenRenderer(fullscreenRenderer); 1408 return fullscreenRenderer; 1409 } 1410 #endif 1411 1364 1412 void Node::createRendererIfNeeded() 1365 1413 { … … 1368 1416 1369 1417 ASSERT(!renderer()); 1370 1371 ContainerNode* parent = parentOrHostNode(); 1372 ASSERT(parent); 1373 1374 RenderObject* parentRenderer = parent->renderer(); 1375 RenderObject* nextRenderer = this->nextRenderer(); 1376 1418 1419 RenderObject* newRenderer = createRendererAndStyle(); 1420 1377 1421 #if ENABLE(FULLSCREEN_API) 1378 // If this node is a fullscreen node, create a new anonymous full screen 1379 // renderer. 1380 if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == this) { 1381 RenderFullScreen* fullscreenRenderer = new (document()->renderArena()) RenderFullScreen(document()); 1382 fullscreenRenderer->setStyle(RenderFullScreen::createFullScreenStyle()); 1383 parentRenderer->addChild(fullscreenRenderer, 0); 1384 parentRenderer = fullscreenRenderer; 1385 nextRenderer = 0; 1386 document()->setFullScreenRenderer(fullscreenRenderer); 1387 } 1422 if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == this) 1423 newRenderer = wrapWithRenderFullScreen(newRenderer, document()); 1388 1424 #endif 1389 1425 1390 // FIXME: Ignoreing canHaveChildren() in a case of isShadowRoot() might be wrong. 1391 // See https://bugs.webkit.org/show_bug.cgi?id=52423 1392 if (parentRenderer && (parentRenderer->canHaveChildren() || isShadowRoot()) && parent->childShouldCreateRenderer(this)) { 1393 RefPtr<RenderStyle> style = styleForRenderer(); 1394 if (rendererIsNeeded(style.get())) { 1395 if (RenderObject* r = createRenderer(document()->renderArena(), style.get())) { 1396 if (!parentRenderer->isChildAllowed(r, style.get())) 1397 r->destroy(); 1398 else { 1399 setRenderer(r); 1400 renderer()->setAnimatableStyle(style.release()); 1401 parentRenderer->addChild(renderer(), nextRenderer); 1402 } 1403 } 1404 } 1405 } 1426 if (!newRenderer) 1427 return; 1428 1429 // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer. 1430 parentOrHostNode()->renderer()->addChild(newRenderer, nextRenderer()); 1406 1431 } 1407 1432 -
trunk/Source/WebCore/dom/Node.h
r80231 r80330 660 660 void markAncestorsWithChildNeedsStyleRecalc(); 661 661 662 RenderObject* createRendererAndStyle(); 663 662 664 virtual void refEventTarget(); 663 665 virtual void derefEventTarget();
Note: See TracChangeset
for help on using the changeset viewer.