Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2015 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #include "SkGpuDevice.h" | |
| 9 | |
| 10 #include "GrBlurUtils.h" | |
| 11 #include "GrCaps.h" | |
| 12 #include "GrDrawContext.h" | |
| 13 #include "GrStrokeInfo.h" | |
| 14 #include "GrTextureParamsAdjuster.h" | |
| 15 #include "SkDraw.h" | |
| 16 #include "SkGrPriv.h" | |
| 17 #include "SkMaskFilter.h" | |
| 18 #include "effects/GrBicubicEffect.h" | |
| 19 #include "effects/GrSimpleTextureEffect.h" | |
| 20 #include "effects/GrTextureDomain.h" | |
| 21 | |
| 22 static inline bool use_shader(bool textureIsAlphaOnly, const SkPaint& paint) { | |
| 23 return textureIsAlphaOnly && paint.getShader(); | |
| 24 } | |
| 25 | |
| 26 static const GrFragmentProcessor* mix_texture_fp_with_paint_color_and_shader( | |
| 27 const GrFragmentProcessor* textureFP, | |
| 28 bool textureIsAlphaOnly, | |
| 29 GrContext* context, | |
| 30 const SkMatrix& viewMatrix, | |
| 31 const SkPaint& paint) { | |
|
robertphillips
2015/11/05 20:49:39
'\n' ?
bsalomon
2015/11/06 15:24:26
Done.
| |
| 32 if (textureIsAlphaOnly) { | |
| 33 if (const SkShader* shader = paint.getShader()) { | |
| 34 SkAutoTUnref<const GrFragmentProcessor> shaderFP( | |
| 35 shader->asFragmentProcessor(context, | |
| 36 viewMatrix, | |
| 37 nullptr, | |
| 38 paint.getFilterQuality())); | |
| 39 if (!shaderFP) { | |
| 40 return nullptr; | |
| 41 } | |
| 42 const GrFragmentProcessor* fpSeries[] = { shaderFP, textureFP }; | |
| 43 return GrFragmentProcessor::RunInSeries(fpSeries, 2); | |
| 44 } else { | |
| 45 return GrFragmentProcessor::MulOutputByInputUnpremulColor(textureFP) ; | |
| 46 } | |
| 47 } else { | |
| 48 return GrFragmentProcessor::MulOutputByInputAlpha(textureFP); | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 void SkGpuDevice::drawTextureRect(GrTextureAdjuster* adjuster, | |
| 53 bool alphaTexture, | |
| 54 const SkRect& clippedSrcRect, | |
| 55 const SkRect& dstRect, | |
| 56 const SkMatrix& viewMatrix, | |
| 57 const GrClip& clip, | |
| 58 const SkPaint& paint, | |
| 59 SkCanvas::SrcRectConstraint constraint) { | |
| 60 SkMatrix localMatrix; | |
| 61 if (localMatrix.setRectToRect(clippedSrcRect, dstRect, SkMatrix::kFill_Scale ToFit)) { | |
| 62 this->drawTextureRectPrecomputedLocalMatrix(adjuster, alphaTexture, clip pedSrcRect, | |
| 63 dstRect, viewMatrix, localMa trix, clip, | |
| 64 paint, constraint); | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 void SkGpuDevice::drawTextureRectPrecomputedLocalMatrix(GrTextureAdjuster* adjus ter, | |
| 69 bool alphaTexture, | |
| 70 const SkRect& clippedSrc Rect, | |
| 71 const SkRect& dstRect, | |
| 72 const SkMatrix& viewMatr ix, | |
| 73 const SkMatrix& localMat rix, | |
| 74 const GrClip& clip, | |
| 75 const SkPaint& paint, | |
| 76 SkCanvas::SrcRectConstra int constraint) { | |
| 77 // Specifying the texture coords as local coordinates is an attempt to enabl e more batching | |
| 78 // by not baking anything about the srcRect, dstRect, or viewMatrix, into th e texture FP. In | |
| 79 // the future this should be an opaque optimization enabled by the combinati on of batch/GP and | |
| 80 // FP. | |
| 81 const SkMatrix* textureFPMatrix; | |
| 82 SkMatrix tempMatrix; | |
| 83 const SkMaskFilter* mf = paint.getMaskFilter(); | |
| 84 GrTexture* texture = adjuster->originalTexture(); | |
| 85 // The shader expects proper local coords, so we can't replace local coords with texture coords | |
| 86 // if the shader will be used. If we have a mask filter we will change the u nderlying geometry | |
| 87 // that is rendered. | |
| 88 bool canUseTextureCoordsAsLocalCoords = !use_shader(alphaTexture, paint) && !mf; | |
| 89 if (canUseTextureCoordsAsLocalCoords) { | |
| 90 textureFPMatrix = &SkMatrix::I(); | |
| 91 } else { | |
| 92 if (!localMatrix.invert(&tempMatrix)) { | |
| 93 return; | |
| 94 } | |
| 95 tempMatrix.postIDiv(texture->width(), texture->height()); | |
| 96 textureFPMatrix = &tempMatrix; | |
| 97 } | |
| 98 | |
| 99 bool doBicubic; | |
| 100 GrTextureParams::FilterMode fm = | |
| 101 GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), viewMatrix, lo calMatrix, | |
| 102 &doBicubic); | |
| 103 const GrTextureParams::FilterMode* filterMode = doBicubic ? nullptr : &fm; | |
| 104 | |
| 105 GrTextureAdjuster::FilterConstraint constraintMode; | |
| 106 if (SkCanvas::kFast_SrcRectConstraint == constraint) { | |
| 107 constraintMode = GrTextureAdjuster::kNo_FilterConstraint; | |
| 108 } else { | |
| 109 constraintMode = GrTextureAdjuster::kYes_FilterConstraint; | |
| 110 } | |
| 111 | |
| 112 // If we have to outset for AA then we will generate texture coords outside the src rect. The | |
| 113 // same happens for any mask filter that extends the bounds rendered in the dst. | |
| 114 bool coordsAllInsideSrcRect = !paint.isAntiAlias() && !mf; | |
| 115 | |
| 116 SkAutoTUnref<const GrFragmentProcessor> fp(adjuster->createFragmentProcessor ( | |
| 117 *textureFPMatrix, clippedSrcRect, constraintMode, coordsAllInsideSrcRect , filterMode)); | |
| 118 if (!fp) { | |
| 119 return; | |
| 120 } | |
| 121 fp.reset(mix_texture_fp_with_paint_color_and_shader(fp, alphaTexture, this-> context(), | |
| 122 viewMatrix, paint)); | |
| 123 GrPaint grPaint; | |
| 124 if (!SkPaintToGrPaintReplaceShader(fContext, paint, fp, &grPaint)) { | |
| 125 return; | |
| 126 } | |
| 127 | |
| 128 if (canUseTextureCoordsAsLocalCoords) { | |
| 129 SkRect localRect; | |
| 130 localRect.fLeft = clippedSrcRect.fLeft / texture->width(); | |
| 131 localRect.fBottom = clippedSrcRect.fBottom / texture->height(); | |
| 132 localRect.fRight = clippedSrcRect.fRight / texture->width(); | |
| 133 localRect.fTop = clippedSrcRect.fTop / texture->height(); | |
| 134 fDrawContext->fillRectToRect(clip, grPaint, viewMatrix, dstRect, localRe ct); | |
| 135 return; | |
| 136 } | |
| 137 | |
| 138 if (!mf) { | |
| 139 fDrawContext->drawRect(clip, grPaint, viewMatrix, dstRect); | |
| 140 return; | |
| 141 } | |
| 142 | |
| 143 // First see if we can do the draw + mask filter direct to the dst. | |
| 144 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); | |
| 145 SkRRect rrect; | |
| 146 rrect.setRect(dstRect); | |
| 147 if (mf->directFilterRRectMaskGPU(fContext->textureProvider(), | |
| 148 fDrawContext, | |
| 149 &grPaint, | |
| 150 clip, | |
| 151 viewMatrix, | |
| 152 rec, | |
| 153 rrect)) { | |
| 154 return; | |
| 155 } | |
| 156 SkPath rectPath; | |
| 157 rectPath.addRect(dstRect); | |
| 158 GrBlurUtils::drawPathWithMaskFilter(this->context(), fDrawContext, fRenderTa rget, fClip, | |
| 159 rectPath, &grPaint, viewMatrix, mf, pain t.getPathEffect(), | |
| 160 GrStrokeInfo::FillInfo()); | |
| 161 } | |
| OLD | NEW |