Skip to content
Permalink
Browse files
2010-10-14 Adrienne Walker <enne@google.com>
        Reviewed by James Robinson.

        Add a test for very large image layers.  Skip this test for mac-wk2
        because of the use of layerTreeAsText().
        https://bugs.webkit.org/show_bug.cgi?id=47016

        * compositing/tiling/huge-layer-img.html: Added.
        * platform/chromium-gpu/compositing/tiling/huge-layer-img-expected.txt: Added.
        * platform/mac-wk2/Skipped:
        * platform/mac/compositing/tiling/huge-layer-img-expected.txt: Added.
2010-10-14  Adrienne Walker  <enne@google.com>

        Reviewed by James Robinson.

        Add a short-term solution for large layers.  Layers that are too
        large to be contained in a single texture just upload the portion of
        the layer that is within the content rect.  A longer-term solution
        is still tiling with proper memory management.  Layers that have full
        3D transforms (more than just translations) are still not drawn.
        https://bugs.webkit.org/show_bug.cgi?id=47016

        Test: compositing/tiling

        * platform/graphics/chromium/ContentLayerChromium.cpp:
        (WebCore::ContentLayerChromium::ContentLayerChromium):
        (WebCore::ContentLayerChromium::requiresClippedUpdateRect):
        (WebCore::ContentLayerChromium::calculateClippedUpdateRect):
        (WebCore::ContentLayerChromium::updateContents):
        (WebCore::ContentLayerChromium::updateTextureRect):
        (WebCore::ContentLayerChromium::draw):
        * platform/graphics/chromium/ContentLayerChromium.h:
        * platform/graphics/chromium/ImageLayerChromium.cpp:
        (WebCore::ImageLayerChromium::updateContents):
        * platform/graphics/chromium/LayerRendererChromium.cpp:
        (WebCore::LayerRendererChromium::drawLayers):
        * platform/graphics/chromium/LayerRendererChromium.h:
        (WebCore::LayerRendererChromium::rootLayerContentRect):

Canonical link: https://commits.webkit.org/60334@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@69747 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
webkit-commit-queue committed Oct 14, 2010
1 parent e603c04 commit 966413c3dfc7cc99d045e3c72328bd9b97976678
Showing 11 changed files with 239 additions and 31 deletions.
@@ -1,3 +1,16 @@
2010-10-14 Adrienne Walker <enne@google.com>

Reviewed by James Robinson.

Add a test for very large image layers. Skip this test for mac-wk2
because of the use of layerTreeAsText().
https://bugs.webkit.org/show_bug.cgi?id=47016

* compositing/tiling/huge-layer-img.html: Added.
* platform/chromium-gpu/compositing/tiling/huge-layer-img-expected.txt: Added.
* platform/mac-wk2/Skipped:
* platform/mac/compositing/tiling/huge-layer-img-expected.txt: Added.

2010-10-13 James Simonsen <simonjam@chromium.org>

Reviewed by Adam Barth.
@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<title>Test of very large image layer</title>

<style type="text/css" media="screen">
#container {
width: 500px;
height: 20000px;
-webkit-transform:translateZ(0);
}
</style>
<script type="text/javascript" charset="utf-8">
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}

function testOnLoad()
{
var canvas = document.createElement('canvas');
var img = document.getElementById("container")
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
context.fillStyle = "yellow";
context.fillRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "red";
context.fillRect(50, 50, 200, 200);
context.fillStyle = "blue";
context.fillRect(50, canvas.height - 250, 200, 200);
img.src = canvas.toDataURL();

window.setTimeout(function() {
if (window.layoutTestController) {
document.getElementById('layers').innerHTML = layoutTestController.layerTreeAsText();
layoutTestController.notifyDone();
}
}, 0);
}

window.addEventListener('load', testOnLoad, false);
</script>
</head>
<body>
<p>
The yellow box should be large enough to scroll off the bottom.
There should be a red box on the first page and a blue box
near the bottom of the yellow box. This tests that we can support
very large composited image layers.
</p>
<img id="container">
<pre id="layers">Layer tree appears here in DRT.</pre>
</body>
</html>
@@ -0,0 +1,19 @@
The yellow box should be large enough to scroll off the bottom. There should be a red box on the first page and a blue box near the bottom of the yellow box. This tests that we can support very large composited image layers.


(GraphicsLayer
(bounds 785.00 20119.00)
(children 1
(GraphicsLayer
(bounds 785.00 20119.00)
(children 1
(GraphicsLayer
(position 8.00 72.00)
(bounds 500.00 20000.00)
(drawsContent 1)
)
)
)
)
)

@@ -78,6 +78,7 @@ compositing/tiling/huge-layer-resize.html
compositing/tiling/huge-layer-with-layer-children-resize.html
compositing/tiling/huge-layer-with-layer-children.html
compositing/tiling/huge-layer.html
compositing/tiling/huge-layer-img.html
compositing/video/video-poster.html

# Uncategorized editing failures
@@ -0,0 +1,20 @@
The yellow box should be large enough to scroll off the bottom. There should be a red box on the first page and a blue box near the bottom of the yellow box. This tests that we can support very large composited image layers.


