Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(640)

Unified Diff: Source/platform/graphics/Pattern.cpp

Issue 358893002: Use newImageSnapshot() to get an image from a Canvas (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Bitmap caching for Shaders/Patterns from StaticBitmapImage/SkImage Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/platform/graphics/Pattern.cpp
diff --git a/Source/platform/graphics/Pattern.cpp b/Source/platform/graphics/Pattern.cpp
index 2c889683b038ce3e5e2d9ac6f21ea33ded08d250..ecd379ee9813776f7d0498dd56d463157c128c24 100644
--- a/Source/platform/graphics/Pattern.cpp
+++ b/Source/platform/graphics/Pattern.cpp
@@ -24,86 +24,107 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#include "config.h"
#include "platform/graphics/Pattern.h"
-#include <v8.h>
-#include "SkCanvas.h"
-#include "SkColorShader.h"
+#include "platform/graphics/BitmapPattern.h"
+#include "platform/graphics/StaticBitmapPattern.h"
#include "platform/graphics/skia/SkiaUtils.h"
-
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkImage.h"
+#include <v8.h>
namespace blink {
-Pattern::Pattern(PassRefPtr<Image> image, bool repeatX, bool repeatY)
- : m_repeatX(repeatX)
- , m_repeatY(repeatY)
- , m_externalMemoryAllocated(0)
+PassRefPtr<Pattern> Pattern::create(PassRefPtr<Image> tileImage, bool repeatX, bool repeatY)
{
- if (image) {
- m_tileImage = image->nativeImageForCurrentFrame();
- }
+ if (tileImage->image())
+ return StaticBitmapPattern::create(tileImage, repeatX, repeatY);
+
+ return BitmapPattern::create(tileImage, repeatX, repeatY);
}
Pattern::~Pattern()
{
- if (m_externalMemoryAllocated)
- v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externalMemoryAllocated);
+ adjustExternalMemoryAllocated(-m_externalMemoryAllocated);
}
-SkShader* Pattern::shader()
+void Pattern::setPatternSpaceTransform(const AffineTransform& patternSpaceTransformation)
{
+ m_patternSpaceTransformation = patternSpaceTransformation;
if (m_pattern)
- return m_pattern.get();
-
- SkMatrix localMatrix = affineTransformToSkMatrix(m_patternSpaceTransformation);
+ m_pattern.clear();
+}
- // If we don't have a bitmap, return a transparent shader.
- if (!m_tileImage)
- m_pattern = adoptRef(new SkColorShader(SK_ColorTRANSPARENT));
- else if (m_repeatX && m_repeatY)
- 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_repeatX ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
- SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
- int expandW = m_repeatX ? 0 : 1;
- int expandH = m_repeatY ? 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);
+SkShader* Pattern::shader(SkShader::ShaderLocation preferredLocation)
+{
+ if (!m_pattern) {
+ m_pattern = createShader(preferredLocation);
}
+
return m_pattern.get();
}
-void Pattern::setPatternSpaceTransform(const AffineTransform& patternSpaceTransformation)
+void Pattern::adjustExternalMemoryAllocated(int64_t delta)
{
- m_patternSpaceTransformation = patternSpaceTransformation;
- if (m_pattern)
- m_pattern.clear();
+ delta = std::max(-m_externalMemoryAllocated, delta);
+
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(delta);
+
+ m_externalMemoryAllocated += delta;
+}
+
+BitmapBackedPattern::BitmapBackedPattern(bool repeatX, bool repeatY, int64_t externalMemoryAllocated) : Pattern(repeatX, repeatY, externalMemoryAllocated) { }
+
+BitmapBackedPattern::~BitmapBackedPattern() { }
+
+PassRefPtr<SkShader> BitmapBackedPattern::createShader(SkShader::ShaderLocation preferredLocation)
Justin Novosad 2014/08/05 17:31:26 unused argument should be commented-out
Rémi Piotaix 2014/08/06 18:09:14 Done.
+{
+ // 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_repeatX ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
+ SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
+ int expandW = m_repeatX ? 0 : 1;
+ int expandH = m_repeatY ? 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 = this->getBitmapInfo();
+ info.fWidth = info.width() + expandW;
+ info.fHeight = info.height() + expandH;
+ // we explicitly require non-opaquness, since we are going to add a transparent strip.
+ info.fAlphaType = kPremul_SkAlphaType;
+
+ SkBitmap bm2;
+ bm2.allocPixels(info);
+ SkCanvas canvas(bm2);
+
+ SkPaint paint;
+ paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref();
Justin Novosad 2014/08/05 17:31:26 You should use the version of setXfermode that tak
Rémi Piotaix 2014/08/06 18:09:14 Done.
+
+ this->drawBitmapToCanvas(canvas, paint);
+
+ paint.setARGB(0x00, 0x00, 0x00, 0x00);
+ paint.setStyle(SkPaint::kFill_Style);
+
+ if (!m_repeatX)
+ canvas.drawRect(SkRect::MakeXYWH(info.width() - 1, 0, 1, info.height()), paint);
+
+ if (!m_repeatY)
+ canvas.drawRect(SkRect::MakeXYWH(0, info.height()-1, info.width(), 1), paint);
+
+ bm2.setImmutable();
+
+ // Clamp to int, since that's what the adjust function takes.
+ adjustExternalMemoryAllocated(bm2.getSafeSize());
+
+ SkMatrix localMatrix = affineTransformToSkMatrix(m_patternSpaceTransformation);
+
+ return adoptRef(SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY, &localMatrix));
}
}

Powered by Google App Engine
This is Rietveld 408576698