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

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: resolved layout test failures 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 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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/gpu/DrawingBuffer.cpp ('k') | Source/core/rendering/RenderVideo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698