summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/WebCore/ChangeLog42
-rw-r--r--Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp43
-rw-r--r--Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h2
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapper.cpp19
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapper.h6
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp26
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h2
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp22
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h2
9 files changed, 143 insertions, 21 deletions
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 985529158..e8af73ebf 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,4 +1,44 @@
-2012-12-06 Andras Becsi <andras.becsi@digia.com>
+2012-12-12 Allan Sandfeld Jensen <allan.jensen@digia.com>
+
+ [Qt] Animation fails on large layers
+ https://bugs.webkit.org/show_bug.cgi?id=104538
+
+ Reviewed by Noam Rosenthal.
+
+ The backing tiles had no upper limit defined for the non-GL backend, which could cause them
+ to allocate pixmaps widier or higher than what the underlying graphics systems can handle.
+
+ On top of that GraphicsLayerTextureMapper::prepareBackingStore() would allocate an intermediate
+ pixmap the size of the dirty rect, which would at least on the first paint be the size of the
+ entire layer, again causing allocation of pixmaps with dimensions outside of platform bounds.
+
+ This patch introduces a limit to the size of image buffer tiles, and adds an alternative path
+ for painting where the GraphicsLayer paints directly to the tile instead of over an intermediate
+ pixmap. This alternative path can also be useful later to minimize the amount of pixel copying
+ happening in full repaints.
+
+ * platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
+ (WebCore::GraphicsLayerTextureMapper::prepareBackingStore):
+ * platform/graphics/texmap/GraphicsLayerTextureMapper.h:
+ (GraphicsLayerTextureMapper):
+ * platform/graphics/texmap/TextureMapper.cpp:
+ (WebCore::BitmapTexture::updateContents):
+ * platform/graphics/texmap/TextureMapper.h:
+ (BitmapTexture):
+ (TextureMapper):
+ * platform/graphics/texmap/TextureMapperBackingStore.cpp:
+ (WebCore::TextureMapperTile::updateContents):
+ (WebCore::TextureMapperTiledBackingStore::updateContents):
+ * platform/graphics/texmap/TextureMapperBackingStore.h:
+ (TextureMapperTile):
+ (TextureMapperTiledBackingStore):
+ * platform/graphics/texmap/TextureMapperImageBuffer.cpp:
+ (WebCore::BitmapTextureImageBuffer::updateContents):
+ (WebCore::TextureMapperImageBuffer::maxTextureSize):
+ * platform/graphics/texmap/TextureMapperImageBuffer.h:
+ (BitmapTextureImageBuffer):
+
+ 2012-12-06 Andras Becsi <andras.becsi@digia.com>
[Qt][Mac] Fix libxslt and libxml2 config tests
https://bugs.webkit.org/show_bug.cgi?id=104164
diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
index b1e9cb10d..88b3e97bd 100644
--- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
+++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
@@ -452,25 +452,34 @@ void GraphicsLayerTextureMapper::prepareBackingStore()
if (!m_backingStore)
m_backingStore = TextureMapperTiledBackingStore::create();
- // Paint the entire dirty rect into an image buffer. This ensures we only paint once.
- OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(dirtyRect.size());
- GraphicsContext* context = imageBuffer->context();
- context->setImageInterpolationQuality(textureMapper->imageInterpolationQuality());
- context->setTextDrawingMode(textureMapper->textDrawingMode());
- context->translate(-dirtyRect.x(), -dirtyRect.y());
- paintGraphicsLayerContents(*context, dirtyRect);
-
- if (isShowingRepaintCounter()) {
- incrementRepaintCount();
- drawRepaintCounter(context);
- }
-
- RefPtr<Image> image = imageBuffer->copyImage(DontCopyBackingStore);
-#if PLATFORM(QT)
ASSERT(dynamic_cast<TextureMapperTiledBackingStore*>(m_backingStore.get()));
-#endif
TextureMapperTiledBackingStore* backingStore = static_cast<TextureMapperTiledBackingStore*>(m_backingStore.get());
- backingStore->updateContents(textureMapper, image.get(), m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData);
+
+ if (isShowingRepaintCounter())
+ incrementRepaintCount();
+
+ // Paint into an intermediate buffer to avoid painting content more than once.
+ bool paintOnce = true;
+ const IntSize maxTextureSize = textureMapper->maxTextureSize();
+ // We need to paint directly if the dirty rect exceeds one of the maximum dimensions.
+ if (dirtyRect.width() > maxTextureSize.width() || dirtyRect.height() > maxTextureSize.height())
+ paintOnce = false;
+
+ if (paintOnce) {
+ OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(dirtyRect.size());
+ GraphicsContext* context = imageBuffer->context();
+ context->setImageInterpolationQuality(textureMapper->imageInterpolationQuality());
+ context->setTextDrawingMode(textureMapper->textDrawingMode());
+ context->translate(-dirtyRect.x(), -dirtyRect.y());
+ paintGraphicsLayerContents(*context, dirtyRect);
+
+ if (isShowingRepaintCounter())
+ drawRepaintCounter(context);
+
+ RefPtr<Image> image = imageBuffer->copyImage(DontCopyBackingStore);
+ backingStore->updateContents(textureMapper, image.get(), m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData);
+ } else
+ backingStore->updateContents(textureMapper, this, m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData);
backingStore->setShowDebugBorders(isShowingDebugBorder());
backingStore->setDebugBorder(m_debugBorderColor, m_debugBorderWidth);
diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
index af4940943..7051a7d97 100644
--- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
+++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
@@ -95,6 +95,7 @@ public:
void setFixedToViewport(bool fixed) { m_fixedToViewport = fixed; }
bool fixedToViewport() const { return m_fixedToViewport; }
+ void drawRepaintCounter(GraphicsContext*);
private:
virtual void willBeDestroyed();
void didFlushCompositingState();
@@ -102,7 +103,6 @@ private:
void updateBackingStore();
void prepareBackingStore();
bool shouldHaveBackingStore() const;
- void drawRepaintCounter(GraphicsContext*);
void animationStartedTimerFired(Timer<GraphicsLayerTextureMapper>*);
OwnPtr<TextureMapperLayer> m_layer;
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp
index 7a980a9c5..43fec543c 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp
@@ -20,6 +20,7 @@
#include "config.h"
#include "TextureMapper.h"
+#include "GraphicsLayer.h"
#include "TextureMapperImageBuffer.h"
#include "Timer.h"
#include <wtf/CurrentTime.h>
@@ -144,5 +145,23 @@ TextureMapper::TextureMapper(AccelerationMode accelerationMode)
TextureMapper::~TextureMapper()
{ }
+void BitmapTexture::updateContents(TextureMapper* textureMapper, GraphicsLayer* sourceLayer, const IntRect& targetRect, const IntPoint& offset, UpdateContentsFlag updateContentsFlag)
+{
+ OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(targetRect.size());
+ GraphicsContext* context = imageBuffer->context();
+ context->setImageInterpolationQuality(textureMapper->imageInterpolationQuality());
+ context->setTextDrawingMode(textureMapper->textDrawingMode());
+
+ IntRect sourceRect(targetRect);
+ sourceRect.setLocation(offset);
+ context->translate(-offset.x(), -offset.y());
+ sourceLayer->paintGraphicsLayerContents(*context, sourceRect);
+
+ RefPtr<Image> image = imageBuffer->copyImage(DontCopyBackingStore);
+
+ updateContents(image.get(), targetRect, IntPoint(), updateContentsFlag);
}
+
+} // namespace
+
#endif
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.h b/Source/WebCore/platform/graphics/texmap/TextureMapper.h
index 144209349..22efd5ff7 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapper.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.h
@@ -49,10 +49,11 @@ namespace WebCore {
class BitmapTexturePool;
class CustomFilterProgram;
+class GraphicsLayer;
class TextureMapper;
// A 2D texture that can be the target of software or GL rendering.
-class BitmapTexture : public RefCounted<BitmapTexture> {
+class BitmapTexture : public RefCounted<BitmapTexture> {
public:
enum Flag {
SupportsAlpha = 0x01
@@ -75,6 +76,7 @@ public:
virtual IntSize size() const = 0;
virtual void updateContents(Image*, const IntRect&, const IntPoint& offset, UpdateContentsFlag) = 0;
+ virtual void updateContents(TextureMapper*, GraphicsLayer*, const IntRect& target, const IntPoint& offset, UpdateContentsFlag);
virtual void updateContents(const void*, const IntRect& target, const IntPoint& offset, int bytesPerLine, UpdateContentsFlag) = 0;
virtual bool isValid() const = 0;
inline Flags flags() const { return m_flags; }
@@ -151,7 +153,7 @@ public:
virtual void beginPainting(PaintFlags = 0) { }
virtual void endPainting() { }
- virtual IntSize maxTextureSize() const { return IntSize(INT_MAX, INT_MAX); }
+ virtual IntSize maxTextureSize() const = 0;
virtual PassRefPtr<BitmapTexture> acquireTextureFromPool(const IntSize&);
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp
index 0ced83611..788bb12a1 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp
@@ -80,6 +80,25 @@ void TextureMapperTile::updateContents(TextureMapper* textureMapper, Image* imag
m_texture->updateContents(image, targetRect, sourceOffset, updateContentsFlag);
}
+void TextureMapperTile::updateContents(TextureMapper* textureMapper, GraphicsLayer* sourceLayer, const IntRect& dirtyRect, BitmapTexture::UpdateContentsFlag updateContentsFlag)
+{
+ IntRect targetRect = enclosingIntRect(m_rect);
+ targetRect.intersect(dirtyRect);
+ if (targetRect.isEmpty())
+ return;
+ IntPoint sourceOffset = targetRect.location();
+
+ // Normalize targetRect to the texture's coordinates.
+ targetRect.move(-m_rect.x(), -m_rect.y());
+
+ if (!m_texture) {
+ m_texture = textureMapper->createTexture();
+ m_texture->reset(targetRect.size(), BitmapTexture::SupportsAlpha);
+ }
+
+ m_texture->updateContents(textureMapper, sourceLayer, targetRect, sourceOffset, updateContentsFlag);
+}
+
void TextureMapperTile::paint(TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, BitmapTexture* mask, const unsigned exposedEdges)
{
if (texture().get())
@@ -197,6 +216,13 @@ void TextureMapperTiledBackingStore::updateContents(TextureMapper* textureMapper
m_tiles[i].updateContents(textureMapper, image, dirtyRect, updateContentsFlag);
}
+void TextureMapperTiledBackingStore::updateContents(TextureMapper* textureMapper, GraphicsLayer* sourceLayer, const FloatSize& totalSize, const IntRect& dirtyRect, BitmapTexture::UpdateContentsFlag updateContentsFlag)
+{
+ createOrDestroyTilesIfNeeded(totalSize, textureMapper->maxTextureSize(), true);
+ for (size_t i = 0; i < m_tiles.size(); ++i)
+ m_tiles[i].updateContents(textureMapper, sourceLayer, dirtyRect, updateContentsFlag);
+}
+
PassRefPtr<BitmapTexture> TextureMapperTiledBackingStore::texture() const
{
for (size_t i = 0; i < m_tiles.size(); ++i) {
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h
index a704ffd23..0dd2df4b1 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h
@@ -73,6 +73,7 @@ public:
inline void setRect(const FloatRect& rect) { m_rect = rect; }
void updateContents(TextureMapper*, Image*, const IntRect&, BitmapTexture::UpdateContentsFlag UpdateCanModifyOriginalImageData);
+ void updateContents(TextureMapper*, GraphicsLayer*, const IntRect&, BitmapTexture::UpdateContentsFlag UpdateCanModifyOriginalImageData);
virtual void paint(TextureMapper*, const TransformationMatrix&, float, BitmapTexture*, const unsigned exposedEdges);
virtual ~TextureMapperTile() { }
@@ -94,6 +95,7 @@ public:
virtual PassRefPtr<BitmapTexture> texture() const OVERRIDE;
virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float, BitmapTexture*) OVERRIDE;
void updateContents(TextureMapper*, Image*, const FloatSize&, const IntRect&, BitmapTexture::UpdateContentsFlag);
+ void updateContents(TextureMapper*, GraphicsLayer*, const FloatSize&, const IntRect&, BitmapTexture::UpdateContentsFlag);
void setContentsToImage(Image* image) { m_image = image; }
void setShowDebugBorders(bool drawsDebugBorders) { m_drawsDebugBorders = drawsDebugBorders; }
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
index 48540c48d..7e9e00175 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
@@ -21,6 +21,7 @@
#include "TextureMapperImageBuffer.h"
#include "FilterEffectRenderer.h"
+#include "GraphicsLayer.h"
#if PLATFORM(QT)
#include "NativeImageQt.h"
#endif
@@ -29,6 +30,8 @@
#if USE(TEXTURE_MAPPER)
namespace WebCore {
+static const int s_maximumAllowedImageBufferDimension = 4096;
+
void BitmapTextureImageBuffer::updateContents(const void* data, const IntRect& targetRect, const IntPoint& sourceOffset, int bytesPerLine, UpdateContentsFlag)
{
#if PLATFORM(QT)
@@ -54,6 +57,20 @@ void BitmapTextureImageBuffer::updateContents(const void* data, const IntRect& t
#endif
}
+void BitmapTextureImageBuffer::updateContents(TextureMapper* textureMapper, GraphicsLayer* sourceLayer, const IntRect& targetRect, const IntPoint& sourceOffset, UpdateContentsFlag)
+{
+ GraphicsContext* context = m_image->context();
+
+ context->clearRect(targetRect);
+
+ IntRect sourceRect(targetRect);
+ sourceRect.setLocation(sourceOffset);
+ context->save();
+ context->translate(targetRect.x() - sourceOffset.x(), targetRect.y() - sourceOffset.y());
+ sourceLayer->paintGraphicsLayerContents(*context, sourceRect);
+ context->restore();
+}
+
void BitmapTextureImageBuffer::didReset()
{
m_image = ImageBuffer::create(contentSize());
@@ -64,6 +81,11 @@ void BitmapTextureImageBuffer::updateContents(Image* image, const IntRect& targe
m_image->context()->drawImage(image, ColorSpaceDeviceRGB, targetRect, IntRect(offset, targetRect.size()), CompositeCopy);
}
+IntSize TextureMapperImageBuffer::maxTextureSize() const
+{
+ return IntSize(s_maximumAllowedImageBufferDimension, s_maximumAllowedImageBufferDimension);
+}
+
void TextureMapperImageBuffer::beginClip(const TransformationMatrix& matrix, const FloatRect& rect)
{
GraphicsContext* context = currentContext();
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h
index 91ff9b005..9de6d4cbd 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h
@@ -35,6 +35,7 @@ public:
virtual bool isValid() const { return m_image; }
inline GraphicsContext* graphicsContext() { return m_image ? m_image->context() : 0; }
virtual void updateContents(Image*, const IntRect&, const IntPoint&, UpdateContentsFlag);
+ virtual void updateContents(TextureMapper*, GraphicsLayer*, const IntRect& target, const IntPoint& offset, UpdateContentsFlag);
virtual void updateContents(const void*, const IntRect& target, const IntPoint& sourceOffset, int bytesPerLine, UpdateContentsFlag);
#if ENABLE(CSS_FILTERS)
PassRefPtr<BitmapTexture> applyFilters(TextureMapper*, const BitmapTexture&, const FilterOperations&);
@@ -65,6 +66,7 @@ public:
virtual void beginClip(const TransformationMatrix&, const FloatRect&) OVERRIDE;
virtual void bindSurface(BitmapTexture* surface) OVERRIDE { m_currentSurface = surface;}
virtual void endClip() OVERRIDE { graphicsContext()->restore(); }
+ virtual IntSize maxTextureSize() const;
virtual PassRefPtr<BitmapTexture> createTexture() OVERRIDE { return BitmapTextureImageBuffer::create(); }
inline GraphicsContext* currentContext()