diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-09 14:16:12 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-09 14:16:12 +0100 |
commit | 03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (patch) | |
tree | 52599cd0ab782b1768e23ad176f7618f98333cb6 /Source/WebCore/platform/graphics/texmap | |
parent | cd44dc59cdfc39534aef4d417e9f3c412e3be139 (diff) | |
download | qtwebkit-03e12282df9aa1e1fb05a8b90f1cfc2e08764cec.tar.gz |
Imported WebKit commit e09a82039aa4273ab318b71122e92d8e5f233525 (http://svn.webkit.org/repository/webkit/trunk@107223)
Diffstat (limited to 'Source/WebCore/platform/graphics/texmap')
7 files changed, 270 insertions, 69 deletions
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp index dd33f0d2a..5e528d46b 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp @@ -20,6 +20,8 @@ #include "config.h" #include "TextureMapper.h" +#include "TextureMapperImageBuffer.h" + #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) namespace WebCore { @@ -71,5 +73,13 @@ PassRefPtr<BitmapTexture> TextureMapper::acquireTextureFromPool(const IntSize& s return selectedTexture; } + +PassOwnPtr<TextureMapper> TextureMapper::create(AccelerationMode mode) +{ + if (mode == SoftwareMode) + return TextureMapperImageBuffer::create(); + return platformCreateAccelerated(); +} + } #endif diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.h b/Source/WebCore/platform/graphics/texmap/TextureMapper.h index d66fe2fb4..f25ce0bc1 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapper.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.h @@ -47,46 +47,31 @@ class TextureMapper; class BitmapTexture : public RefCounted<BitmapTexture> { public: enum PixelFormat { BGRAFormat, RGBAFormat, BGRFormat, RGBFormat }; - BitmapTexture() : m_lockCount(0) {} + BitmapTexture() + : m_isOpaque(true) + { + } + virtual ~BitmapTexture() { } virtual void destroy() { } - virtual bool allowOfflineTextureUpload() const { return false; } virtual IntSize size() const = 0; - virtual int bpp() const { return 32; } + virtual void updateContents(Image*, const IntRect&, const IntRect&, BitmapTexture::PixelFormat) = 0; + virtual void updateContents(const void*, const IntRect&) = 0; virtual bool isValid() const = 0; + + virtual int bpp() const { return 32; } virtual void reset(const IntSize& size, bool opaque = false) { m_isOpaque = opaque; m_contentSize = size; } - virtual void pack() { } - virtual void unpack() { } - virtual bool isPacked() const { return false; } - - virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect) = 0; - virtual void endPaint() = 0; - - // For performance reasons, BitmapTexture might modify the bits directly (swizzle). - // Thus, this method is only recommended for buffer update, such as used by WebKit2. - virtual void updateContents(PixelFormat, const IntRect&, void* bits) = 0; - virtual void updateRawContents(const IntRect&, const void* bits) { } - virtual PlatformGraphicsContext* beginPaintMedia() - { - return beginPaint(IntRect(0, 0, size().width(), size().height())); - } - virtual void setContentsToImage(Image*) = 0; - virtual bool save(const String&) { return false; } - - inline void lock() { ++m_lockCount; } - inline void unlock() { --m_lockCount; } - inline bool isLocked() { return m_lockCount; } inline IntSize contentSize() const { return m_contentSize; } inline int numberOfBytes() const { return size().width() * size().height() * bpp() >> 3; } + inline bool isOpaque() const { return m_isOpaque; } protected: - int m_lockCount; IntSize m_contentSize; bool m_isOpaque; }; @@ -97,32 +82,26 @@ class TextureMapper { friend class BitmapTexture; public: - static PassOwnPtr<TextureMapper> create(GraphicsContext* graphicsContext = 0); + enum AccelerationMode { SoftwareMode, OpenGLMode }; + static PassOwnPtr<TextureMapper> create(AccelerationMode newMode = SoftwareMode); virtual ~TextureMapper() { } virtual void drawTexture(const BitmapTexture&, const FloatRect& target, const TransformationMatrix& modelViewMatrix = TransformationMatrix(), float opacity = 1.0f, const BitmapTexture* maskTexture = 0) = 0; // makes a surface the target for the following drawTexture calls. virtual void bindSurface(BitmapTexture* surface) = 0; - virtual void setGraphicsContext(GraphicsContext*) = 0; - virtual GraphicsContext* graphicsContext() = 0; + virtual void setGraphicsContext(GraphicsContext* context) { m_context = context; } + virtual GraphicsContext* graphicsContext() { return m_context; } virtual void beginClip(const TransformationMatrix&, const FloatRect&) = 0; virtual void endClip() = 0; - virtual bool allowSurfaceForRoot() const = 0; virtual PassRefPtr<BitmapTexture> createTexture() = 0; - IntSize viewportSize() const { return m_viewportSize; } - void setViewportSize(const IntSize& s) { m_viewportSize = s; } void setImageInterpolationQuality(InterpolationQuality quality) { m_interpolationQuality = quality; } void setTextDrawingMode(TextDrawingModeFlags mode) { m_textDrawingMode = mode; } InterpolationQuality imageInterpolationQuality() const { return m_interpolationQuality; } TextDrawingModeFlags textDrawingMode() const { return m_textDrawingMode; } - virtual bool allowPartialUpdates() const { return false; } - virtual bool isOpenGLBacked() const { return false; } - - void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; } - TransformationMatrix transform() const { return m_transform; } + virtual AccelerationMode accelerationMode() const = 0; virtual void beginPainting() { } virtual void endPainting() { } @@ -130,7 +109,6 @@ public: // A surface is released implicitly when dereferenced. virtual PassRefPtr<BitmapTexture> acquireTextureFromPool(const IntSize&); - protected: TextureMapper() : m_interpolationQuality(InterpolationDefault) @@ -138,14 +116,21 @@ protected: {} private: +#if USE(TEXTURE_MAPPER_GL) + static PassOwnPtr<TextureMapper> platformCreateAccelerated(); +#else + static PassOwnPtr<TextureMapper> platformCreateAccelerated() + { + return PassOwnPtr<TextureMapper>(); + } +#endif InterpolationQuality m_interpolationQuality; TextDrawingModeFlags m_textDrawingMode; - TransformationMatrix m_transform; - IntSize m_viewportSize; Vector<RefPtr<BitmapTexture> > m_texturePool; + GraphicsContext* m_context; }; -}; +} #endif diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.cpp index 09714d909..6be518a8b 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.cpp @@ -26,7 +26,17 @@ #if USE(TEXTURE_MAPPER) namespace WebCore { -static double normalizedAnimationValue(double runningTime, double duration, bool alternate) + +static bool shouldReverseAnimationValue(Animation::AnimationDirection direction, int loopCount) +{ + if (((direction == Animation::AnimationDirectionAlternate) && (loopCount & 1)) + || ((direction == Animation::AnimationDirectionAlternateReverse) && !(loopCount & 1)) + || direction == Animation::AnimationDirectionReverse) + return true; + return false; +} + +static double normalizedAnimationValue(double runningTime, double duration, Animation::AnimationDirection direction) { if (!duration) return 0; @@ -35,7 +45,8 @@ static double normalizedAnimationValue(double runningTime, double duration, bool const double lastFullLoop = duration * double(loopCount); const double remainder = runningTime - lastFullLoop; const double normalized = remainder / duration; - return (loopCount % 2 && alternate) ? (1 - normalized) : normalized; + + return shouldReverseAnimationValue(direction, loopCount) ? 1 - normalized : normalized; } static float applyOpacityAnimation(float fromOpacity, float toOpacity, double progress) diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp new file mode 100644 index 000000000..783b03bf7 --- /dev/null +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp @@ -0,0 +1,105 @@ +/* + Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "TextureMapperImageBuffer.h" + +#if USE(TEXTURE_MAPPER) +namespace WebCore { + +void BitmapTextureImageBuffer::updateContents(const void* data, const IntRect& targetRect) +{ +#if PLATFORM(QT) + QImage image(reinterpret_cast<const uchar*>(data), targetRect.width(), targetRect.height(), targetRect.width() * 4, QImage::Format_ARGB32_Premultiplied); + QPainter* painter = m_image->context()->platformContext(); + painter->save(); + painter->setCompositionMode(QPainter::CompositionMode_Source); + painter->drawImage(targetRect, image); + painter->restore(); +#endif +} + +void BitmapTextureImageBuffer::updateContents(Image* image, const IntRect& targetRect, const IntRect& sourceRect, PixelFormat) +{ + m_image->context()->drawImage(image, ColorSpaceDeviceRGB, targetRect, sourceRect, CompositeCopy); +} + +void TextureMapperImageBuffer::beginClip(const TransformationMatrix& matrix, const FloatRect& rect) +{ + GraphicsContext* context = currentContext(); + if (!context) + return; +#if ENABLE(3D_RENDERING) + TransformationMatrix previousTransform = context->get3DTransform(); +#else + AffineTransform previousTransform = context->getCTM(); +#endif + context->save(); + +#if ENABLE(3D_RENDERING) + context->concat3DTransform(matrix); +#else + context->concatCTM(matrix.toAffineTransform()); +#endif + + context->clip(rect); + +#if ENABLE(3D_RENDERING) + context->set3DTransform(previousTransform); +#else + context->setCTM(previousTransform); +#endif +} + +void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture) +{ + GraphicsContext* context = currentContext(); + if (!context) + return; + + const BitmapTextureImageBuffer& textureImageBuffer = static_cast<const BitmapTextureImageBuffer&>(texture); + ImageBuffer* image = textureImageBuffer.m_image.get(); + OwnPtr<ImageBuffer> maskedImage; + + if (maskTexture && maskTexture->isValid()) { + const BitmapTextureImageBuffer* mask = static_cast<const BitmapTextureImageBuffer*>(maskTexture); + maskedImage = ImageBuffer::create(maskTexture->contentSize()); + GraphicsContext* maskContext = maskedImage->context(); + maskContext->drawImageBuffer(image, ColorSpaceDeviceRGB, IntPoint::zero(), CompositeCopy); + if (opacity < 1) { + maskContext->setAlpha(opacity); + opacity = 1; + } + maskContext->drawImageBuffer(mask->m_image.get(), ColorSpaceDeviceRGB, IntPoint::zero(), CompositeDestinationIn); + image = maskedImage.get(); + } + + context->save(); + context->setAlpha(opacity); +#if ENABLE(3D_RENDERING) + context->concat3DTransform(matrix); +#else + context->concatCTM(matrix.toAffineTransform()); +#endif + context->drawImageBuffer(image, ColorSpaceDeviceRGB, targetRect); + context->restore(); +} + +} +#endif diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h new file mode 100644 index 000000000..8411206cf --- /dev/null +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h @@ -0,0 +1,74 @@ +/* + Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef TextureMapperImageBuffer_h +#define TextureMapperImageBuffer_h + +#include "ImageBuffer.h" +#include "TextureMapper.h" + +#if USE(TEXTURE_MAPPER) +namespace WebCore { + +class BitmapTextureImageBuffer : public BitmapTexture { + friend class TextureMapperImageBuffer; +public: + static PassRefPtr<BitmapTexture> create() { return adoptRef(new BitmapTextureImageBuffer); } + ~BitmapTextureImageBuffer() { destroy(); } + virtual void destroy() { m_image.clear(); } + virtual IntSize size() const { return m_image->size(); } + virtual void reset(const IntSize& size, bool opaque) + { + BitmapTexture::reset(size, opaque); + m_image = ImageBuffer::create(size); + } + + virtual bool isValid() const { return m_image; } + inline GraphicsContext* graphicsContext() { return m_image ? m_image->context() : 0; } + virtual void updateContents(Image*, const IntRect&, const IntRect&, PixelFormat); + void updateContents(const void* data, const IntRect& targetRect); +private: + BitmapTextureImageBuffer() { } + OwnPtr<ImageBuffer> m_image; +}; + + +class TextureMapperImageBuffer : public TextureMapper { +public: + virtual void drawTexture(const BitmapTexture&, const FloatRect& targetRect, const TransformationMatrix&, float opacity, const BitmapTexture* maskTexture); + virtual void beginClip(const TransformationMatrix&, const FloatRect&); + virtual void bindSurface(BitmapTexture* surface) { m_currentSurface = surface;} + virtual void endClip() { graphicsContext()->restore(); } + static PassOwnPtr<TextureMapper> create() { return adoptPtr(new TextureMapperImageBuffer); } + PassRefPtr<BitmapTexture> createTexture() { return BitmapTextureImageBuffer::create(); } + inline GraphicsContext* currentContext() + { + return m_currentSurface ? static_cast<BitmapTextureImageBuffer*>(m_currentSurface.get())->graphicsContext() : graphicsContext(); + } + + virtual AccelerationMode accelerationMode() const { return SoftwareMode; } + +private: + RefPtr<BitmapTexture> m_currentSurface; +}; + +} +#endif // USE(TEXTURE_MAPPER) + +#endif // TextureMapperImageBuffer_h diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp index ccf49bc98..45b94bd91 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp @@ -23,6 +23,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "GraphicsLayerTextureMapper.h" +#include "ImageBuffer.h" #include "MathExtras.h" namespace { @@ -156,12 +157,10 @@ void TextureMapperNode::renderContent(TextureMapper* textureMapper, GraphicsLaye if (!textureMapper) return; - // FIXME: Add directly composited images. - FloatRect dirtyRect = m_currentContent.needsDisplay ? entireRect() : m_currentContent.needsDisplayRect; + IntRect dirtyRect = enclosingIntRect(m_currentContent.needsDisplay ? entireRect() : m_currentContent.needsDisplayRect); for (size_t tileIndex = 0; tileIndex < m_ownedTiles.size(); ++tileIndex) { OwnedTile& tile = m_ownedTiles[tileIndex]; - FloatRect rect = dirtyRect; if (!tile.texture) tile.texture = textureMapper->createTexture(); RefPtr<BitmapTexture>& texture = tile.texture; @@ -169,31 +168,48 @@ void TextureMapperNode::renderContent(TextureMapper* textureMapper, GraphicsLaye if (tile.needsReset || texture->contentSize() != tileSize || !texture->isValid()) { tile.needsReset = false; - texture->reset(tileSize, m_currentContent.contentType == DirectImageContentType ? false : m_state.contentsOpaque); - rect = tile.rect; + texture->reset(tileSize, m_state.contentsOpaque); + dirtyRect.unite(enclosingIntRect(tile.rect)); } + } + + if (dirtyRect.isEmpty()) + return; + + // 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()); + layer->paintGraphicsLayerContents(*context, dirtyRect); + if (m_currentContent.contentType == DirectImageContentType) + context->drawImage(m_currentContent.image.get(), ColorSpaceDeviceRGB, m_state.contentsRect); + + RefPtr<Image> image; + +#if PLATFORM(QT) + image = imageBuffer->copyImage(DontCopyBackingStore); +#else + // FIXME: support DontCopyBackingStore in non-Qt ports that use TextureMapper. + image = imageBuffer->copyImage(CopyBackingStore); +#endif - IntRect contentRect = enclosingIntRect(tile.rect); - contentRect.intersect(enclosingIntRect(rect)); - if (contentRect.isEmpty()) + // Divide the image to tiles. + for (size_t tileIndex = 0; tileIndex < m_ownedTiles.size(); ++tileIndex) { + OwnedTile& tile = m_ownedTiles[tileIndex]; + IntRect targetRect = enclosingIntRect(tile.rect); + targetRect.intersect(dirtyRect); + if (targetRect.isEmpty()) continue; + IntRect sourceRect = targetRect; - FloatRect contentRectInTileCoordinates = contentRect; - FloatPoint offset(-tile.rect.x(), -tile.rect.y()); - contentRectInTileCoordinates.move(offset.x(), offset.y()); - - { - GraphicsContext context(texture->beginPaint(enclosingIntRect(contentRectInTileCoordinates))); - context.setImageInterpolationQuality(textureMapper->imageInterpolationQuality()); - context.setTextDrawingMode(textureMapper->textDrawingMode()); - context.translate(offset.x(), offset.y()); - FloatRect scaledContentRect(contentRect); - if (m_currentContent.contentType == DirectImageContentType) - context.drawImage(m_currentContent.image.get(), ColorSpaceDeviceRGB, IntPoint(0, 0)); - else - layer->paintGraphicsLayerContents(context, enclosingIntRect(scaledContentRect)); - texture->endPaint(); - } + // Normalize sourceRect to the buffer's coordinates. + sourceRect.move(-dirtyRect.x(), -dirtyRect.y()); + + // Normalize targetRect to the texture's coordinqates. + targetRect.move(-tile.rect.x(), -tile.rect.y()); + tile.texture->updateContents(image.get(), targetRect, sourceRect, BitmapTexture::RGBAFormat); } m_currentContent.needsDisplay = false; @@ -481,7 +497,7 @@ void TextureMapperNode::clearAllDirectlyCompositedImageTiles() } } -void TextureMapperNode::setContentsTileBackBuffer(int id, const IntRect& sourceRect, const IntRect& targetRect, const void* bits) +void TextureMapperNode::setContentsTileBackBuffer(int id, const IntRect& sourceRect, const IntRect& targetRect, const void* data) { ASSERT(m_textureMapper); @@ -498,7 +514,7 @@ void TextureMapperNode::setContentsTileBackBuffer(int id, const IntRect& sourceR if (!tile.backBuffer.texture) tile.backBuffer.texture = m_textureMapper->createTexture(); tile.backBuffer.texture->reset(sourceRect.size(), false); - tile.backBuffer.texture->updateRawContents(sourceRect, bits); + tile.backBuffer.texture->updateContents(data, sourceRect); tile.isBackBufferUpdated = true; } diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h index fe4b14c73..230c9e0e0 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h @@ -148,7 +148,7 @@ public: void setTileOwnership(TileOwnership ownership) { m_state.tileOwnership = ownership; } int createContentsTile(float scale); void removeContentsTile(int id); - void setContentsTileBackBuffer(int id, const IntRect& sourceRect, const IntRect& targetRect, const void* bits); + void setContentsTileBackBuffer(int id, const IntRect& sourceRect, const IntRect& targetRect, const void*); void setTileBackBufferTextureForDirectlyCompositedImage(int id, const IntRect& sourceRect, const FloatRect& targetRect, BitmapTexture*); void clearAllDirectlyCompositedImageTiles(); void purgeNodeTexturesRecursive(); |