Skip to content
Permalink
Browse files
Add ImageBuffer support for having a hi-res backing store. This allows
ImageBuffer clients to specify a scale factor upon creation so that they
don't have to maintain that info themselves as they use/pass around the ImageBuffer.
https://bugs.webkit.org/show_bug.cgi?id=79395

Reviewed by Dan Bernstein.

No new tests. This patch doesn't change behavior.

* platform/graphics/ImageBuffer.h:
(WebCore::ImageBuffer::create): Scale the backing store by the resolution scale.
(WebCore::ImageBuffer::logicalSize): Differentiate the logical size from the backing store's size.
(WebCore::ImageBuffer::internalSize): The backing store's size.

* platform/graphics/cg/ImageBufferCG.cpp: Prefer the explicit use of logicalSize and internalSize.

Explicitly state a 1x scale for all ImageBuffer creation sites
since this is what they currently assume.
* html/HTMLCanvasElement.cpp:
* html/canvas/CanvasRenderingContext2D.cpp:
* html/canvas/WebGLRenderingContext.cpp:
* page/Frame.cpp:
* platform/graphics/CrossfadeGeneratedImage.cpp:
* platform/graphics/ShadowBlur.cpp:
* platform/graphics/filters/FEColorMatrix.cpp:
* platform/graphics/filters/FEDropShadow.cpp:
* platform/graphics/filters/FilterEffect.cpp:
* platform/mac/ScrollbarThemeMac.mm:
* rendering/FilterEffectRenderer.cpp:
* rendering/RenderThemeMac.mm:
* rendering/svg/SVGImageBufferTools.cpp:
* svg/graphics/SVGImage.cpp:
* svg/graphics/SVGImageCache.cpp:

Update ImageBuffer::size() calls to new versions.
* platform/graphics/GraphicsContext.cpp:
* platform/graphics/ImageBuffer.cpp:
* platform/graphics/skia/PlatformContextSkia.cpp:


Canonical link: https://commits.webkit.org/96783@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@109016 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Matt Delaney committed Feb 27, 2012
1 parent b2b8ec6 commit a1928722a27d385eddbaaed743c08b65ea443713
Showing with 125 additions and 101 deletions.
  1. +41 −0 Source/WebCore/ChangeLog
  2. +3 −2 Source/WebCore/html/HTMLCanvasElement.cpp
  3. +4 −4 Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
  4. +2 −2 Source/WebCore/html/canvas/WebGLRenderingContext.cpp
  5. +2 −2 Source/WebCore/page/Frame.cpp
  6. +1 −1 Source/WebCore/platform/graphics/CrossfadeGeneratedImage.cpp
  7. +8 −8 Source/WebCore/platform/graphics/GraphicsContext.cpp
  8. +1 −1 Source/WebCore/platform/graphics/ImageBuffer.cpp
  9. +21 −15 Source/WebCore/platform/graphics/ImageBuffer.h
  10. +3 −3 Source/WebCore/platform/graphics/ShadowBlur.cpp
  11. +0 −5 Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
  12. +26 −25 Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
  13. +1 −1 Source/WebCore/platform/graphics/filters/FEDropShadow.cpp
  14. +2 −2 Source/WebCore/platform/graphics/filters/FilterEffect.cpp
  15. +0 −5 Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
  16. +0 −5 Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
  17. +1 −1 Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
  18. +1 −1 Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h
  19. +0 −5 Source/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp
  20. +0 −6 Source/WebCore/platform/graphics/wx/ImageBufferWx.cpp
  21. +1 −1 Source/WebCore/platform/mac/ScrollbarThemeMac.mm
  22. +2 −1 Source/WebCore/rendering/FilterEffectRenderer.cpp
  23. +1 −1 Source/WebCore/rendering/RenderThemeMac.mm
  24. +2 −2 Source/WebCore/rendering/svg/SVGImageBufferTools.cpp
  25. +1 −1 Source/WebCore/svg/graphics/SVGImage.cpp
  26. +1 −1 Source/WebCore/svg/graphics/SVGImageCache.cpp
@@ -1,3 +1,44 @@
2012-02-27 Matthew Delaney <mdelaney@apple.com>

Add ImageBuffer support for having a hi-res backing store. This allows
ImageBuffer clients to specify a scale factor upon creation so that they
don't have to maintain that info themselves as they use/pass around the ImageBuffer.
https://bugs.webkit.org/show_bug.cgi?id=79395

Reviewed by Dan Bernstein.

No new tests. This patch doesn't change behavior.