(GraphicsLayer
(bounds 785.00 20113.00)
(children 1
(GraphicsLayer
(bounds 785.00 20113.00)
(children 1
(GraphicsLayer
(position 8.00 68.00)
(bounds 500.00 20000.00)
(usingTiledLayer 1)
(drawsContent 1)
)
)
)
)
)

@@ -1,3 +1,31 @@
2010-10-14 Adrienne Walker <enne@google.com>

Reviewed by James Robinson.

Add a short-term solution for large layers. Layers that are too
large to be contained in a single texture just upload the portion of
the layer that is within the content rect. A longer-term solution
is still tiling with proper memory management. Layers that have full
3D transforms (more than just translations) are still not drawn.
https://bugs.webkit.org/show_bug.cgi?id=47016

Test: compositing/tiling

* platform/graphics/chromium/ContentLayerChromium.cpp:
(WebCore::ContentLayerChromium::ContentLayerChromium):
(WebCore::ContentLayerChromium::requiresClippedUpdateRect):
(WebCore::ContentLayerChromium::calculateClippedUpdateRect):
(WebCore::ContentLayerChromium::updateContents):
(WebCore::ContentLayerChromium::updateTextureRect):
(WebCore::ContentLayerChromium::draw):
* platform/graphics/chromium/ContentLayerChromium.h:
* platform/graphics/chromium/ImageLayerChromium.cpp:
(WebCore::ImageLayerChromium::updateContents):
* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::drawLayers):
* platform/graphics/chromium/LayerRendererChromium.h:
(WebCore::LayerRendererChromium::rootLayerContentRect):

2010-10-14 Chris Rogers <crogers@google.com>

Reviewed by Chris Fleizach.
@@ -122,6 +122,7 @@ PassRefPtr<ContentLayerChromium> ContentLayerChromium::create(GraphicsLayerChrom
ContentLayerChromium::ContentLayerChromium(GraphicsLayerChromium* owner)
: LayerChromium(owner)
, m_contentsTexture(0)
, m_skipsDraw(false)
{
}

@@ -140,6 +141,36 @@ void ContentLayerChromium::cleanupResources()
}
}

bool ContentLayerChromium::requiresClippedUpdateRect() const
{
return !layerRenderer()->checkTextureSize(m_bounds);
}

void ContentLayerChromium::calculateClippedUpdateRect(IntRect& dirtyRect, IntRect& drawRect) const
{
// For the given layer size and content rect, calculate:
// 1) The minimal texture space rectangle to be uploaded, returned in dirtyRect.
// 2) The content rect-relative rectangle to draw this texture in, returned in drawRect.

const IntRect contentRect = layerRenderer()->rootLayerContentRect();
const TransformationMatrix& transform = drawTransform();
// The layer's draw transform points to the center of the layer, relative to
// the content rect. layerPos is the distance from the top left of the
// layer to the top left of the content rect.
const IntPoint layerPos(m_bounds.width() / 2 - transform.m41(),
m_bounds.height() / 2 - transform.m42());
// Transform the contentRect into the space of the layer.
IntRect contentRectInLayerSpace(layerPos, contentRect.size());

// Clip the entire layer against the visible region in the content rect
// and use that as the drawable texture, instead of the entire layer.
dirtyRect = IntRect(IntPoint(0, 0), m_bounds);
dirtyRect.intersect(contentRectInLayerSpace);

// The draw position is relative to the content rect.
drawRect = IntRect(toPoint(dirtyRect.location() - layerPos), dirtyRect.size());
}

void ContentLayerChromium::updateContents()
{
RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
@@ -150,29 +181,47 @@ void ContentLayerChromium::updateContents()

ASSERT(layerRenderer());

// FIXME: Remove this test when tiled layers are implemented.
m_skipsDraw = false;
if (!layerRenderer()->checkTextureSize(m_bounds)) {
m_skipsDraw = true;
return;
}

void* pixels = 0;
IntRect dirtyRect(m_dirtyRect);
IntRect dirtyRect;
IntRect updateRect;
IntSize requiredTextureSize;
IntSize bitmapSize;

requiredTextureSize = m_bounds;
IntRect boundsRect(IntPoint(0, 0), m_bounds);

// If the texture needs to be reallocated then we must redraw the entire
// contents of the layer.
if (requiredTextureSize != m_allocatedTextureSize)
dirtyRect = boundsRect;
else {
// Clip the dirtyRect to the size of the layer to avoid drawing outside
// the bounds of the backing texture.
dirtyRect.intersect(boundsRect);
// FIXME: Remove this test when tiled layers are implemented.
if (requiresClippedUpdateRect()) {
// A layer with 3D transforms could require an arbitrarily large number
// of texels to be repainted, so ignore these layers until tiling is
// implemented.
if (!drawTransform().isIdentityOrTranslation()) {
m_skipsDraw = true;
return;
}

calculateClippedUpdateRect(dirtyRect, m_largeLayerDrawRect);
if (!layerRenderer()->checkTextureSize(m_largeLayerDrawRect.size())) {
m_skipsDraw = true;
return;
}
if (m_largeLayerDirtyRect == dirtyRect)
return;

m_largeLayerDirtyRect = dirtyRect;
requiredTextureSize = dirtyRect.size();
updateRect = IntRect(IntPoint(0, 0), dirtyRect.size());
} else {
dirtyRect = IntRect(m_dirtyRect);
IntRect boundsRect(IntPoint(0, 0), m_bounds);
requiredTextureSize = m_bounds;
// If the texture needs to be reallocated then we must redraw the entire
// contents of the layer.
if (requiredTextureSize != m_allocatedTextureSize)
dirtyRect = boundsRect;
else {
// Clip the dirtyRect to the size of the layer to avoid drawing
// outside the bounds of the backing texture.
dirtyRect.intersect(boundsRect);
}
updateRect = dirtyRect;
}

#if PLATFORM(SKIA)
@@ -236,7 +285,7 @@ void ContentLayerChromium::updateContents()
textureId = layerRenderer()->createLayerTexture();

if (pixels)
updateTextureRect(pixels, bitmapSize, requiredTextureSize, dirtyRect, textureId);
updateTextureRect(pixels, bitmapSize, requiredTextureSize, updateRect, textureId);
}

static inline bool isPowerOfTwo(int x)
@@ -287,7 +336,8 @@ void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& bitmap
GLC(context, context->generateMipmap(GraphicsContext3D::TEXTURE_2D));

m_dirtyRect.setSize(FloatSize());
m_contentsDirty = false;
// Large layers always stay dirty, because they need to update when the content rect changes.
m_contentsDirty = requiresClippedUpdateRect();
}

