Start using vertex attributes for nine-patch blurred rrect draws

Calved off:
https://codereview.chromium.org/2243133002/ (Pull handling of blurred circles out of GrRRectBlurEffect::Make)
https://codereview.chromium.org/2249463002/ (Update blurred rrect mask filter creation method to also handle caching)
https://codereview.chromium.org/2248533002/ (Update ComputeBlurredRRectParams to compute all the parameters needed for occluded blurred rrect ninepatch draws)

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2245653002

Review-Url: https://codereview.chromium.org/2245653002
This commit is contained in:
robertphillips 2016-08-16 14:50:18 -07:00 committed by Commit bot
parent 179d88522c
commit 087905a730

View File

@ -1081,7 +1081,7 @@ public:
private:
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture);
GrRRectBlurEffect(float xformedSigma, const SkRRect& devRRect, GrTexture* mask);
virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps,
GrProcessorKeyBuilder* b) const override;
@ -1192,19 +1192,19 @@ sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context,
return nullptr;
}
return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma,
devRRect,
mask.get()));
return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(xformedSigma, devRRect, mask.get()));
}
void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownSingleComponent();
}
GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture *ninePatchTexture)
: fRRect(rrect),
fSigma(sigma),
fNinePatchAccess(ninePatchTexture) {
GrRRectBlurEffect::GrRRectBlurEffect(float xformedSigma,
const SkRRect& devRRect,
GrTexture *ninePatchTexture)
: fRRect(devRRect)
, fSigma(xformedSigma)
, fNinePatchAccess(ninePatchTexture) {
this->initClassID<GrRRectBlurEffect>();
this->addTextureAccess(&fNinePatchAccess);
this->setWillReadFragmentPosition();
@ -1351,6 +1351,9 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
SkScalar xformedSigma = this->computeXformedSigma(viewMatrix);
GrPaint newPaint(*grp);
newPaint.setAntiAlias(false);
if (devRRect.isCircle()) {
sk_sp<GrFragmentProcessor> fp(GrCircleBlurFragmentProcessor::Make(
context->textureProvider(),
@ -1360,9 +1363,7 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
return false;
}
GrPaint newPaint(*grp);
newPaint.addCoverageFragmentProcessor(std::move(fp));
newPaint.setAntiAlias(false);
SkRect srcProxyRect = srcRRect.rect();
srcProxyRect.outset(3.0f*fSigma, 3.0f*fSigma);
@ -1371,51 +1372,69 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
return true;
}
sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context, fSigma, xformedSigma,
SkRRect maskSpaceRRectToDraw;
SkISize maskSize;
SkScalar rectXs[SkBlurMaskFilter::kMaxDivisions], rectYs[SkBlurMaskFilter::kMaxDivisions];
SkScalar texXs[SkBlurMaskFilter::kMaxDivisions], texYs[SkBlurMaskFilter::kMaxDivisions];
int numX, numY;
uint32_t skipMask;
bool ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(srcRRect, devRRect, fOccluder,
fSigma, xformedSigma,
&maskSpaceRRectToDraw,
&maskSize,
rectXs, rectYs, texXs, texYs,
&numX, &numY, &skipMask);
if (!ninePatchable) {
return false;
}
if (!this->ignoreXform()) {
sk_sp<GrTexture> mask(find_or_create_rrect_blur_mask(context,
maskSpaceRRectToDraw, maskSize,
xformedSigma, true));
if (!mask) {
return false;
}
SkMatrix texMatrix;
texMatrix.setIDiv(mask->width(), mask->height());
GrTextureParams params;
params.reset(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
sk_sp<GrFragmentProcessor> fp = GrSimpleTextureEffect::Make(mask.get(), nullptr,
texMatrix, params);
if (!fp) {
return false;
}
newPaint.addColorFragmentProcessor(std::move(fp));
uint32_t checkBit = 0x1;
for (int y = 0; y < numY-1; ++y) {
for (int x = 0; x < numX-1; ++x) {
if (skipMask & checkBit) {
checkBit <<= 1;
continue;
}
drawContext->fillRectToRect(
clip, newPaint, viewMatrix,
SkRect::MakeLTRB(rectXs[x], rectYs[y], rectXs[x+1], rectYs[y+1]), // dst
SkRect::MakeLTRB(texXs[x], texYs[y], texXs[x+1], texYs[y+1])); // src
checkBit <<= 1;
}
}
} else {
sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context,
fSigma, xformedSigma,
srcRRect, devRRect));
if (!fp) {
return false;
}
GrPaint newPaint(*grp);
newPaint.addCoverageFragmentProcessor(std::move(fp));
newPaint.setAntiAlias(false);
if (!this->ignoreXform()) {
SkRect srcProxyRect = srcRRect.rect();
srcProxyRect.outset(3.0f*fSigma, 3.0f*fSigma);
SkPoint points[8];
uint16_t indices[24];
int numPoints, numIndices;
SkRect temp = fOccluder;
if (!temp.isEmpty() && (srcProxyRect.contains(temp) || temp.intersect(srcProxyRect))) {
srcProxyRect.toQuad(points);
temp.toQuad(&points[4]);
numPoints = 8;
static const uint16_t ringI[24] = { 0, 1, 5, 5, 4, 0,
1, 2, 6, 6, 5, 1,
2, 3, 7, 7, 6, 2,
3, 0, 4, 4, 7, 3 };
memcpy(indices, ringI, sizeof(ringI));
numIndices = 24;
} else {
// full rect case
srcProxyRect.toQuad(points);
numPoints = 4;
static const uint16_t fullI[6] = { 0, 1, 2, 0, 2, 3 };
memcpy(indices, fullI, sizeof(fullI));
numIndices = 6;
}
drawContext->drawVertices(clip, newPaint, viewMatrix, kTriangles_GrPrimitiveType,
numPoints, points, nullptr, nullptr, indices, numIndices);
} else {
SkMatrix inverse;
if (!viewMatrix.invert(&inverse)) {
return false;