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

Side by Side Diff: Source/core/rendering/RenderLayerBacking.cpp

Issue 19543014: Direct composite canvas background if possible. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: re-uploading patch Created 7 years, 5 months 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
OLDNEW
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
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
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 Color bgColor;
830 if (contentLayerSupportsDirectBackgroundComposition(renderer())) {
831 bgColor = rendererBackgroundColor();
832 hasPaintedContent = false;
833 }
834 HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()-> node());
835 CanvasRenderingContext* context = canvas->renderingContext();
836 context->platformLayer()->setBackgroundColor(bgColor.rgb());
837 }
769 838
770 // FIXME: we could refine this to only allocate backing for one of these lay ers if possible. 839 // FIXME: we could refine this to only allocate backing for one of these lay ers if possible.
771 m_graphicsLayer->setDrawsContent(hasPaintedContent); 840 m_graphicsLayer->setDrawsContent(hasPaintedContent);
772 if (m_foregroundLayer) 841 if (m_foregroundLayer)
773 m_foregroundLayer->setDrawsContent(hasPaintedContent); 842 m_foregroundLayer->setDrawsContent(hasPaintedContent);
774 843
775 if (m_backgroundLayer) 844 if (m_backgroundLayer)
776 m_backgroundLayer->setDrawsContent(hasPaintedContent); 845 m_backgroundLayer->setDrawsContent(hasPaintedContent);
777 } 846 }
778 847
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 // relative to it. So we can break here. 1138 // relative to it. So we can break here.
1070 if (curr->isComposited()) 1139 if (curr->isComposited())
1071 break; 1140 break;
1072 1141
1073 finalOpacity *= curr->renderer()->opacity(); 1142 finalOpacity *= curr->renderer()->opacity();
1074 } 1143 }
1075 1144
1076 return finalOpacity; 1145 return finalOpacity;
1077 } 1146 }
1078 1147
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 1148 Color RenderLayerBacking::rendererBackgroundColor() const
1090 { 1149 {
1091 RenderObject* backgroundRenderer = renderer(); 1150 RenderObject* backgroundRenderer = renderer();
1092 if (backgroundRenderer->isRoot()) 1151 if (backgroundRenderer->isRoot())
1093 backgroundRenderer = backgroundRenderer->rendererForRootBackground(); 1152 backgroundRenderer = backgroundRenderer->rendererForRootBackground();
1094 1153
1095 return backgroundRenderer->resolveColor(CSSPropertyBackgroundColor); 1154 return backgroundRenderer->resolveColor(CSSPropertyBackgroundColor);
1096 } 1155 }
1097 1156
1098 void RenderLayerBacking::updateBackgroundColor(bool isSimpleContainer) 1157 void RenderLayerBacking::updateBackgroundColor(bool isSimpleContainer)
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 return false; 1321 return false;
1263 1322
1264 if (isDirectlyCompositedImage()) 1323 if (isDirectlyCompositedImage())
1265 return false; 1324 return false;
1266 1325
1267 // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely, 1326 // 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. 1327 // and set background color on the layer in that case, instead of allocating backing store and painting.
1269 if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo() ) 1328 if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo() )
1270 return m_owningLayer->hasBoxDecorationsOrBackground(); 1329 return m_owningLayer->hasBoxDecorationsOrBackground();
1271 1330
1272 if (isAcceleratedCanvas(renderer()))
1273 return m_owningLayer->hasBoxDecorationsOrBackground();
1274
1275 return true; 1331 return true;
1276 } 1332 }
1277 1333
1278 // An image can be directly compositing if it's the sole content of the layer, a nd has no box decorations 1334 // 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. 1335 // that require painting. Direct compositing saves backing store.
1280 bool RenderLayerBacking::isDirectlyCompositedImage() const 1336 bool RenderLayerBacking::isDirectlyCompositedImage() const
1281 { 1337 {
1282 RenderObject* renderObject = renderer(); 1338 RenderObject* renderObject = renderer();
1283 1339
1284 if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground () || renderObject->hasClip()) 1340 if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground () || renderObject->hasClip())
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 } 1429 }
1374 1430
1375 // Return the offset from the top-left of this compositing layer at which the re nderer's contents are painted. 1431 // 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 1432 IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const
1377 { 1433 {
1378 return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y()); 1434 return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y());
1379 } 1435 }
1380 1436
1381 IntRect RenderLayerBacking::contentsBox() const 1437 IntRect RenderLayerBacking::contentsBox() const
1382 { 1438 {
1383 if (!renderer()->isBox()) 1439 IntRect contentsBox = contentsRect(renderer());
1384 return IntRect(); 1440 contentsBox.move(contentOffsetInCompostingLayer());
1385 1441 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 } 1442 }
1414 1443
1415 IntRect RenderLayerBacking::backgroundBox() const 1444 IntRect RenderLayerBacking::backgroundBox() const
1416 { 1445 {
1417 if (!renderer()->isBox()) 1446 IntRect backgroundBox = backgroundRect(renderer());
1418 return IntRect(); 1447 backgroundBox.move(contentOffsetInCompostingLayer());
1419 1448 return backgroundBox;
1420 IntRect pixelSnappedBackgroundBox = pixelSnappedIntRect(backgroundRectForBox (toRenderBox(renderer())));
1421 pixelSnappedBackgroundBox.move(contentOffsetInCompostingLayer());
1422 return pixelSnappedBackgroundBox;
1423 } 1449 }
1424 1450
1425 GraphicsLayer* RenderLayerBacking::parentForSublayers() const 1451 GraphicsLayer* RenderLayerBacking::parentForSublayers() const
1426 { 1452 {
1427 if (m_scrollingContentsLayer) 1453 if (m_scrollingContentsLayer)
1428 return m_scrollingContentsLayer.get(); 1454 return m_scrollingContentsLayer.get();
1429 1455
1430 return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsL ayer.get(); 1456 return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsL ayer.get();
1431 } 1457 }
1432 1458
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
1866 if (m_layerForVerticalScrollbar) 1892 if (m_layerForVerticalScrollbar)
1867 backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate (); 1893 backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate ();
1868 1894
1869 if (m_layerForScrollCorner) 1895 if (m_layerForScrollCorner)
1870 backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate(); 1896 backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
1871 1897
1872 return backingMemory; 1898 return backingMemory;
1873 } 1899 }
1874 1900
1875 } // namespace WebCore 1901 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698