aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/image
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2015-09-10 14:33:38 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-09-10 14:33:38 -0700
commit85d9178832f4a64c9d80ffb14cb9dab4fe0fa54a (patch)
tree809af195b135b0118ce2e6b9f060bdf2f5dfbfbc /src/image
parente70afc9f48d00828ee6b707899a8ff542b0e8b98 (diff)
Use SkImageCacherator in SkImages
Possible follow-up changes to consider 1. Roll SkImage_Raster and _Gpu into _Generator, where the generator (or cacherator) is backed by a pre-existing texture or raster. 2. Evolve SkImageUsageType into a verb requiring stretching, and have the caller (common code) digest the caps() and usage, so that subclasses are just told what to do (stretch or not) 3. Common code/utility to convert an unstretched texture into a stretch one (and cache it) if the generator can only make an unstretched one. BUG=skia: Review URL: https://codereview.chromium.org/1282363002
Diffstat (limited to 'src/image')
-rw-r--r--src/image/SkImage.cpp2
-rw-r--r--src/image/SkImage_Base.h5
-rw-r--r--src/image/SkImage_Generator.cpp95
-rw-r--r--src/image/SkImage_Gpu.cpp5
-rw-r--r--src/image/SkImage_Gpu.h4
-rw-r--r--src/image/SkImage_Raster.cpp25
6 files changed, 121 insertions, 15 deletions
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index 5a67c84caf..4315ad7e87 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -158,7 +158,7 @@ SkImage* SkImage::newImage(int newWidth, int newHeight, const SkIRect* subset,
#if SK_SUPPORT_GPU
GrTexture* SkImage::getTexture() const {
- return as_IB(this)->getTexture();
+ return as_IB(this)->peekTexture();
}
bool SkImage::isTextureBacked() const { return SkToBool(as_IB(this)->getTexture()); }
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index 01b39be383..8c9a73ba36 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -54,7 +54,7 @@ public:
virtual void onPreroll(GrContext*) const {}
- virtual GrTexture* getTexture() const { return nullptr; }
+ virtual GrTexture* peekTexture() const { return nullptr; }
// return a read-only copy of the pixels. We promise to not modify them,
// but only inspect them (or encode them).
@@ -73,6 +73,9 @@ public:
virtual bool onIsLazyGenerated() const { return false; }
+ // Caller must call unref when they are done.
+ virtual GrTexture* asTextureRef(GrContext*, SkImageUsageType) const { return nullptr; }
+
private:
const SkSurfaceProps fProps;
diff --git a/src/image/SkImage_Generator.cpp b/src/image/SkImage_Generator.cpp
new file mode 100644
index 0000000000..731881c059
--- /dev/null
+++ b/src/image/SkImage_Generator.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkImage_Base.h"
+#include "SkBitmap.h"
+#include "SkData.h"
+#include "SkImageCacherator.h"
+#include "SkImagePriv.h"
+#include "SkPixelRef.h"
+#include "SkSurface.h"
+
+class SkImage_Generator : public SkImage_Base {
+public:
+ SkImage_Generator(SkImageCacherator* cache)
+ : INHERITED(cache->info().width(), cache->info().height(), kNeedNewImageUniqueID, NULL)
+ , fCache(cache) // take ownership
+ {}
+
+ SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const override;
+ bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY) const override;
+ const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const override;
+ SkData* onRefEncoded() const override;
+ bool isOpaque() const override { return fCache->info().isOpaque(); }
+
+ bool getROPixels(SkBitmap*) const override;
+ GrTexture* asTextureRef(GrContext*, SkImageUsageType) const override;
+
+ SkShader* onNewShader(SkShader::TileMode,
+ SkShader::TileMode,
+ const SkMatrix* localMatrix) const override;
+
+ bool onIsLazyGenerated() const override { return true; }
+
+private:
+ SkAutoTDelete<SkImageCacherator> fCache;
+
+ typedef SkImage_Base INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkShader* SkImage_Generator::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
+ const SkMatrix* localMatrix) const {
+ // TODO: need a native Shader that takes Cacherator (or this image) so we can natively return
+ // textures as output from the shader.
+ SkBitmap bm;
+ if (this->getROPixels(&bm)) {
+ return SkShader::CreateBitmapShader(bm, tileX, tileY, localMatrix);
+ }
+ return nullptr;
+}
+
+SkSurface* SkImage_Generator::onNewSurface(const SkImageInfo& info,
+ const SkSurfaceProps& props) const {
+ return SkSurface::NewRaster(info, &props);
+}
+
+bool SkImage_Generator::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
+ int srcX, int srcY) const {
+ SkBitmap bm;
+ if (this->getROPixels(&bm)) {
+ return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
+ }
+ return false;
+}
+
+const void* SkImage_Generator::onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytesPtr) const {
+ return NULL;
+}
+
+SkData* SkImage_Generator::onRefEncoded() const {
+ return fCache->refEncoded();
+}
+
+bool SkImage_Generator::getROPixels(SkBitmap* bitmap) const {
+ return fCache->lockAsBitmap(bitmap);
+}
+
+GrTexture* SkImage_Generator::asTextureRef(GrContext* ctx, SkImageUsageType usage) const {
+ return fCache->lockAsTexture(ctx, usage);
+}
+
+#ifndef SK_SUPPORT_LEGACY_NEWFROMGENERATOR
+SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* subset) {
+ SkImageCacherator* cache = SkImageCacherator::NewFromGenerator(generator, subset);
+ if (!cache) {
+ return nullptr;
+ }
+ return SkNEW_ARGS(SkImage_Generator, (cache));
+}
+#endif
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index fdcb87136d..163e62e02d 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -79,6 +79,11 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst) const {
return true;
}
+GrTexture* SkImage_Gpu::asTextureRef(GrContext* ctx, SkImageUsageType usage) const {
+ fTexture->ref();
+ return fTexture;
+}
+
bool SkImage_Gpu::isOpaque() const {
return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaque_SkAlphaType;
}
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
index 9481690714..d168fb6853 100644
--- a/src/image/SkImage_Gpu.h
+++ b/src/image/SkImage_Gpu.h
@@ -37,7 +37,9 @@ public:
}
bool getROPixels(SkBitmap*) const override;
- GrTexture* getTexture() const override { return fTexture; }
+ GrTexture* asTextureRef(GrContext* ctx, SkImageUsageType usage) const override;
+
+ GrTexture* peekTexture() const override { return fTexture; }
SkShader* onNewShader(SkShader::TileMode,
SkShader::TileMode,
const SkMatrix* localMatrix) const override;
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 8afe7fd13a..5025dfa8c4 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -231,18 +231,6 @@ SkImage* SkImage::NewFromRaster(const SkImageInfo& info, const void* pixels, siz
return new SkImage_Raster(info, data, rowBytes, ctable, nullptr);
}
-SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* subset) {
- SkBitmap bitmap;
- if (!SkInstallDiscardablePixelRef(generator, subset, &bitmap, nullptr)) {
- return nullptr;
- }
- if (0 == bitmap.width() || 0 == bitmap.height()) {
- return nullptr;
- }
-
- return new SkImage_Raster(bitmap, nullptr);
-}
-
SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
const SkIPoint& pixelRefOrigin, size_t rowBytes,
const SkSurfaceProps* props) {
@@ -301,3 +289,16 @@ bool SkImage_Raster::onAsLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode mode) c
}
return this->INHERITED::onAsLegacyBitmap(bitmap, mode);
}
+
+#ifdef SK_SUPPORT_LEGACY_NEWFROMGENERATOR
+SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* subset) {
+ SkBitmap bitmap;
+ if (!SkInstallDiscardablePixelRef(generator, subset, &bitmap, nullptr)) {
+ return nullptr;
+ }
+ if (0 == bitmap.width() || 0 == bitmap.height()) {
+ return nullptr;
+ }
+ return new SkImage_Raster(bitmap, nullptr);
+}
+#endif