diff options
author | 2015-09-25 02:31:09 -0700 | |
---|---|---|
committer | 2015-09-25 02:31:09 -0700 | |
commit | fe05707c356d2a8c2c69222591d4cafbd456b4e5 (patch) | |
tree | c490b4a707c52d58fc1bcadf1fb4d5d816db392f /src/image | |
parent | 00d6e515e5835f7df6163ceb5f5ceb1770552bf7 (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.cpp | 3 | ||||
-rw-r--r-- | src/image/SkImageShader.cpp | 144 | ||||
-rw-r--r-- | src/image/SkImageShader.h | 44 | ||||
-rw-r--r-- | src/image/SkImage_Base.h | 5 | ||||
-rw-r--r-- | src/image/SkImage_Generator.cpp | 16 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 21 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.h | 3 | ||||
-rw-r--r-- | src/image/SkImage_Raster.cpp | 9 |
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); |