* platform/graphics/ImageBuffer.h:
(WebCore::ImageBuffer::create): Scale the backing store by the resolution scale.
(WebCore::ImageBuffer::logicalSize): Differentiate the logical size from the backing store's size.
(WebCore::ImageBuffer::internalSize): The backing store's size.

* platform/graphics/cg/ImageBufferCG.cpp: Prefer the explicit use of logicalSize and internalSize.

Explicitly state a 1x scale for all ImageBuffer creation sites
since this is what they currently assume.
* html/HTMLCanvasElement.cpp:
* html/canvas/CanvasRenderingContext2D.cpp:
* html/canvas/WebGLRenderingContext.cpp:
* page/Frame.cpp:
* platform/graphics/CrossfadeGeneratedImage.cpp:
* platform/graphics/ShadowBlur.cpp:
* platform/graphics/filters/FEColorMatrix.cpp:
* platform/graphics/filters/FEDropShadow.cpp:
* platform/graphics/filters/FilterEffect.cpp:
* platform/mac/ScrollbarThemeMac.mm:
* rendering/FilterEffectRenderer.cpp:
* rendering/RenderThemeMac.mm:
* rendering/svg/SVGImageBufferTools.cpp:
* svg/graphics/SVGImage.cpp:
* svg/graphics/SVGImageCache.cpp:

Update ImageBuffer::size() calls to new versions.
* platform/graphics/GraphicsContext.cpp:
* platform/graphics/ImageBuffer.cpp:
* platform/graphics/skia/PlatformContextSkia.cpp:

2012-02-27 Mihnea Ovidenie <mihnea@adobe.com>

[CSSRegions]-webkit-flow-into initial value should be none instead of auto
@@ -513,7 +513,7 @@ void HTMLCanvasElement::createImageBuffer() const
Unaccelerated;
#endif
DeferralMode deferralMode = shouldDefer() ? Deferred : NonDeferred;
m_imageBuffer = ImageBuffer::create(bufferSize, ColorSpaceDeviceRGB, renderingMode, deferralMode);
m_imageBuffer = ImageBuffer::create(bufferSize, 1, ColorSpaceDeviceRGB, renderingMode, deferralMode);
if (!m_imageBuffer)
return;
m_imageBuffer->context()->scale(FloatSize(bufferSize.width() / logicalSize.width(), bufferSize.height() / logicalSize.height()));
@@ -523,7 +523,8 @@ void HTMLCanvasElement::createImageBuffer() const

#if USE(JSC)
JSC::JSLock lock(JSC::SilenceAssertionsOnly);
scriptExecutionContext()->globalData()->heap.reportExtraMemoryCost(m_imageBuffer->dataSize());
size_t numBytes = 4 * m_imageBuffer->internalSize().width() * m_imageBuffer->internalSize().height();
scriptExecutionContext()->globalData()->heap.reportExtraMemoryCost(numBytes);
#endif

#if USE(IOSURFACE_CANVAS_BACKING_STORE) || (ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING))
@@ -1521,7 +1521,7 @@ template<class T> IntRect CanvasRenderingContext2D::calculateCompositingBufferRe
PassOwnPtr<ImageBuffer> CanvasRenderingContext2D::createCompositingBuffer(const IntRect& bufferRect)
{
RenderingMode renderMode = isAccelerated() ? Accelerated : Unaccelerated;
return ImageBuffer::create(bufferRect.size(), ColorSpaceDeviceRGB, renderMode);
return ImageBuffer::create(bufferRect.size(), 1, ColorSpaceDeviceRGB, renderMode);
}

void CanvasRenderingContext2D::compositeBuffer(ImageBuffer* buffer, const IntRect& bufferRect, CompositeOperator op)
@@ -1883,7 +1883,7 @@ void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy,
IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy));
IntRect destRect = enclosingIntRect(clipRect);
destRect.move(destOffset);
destRect.intersect(IntRect(IntPoint(), buffer->size()));
destRect.intersect(IntRect(IntPoint(), buffer->internalSize()));
if (destRect.isEmpty())
return;
IntRect sourceRect(destRect);
@@ -2089,9 +2089,9 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
IntRect maskRect = enclosingIntRect(textRect);

#if USE(IOSURFACE_CANVAS_BACKING_STORE)
OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), ColorSpaceDeviceRGB, Accelerated);
OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), 1, ColorSpaceDeviceRGB, Accelerated);
#else
OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size());
OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), 1);
#endif

