sk_sp<GrFragmentProcessor> SkPerlinNoiseShader::asFragmentProcessor(const AsFPArgs& args) const { SkASSERT(args.fContext); SkMatrix localMatrix = this->getLocalMatrix(); if (args.fLocalMatrix) { localMatrix.preConcat(*args.fLocalMatrix); } SkMatrix matrix = *args.fViewMatrix; matrix.preConcat(localMatrix); if (0 == fNumOctaves) { if (kFractalNoise_Type == fType) { // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2) // TODO: Either treat the output of this shader as sRGB or allow client to specify a // color space of the noise. Either way, this case (and the GLSL) need to convert to // the destination. sk_sp<GrFragmentProcessor> inner( GrConstColorProcessor::Make(GrColor4f::FromGrColor(0x80404040), GrConstColorProcessor::kModulateRGBA_InputMode)); return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)); } // Emit zero. return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), GrConstColorProcessor::kIgnore_InputMode); } // Either we don't stitch tiles, either we have a valid tile size SkASSERT(!fStitchTiles || !fTileSize.isEmpty()); SkPerlinNoiseShader::PaintingData* paintingData = new PaintingData(fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY, matrix); sk_sp<GrTextureProxy> permutationsProxy(GrMakeCachedBitmapProxy( args.fContext->resourceProvider(), paintingData->getPermutationsBitmap())); sk_sp<GrTextureProxy> noiseProxy(GrMakeCachedBitmapProxy(args.fContext->resourceProvider(), paintingData->getNoiseBitmap())); SkMatrix m = *args.fViewMatrix; m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1); m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1); if (permutationsProxy && noiseProxy) { sk_sp<GrFragmentProcessor> inner( GrPerlinNoiseEffect::Make(args.fContext->resourceProvider(), fType, fNumOctaves, fStitchTiles, paintingData, std::move(permutationsProxy), std::move(noiseProxy), m)); return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)); } delete paintingData; return nullptr; }
const GrFragmentProcessor* SkPerlinNoiseShader::asFragmentProcessor( GrContext* context, const SkMatrix& viewM, const SkMatrix* externalLocalMatrix, SkFilterQuality) const { SkASSERT(context); SkMatrix localMatrix = this->getLocalMatrix(); if (externalLocalMatrix) { localMatrix.preConcat(*externalLocalMatrix); } SkMatrix matrix = viewM; matrix.preConcat(localMatrix); if (0 == fNumOctaves) { if (kFractalNoise_Type == fType) { // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2) SkAutoTUnref<const GrFragmentProcessor> inner( GrConstColorProcessor::Create(0x80404040, GrConstColorProcessor::kModulateRGBA_InputMode)); return GrFragmentProcessor::MulOutputByInputAlpha(inner); } // Emit zero. return GrConstColorProcessor::Create(0x0, GrConstColorProcessor::kIgnore_InputMode); } // Either we don't stitch tiles, either we have a valid tile size SkASSERT(!fStitchTiles || !fTileSize.isEmpty()); SkPerlinNoiseShader::PaintingData* paintingData = new PaintingData(fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY, matrix); SkAutoTUnref<GrTexture> permutationsTexture( GrRefCachedBitmapTexture(context, paintingData->getPermutationsBitmap(), GrTextureParams::ClampNoFilter())); SkAutoTUnref<GrTexture> noiseTexture( GrRefCachedBitmapTexture(context, paintingData->getNoiseBitmap(), GrTextureParams::ClampNoFilter())); SkMatrix m = viewM; m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1); m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1); if ((permutationsTexture) && (noiseTexture)) { SkAutoTUnref<GrFragmentProcessor> inner( GrPerlinNoiseEffect::Create(fType, fNumOctaves, fStitchTiles, paintingData, permutationsTexture, noiseTexture, m)); return GrFragmentProcessor::MulOutputByInputAlpha(inner); } delete paintingData; return nullptr; }