| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 #include "core/rendering/FilterEffectRenderer.h" | 60 #include "core/rendering/FilterEffectRenderer.h" |
| 61 | 61 |
| 62 #include "core/platform/graphics/GraphicsContext3D.h" | 62 #include "core/platform/graphics/GraphicsContext3D.h" |
| 63 | 63 |
| 64 using namespace std; | 64 using namespace std; |
| 65 | 65 |
| 66 namespace WebCore { | 66 namespace WebCore { |
| 67 | 67 |
| 68 using namespace HTMLNames; | 68 using namespace HTMLNames; |
| 69 | 69 |
| 70 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*); | |
| 71 static IntRect clipBox(RenderBox* renderer); | 70 static IntRect clipBox(RenderBox* renderer); |
| 72 | 71 |
| 73 static inline bool isAcceleratedCanvas(RenderObject* renderer) | 72 static IntRect contentsRect(const RenderObject* renderer) |
| 73 { |
| 74 if (!renderer->isBox()) |
| 75 return IntRect(); |
| 76 |
| 77 return renderer->isVideo() ? |
| 78 toRenderVideo(renderer)->videoBox() : |
| 79 pixelSnappedIntRect(toRenderBox(renderer)->contentBoxRect()); |
| 80 } |
| 81 |
| 82 static IntRect backgroundRect(const RenderObject* renderer) |
| 83 { |
| 84 if (!renderer->isBox()) |
| 85 return IntRect(); |
| 86 |
| 87 LayoutRect rect; |
| 88 const RenderBox* box = toRenderBox(renderer); |
| 89 EFillBox clip = box->style()->backgroundClip(); |
| 90 switch (clip) { |
| 91 case BorderFillBox: |
| 92 rect = box->borderBoxRect(); |
| 93 break; |
| 94 case PaddingFillBox: |
| 95 rect = box->paddingBoxRect(); |
| 96 break; |
| 97 case ContentFillBox: |
| 98 rect = box->contentBoxRect(); |
| 99 break; |
| 100 case TextFillBox: |
| 101 break; |
| 102 } |
| 103 |
| 104 return pixelSnappedIntRect(rect); |
| 105 } |
| 106 |
| 107 static inline bool isAcceleratedCanvas(const RenderObject* renderer) |
| 74 { | 108 { |
| 75 if (renderer->isCanvas()) { | 109 if (renderer->isCanvas()) { |
| 76 HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node()); | 110 HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node()); |
| 77 if (CanvasRenderingContext* context = canvas->renderingContext()) | 111 if (CanvasRenderingContext* context = canvas->renderingContext()) |
| 78 return context->isAccelerated(); | 112 return context->isAccelerated(); |
| 79 } | 113 } |
| 80 return false; | 114 return false; |
| 81 } | 115 } |
| 82 | 116 |
| 117 static bool hasBoxDecorations(const RenderStyle* style) |
| 118 { |
| 119 return style->hasBorder() || style->hasBorderRadius() || style->hasOutline()
|| style->hasAppearance() || style->boxShadow() || style->hasFilter(); |
| 120 } |
| 121 |
| 122 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style) |
| 123 { |
| 124 return hasBoxDecorations(style) || style->hasBackgroundImage(); |
| 125 } |
| 126 |
| 127 static bool contentLayerSupportsDirectBackgroundComposition(const RenderObject*
renderer) |
| 128 { |
| 129 // No support for decorations - border, border-radius or outline. |
| 130 // Only simple background - solid color or transparent. |
| 131 if (hasBoxDecorationsOrBackgroundImage(renderer->style())) |
| 132 return false; |
| 133 |
| 134 // If there is no background, there is nothing to support. |
| 135 if (!renderer->style()->hasBackground()) |
| 136 return true; |
| 137 |
| 138 // Simple background that is contained within the contents rect. |
| 139 return contentsRect(renderer).contains(backgroundRect(renderer)); |
| 140 } |
| 141 |
| 83 // Get the scrolling coordinator in a way that works inside RenderLayerBacking's
destructor. | 142 // Get the scrolling coordinator in a way that works inside RenderLayerBacking's
destructor. |
| 84 static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer* layer) | 143 static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer* layer) |
| 85 { | 144 { |
| 86 Page* page = layer->renderer()->frame()->page(); | 145 Page* page = layer->renderer()->frame()->page(); |
| 87 if (!page) | 146 if (!page) |
| 88 return 0; | 147 return 0; |
| 89 | 148 |
| 90 return page->scrollingCoordinator(); | 149 return page->scrollingCoordinator(); |
| 91 } | 150 } |
| 92 | 151 |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 // m_scrollingContentsLayer only needs backing store if the scrolled con
tents need to paint. | 818 // m_scrollingContentsLayer only needs backing store if the scrolled con
tents need to paint. |
| 760 bool hasNonScrollingPaintedContent = m_owningLayer->hasVisibleContent()
&& m_owningLayer->hasBoxDecorationsOrBackground(); | 819 bool hasNonScrollingPaintedContent = m_owningLayer->hasVisibleContent()
&& m_owningLayer->hasBoxDecorationsOrBackground(); |
| 761 m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent); | 820 m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent); |
| 762 | 821 |
| 763 bool hasScrollingPaintedContent = m_owningLayer->hasVisibleContent() &&
(renderer()->hasBackground() || paintsChildren()); | 822 bool hasScrollingPaintedContent = m_owningLayer->hasVisibleContent() &&
(renderer()->hasBackground() || paintsChildren()); |
| 764 m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent); | 823 m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent); |
| 765 return; | 824 return; |
| 766 } | 825 } |
| 767 | 826 |
| 768 bool hasPaintedContent = containsPaintedContent(isSimpleContainer); | 827 bool hasPaintedContent = containsPaintedContent(isSimpleContainer); |
| 828 if (hasPaintedContent && isAcceleratedCanvas(renderer())) { |
| 829 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->
node()); |
| 830 CanvasRenderingContext* context = canvas->renderingContext(); |
| 831 // Content layer may be null if context is lost. |
| 832 if (WebKit::WebLayer* contentLayer = context->platformLayer()) { |
| 833 Color bgColor; |
| 834 if (contentLayerSupportsDirectBackgroundComposition(renderer())) { |
| 835 bgColor = rendererBackgroundColor(); |
| 836 hasPaintedContent = false; |
| 837 } |
| 838 contentLayer->setBackgroundColor(bgColor.rgb()); |
| 839 } |
| 840 } |
| 769 | 841 |
| 770 // FIXME: we could refine this to only allocate backing for one of these lay
ers if possible. | 842 // FIXME: we could refine this to only allocate backing for one of these lay
ers if possible. |
| 771 m_graphicsLayer->setDrawsContent(hasPaintedContent); | 843 m_graphicsLayer->setDrawsContent(hasPaintedContent); |
| 772 if (m_foregroundLayer) | 844 if (m_foregroundLayer) |
| 773 m_foregroundLayer->setDrawsContent(hasPaintedContent); | 845 m_foregroundLayer->setDrawsContent(hasPaintedContent); |
| 774 | 846 |
| 775 if (m_backgroundLayer) | 847 if (m_backgroundLayer) |
| 776 m_backgroundLayer->setDrawsContent(hasPaintedContent); | 848 m_backgroundLayer->setDrawsContent(hasPaintedContent); |
| 777 } | 849 } |
| 778 | 850 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 // relative to it. So we can break here. | 1141 // relative to it. So we can break here. |
| 1070 if (curr->isComposited()) | 1142 if (curr->isComposited()) |
| 1071 break; | 1143 break; |
| 1072 | 1144 |
| 1073 finalOpacity *= curr->renderer()->opacity(); | 1145 finalOpacity *= curr->renderer()->opacity(); |
| 1074 } | 1146 } |
| 1075 | 1147 |
| 1076 return finalOpacity; | 1148 return finalOpacity; |
| 1077 } | 1149 } |
| 1078 | 1150 |
| 1079 static bool hasBoxDecorations(const RenderStyle* style) | |
| 1080 { | |
| 1081 return style->hasBorder() || style->hasBorderRadius() || style->hasOutline()
|| style->hasAppearance() || style->boxShadow() || style->hasFilter(); | |
| 1082 } | |
| 1083 | |
| 1084 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style) | |
| 1085 { | |
| 1086 return hasBoxDecorations(style) || style->hasBackgroundImage(); | |
| 1087 } | |
| 1088 | |
| 1089 Color RenderLayerBacking::rendererBackgroundColor() const | 1151 Color RenderLayerBacking::rendererBackgroundColor() const |
| 1090 { | 1152 { |
| 1091 RenderObject* backgroundRenderer = renderer(); | 1153 RenderObject* backgroundRenderer = renderer(); |
| 1092 if (backgroundRenderer->isRoot()) | 1154 if (backgroundRenderer->isRoot()) |
| 1093 backgroundRenderer = backgroundRenderer->rendererForRootBackground(); | 1155 backgroundRenderer = backgroundRenderer->rendererForRootBackground(); |
| 1094 | 1156 |
| 1095 return backgroundRenderer->resolveColor(CSSPropertyBackgroundColor); | 1157 return backgroundRenderer->resolveColor(CSSPropertyBackgroundColor); |
| 1096 } | 1158 } |
| 1097 | 1159 |
| 1098 void RenderLayerBacking::updateBackgroundColor(bool isSimpleContainer) | 1160 void RenderLayerBacking::updateBackgroundColor(bool isSimpleContainer) |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1262 return false; | 1324 return false; |
| 1263 | 1325 |
| 1264 if (isDirectlyCompositedImage()) | 1326 if (isDirectlyCompositedImage()) |
| 1265 return false; | 1327 return false; |
| 1266 | 1328 |
| 1267 // FIXME: we could optimize cases where the image, video or canvas is known
to fill the border box entirely, | 1329 // FIXME: we could optimize cases where the image, video or canvas is known
to fill the border box entirely, |
| 1268 // and set background color on the layer in that case, instead of allocating
backing store and painting. | 1330 // and set background color on the layer in that case, instead of allocating
backing store and painting. |
| 1269 if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo()
) | 1331 if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo()
) |
| 1270 return m_owningLayer->hasBoxDecorationsOrBackground(); | 1332 return m_owningLayer->hasBoxDecorationsOrBackground(); |
| 1271 | 1333 |
| 1272 if (isAcceleratedCanvas(renderer())) | |
| 1273 return m_owningLayer->hasBoxDecorationsOrBackground(); | |
| 1274 | |
| 1275 return true; | 1334 return true; |
| 1276 } | 1335 } |
| 1277 | 1336 |
| 1278 // An image can be directly compositing if it's the sole content of the layer, a
nd has no box decorations | 1337 // An image can be directly compositing if it's the sole content of the layer, a
nd has no box decorations |
| 1279 // that require painting. Direct compositing saves backing store. | 1338 // that require painting. Direct compositing saves backing store. |
| 1280 bool RenderLayerBacking::isDirectlyCompositedImage() const | 1339 bool RenderLayerBacking::isDirectlyCompositedImage() const |
| 1281 { | 1340 { |
| 1282 RenderObject* renderObject = renderer(); | 1341 RenderObject* renderObject = renderer(); |
| 1283 | 1342 |
| 1284 if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground
() || renderObject->hasClip()) | 1343 if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground
() || renderObject->hasClip()) |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1373 } | 1432 } |
| 1374 | 1433 |
| 1375 // Return the offset from the top-left of this compositing layer at which the re
nderer's contents are painted. | 1434 // Return the offset from the top-left of this compositing layer at which the re
nderer's contents are painted. |
| 1376 IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const | 1435 IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const |
| 1377 { | 1436 { |
| 1378 return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y()); | 1437 return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y()); |
| 1379 } | 1438 } |
| 1380 | 1439 |
| 1381 IntRect RenderLayerBacking::contentsBox() const | 1440 IntRect RenderLayerBacking::contentsBox() const |
| 1382 { | 1441 { |
| 1383 if (!renderer()->isBox()) | 1442 IntRect contentsBox = contentsRect(renderer()); |
| 1384 return IntRect(); | 1443 contentsBox.move(contentOffsetInCompostingLayer()); |
| 1385 | 1444 return contentsBox; |
| 1386 IntRect contentsRect; | |
| 1387 if (renderer()->isVideo()) { | |
| 1388 RenderVideo* videoRenderer = toRenderVideo(renderer()); | |
| 1389 contentsRect = videoRenderer->videoBox(); | |
| 1390 } else | |
| 1391 contentsRect = pixelSnappedIntRect(toRenderBox(renderer())->contentBoxRe
ct()); | |
| 1392 | |
| 1393 contentsRect.move(contentOffsetInCompostingLayer()); | |
| 1394 return contentsRect; | |
| 1395 } | |
| 1396 | |
| 1397 static LayoutRect backgroundRectForBox(const RenderBox* box) | |
| 1398 { | |
| 1399 EFillBox clip = box->style()->backgroundClip(); | |
| 1400 switch (clip) { | |
| 1401 case BorderFillBox: | |
| 1402 return box->borderBoxRect(); | |
| 1403 case PaddingFillBox: | |
| 1404 return box->paddingBoxRect(); | |
| 1405 case ContentFillBox: | |
| 1406 return box->contentBoxRect(); | |
| 1407 case TextFillBox: | |
| 1408 break; | |
| 1409 } | |
| 1410 | |
| 1411 ASSERT_NOT_REACHED(); | |
| 1412 return LayoutRect(); | |
| 1413 } | 1445 } |
| 1414 | 1446 |
| 1415 IntRect RenderLayerBacking::backgroundBox() const | 1447 IntRect RenderLayerBacking::backgroundBox() const |
| 1416 { | 1448 { |
| 1417 if (!renderer()->isBox()) | 1449 IntRect backgroundBox = backgroundRect(renderer()); |
| 1418 return IntRect(); | 1450 backgroundBox.move(contentOffsetInCompostingLayer()); |
| 1419 | 1451 return backgroundBox; |
| 1420 IntRect pixelSnappedBackgroundBox = pixelSnappedIntRect(backgroundRectForBox
(toRenderBox(renderer()))); | |
| 1421 pixelSnappedBackgroundBox.move(contentOffsetInCompostingLayer()); | |
| 1422 return pixelSnappedBackgroundBox; | |
| 1423 } | 1452 } |
| 1424 | 1453 |
| 1425 GraphicsLayer* RenderLayerBacking::parentForSublayers() const | 1454 GraphicsLayer* RenderLayerBacking::parentForSublayers() const |
| 1426 { | 1455 { |
| 1427 if (m_scrollingContentsLayer) | 1456 if (m_scrollingContentsLayer) |
| 1428 return m_scrollingContentsLayer.get(); | 1457 return m_scrollingContentsLayer.get(); |
| 1429 | 1458 |
| 1430 return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsL
ayer.get(); | 1459 return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsL
ayer.get(); |
| 1431 } | 1460 } |
| 1432 | 1461 |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1866 if (m_layerForVerticalScrollbar) | 1895 if (m_layerForVerticalScrollbar) |
| 1867 backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate
(); | 1896 backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate
(); |
| 1868 | 1897 |
| 1869 if (m_layerForScrollCorner) | 1898 if (m_layerForScrollCorner) |
| 1870 backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate(); | 1899 backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate(); |
| 1871 | 1900 |
| 1872 return backingMemory; | 1901 return backingMemory; |
| 1873 } | 1902 } |
| 1874 | 1903 |
| 1875 } // namespace WebCore | 1904 } // namespace WebCore |
| OLD | NEW |