GraphicsContext* maskImageContext = maskImage->context();
@@ -5330,13 +5330,13 @@ ImageBuffer* WebGLRenderingContext::LRUImageBufferCache::imageBuffer(const IntSi
ImageBuffer* buf = m_buffers[i].get();
if (!buf)
break;
if (buf->size() != size)
if (buf->logicalSize() != size)
continue;
bubbleToFront(i);
return buf;
}

OwnPtr<ImageBuffer> temp = ImageBuffer::create(size);
OwnPtr<ImageBuffer> temp = ImageBuffer::create(size, 1);
if (!temp)
return 0;
i = std::min(m_capacity - 1, i);
@@ -1094,7 +1094,7 @@ DragImageRef Frame::nodeImage(Node* node)
LayoutRect topLevelRect;
IntRect paintingRect = pixelSnappedIntRect(renderer->paintingRootRect(topLevelRect));

OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size()));
OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), 1, ColorSpaceDeviceRGB));
if (!buffer)
return 0;
buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
@@ -1117,7 +1117,7 @@ DragImageRef Frame::dragImageForSelection()

IntRect paintingRect = enclosingIntRect(selection()->bounds());

OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size()));
OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), 1, ColorSpaceDeviceRGB));
if (!buffer)
return 0;
buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
@@ -95,7 +95,7 @@ void CrossfadeGeneratedImage::draw(GraphicsContext* context, const FloatRect& ds

void CrossfadeGeneratedImage::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator compositeOp, const FloatRect& dstRect)
{
OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(m_size, ColorSpaceDeviceRGB, context->isAcceleratedContext() ? Accelerated : Unaccelerated);
OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(m_size, 1, ColorSpaceDeviceRGB, context->isAcceleratedContext() ? Accelerated : Unaccelerated);
if (!imageBuffer)
return;

@@ -487,18 +487,18 @@ void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const
image->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), styleColorSpace, op);
}

void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& rect, const IntPoint& srcPoint, const IntSize& tileSize, CompositeOperator op, bool useLowQualityScale)
void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize, CompositeOperator op, bool useLowQualityScale)
{
if (paintingDisabled() || !image)
return;

if (useLowQualityScale) {
InterpolationQuality previousInterpolationQuality = imageInterpolationQuality();
setImageInterpolationQuality(InterpolationLow);
image->drawTiled(this, rect, srcPoint, tileSize, styleColorSpace, op);
image->drawTiled(this, destRect, srcPoint, tileSize, styleColorSpace, op);
setImageInterpolationQuality(previousInterpolationQuality);
} else
image->drawTiled(this, rect, srcPoint, tileSize, styleColorSpace, op);
image->drawTiled(this, destRect, srcPoint, tileSize, styleColorSpace, op);
}

void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect,
@@ -553,14 +553,14 @@ void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorS
float th = dest.height();

if (tsw == -1)
tsw = image->width();
tsw = image->logicalSize().width();
if (tsh == -1)
tsh = image->height();
tsh = image->logicalSize().height();

if (tw == -1)
tw = image->width();
tw = image->logicalSize().width();
if (th == -1)
th = image->height();
th = image->logicalSize().height();

