Diff
Modified: trunk/Source/WebCore/ChangeLog (98312 => 98313)
--- trunk/Source/WebCore/ChangeLog 2011-10-25 02:53:31 UTC (rev 98312)
+++ trunk/Source/WebCore/ChangeLog 2011-10-25 02:54:22 UTC (rev 98313)
@@ -1,3 +1,34 @@
+2011-10-24 Shawn Singh <[email protected]>
+
+ [chromium] Refactor painting/updating/drawing code.
+ https://bugs.webkit.org/show_bug.cgi?id=70057
+
+ Reviewed by James Robinson.
+
+ This refactoring separates the "early exits" from the actual loop
+ that draws layers. As part of this, it was also appropriate to
+ clean up the way that masks and replicas are dealt with when
+ painting and updating. The purpose of all this is to make things
+ easier to test, and for a scissoring optimization that needs to
+ know exatly what gets drawn. Existing layout tests were able to
+ verify the refactoring did not change behavior.
+
+ * platform/graphics/chromium/LayerRendererChromium.cpp:
+ (WebCore::LayerRendererChromium::drawLayersOntoRenderSurfaces):
+ (WebCore::LayerRendererChromium::drawLayersInternal):
+ (WebCore::LayerRendererChromium::drawLayer):
+ * platform/graphics/chromium/LayerRendererChromium.h:
+ * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+ (WebCore::CCLayerTreeHost::paintMaskAndReplicaForRenderSurface):
+ (WebCore::CCLayerTreeHost::paintLayerContents):
+ (WebCore::CCLayerTreeHost::updateCompositorResources):
+ * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+ * platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp:
+ (WebCore::layerShouldBeAppended):
+ (WebCore::calculateDrawTransformsAndVisibilityInternal):
+ * platform/graphics/chromium/cc/CCLayerTreeHostCommon.h:
+ (WebCore::CCLayerTreeHostCommon::calculateVisibleLayerRect):
+
2011-10-24 Luke Macpherson <[email protected]>
REGRESSION(80893): HTML5 spec takes 2s longer to load due to time spent in CSSStyleSelector
Property changes on: trunk/Source/WebCore/ChangeLog
___________________________________________________________________
Deleted: svn:executable
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp (98312 => 98313)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp 2011-10-25 02:53:31 UTC (rev 98312)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp 2011-10-25 02:54:22 UTC (rev 98313)
@@ -301,6 +301,45 @@
copyOffscreenTextureToDisplay();
}
+void LayerRendererChromium::drawLayersOntoRenderSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList)
+{
+ TRACE_EVENT("LayerRendererChromium::drawLayersOntoRenderSurfaces", this, 0);
+
+ // Update the contents of the render surfaces. We traverse the render surfaces
+ // from back to front to guarantee that nested render surfaces get rendered in
+ // the correct order.
+ for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
+ CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
+ CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface();
+ ASSERT(renderSurface);
+
+ renderSurface->setSkipsDraw(true);
+
+ if (!renderSurface->layerList().size())
+ continue;
+
+ // Skip completely transparent render surfaces.
+ if (!renderSurface->drawOpacity())
+ continue;
+
+ if (useRenderSurface(renderSurface)) {
+ renderSurface->setSkipsDraw(false);
+
+ if (renderSurfaceLayer != rootDrawLayer) {
+ GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
+ GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0));
+ GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
+ GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
+ }
+
+ const CCLayerList& layerList = renderSurface->layerList();
+ for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
+ drawLayer(layerList[layerIndex].get(), renderSurface);
+ }
+ }
+}
+
+
void LayerRendererChromium::drawLayersInternal()
{
if (viewportSize().isEmpty() || !rootLayer())
@@ -354,41 +393,8 @@
GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
- // Update the contents of the render surfaces. We traverse the array from
- // back to front to guarantee that nested render surfaces get rendered in the
- // correct order.
- for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
- CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
- CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface();
- ASSERT(renderSurface);
+ drawLayersOntoRenderSurfaces(rootDrawLayer, renderSurfaceLayerList);
- renderSurface->setSkipsDraw(true);
-
- // Render surfaces whose drawable area has zero width or height
- // will have no layers associated with them and should be skipped.
- if (!renderSurface->layerList().size())
- continue;
-
- // Skip completely transparent render surfaces.
- if (!renderSurface->drawOpacity())
- continue;
-
- if (useRenderSurface(renderSurface)) {
- renderSurface->setSkipsDraw(false);
-
- if (renderSurfaceLayer != rootDrawLayer) {
- GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
- GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0));
- GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
- GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
- }
-
- const CCLayerList& layerList = renderSurface->layerList();
- for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
- drawLayer(layerList[layerIndex].get(), renderSurface);
- }
- }
-
if (m_headsUpDisplay->enabled()) {
GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
@@ -570,43 +576,17 @@
return;
}
- if (!layer->drawsContent())
- return;
+ IntRect visibleLayerRect = CCLayerTreeHostCommon::calculateVisibleLayerRect<CCLayerImpl>(layer);
+ layer->setVisibleLayerRect(visibleLayerRect);
- if (!layer->opacity())
+ if (visibleLayerRect.isEmpty())
return;
- if (layer->bounds().isEmpty())
- return;
-
- IntRect targetSurfaceRect = layer->targetRenderSurface() ? layer->targetRenderSurface()->contentRect() : m_defaultRenderSurface->contentRect();
- if (layer->usesLayerScissor()) {
- IntRect scissorRect = layer->scissorRect();
- targetSurfaceRect.intersect(scissorRect);
- if (targetSurfaceRect.isEmpty())
- return;
- setScissorToRect(scissorRect);
- } else
+ if (layer->usesLayerScissor())
+ setScissorToRect(layer->scissorRect());
+ else
GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
- IntRect visibleLayerRect = CCLayerTreeHostCommon::calculateVisibleLayerRect(targetSurfaceRect, layer->bounds(), layer->contentBounds(), layer->drawTransform());
- visibleLayerRect.move(toSize(layer->scrollPosition()));
- layer->setVisibleLayerRect(visibleLayerRect);
-
- // The layer should not be drawn if (1) it is not double-sided and (2) the back of the layer is facing the screen.
- // This second condition is checked by computing the transformed normal of the layer.
- if (!layer->doubleSided()) {
- FloatRect layerRect(FloatPoint(0, 0), FloatSize(layer->bounds()));
- FloatQuad mappedLayer = layer->screenSpaceTransform().mapQuad(FloatQuad(layerRect));
- FloatSize horizontalDir = mappedLayer.p2() - mappedLayer.p1();
- FloatSize verticalDir = mappedLayer.p4() - mappedLayer.p1();
- FloatPoint3D xAxis(horizontalDir.width(), horizontalDir.height(), 0);
- FloatPoint3D yAxis(verticalDir.width(), verticalDir.height(), 0);
- FloatPoint3D zAxis = xAxis.cross(yAxis);
- if (zAxis.z() < 0)
- return;
- }
-
layer->draw(this);
// Draw the debug border if there is one.
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h (98312 => 98313)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h 2011-10-25 02:53:31 UTC (rev 98312)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h 2011-10-25 02:54:22 UTC (rev 98313)
@@ -161,6 +161,7 @@
bool initialize();
void drawLayersInternal();
+ void drawLayersOntoRenderSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList);
void drawLayer(CCLayerImpl*, CCRenderSurface*);
ManagedTexture* getOffscreenLayerTexture();
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp (98312 => 98313)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp 2011-10-25 02:53:31 UTC (rev 98312)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp 2011-10-25 02:54:22 UTC (rev 98313)
@@ -296,6 +296,32 @@
}
}
+void CCLayerTreeHost::paintMaskAndReplicaForRenderSurface(LayerChromium* renderSurfaceLayer)
+{
+ // Note: Masks and replicas only exist for layers that own render surfaces. If we reach this point
+ // in code, we already know that at least something will be drawn into this render surface, so the
+ // mask and replica should be painted.
+
+ if (renderSurfaceLayer->maskLayer()) {
+ renderSurfaceLayer->maskLayer()->setLayerTreeHost(this);
+ paintContentsIfDirty(renderSurfaceLayer->maskLayer(), IntRect(IntPoint(), renderSurfaceLayer->contentBounds()));
+ }
+
+ LayerChromium* replicaLayer = renderSurfaceLayer->replicaLayer();
+ if (replicaLayer) {
+
+ IntRect visibleLayerRect = CCLayerTreeHostCommon::calculateVisibleLayerRect<LayerChromium>(renderSurfaceLayer);
+
+ replicaLayer->setLayerTreeHost(this);
+ paintContentsIfDirty(replicaLayer, visibleLayerRect);
+
+ if (replicaLayer->maskLayer()) {
+ replicaLayer->maskLayer()->setLayerTreeHost(this);
+ paintContentsIfDirty(replicaLayer->maskLayer(), IntRect(IntPoint(), replicaLayer->maskLayer()->contentBounds()));
+ }
+ }
+}
+
void CCLayerTreeHost::paintLayerContents(const LayerList& renderSurfaceLayerList)
{
for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
@@ -303,8 +329,6 @@
RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
ASSERT(renderSurface);
- renderSurfaceLayer->setLayerTreeHost(this);
-
// Render surfaces whose drawable area has zero width or height
// will have no layers associated with them and should be skipped.
if (!renderSurface->layerList().size())
@@ -313,6 +337,9 @@
if (!renderSurface->drawOpacity())
continue;
+ renderSurfaceLayer->setLayerTreeHost(this);
+ paintMaskAndReplicaForRenderSurface(renderSurfaceLayer);
+
const LayerList& layerList = renderSurface->layerList();
ASSERT(layerList.size());
for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
@@ -325,39 +352,12 @@
layer->setLayerTreeHost(this);
- if (!layer->opacity())
- continue;
-
- if (layer->maskLayer())
- layer->maskLayer()->setLayerTreeHost(this);
- if (layer->replicaLayer()) {
- layer->replicaLayer()->setLayerTreeHost(this);
- if (layer->replicaLayer()->maskLayer())
- layer->replicaLayer()->maskLayer()->setLayerTreeHost(this);
- }
-
- if (layer->bounds().isEmpty())
- continue;
-
- IntRect defaultContentRect = IntRect(rootLayer()->scrollPosition(), viewportSize());
-
- IntRect targetSurfaceRect = layer->targetRenderSurface() ? layer->targetRenderSurface()->contentRect() : defaultContentRect;
- if (layer->usesLayerScissor())
- targetSurfaceRect.intersect(layer->scissorRect());
- IntRect visibleLayerRect = CCLayerTreeHostCommon::calculateVisibleLayerRect(targetSurfaceRect, layer->bounds(), layer->contentBounds(), layer->drawTransform());
-
- visibleLayerRect.move(toSize(layer->scrollPosition()));
+ ASSERT(layer->opacity());
+ ASSERT(!layer->bounds().isEmpty());
+
+ IntRect visibleLayerRect = CCLayerTreeHostCommon::calculateVisibleLayerRect<LayerChromium>(layer);
+
paintContentsIfDirty(layer, visibleLayerRect);
-
- if (LayerChromium* maskLayer = layer->maskLayer())
- paintContentsIfDirty(maskLayer, IntRect(IntPoint(), maskLayer->contentBounds()));
-
- if (LayerChromium* replicaLayer = layer->replicaLayer()) {
- paintContentsIfDirty(replicaLayer, visibleLayerRect);
-
- if (LayerChromium* replicaMaskLayer = replicaLayer->maskLayer())
- paintContentsIfDirty(replicaMaskLayer, IntRect(IntPoint(), replicaMaskLayer->contentBounds()));
- }
}
}
}
@@ -372,6 +372,16 @@
if (!renderSurface->layerList().size() || !renderSurface->drawOpacity())
continue;
+ if (renderSurfaceLayer->maskLayer())
+ updateCompositorResources(renderSurfaceLayer->maskLayer(), context, allocator);
+
+ if (renderSurfaceLayer->replicaLayer()) {
+ updateCompositorResources(renderSurfaceLayer->replicaLayer(), context, allocator);
+
+ if (renderSurfaceLayer->replicaLayer()->maskLayer())
+ updateCompositorResources(renderSurfaceLayer->replicaLayer()->maskLayer(), context, allocator);
+ }
+
const LayerList& layerList = renderSurface->layerList();
ASSERT(layerList.size());
for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
@@ -386,19 +396,12 @@
void CCLayerTreeHost::updateCompositorResources(LayerChromium* layer, GraphicsContext3D* context, TextureAllocator* allocator)
{
- if (layer->bounds().isEmpty())
+ // For normal layers, these conditions should have already been checked while creating the render surface layer lists.
+ // For masks and replicas however, we may still need to check them here.
+ if (layer->bounds().isEmpty() || !layer->opacity() || !layer->drawsContent())
return;
- if (!layer->opacity())
- return;
-
- if (layer->maskLayer())
- updateCompositorResources(layer->maskLayer(), context, allocator);
- if (layer->replicaLayer())
- updateCompositorResources(layer->replicaLayer(), context, allocator);
-
- if (layer->drawsContent())
- layer->updateCompositorResources(context, allocator);
+ layer->updateCompositorResources(context, allocator);
}
void CCLayerTreeHost::clearPendingUpdate()
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h (98312 => 98313)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h 2011-10-25 02:53:31 UTC (rev 98312)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h 2011-10-25 02:54:22 UTC (rev 98313)
@@ -165,9 +165,12 @@
typedef Vector<RefPtr<LayerChromium> > LayerList;
void paintLayerContents(const LayerList&);
+ void paintMaskAndReplicaForRenderSurface(LayerChromium*);
+
void updateLayers(LayerChromium*);
void updateCompositorResources(const LayerList&, GraphicsContext3D*, TextureAllocator*);
void updateCompositorResources(LayerChromium*, GraphicsContext3D*, TextureAllocator*);
+ void updateMaskResourcesForRenderSurface(LayerChromium*, GraphicsContext3D*, TextureAllocator*);
void clearPendingUpdate();
int m_compositorIdentifier;
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp (98312 => 98313)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp 2011-10-25 02:53:31 UTC (rev 98312)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp 2011-10-25 02:54:22 UTC (rev 98313)
@@ -61,21 +61,6 @@
return layerRect;
}
-IntRect CCLayerTreeHostCommon::calculateVisibleLayerRect(const IntRect& targetSurfaceRect, const IntSize& bounds, const IntSize& contentBounds, const TransformationMatrix& tilingTransform)
-{
- if (targetSurfaceRect.isEmpty() || contentBounds.isEmpty())
- return targetSurfaceRect;
-
- const IntRect layerBoundRect = IntRect(IntPoint(), contentBounds);
- TransformationMatrix transform = tilingTransform;
-
- transform.scaleNonUniform(bounds.width() / static_cast<double>(contentBounds.width()),
- bounds.height() / static_cast<double>(contentBounds.height()));
- transform.translate(-contentBounds.width() / 2.0, -contentBounds.height() / 2.0);
-
- return calculateVisibleRect(targetSurfaceRect, layerBoundRect, transform);
-}
-
static bool isScaleOrTranslation(const TransformationMatrix& m)
{
return !m.m12() && !m.m13() && !m.m14()
@@ -85,6 +70,39 @@
}
+template<typename LayerType>
+bool layerShouldBeSkipped(LayerType* layer)
+{
+ // Layers can be skipped if any of these conditions are met.
+ // - does not draw content.
+ // - is transparent
+ // - has empty bounds
+ // - the layer is not double-sided, but its back face is visible.
+ //
+ // Some additional conditions need to be computed at a later point after the recursion is finished.
+ // - the intersection of render surface content and layer scissor is empty
+ // - the visibleLayerRect is empty
+
+ if (!layer->drawsContent() || !layer->opacity() || layer->bounds().isEmpty())
+ return true;
+
+ // The layer should not be drawn if (1) it is not double-sided and (2) the back of the layer is facing the screen.
+ // This second condition is checked by computing the transformed normal of the layer.
+ if (!layer->doubleSided()) {
+ FloatRect layerRect(FloatPoint(0, 0), FloatSize(layer->bounds()));
+ FloatQuad mappedLayer = layer->screenSpaceTransform().mapQuad(FloatQuad(layerRect));
+ FloatSize horizontalDir = mappedLayer.p2() - mappedLayer.p1();
+ FloatSize verticalDir = mappedLayer.p4() - mappedLayer.p1();
+ FloatPoint3D xAxis(horizontalDir.width(), horizontalDir.height(), 0);
+ FloatPoint3D yAxis(verticalDir.width(), verticalDir.height(), 0);
+ FloatPoint3D zAxis = xAxis.cross(yAxis);
+ if (zAxis.z() < 0)
+ return true;
+ }
+
+ return false;
+}
+
// Recursively walks the layer tree starting at the given node and computes all the
// necessary transformations, scissor rectangles, render surfaces, etc.
template<typename LayerType, typename RenderSurfaceType, typename LayerSorter>
@@ -329,10 +347,13 @@
sublayerMatrix.translate3d(-bounds.width() * 0.5, -bounds.height() * 0.5, 0);
LayerList& descendants = (layer->renderSurface() ? layer->renderSurface()->layerList() : layerList);
- descendants.append(layer);
- unsigned thisLayerIndex = descendants.size() - 1;
+ // Any layers that are appended after this point are in the layer's subtree and should be included in the sorting process.
+ unsigned sortingStartIndex = descendants.size();
+ if (!layerShouldBeSkipped(layer))
+ descendants.append(layer);
+
for (size_t i = 0; i < layer->children().size(); ++i) {
LayerType* child = layer->children()[i].get();
calculateDrawTransformsAndVisibilityInternal<LayerType, RenderSurfaceType, LayerSorter>(child, rootLayer, sublayerMatrix, nextHierarchyMatrix, renderSurfaceLayerList, descendants, layerSorter, maxTextureSize);
@@ -408,8 +429,8 @@
// If preserves-3d then sort all the descendants in 3D so that they can be
// drawn from back to front. If the preserves-3d property is also set on the parent then
// skip the sorting as the parent will sort all the descendants anyway.
- if (layer->preserves3D() && (!layer->parent() || !layer->parent()->preserves3D()))
- sortLayers(&descendants.at(thisLayerIndex), descendants.end(), layerSorter);
+ if (descendants.size() && layer->preserves3D() && (!layer->parent() || !layer->parent()->preserves3D()))
+ sortLayers(&descendants.at(sortingStartIndex), descendants.end(), layerSorter);
}
void CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(LayerChromium* layer, LayerChromium* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList, Vector<RefPtr<LayerChromium> >& layerList, int maxTextureSize)
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h (98312 => 98313)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h 2011-10-25 02:53:31 UTC (rev 98312)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h 2011-10-25 02:54:22 UTC (rev 98313)
@@ -25,7 +25,9 @@
#ifndef CCLayerTreeHostCommon_h
#define CCLayerTreeHostCommon_h
+#include "IntRect.h"
#include "IntSize.h"
+#include "TransformationMatrix.h"
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
@@ -33,17 +35,14 @@
class CCLayerImpl;
class CCLayerSorter;
-class IntRect;
class LayerChromium;
-class TransformationMatrix;
class CCLayerTreeHostCommon {
public:
- static IntRect calculateVisibleLayerRect(const IntRect& targetSurfaceRect, const IntSize& bounds, const IntSize& contentBounds, const TransformationMatrix& tilingTransform);
static IntRect calculateVisibleRect(const IntRect& targetSurfaceRect, const IntRect& layerBoundRect, const TransformationMatrix&);
+ template<typename LayerType> static IntRect calculateVisibleLayerRect(LayerType*);
static void calculateDrawTransformsAndVisibility(LayerChromium*, LayerChromium* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList, Vector<RefPtr<LayerChromium> >& layerList, int maxTextureSize);
-
static void calculateDrawTransformsAndVisibility(CCLayerImpl*, CCLayerImpl* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<CCLayerImpl> >& renderSurfaceLayerList, Vector<RefPtr<CCLayerImpl> >& layerList, CCLayerSorter*, int maxTextureSize);
struct ScrollUpdateInfo {
@@ -54,6 +53,35 @@
typedef Vector<CCLayerTreeHostCommon::ScrollUpdateInfo> CCScrollUpdateSet;
+template<typename LayerType>
+IntRect CCLayerTreeHostCommon::calculateVisibleLayerRect(LayerType* layer)
+{
+ ASSERT(layer->targetRenderSurface());
+ IntRect targetSurfaceRect = layer->targetRenderSurface()->contentRect();
+
+ if (layer->usesLayerScissor())
+ targetSurfaceRect.intersect(layer->scissorRect());
+
+ if (targetSurfaceRect.isEmpty() || layer->contentBounds().isEmpty())
+ return targetSurfaceRect;
+
+ // Note carefully these are aliases
+ const IntSize& bounds = layer->bounds();
+ const IntSize& contentBounds = layer->contentBounds();
+
+ const IntRect layerBoundRect = IntRect(IntPoint(), contentBounds);
+ TransformationMatrix transform = layer->drawTransform();
+
+ transform.scaleNonUniform(bounds.width() / static_cast<double>(contentBounds.width()),
+ bounds.height() / static_cast<double>(contentBounds.height()));
+ transform.translate(-contentBounds.width() / 2.0, -contentBounds.height() / 2.0);
+
+ IntRect visibleLayerRect = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerBoundRect, transform);
+ visibleLayerRect.move(toSize(layer->scrollPosition()));
+
+ return visibleLayerRect;
+}
+
} // namespace WebCore
#endif