diff options
author | 2015-09-30 12:21:45 -0700 | |
---|---|---|
committer | 2015-09-30 12:21:45 -0700 | |
commit | 856e9d921462136da8562f8f122d42e114cd4710 (patch) | |
tree | 9ebc00a92f5aacdd54d00c528fa3ed19f48f6fd6 /src/image/SkImageShader.cpp | |
parent | 8a6697af95b340aad6dee7e6228048fa305c1e59 (diff) |
Revert[4] of add ImageShader, sharing code with its Bitmap cousin
Now with GrTextureMaker subclasses to handle npot usage.
This reverts commit 476506d070dbc59b158acc1a00c34bff95ab2968.
BUG=skia:
Review URL: https://codereview.chromium.org/1370223002
Diffstat (limited to 'src/image/SkImageShader.cpp')
-rw-r--r-- | src/image/SkImageShader.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/image/SkImageShader.cpp b/src/image/SkImageShader.cpp new file mode 100644 index 0000000000..fde0f0c9d5 --- /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::MulOutputByInputAlpha(inner); +} + +#endif |