aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/image
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2015-09-25 02:31:09 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-09-25 02:31:09 -0700
commitfe05707c356d2a8c2c69222591d4cafbd456b4e5 (patch)
treec490b4a707c52d58fc1bcadf1fb4d5d816db392f /src/image
parent00d6e515e5835f7df6163ceb5f5ceb1770552bf7 (diff)
Revert[2] of add ImageShader, sharing code with its Bitmap cousin
Adjustment from previous land : runtime check for npot-support when texture is requested for tiling. (patchset #10 id:180001 of https://codereview.chromium.org/1342113002/ ) This reverts commit f2608513626264459a00388537175600b515cae2. BUG=skia:4365 Review URL: https://codereview.chromium.org/1352293002
Diffstat (limited to 'src/image')
-rw-r--r--src/image/SkImage.cpp3
-rw-r--r--src/image/SkImageShader.cpp144
-rw-r--r--src/image/SkImageShader.h44
-rw-r--r--src/image/SkImage_Base.h5
-rw-r--r--src/image/SkImage_Generator.cpp16
-rw-r--r--src/image/SkImage_Gpu.cpp21
-rw-r--r--src/image/SkImage_Gpu.h3
-rw-r--r--src/image/SkImage_Raster.cpp9
8 files changed, 205 insertions, 40 deletions
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index b639821a95..ee76a7ea39 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -11,6 +11,7 @@
#include "SkData.h"
#include "SkImageGenerator.h"
#include "SkImagePriv.h"
+#include "SkImageShader.h"
#include "SkImage_Base.h"
#include "SkNextID.h"
#include "SkPixelRef.h"
@@ -69,7 +70,7 @@ void SkImage::preroll(GrContext* ctx) const {
SkShader* SkImage::newShader(SkShader::TileMode tileX,
SkShader::TileMode tileY,
const SkMatrix* localMatrix) const {
- return as_IB(this)->onNewShader(tileX, tileY, localMatrix);
+ return SkImageShader::Create(this, tileX, tileY, localMatrix);
}
SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const {
diff --git a/src/image/SkImageShader.cpp b/src/image/SkImageShader.cpp
new file mode 100644
index 0000000000..957081d20d
--- /dev/null
+++ b/src/image/SkImageShader.cpp
@@ -0,0 +1,144 @@
+/*
+ * 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 "SkBitmapProcShader.h"
+#include "SkBitmapProvider.h"
+#include "SkImage_Base.h"
+#include "SkImageShader.h"
+#include "SkReadBuffer.h"
+#include "SkWriteBuffer.h"
+
+SkImageShader::SkImageShader(const SkImage* img, TileMode tmx, TileMode tmy, const SkMatrix* matrix)
+ : INHERITED(matrix)
+ , fImage(SkRef(img))
+ , fTileModeX(tmx)
+ , fTileModeY(tmy)
+{}
+
+SkFlattenable* SkImageShader::CreateProc(SkReadBuffer& buffer) {
+ const TileMode tx = (TileMode)buffer.readUInt();
+ const TileMode ty = (TileMode)buffer.readUInt();
+ SkMatrix matrix;
+ buffer.readMatrix(&matrix);
+ SkAutoTUnref<SkImage> img(buffer.readImage());
+ if (!img) {
+ return nullptr;
+ }
+ return new SkImageShader(img, tx, ty, &matrix);
+}
+
+void SkImageShader::flatten(SkWriteBuffer& buffer) const {
+ buffer.writeUInt(fTileModeX);
+ buffer.writeUInt(fTileModeY);
+ buffer.writeMatrix(this->getLocalMatrix());
+ buffer.writeImage(fImage);
+}
+
+bool SkImageShader::isOpaque() const {
+ return fImage->isOpaque();
+}
+
+size_t SkImageShader::contextSize() const {
+ return SkBitmapProcShader::ContextSize();
+}
+
+SkShader::Context* SkImageShader::onCreateContext(const ContextRec& rec, void* storage) const {
+ return SkBitmapProcShader::MakeContext(*this, fTileModeX, fTileModeY,
+ SkBitmapProvider(fImage), rec, storage);
+}
+
+SkShader* SkImageShader::Create(const SkImage* image, TileMode tx, TileMode ty,
+ const SkMatrix* localMatrix) {
+ if (!image) {
+ return nullptr;
+ }
+ return new SkImageShader(image, tx, ty, localMatrix);
+}
+
+#ifndef SK_IGNORE_TO_STRING
+void SkImageShader::toString(SkString* str) const {
+ const char* gTileModeName[SkShader::kTileModeCount] = {
+ "clamp", "repeat", "mirror"
+ };
+
+ str->appendf("ImageShader: ((%s %s) ", gTileModeName[fTileModeX], gTileModeName[fTileModeY]);
+ fImage->toString(str);
+ this->INHERITED::toString(str);
+ str->append(")");
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if SK_SUPPORT_GPU
+
+#include "GrTextureAccess.h"
+#include "SkGr.h"
+#include "effects/GrSimpleTextureEffect.h"
+#include "effects/GrBicubicEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
+
+const GrFragmentProcessor* SkImageShader::asFragmentProcessor(GrContext* context,
+ const SkMatrix& viewM,
+ const SkMatrix* localMatrix,
+ SkFilterQuality filterQuality,
+ GrProcessorDataManager* mgr) const {
+ SkMatrix matrix;
+ matrix.setIDiv(fImage->width(), fImage->height());
+
+ SkMatrix lmInverse;
+ if (!this->getLocalMatrix().invert(&lmInverse)) {
+ return nullptr;
+ }
+ if (localMatrix) {
+ SkMatrix inv;
+ if (!localMatrix->invert(&inv)) {
+ return nullptr;
+ }
+ lmInverse.postConcat(inv);
+ }
+ matrix.preConcat(lmInverse);
+
+ SkShader::TileMode tm[] = { fTileModeX, fTileModeY };
+
+ // Must set wrap and filter on the sampler before requesting a texture. In two places below
+ // we check the matrix scale factors to determine how to interpret the filter quality setting.
+ // This completely ignores the complexity of the drawVertices case where explicit local coords
+ // are provided by the caller.
+ bool doBicubic;
+ GrTextureParams::FilterMode textureFilterMode =
+ GrSkFilterQualityToGrFilterMode(filterQuality, viewM, this->getLocalMatrix(), &doBicubic);
+ GrTextureParams params(tm, textureFilterMode);
+
+ SkImageUsageType usageType;
+ if (kClamp_TileMode == fTileModeX && kClamp_TileMode == fTileModeY) {
+ usageType = kUntiled_SkImageUsageType;
+ } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
+ usageType = kTiled_Unfiltered_SkImageUsageType;
+ } else {
+ usageType = kTiled_Filtered_SkImageUsageType;
+ }
+
+ SkAutoTUnref<GrTexture> texture(as_IB(fImage)->asTextureRef(context, usageType));
+ if (!texture) {
+ return nullptr;
+ }
+
+ SkAutoTUnref<GrFragmentProcessor> inner;
+ if (doBicubic) {
+ inner.reset(GrBicubicEffect::Create(mgr, texture, matrix, tm));
+ } else {
+ inner.reset(GrSimpleTextureEffect::Create(mgr, texture, matrix, params));
+ }
+
+ if (GrPixelConfigIsAlphaOnly(texture->config())) {
+ return SkRef(inner.get());
+ }
+ return GrFragmentProcessor::MulOuputByInputAlpha(inner);
+}
+
+#endif
diff --git a/src/image/SkImageShader.h b/src/image/SkImageShader.h
new file mode 100644
index 0000000000..fdd7976aad
--- /dev/null
+++ b/src/image/SkImageShader.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkImageShader_DEFINED
+#define SkImageShader_DEFINED
+
+#include "SkImage.h"
+#include "SkShader.h"
+
+class SkImageShader : public SkShader {
+public:
+ static SkShader* Create(const SkImage*, TileMode tx, TileMode ty, const SkMatrix* localMatrix);
+
+ bool isOpaque() const override;
+ size_t contextSize() const override;
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkImageShader)
+
+#if SK_SUPPORT_GPU
+ const GrFragmentProcessor* asFragmentProcessor(GrContext*, const SkMatrix& viewM,
+ const SkMatrix*, SkFilterQuality,
+ GrProcessorDataManager*) const override;
+#endif
+
+protected:
+ void flatten(SkWriteBuffer&) const override;
+ Context* onCreateContext(const ContextRec&, void* storage) const override;
+
+ SkAutoTUnref<const SkImage> fImage;
+ const TileMode fTileModeX;
+ const TileMode fTileModeY;
+
+private:
+ SkImageShader(const SkImage*, TileMode tx, TileMode ty, const SkMatrix* localMatrix);
+
+ typedef SkShader INHERITED;
+};
+
+#endif
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index bbcf182ab8..757262ad3d 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -54,11 +54,8 @@ public:
// Caller must call unref when they are done.
virtual GrTexture* asTextureRef(GrContext*, SkImageUsageType) const = 0;
- virtual SkShader* onNewShader(SkShader::TileMode,
- SkShader::TileMode,
- const SkMatrix* localMatrix) const { return nullptr; }
-
virtual SkImage* onNewSubset(const SkIRect&) const = 0;
+
virtual SkData* onRefEncoded() const { return nullptr; }
virtual bool onAsLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;
diff --git a/src/image/SkImage_Generator.cpp b/src/image/SkImage_Generator.cpp
index 765234fa0c..1c1b263371 100644
--- a/src/image/SkImage_Generator.cpp
+++ b/src/image/SkImage_Generator.cpp
@@ -28,11 +28,6 @@ public:
SkImage* onNewSubset(const SkIRect&) const override;
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:
@@ -43,17 +38,6 @@ private:
///////////////////////////////////////////////////////////////////////////////
-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;
-}
-
bool SkImage_Generator::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
int srcX, int srcY) const {
SkBitmap bm;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 1a63a0d6ba..4417c7bc93 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -7,6 +7,7 @@
#include "SkBitmapCache.h"
#include "SkImage_Gpu.h"
+#include "GrCaps.h"
#include "GrContext.h"
#include "GrDrawContext.h"
#include "effects/GrYUVtoRGBEffect.h"
@@ -35,13 +36,6 @@ extern void SkTextureImageApplyBudgetedDecision(SkImage* image) {
}
}
-SkShader* SkImage_Gpu::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
- const SkMatrix* localMatrix) const {
- SkBitmap bm;
- GrWrapTextureInBitmap(fTexture, this->width(), this->height(), this->isOpaque(), &bm);
- return SkShader::CreateBitmapShader(bm, tileX, tileY, localMatrix);
-}
-
bool SkImage_Gpu::getROPixels(SkBitmap* dst) const {
if (SkBitmapCache::Find(this->uniqueID(), dst)) {
SkASSERT(dst->getGenerationID() == this->uniqueID());
@@ -66,6 +60,19 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst) const {
}
GrTexture* SkImage_Gpu::asTextureRef(GrContext* ctx, SkImageUsageType usage) const {
+ const bool is_pow2 = SkIsPow2(this->width()) && SkIsPow2(this->height());
+ const bool npot_tex_supported = ctx->caps()->npotTextureTileSupport();
+ if (!is_pow2 && kUntiled_SkImageUsageType != usage && !npot_tex_supported) {
+ // load as bitmap, since the GPU can support tiling a non-pow2 texture
+ // related to skbug.com/4365
+ SkBitmap bitmap;
+ if (this->getROPixels(&bitmap)) {
+ return GrRefCachedBitmapTexture(ctx, bitmap, usage);
+ } else {
+ return nullptr;
+ }
+ }
+
fTexture->ref();
return fTexture;
}
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
index 5e847dd381..8bfdfa7cd8 100644
--- a/src/image/SkImage_Gpu.h
+++ b/src/image/SkImage_Gpu.h
@@ -40,9 +40,6 @@ public:
SkImage* onNewSubset(const SkIRect&) const override;
GrTexture* peekTexture() const override { return fTexture; }
- SkShader* onNewShader(SkShader::TileMode,
- SkShader::TileMode,
- const SkMatrix* localMatrix) const override;
bool isOpaque() const override;
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY) const override;
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 30ea7cc1a4..64f875924e 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -80,10 +80,6 @@ public:
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
- SkShader* onNewShader(SkShader::TileMode,
- SkShader::TileMode,
- const SkMatrix* localMatrix) const override;
-
bool isOpaque() const override;
bool onAsLegacyBitmap(SkBitmap*, LegacyBitmapMode) const override;
@@ -144,11 +140,6 @@ SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, const SkIPoint&
SkImage_Raster::~SkImage_Raster() {}
-SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
- const SkMatrix* localMatrix) const {
- return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix);
-}
-
bool SkImage_Raster::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY) const {
SkBitmap shallowCopy(fBitmap);