| Index: Source/platform/graphics/Pattern.cpp
 | 
| diff --git a/Source/platform/graphics/Pattern.cpp b/Source/platform/graphics/Pattern.cpp
 | 
| index 51c1796506602347d3fd3d4d8c77f0197f6d147b..932c17c4fb9025034cf9d0b4d3653ce86ae18395 100644
 | 
| --- a/Source/platform/graphics/Pattern.cpp
 | 
| +++ b/Source/platform/graphics/Pattern.cpp
 | 
| @@ -28,82 +28,40 @@
 | 
|  #include "config.h"
 | 
|  #include "platform/graphics/Pattern.h"
 | 
|  
 | 
| +#include "platform/graphics/BitmapPattern.h"
 | 
| +#include "platform/graphics/StaticBitmapPattern.h"
 | 
| +#include "third_party/skia/include/core/SkImage.h"
 | 
| +#include "third_party/skia/include/core/SkShader.h"
 | 
|  #include <v8.h>
 | 
| -#include "SkCanvas.h"
 | 
| -#include "SkColorShader.h"
 | 
| -#include "platform/graphics/skia/SkiaUtils.h"
 | 
|  
 | 
|  namespace blink {
 | 
|  
 | 
|  PassRefPtr<Pattern> Pattern::createBitmapPattern(PassRefPtr<Image> tileImage, RepeatMode repeatMode)
 | 
|  {
 | 
| -    return adoptRef(new Pattern(tileImage, repeatMode));
 | 
| +    if (tileImage->skImage())
 | 
| +        return StaticBitmapPattern::create(tileImage, repeatMode);
 | 
| +
 | 
| +    return BitmapPattern::create(tileImage, repeatMode);
 | 
|  }
 | 
|  
 | 
| -Pattern::Pattern(PassRefPtr<Image> image, RepeatMode repeatMode)
 | 
| +Pattern::Pattern(RepeatMode repeatMode, int64_t externalMemoryAllocated)
 | 
|      : m_repeatMode(repeatMode)
 | 
|      , m_externalMemoryAllocated(0)
 | 
|  {
 | 
| -    if (image) {
 | 
| -        m_tileImage = image->nativeImageForCurrentFrame();
 | 
| -    }
 | 
| +    adjustExternalMemoryAllocated(externalMemoryAllocated);
 | 
|  }
 | 
|  
 | 
|  Pattern::~Pattern()
 | 
|  {
 | 
| -    if (m_externalMemoryAllocated)
 | 
| -        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externalMemoryAllocated);
 | 
| +    adjustExternalMemoryAllocated(-m_externalMemoryAllocated);
 | 
|  }
 | 
|  
 | 
|  SkShader* Pattern::shader()
 | 
|  {
 | 
| -    if (m_pattern)
 | 
| -        return m_pattern.get();
 | 
| -
 | 
| -    SkMatrix localMatrix = affineTransformToSkMatrix(m_patternSpaceTransformation);
 | 
| -
 | 
| -    // If we don't have a bitmap, return a transparent shader.
 | 
| -    if (!m_tileImage) {
 | 
| -        m_pattern = adoptRef(new SkColorShader(SK_ColorTRANSPARENT));
 | 
| -    } else if (m_repeatMode == RepeatModeXY) {
 | 
| -        m_pattern = adoptRef(SkShader::CreateBitmapShader(m_tileImage->bitmap(),
 | 
| -            SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix));
 | 
| -    } else {
 | 
| -        // Skia does not have a "draw the tile only once" option. Clamp_TileMode
 | 
| -        // repeats the last line of the image after drawing one tile. To avoid
 | 
| -        // filling the space with arbitrary pixels, this workaround forces the
 | 
| -        // image to have a line of transparent pixels on the "repeated" edge(s),
 | 
| -        // thus causing extra space to be transparent filled.
 | 
| -        SkShader::TileMode tileModeX = (m_repeatMode & RepeatModeX)
 | 
| -            ? SkShader::kRepeat_TileMode
 | 
| -            : SkShader::kClamp_TileMode;
 | 
| -        SkShader::TileMode tileModeY = (m_repeatMode & RepeatModeY)
 | 
| -            ? SkShader::kRepeat_TileMode
 | 
| -            : SkShader::kClamp_TileMode;
 | 
| -        int expandW = (m_repeatMode & RepeatModeX) ? 0 : 1;
 | 
| -        int expandH = (m_repeatMode & RepeatModeY) ? 0 : 1;
 | 
| -
 | 
| -        // Create a transparent bitmap 1 pixel wider and/or taller than the
 | 
| -        // original, then copy the orignal into it.
 | 
| -        // FIXME: Is there a better way to pad (not scale) an image in skia?
 | 
| -        SkImageInfo info = m_tileImage->bitmap().info();
 | 
| -        info.fWidth += expandW;
 | 
| -        info.fHeight += expandH;
 | 
| -        // we explicitly require non-opaquness, since we are going to add a transparent strip.
 | 
| -        info.fAlphaType = kPremul_SkAlphaType;
 | 
| -
 | 
| -        SkBitmap bm2;
 | 
| -        bm2.allocPixels(info);
 | 
| -        bm2.eraseARGB(0x00, 0x00, 0x00, 0x00);
 | 
| -        SkCanvas canvas(bm2);
 | 
| -        canvas.drawBitmap(m_tileImage->bitmap(), 0, 0);
 | 
| -        bm2.setImmutable();
 | 
| -        m_pattern = adoptRef(SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY, &localMatrix));
 | 
| -
 | 
| -        // Clamp to int, since that's what the adjust function takes.
 | 
| -        m_externalMemoryAllocated = static_cast<int>(std::min(static_cast<size_t>(INT_MAX), bm2.getSafeSize()));
 | 
| -        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externalMemoryAllocated);
 | 
| +    if (!m_pattern) {
 | 
| +        m_pattern = createShader();
 | 
|      }
 | 
| +
 | 
|      return m_pattern.get();
 | 
|  }
 | 
|  
 | 
| @@ -116,4 +74,13 @@ void Pattern::setPatternSpaceTransform(const AffineTransform& patternSpaceTransf
 | 
|      m_pattern.clear();
 | 
|  }
 | 
|  
 | 
| +void Pattern::adjustExternalMemoryAllocated(int64_t delta)
 | 
| +{
 | 
| +    delta = std::max(-m_externalMemoryAllocated, delta);
 | 
| +
 | 
| +    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(delta);
 | 
| +
 | 
| +    m_externalMemoryAllocated += delta;
 | 
| +}
 | 
| +
 | 
|  } // namespace blink
 | 
| 
 |