| Index: src/gpu/SkGpuDevice.cpp
|
| diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
|
| index 1af4929ae41d296d171a1be4c560a19c9b27e62e..c4239bd40f4dccb045cf04d5ddce2edf7f113446 100644
|
| --- a/src/gpu/SkGpuDevice.cpp
|
| +++ b/src/gpu/SkGpuDevice.cpp
|
| @@ -1301,6 +1301,16 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
|
| SkScalarMul(srcRect.fRight, wInv),
|
| SkScalarMul(srcRect.fBottom, hInv));
|
|
|
| + SkMatrix texMatrix;
|
| + texMatrix.reset();
|
| + if (kAlpha_8_SkColorType == bitmap.colorType() && paint.getShader()) {
|
| + // In cases where we are doing an A8 bitmap draw with a shader installed, we cannot use
|
| + // local coords with the bitmap draw since it may mess up texture look ups for the shader.
|
| + // Thus we need to pass in the transform matrix directly to the texture processor used for
|
| + // the bitmap draw.
|
| + texMatrix.setScale(wInv, hInv);
|
| + }
|
| +
|
| SkRect textureDomain = SkRect::MakeEmpty();
|
|
|
| // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
|
| @@ -1327,10 +1337,10 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
|
| }
|
| textureDomain.setLTRB(left, top, right, bottom);
|
| if (bicubic) {
|
| - fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), textureDomain));
|
| + fp.reset(GrBicubicEffect::Create(texture, texMatrix, textureDomain));
|
| } else {
|
| fp.reset(GrTextureDomainEffect::Create(texture,
|
| - SkMatrix::I(),
|
| + texMatrix,
|
| textureDomain,
|
| GrTextureDomain::kClamp_Mode,
|
| params.filterMode()));
|
| @@ -1338,13 +1348,27 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
|
| } else if (bicubic) {
|
| SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode());
|
| SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTileModeY() };
|
| - fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tileModes));
|
| + fp.reset(GrBicubicEffect::Create(texture, texMatrix, tileModes));
|
| } else {
|
| - fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
|
| + fp.reset(GrSimpleTextureEffect::Create(texture, texMatrix, params));
|
| }
|
|
|
| + SkAutoTUnref<const GrFragmentProcessor> shaderFP;
|
| +
|
| if (kAlpha_8_SkColorType == bitmap.colorType()) {
|
| - fp.reset(GrFragmentProcessor::MulOutputByInputUnpremulColor(fp));
|
| + if (const SkShader* shader = paint.getShader()) {
|
| + shaderFP.reset(shader->asFragmentProcessor(this->context(),
|
| + viewMatrix,
|
| + nullptr,
|
| + paint.getFilterQuality()));
|
| + if (!shaderFP) {
|
| + return;
|
| + }
|
| + const GrFragmentProcessor* fpSeries[] = { shaderFP.get(), fp.get() };
|
| + fp.reset(GrFragmentProcessor::RunInSeries(fpSeries, 2));
|
| + } else {
|
| + fp.reset(GrFragmentProcessor::MulOutputByInputUnpremulColor(fp));
|
| + }
|
| } else {
|
| fp.reset(GrFragmentProcessor::MulOutputByInputAlpha(fp));
|
| }
|
| @@ -1353,8 +1377,14 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
|
| return;
|
| }
|
|
|
| - fDrawContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, viewMatrix, dstRect,
|
| - paintRect);
|
| + if (kAlpha_8_SkColorType == bitmap.colorType() && paint.getShader()) {
|
| + // We don't have local coords in this case and have previously set the transform
|
| + // matrices directly on the texture processor.
|
| + fDrawContext->drawRect(fRenderTarget, fClip, grPaint, viewMatrix, dstRect);
|
| + } else {
|
| + fDrawContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, viewMatrix, dstRect,
|
| + paintRect);
|
| + }
|
| }
|
|
|
| bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture,
|
|
|