Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkGpuDevice.h" | 8 #include "SkGpuDevice.h" |
| 9 | 9 |
| 10 #include "GrBlurUtils.h" | 10 #include "GrBlurUtils.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 const GrFragmentProcessor* fpSeries[] = { shaderFP, textureFP }; | 45 const GrFragmentProcessor* fpSeries[] = { shaderFP, textureFP }; |
| 46 return GrFragmentProcessor::RunInSeries(fpSeries, 2); | 46 return GrFragmentProcessor::RunInSeries(fpSeries, 2); |
| 47 } else { | 47 } else { |
| 48 return GrFragmentProcessor::MulOutputByInputUnpremulColor(textureFP) ; | 48 return GrFragmentProcessor::MulOutputByInputUnpremulColor(textureFP) ; |
| 49 } | 49 } |
| 50 } else { | 50 } else { |
| 51 return GrFragmentProcessor::MulOutputByInputAlpha(textureFP); | 51 return GrFragmentProcessor::MulOutputByInputAlpha(textureFP); |
| 52 } | 52 } |
| 53 } | 53 } |
| 54 | 54 |
| 55 void SkGpuDevice::drawTextureAdjuster(GrTextureAdjuster* adjuster, | 55 ////////////////////////////////////////////////////////////////////////////// |
| 56 // Helper functions for dropping src rect constraint in bilerp mode. | |
| 57 | |
| 58 static const SkScalar kColorBleedTolerance = 0.001f; | |
| 59 | |
| 60 static bool has_aligned_samples(const SkRect& srcRect, const SkRect& transformed Rect) { | |
|
bsalomon
2015/11/17 23:15:57
these functions are lifted and simplified from SkG
| |
| 61 // detect pixel disalignment | |
| 62 if (SkScalarAbs(SkScalarFraction(transformedRect.left())) < kColorBleedToler ance && | |
| 63 SkScalarAbs(SkScalarFraction(transformedRect.top())) < kColorBleedTolera nce && | |
|
bsalomon
2015/11/17 23:15:57
Changed this to use abs(fraction(x)) instead of ab
| |
| 64 SkScalarAbs(transformedRect.width() - srcRect.width()) < kColorBleedTole rance && | |
| 65 SkScalarAbs(transformedRect.height() - srcRect.height()) < kColorBleedTo lerance) { | |
| 66 return true; | |
| 67 } | |
| 68 return false; | |
| 69 } | |
| 70 | |
| 71 static bool may_color_bleed(const SkRect& srcRect, | |
|
bsalomon
2015/11/17 23:15:57
this function is unchanged.
| |
| 72 const SkRect& transformedRect, | |
| 73 const SkMatrix& m, | |
| 74 bool isMSAA) { | |
| 75 // Only gets called if has_aligned_samples returned false. | |
| 76 // So we can assume that sampling is axis aligned but not texel aligned. | |
| 77 SkASSERT(!has_aligned_samples(srcRect, transformedRect)); | |
| 78 SkRect innerSrcRect(srcRect), innerTransformedRect, outerTransformedRect(tra nsformedRect); | |
| 79 if (isMSAA) { | |
| 80 innerSrcRect.inset(SK_Scalar1, SK_Scalar1); | |
| 81 } else { | |
| 82 innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf); | |
| 83 } | |
| 84 m.mapRect(&innerTransformedRect, innerSrcRect); | |
| 85 | |
| 86 // The gap between outerTransformedRect and innerTransformedRect | |
| 87 // represents the projection of the source border area, which is | |
| 88 // problematic for color bleeding. We must check whether any | |
| 89 // destination pixels sample the border area. | |
| 90 outerTransformedRect.inset(kColorBleedTolerance, kColorBleedTolerance); | |
| 91 innerTransformedRect.outset(kColorBleedTolerance, kColorBleedTolerance); | |
| 92 SkIRect outer, inner; | |
| 93 outerTransformedRect.round(&outer); | |
| 94 innerTransformedRect.round(&inner); | |
| 95 // If the inner and outer rects round to the same result, it means the | |
| 96 // border does not overlap any pixel centers. Yay! | |
| 97 return inner != outer; | |
| 98 } | |
| 99 | |
| 100 static bool can_ignore_bilerp_constraint(const GrTextureProducer& producer, | |
|
bsalomon
2015/11/17 23:15:57
was needs_texture_domain() in the original. That f
| |
| 101 const SkRect& srcRect, | |
| 102 const SkMatrix& srcRectToDeviceSpace, | |
| 103 bool isMSAA) { | |
| 104 if (srcRectToDeviceSpace.rectStaysRect()) { | |
| 105 // sampling is axis-aligned | |
| 106 SkRect transformedRect; | |
| 107 srcRectToDeviceSpace.mapRect(&transformedRect, srcRect); | |
| 108 | |
| 109 if (has_aligned_samples(srcRect, transformedRect) || | |
| 110 !may_color_bleed(srcRect, transformedRect, srcRectToDeviceSpace, isM SAA)) { | |
| 111 return true; | |
| 112 } | |
| 113 } | |
| 114 return false; | |
| 115 } | |
| 116 | |
| 117 ////////////////////////////////////////////////////////////////////////////// | |
| 118 | |
| 119 void SkGpuDevice::drawTextureProducer(GrTextureProducer* producer, | |
| 56 bool alphaOnly, | 120 bool alphaOnly, |
| 57 const SkRect* srcRect, | 121 const SkRect* srcRect, |
| 58 const SkRect* dstRect, | 122 const SkRect* dstRect, |
| 59 SkCanvas::SrcRectConstraint constraint, | 123 SkCanvas::SrcRectConstraint constraint, |
| 60 const SkMatrix& viewMatrix, | 124 const SkMatrix& viewMatrix, |
| 61 const GrClip& clip, | 125 const GrClip& clip, |
| 62 const SkPaint& paint) { | 126 const SkPaint& paint) { |
| 63 // Figure out the actual dst and src rect by clipping the src rect to the bo unds of the | 127 // Figure out the actual dst and src rect by clipping the src rect to the bo unds of the |
| 64 // adjuster. If the src rect is clipped then the dst rect must be recomputed . Also determine | 128 // adjuster. If the src rect is clipped then the dst rect must be recomputed . Also determine |
| 65 // the matrix that maps the src rect to the dst rect. | 129 // the matrix that maps the src rect to the dst rect. |
| 66 SkRect clippedSrcRect; | 130 SkRect clippedSrcRect; |
| 67 SkRect clippedDstRect; | 131 SkRect clippedDstRect; |
| 68 const SkRect srcBounds = SkRect::MakeIWH(adjuster->width(), adjuster->height ()); | 132 const SkRect srcBounds = SkRect::MakeIWH(producer->width(), producer->height ()); |
| 69 SkMatrix srcToDstMatrix; | 133 SkMatrix srcToDstMatrix; |
| 70 if (srcRect) { | 134 if (srcRect) { |
| 71 if (!dstRect) { | 135 if (!dstRect) { |
| 72 dstRect = &srcBounds; | 136 dstRect = &srcBounds; |
| 73 } | 137 } |
| 74 if (!srcBounds.contains(*srcRect)) { | 138 if (!srcBounds.contains(*srcRect)) { |
| 75 clippedSrcRect = *srcRect; | 139 clippedSrcRect = *srcRect; |
| 76 if (!clippedSrcRect.intersect(srcBounds)) { | 140 if (!clippedSrcRect.intersect(srcBounds)) { |
| 77 return; | 141 return; |
| 78 } | 142 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 93 clippedDstRect = *dstRect; | 157 clippedDstRect = *dstRect; |
| 94 if (!srcToDstMatrix.setRectToRect(srcBounds, *dstRect, SkMatrix::kFi ll_ScaleToFit)) { | 158 if (!srcToDstMatrix.setRectToRect(srcBounds, *dstRect, SkMatrix::kFi ll_ScaleToFit)) { |
| 95 return; | 159 return; |
| 96 } | 160 } |
| 97 } else { | 161 } else { |
| 98 clippedDstRect = srcBounds; | 162 clippedDstRect = srcBounds; |
| 99 srcToDstMatrix.reset(); | 163 srcToDstMatrix.reset(); |
| 100 } | 164 } |
| 101 } | 165 } |
| 102 | 166 |
| 103 this->drawTextureAdjusterImpl(adjuster, alphaOnly, clippedSrcRect, clippedDs tRect, constraint, | 167 this->drawTextureProducerImpl(producer, alphaOnly, clippedSrcRect, clippedDs tRect, constraint, |
| 104 viewMatrix, srcToDstMatrix, clip, paint); | 168 viewMatrix, srcToDstMatrix, clip, paint); |
| 105 } | 169 } |
| 106 | 170 |
| 107 void SkGpuDevice::drawTextureAdjusterImpl(GrTextureAdjuster* adjuster, | 171 void SkGpuDevice::drawTextureProducerImpl(GrTextureProducer* producer, |
| 108 bool alphaTexture, | 172 bool alphaTexture, |
| 109 const SkRect& clippedSrcRect, | 173 const SkRect& clippedSrcRect, |
| 110 const SkRect& clippedDstRect, | 174 const SkRect& clippedDstRect, |
| 111 SkCanvas::SrcRectConstraint constraint , | 175 SkCanvas::SrcRectConstraint constraint , |
| 112 const SkMatrix& viewMatrix, | 176 const SkMatrix& viewMatrix, |
| 113 const SkMatrix& srcToDstMatrix, | 177 const SkMatrix& srcToDstMatrix, |
| 114 const GrClip& clip, | 178 const GrClip& clip, |
| 115 const SkPaint& paint) { | 179 const SkPaint& paint) { |
| 116 // Specifying the texture coords as local coordinates is an attempt to enabl e more batching | 180 // Specifying the texture coords as local coordinates is an attempt to enabl e more batching |
| 117 // by not baking anything about the srcRect, dstRect, or viewMatrix, into th e texture FP. In | 181 // by not baking anything about the srcRect, dstRect, or viewMatrix, into th e texture FP. In |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 134 constraintMode = GrTextureAdjuster::kNo_FilterConstraint; | 198 constraintMode = GrTextureAdjuster::kNo_FilterConstraint; |
| 135 } else { | 199 } else { |
| 136 constraintMode = GrTextureAdjuster::kYes_FilterConstraint; | 200 constraintMode = GrTextureAdjuster::kYes_FilterConstraint; |
| 137 } | 201 } |
| 138 | 202 |
| 139 // If we have to outset for AA then we will generate texture coords outside the src rect. The | 203 // If we have to outset for AA then we will generate texture coords outside the src rect. The |
| 140 // same happens for any mask filter that extends the bounds rendered in the dst. | 204 // same happens for any mask filter that extends the bounds rendered in the dst. |
| 141 // This is conservative as a mask filter does not have to expand the bounds rendered. | 205 // This is conservative as a mask filter does not have to expand the bounds rendered. |
| 142 bool coordsAllInsideSrcRect = !paint.isAntiAlias() && !mf; | 206 bool coordsAllInsideSrcRect = !paint.isAntiAlias() && !mf; |
| 143 | 207 |
| 208 // Check for optimization to drop the src rect constraint when on bilerp. | |
| 209 if (filterMode && GrTextureParams::kBilerp_FilterMode == *filterMode && | |
| 210 GrTextureAdjuster::kYes_FilterConstraint == constraintMode && coordsAllI nsideSrcRect) { | |
| 211 SkMatrix combinedMatrix; | |
| 212 combinedMatrix.setConcat(viewMatrix, srcToDstMatrix); | |
| 213 if (can_ignore_bilerp_constraint(*producer, clippedSrcRect, combinedMatr ix, | |
| 214 fRenderTarget->isUnifiedMultisampled()) ) { | |
| 215 constraintMode = GrTextureAdjuster::kNo_FilterConstraint; | |
| 216 } | |
| 217 } | |
| 218 | |
| 144 const SkMatrix* textureMatrix; | 219 const SkMatrix* textureMatrix; |
| 145 SkMatrix tempMatrix; | 220 SkMatrix tempMatrix; |
| 146 if (canUseTextureCoordsAsLocalCoords) { | 221 if (canUseTextureCoordsAsLocalCoords) { |
| 147 textureMatrix = &SkMatrix::I(); | 222 textureMatrix = &SkMatrix::I(); |
| 148 } else { | 223 } else { |
| 149 if (!srcToDstMatrix.invert(&tempMatrix)) { | 224 if (!srcToDstMatrix.invert(&tempMatrix)) { |
| 150 return; | 225 return; |
| 151 } | 226 } |
| 152 textureMatrix = &tempMatrix; | 227 textureMatrix = &tempMatrix; |
| 153 } | 228 } |
| 154 SkAutoTUnref<const GrFragmentProcessor> fp(adjuster->createFragmentProcessor ( | 229 SkAutoTUnref<const GrFragmentProcessor> fp(producer->createFragmentProcessor ( |
| 155 *textureMatrix, clippedSrcRect, constraintMode, coordsAllInsideSrcRect, filterMode)); | 230 *textureMatrix, clippedSrcRect, constraintMode, coordsAllInsideSrcRect, filterMode)); |
| 156 if (!fp) { | 231 if (!fp) { |
| 157 return; | 232 return; |
| 158 } | 233 } |
| 159 fp.reset(mix_texture_fp_with_paint_color_and_shader(fp, alphaTexture, this-> context(), | 234 fp.reset(mix_texture_fp_with_paint_color_and_shader(fp, alphaTexture, this-> context(), |
| 160 viewMatrix, paint)); | 235 viewMatrix, paint)); |
| 161 GrPaint grPaint; | 236 GrPaint grPaint; |
| 162 if (!SkPaintToGrPaintReplaceShader(fContext, paint, fp, &grPaint)) { | 237 if (!SkPaintToGrPaintReplaceShader(fContext, paint, fp, &grPaint)) { |
| 163 return; | 238 return; |
| 164 } | 239 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 185 rec, | 260 rec, |
| 186 rrect)) { | 261 rrect)) { |
| 187 return; | 262 return; |
| 188 } | 263 } |
| 189 SkPath rectPath; | 264 SkPath rectPath; |
| 190 rectPath.addRect(clippedDstRect); | 265 rectPath.addRect(clippedDstRect); |
| 191 GrBlurUtils::drawPathWithMaskFilter(this->context(), fDrawContext, fRenderTa rget, fClip, | 266 GrBlurUtils::drawPathWithMaskFilter(this->context(), fDrawContext, fRenderTa rget, fClip, |
| 192 rectPath, &grPaint, viewMatrix, mf, pain t.getPathEffect(), | 267 rectPath, &grPaint, viewMatrix, mf, pain t.getPathEffect(), |
| 193 GrStrokeInfo::FillInfo()); | 268 GrStrokeInfo::FillInfo()); |
| 194 } | 269 } |
| OLD | NEW |