if (useLowQualityScale) {
InterpolationQuality previousInterpolationQuality = imageInterpolationQuality();
@@ -754,7 +754,7 @@ PassOwnPtr<ImageBuffer> GraphicsContext::createCompatibleBuffer(const IntSize& s
AffineTransform transform = getCTM();
IntSize scaledSize(static_cast<int>(ceil(size.width() * transform.xScale())), static_cast<int>(ceil(size.height() * transform.yScale())));

OwnPtr<ImageBuffer> buffer = ImageBuffer::create(scaledSize, ColorSpaceDeviceRGB, isAcceleratedContext() ? Accelerated : Unaccelerated);
OwnPtr<ImageBuffer> buffer = ImageBuffer::create(scaledSize, 1, ColorSpaceDeviceRGB, isAcceleratedContext() ? Accelerated : Unaccelerated);
if (!buffer)
return nullptr;

@@ -71,7 +71,7 @@ void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo

inline void ImageBuffer::genericConvertToLuminanceMask()
{
IntRect luminanceRect(IntPoint(), size());
IntRect luminanceRect(IntPoint(), internalSize());
RefPtr<ByteArray> srcPixelArray = getUnmultipliedImageData(luminanceRect);

unsigned pixelArrayLength = srcPixelArray->length();
@@ -31,6 +31,7 @@
#include "AffineTransform.h"
#include "ColorSpace.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
#if USE(ACCELERATED_COMPOSITING)
#include "GraphicsLayer.h"
#endif
@@ -46,7 +47,6 @@

namespace WebCore {

class GraphicsContext;
class Image;
class ImageData;
class IntPoint;
@@ -77,23 +77,29 @@ namespace WebCore {
WTF_MAKE_NONCOPYABLE(ImageBuffer); WTF_MAKE_FAST_ALLOCATED;
public:
// Will return a null pointer on allocation failure.
static PassOwnPtr<ImageBuffer> create(const IntSize& size, ColorSpace colorSpace = ColorSpaceDeviceRGB, RenderingMode renderingMode = Unaccelerated, DeferralMode deferralMode = NonDeferred)
static PassOwnPtr<ImageBuffer> create(const IntSize& size, float resolutionScale = 1, ColorSpace colorSpace = ColorSpaceDeviceRGB, RenderingMode renderingMode = Unaccelerated, DeferralMode deferralMode = NonDeferred)
{
bool success = false;
OwnPtr<ImageBuffer> buf = adoptPtr(new ImageBuffer(size, colorSpace, renderingMode, deferralMode, success));
if (success)
return buf.release();
return nullptr;
float scaledWidth = ceilf(resolutionScale * size.width());
float scaledHeight = ceilf(resolutionScale * size.height());
IntSize internalSize(scaledWidth, scaledHeight);

OwnPtr<ImageBuffer> buf = adoptPtr(new ImageBuffer(internalSize, colorSpace, renderingMode, deferralMode, success));
if (!success)
return nullptr;

buf->m_logicalSize = size;
buf->m_resolutionScale = resolutionScale;
buf->context()->scale(FloatSize(resolutionScale, resolutionScale));
return buf.release();
}

~ImageBuffer();

const IntSize& size() const { return m_size; }
int width() const { return m_size.width(); }
int height() const { return m_size.height(); }

size_t dataSize() const;

// The actual resolution of the backing store
const IntSize& internalSize() const { return m_size; }
const IntSize& logicalSize() const { return m_logicalSize; }

GraphicsContext* context() const;

PassRefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore) const;
@@ -111,7 +117,7 @@ namespace WebCore {
void transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace);
void platformTransformColorSpace(const Vector<int>&);
#else
AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_size.height()); }
AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, internalSize().height()); }
#endif
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* platformLayer() const;
@@ -121,7 +127,6 @@ namespace WebCore {
#if USE(CG)
NativeImagePtr copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
#endif

void clip(GraphicsContext*, const FloatRect&) const;

void draw(GraphicsContext*, ColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
@@ -136,8 +141,9 @@ namespace WebCore {

private:
ImageBufferData m_data;

IntSize m_size;
IntSize m_logicalSize;
float m_resolutionScale;
OwnPtr<GraphicsContext> m_context;

#if !USE(CG)
@@ -73,14 +73,14 @@ class ScratchBuffer {
m_bufferInUse = true;
#endif
// We do not need to recreate the buffer if the current buffer is large enough.
if (m_imageBuffer && m_imageBuffer->width() >= size.width() && m_imageBuffer->height() >= size.height())
if (m_imageBuffer && m_imageBuffer->logicalSize().width() >= size.width() && m_imageBuffer->logicalSize().height() >= size.height())
return m_imageBuffer.get();

// Round to the nearest 32 pixels so we do not grow the buffer for similar sized requests.
IntSize roundedSize(roundUpToMultipleOf32(size.width()), roundUpToMultipleOf32(size.height()));

clearScratchBuffer();
m_imageBuffer = ImageBuffer::create(roundedSize);
m_imageBuffer = ImageBuffer::create(roundedSize, 1);
return m_imageBuffer.get();
}

@@ -440,7 +440,7 @@ void ShadowBlur::drawShadowBuffer(GraphicsContext* graphicsContext)

GraphicsContextStateSaver stateSaver(*graphicsContext);

IntSize bufferSize = m_layerImage->size();
IntSize bufferSize = m_layerImage->internalSize();
if (bufferSize != m_layerSize) {
// The rect passed to clipToImageBuffer() has to be the size of the entire buffer,
// but we may not have cleared it all, so clip to the filled part first.
@@ -76,11 +76,6 @@ ImageBuffer::~ImageBuffer()
cairo_surface_destroy(m_data.m_surface);
}

size_t ImageBuffer::dataSize() const
{
return m_size.width() * m_size.height() * 4;
}

GraphicsContext* ImageBuffer::context() const
{
return m_context.get();

0 comments on commit a192872

Please sign in to comment.