static uint8_t* create_profile(float halfWH, float sigma) { int kernelWH = SkScalarCeilToInt(6.0f*sigma); kernelWH = (kernelWH + 1) & ~1; // make it the next even number up SkAutoTArray<float> halfKernel(kernelWH*kernelWH/2); make_half_kernel(halfKernel.get(), kernelWH, sigma); float offset; int numSteps; compute_profile_offset_and_size(halfWH, sigma, &offset, &numSteps); uint8_t* weights = new uint8_t[numSteps]; for (int i = 0; i < numSteps; ++i) { weights[i] = eval_at(offset+i, halfWH, halfKernel.get(), kernelWH); } return weights; }
GrTexture* GrCircleBlurFragmentProcessor::CreateCircleBlurProfileTexture( GrTextureProvider* textureProvider, const SkRect& circle, float sigma, float* offset) { float halfWH = circle.width() / 2.0f; int size; compute_profile_offset_and_size(halfWH, sigma, offset, &size); GrSurfaceDesc texDesc; texDesc.fWidth = size; texDesc.fHeight = 1; texDesc.fConfig = kAlpha_8_GrPixelConfig; static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); GrUniqueKey key; GrUniqueKey::Builder builder(&key, kDomain, 2); // The profile curve varies with both the sigma of the Gaussian and the size of the // disk. Quantizing to 16.16 should be close enough though. builder[0] = SkScalarToFixed(sigma); builder[1] = SkScalarToFixed(halfWH); builder.finish(); GrTexture *blurProfile = textureProvider->findAndRefTextureByUniqueKey(key); if (!blurProfile) { SkAutoTDeleteArray<uint8_t> profile(create_profile(halfWH, sigma)); blurProfile = textureProvider->createTexture(texDesc, SkBudgeted::kYes, profile.get(), 0); if (blurProfile) { textureProvider->assignUniqueKeyToTexture(key, blurProfile); } } return blurProfile; }