void ContentLayerChromium::draw()
@@ -303,9 +353,21 @@ void ContentLayerChromium::draw()
GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_contentsTexture));
layerRenderer()->useShader(sv->contentShaderProgram());
GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0));
drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
bounds().width(), bounds().height(), drawOpacity(),
sv->shaderMatrixLocation(), sv->shaderAlphaLocation());

if (requiresClippedUpdateRect()) {
float m43 = drawTransform().m43();
TransformationMatrix transform;
transform.translate3d(m_largeLayerDrawRect.center().x(), m_largeLayerDrawRect.center().y(), m43);
drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
transform, m_largeLayerDrawRect.width(),
m_largeLayerDrawRect.height(), drawOpacity(),
sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
} else {
drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
drawTransform(), m_bounds.width(), m_bounds.height(),
drawOpacity(), sv->shaderMatrixLocation(),
sv->shaderAlphaLocation());
}
}

}
@@ -84,11 +84,16 @@ class ContentLayerChromium : public LayerChromium {
const IntRect& updateRect, unsigned textureId, MipmapUse generateMipmap = noMipmap);

virtual void cleanupResources();
bool requiresClippedUpdateRect() const;

unsigned m_contentsTexture;
IntSize m_allocatedTextureSize;
bool m_skipsDraw;

private:
void calculateClippedUpdateRect(IntRect& dirtyRect, IntRect& drawRect) const;
IntRect m_largeLayerDrawRect;
IntRect m_largeLayerDirtyRect;
};

}
@@ -75,6 +75,14 @@ void ImageLayerChromium::updateContents()
{
ASSERT(layerRenderer());

// FIXME: Remove this test when tiled layers are implemented.
if (requiresClippedUpdateRect()) {
// Use the base version of updateContents which draws a subset of the
// image to a bitmap, as the pixel contents can't be uploaded directly.
ContentLayerChromium::updateContents();
return;
}

void* pixels = 0;
IntSize requiredTextureSize;
IntSize bitmapSize;
@@ -136,12 +144,6 @@ void ImageLayerChromium::updateContents()
#else
#error "Need to implement for your platform."
#endif
// FIXME: Remove this test when tiled layers are implemented.
m_skipsDraw = false;
if (!layerRenderer()->checkTextureSize(requiredTextureSize)) {
m_skipsDraw = true;
return;
}

unsigned textureId = m_contentsTexture;
if (!textureId)
@@ -307,8 +307,9 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect
GLC(m_context, m_context->enable(GraphicsContext3D::BLEND));
GLC(m_context, m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));

// Set the rootVisibleRect --- used by subsequent drawLayers calls
// Set the root visible/content rects --- used by subsequent drawLayers calls.
m_rootVisibleRect = visibleRect;
m_rootContentRect = contentRect;

// Traverse the layer tree and update the layer transforms.
float opacity = 1;
@@ -108,6 +108,7 @@ class LayerRendererChromium : public RefCounted<LayerRendererChromium> {
void resizeOnscreenContent(const IntSize&);

IntSize rootLayerTextureSize() const { return IntSize(m_rootLayerTextureWidth, m_rootLayerTextureHeight); }
IntRect rootLayerContentRect() const { return m_rootContentRect; }
void getFramebufferPixels(void *pixels, const IntRect& rect);

private:
@@ -161,6 +162,7 @@ class LayerRendererChromium : public RefCounted<LayerRendererChromium> {
IntSize m_rootLayerCanvasSize;

IntRect m_rootVisibleRect;
IntRect m_rootContentRect;

int m_maxTextureSize;

0 comments on commit 966413c

Please sign in to comment.