OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 | 1294 |
1295 SkRect dstRect = {0, 0, srcRect.width(), srcRect.height() }; | 1295 SkRect dstRect = {0, 0, srcRect.width(), srcRect.height() }; |
1296 SkRect paintRect; | 1296 SkRect paintRect; |
1297 SkScalar wInv = SkScalarInvert(SkIntToScalar(texture->width())); | 1297 SkScalar wInv = SkScalarInvert(SkIntToScalar(texture->width())); |
1298 SkScalar hInv = SkScalarInvert(SkIntToScalar(texture->height())); | 1298 SkScalar hInv = SkScalarInvert(SkIntToScalar(texture->height())); |
1299 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), | 1299 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), |
1300 SkScalarMul(srcRect.fTop, hInv), | 1300 SkScalarMul(srcRect.fTop, hInv), |
1301 SkScalarMul(srcRect.fRight, wInv), | 1301 SkScalarMul(srcRect.fRight, wInv), |
1302 SkScalarMul(srcRect.fBottom, hInv)); | 1302 SkScalarMul(srcRect.fBottom, hInv)); |
1303 | 1303 |
| 1304 SkMatrix texMatrix; |
| 1305 texMatrix.reset(); |
| 1306 if (kAlpha_8_SkColorType == bitmap.colorType() && paint.getShader()) { |
| 1307 // In cases where we are doing an A8 bitmap draw with a shader installed
, we cannot use |
| 1308 // local coords with the bitmap draw since it may mess up texture look u
ps for the shader. |
| 1309 // Thus we need to pass in the transform matrix directly to the texture
processor used for |
| 1310 // the bitmap draw. |
| 1311 texMatrix.setScale(wInv, hInv); |
| 1312 } |
| 1313 |
1304 SkRect textureDomain = SkRect::MakeEmpty(); | 1314 SkRect textureDomain = SkRect::MakeEmpty(); |
1305 | 1315 |
1306 // Construct a GrPaint by setting the bitmap texture as the first effect and
then configuring | 1316 // Construct a GrPaint by setting the bitmap texture as the first effect and
then configuring |
1307 // the rest from the SkPaint. | 1317 // the rest from the SkPaint. |
1308 GrPaint grPaint; | 1318 GrPaint grPaint; |
1309 SkAutoTUnref<const GrFragmentProcessor> fp; | 1319 SkAutoTUnref<const GrFragmentProcessor> fp; |
1310 | 1320 |
1311 if (needsTextureDomain && (SkCanvas::kStrict_SrcRectConstraint == constraint
)) { | 1321 if (needsTextureDomain && (SkCanvas::kStrict_SrcRectConstraint == constraint
)) { |
1312 // Use a constrained texture domain to avoid color bleeding | 1322 // Use a constrained texture domain to avoid color bleeding |
1313 SkScalar left, top, right, bottom; | 1323 SkScalar left, top, right, bottom; |
1314 if (srcRect.width() > SK_Scalar1) { | 1324 if (srcRect.width() > SK_Scalar1) { |
1315 SkScalar border = SK_ScalarHalf / texture->width(); | 1325 SkScalar border = SK_ScalarHalf / texture->width(); |
1316 left = paintRect.left() + border; | 1326 left = paintRect.left() + border; |
1317 right = paintRect.right() - border; | 1327 right = paintRect.right() - border; |
1318 } else { | 1328 } else { |
1319 left = right = SkScalarHalf(paintRect.left() + paintRect.right()); | 1329 left = right = SkScalarHalf(paintRect.left() + paintRect.right()); |
1320 } | 1330 } |
1321 if (srcRect.height() > SK_Scalar1) { | 1331 if (srcRect.height() > SK_Scalar1) { |
1322 SkScalar border = SK_ScalarHalf / texture->height(); | 1332 SkScalar border = SK_ScalarHalf / texture->height(); |
1323 top = paintRect.top() + border; | 1333 top = paintRect.top() + border; |
1324 bottom = paintRect.bottom() - border; | 1334 bottom = paintRect.bottom() - border; |
1325 } else { | 1335 } else { |
1326 top = bottom = SkScalarHalf(paintRect.top() + paintRect.bottom()); | 1336 top = bottom = SkScalarHalf(paintRect.top() + paintRect.bottom()); |
1327 } | 1337 } |
1328 textureDomain.setLTRB(left, top, right, bottom); | 1338 textureDomain.setLTRB(left, top, right, bottom); |
1329 if (bicubic) { | 1339 if (bicubic) { |
1330 fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), textureDoma
in)); | 1340 fp.reset(GrBicubicEffect::Create(texture, texMatrix, textureDomain))
; |
1331 } else { | 1341 } else { |
1332 fp.reset(GrTextureDomainEffect::Create(texture, | 1342 fp.reset(GrTextureDomainEffect::Create(texture, |
1333 SkMatrix::I(), | 1343 texMatrix, |
1334 textureDomain, | 1344 textureDomain, |
1335 GrTextureDomain::kClamp_Mode, | 1345 GrTextureDomain::kClamp_Mode, |
1336 params.filterMode())); | 1346 params.filterMode())); |
1337 } | 1347 } |
1338 } else if (bicubic) { | 1348 } else if (bicubic) { |
1339 SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode()); | 1349 SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode()); |
1340 SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTil
eModeY() }; | 1350 SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTil
eModeY() }; |
1341 fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tileModes)); | 1351 fp.reset(GrBicubicEffect::Create(texture, texMatrix, tileModes)); |
1342 } else { | 1352 } else { |
1343 fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params)); | 1353 fp.reset(GrSimpleTextureEffect::Create(texture, texMatrix, params)); |
1344 } | 1354 } |
1345 | 1355 |
| 1356 SkAutoTUnref<const GrFragmentProcessor> shaderFP; |
| 1357 |
1346 if (kAlpha_8_SkColorType == bitmap.colorType()) { | 1358 if (kAlpha_8_SkColorType == bitmap.colorType()) { |
1347 fp.reset(GrFragmentProcessor::MulOutputByInputUnpremulColor(fp)); | 1359 if (const SkShader* shader = paint.getShader()) { |
| 1360 shaderFP.reset(shader->asFragmentProcessor(this->context(), |
| 1361 viewMatrix, |
| 1362 nullptr, |
| 1363 paint.getFilterQuality())
); |
| 1364 if (!shaderFP) { |
| 1365 return; |
| 1366 } |
| 1367 const GrFragmentProcessor* fpSeries[] = { shaderFP.get(), fp.get() }
; |
| 1368 fp.reset(GrFragmentProcessor::RunInSeries(fpSeries, 2)); |
| 1369 } else { |
| 1370 fp.reset(GrFragmentProcessor::MulOutputByInputUnpremulColor(fp)); |
| 1371 } |
1348 } else { | 1372 } else { |
1349 fp.reset(GrFragmentProcessor::MulOutputByInputAlpha(fp)); | 1373 fp.reset(GrFragmentProcessor::MulOutputByInputAlpha(fp)); |
1350 } | 1374 } |
1351 | 1375 |
1352 if (!SkPaintToGrPaintReplaceShader(this->context(), paint, fp, &grPaint)) { | 1376 if (!SkPaintToGrPaintReplaceShader(this->context(), paint, fp, &grPaint)) { |
1353 return; | 1377 return; |
1354 } | 1378 } |
1355 | 1379 |
1356 fDrawContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, viewMatrix,
dstRect, | 1380 if (kAlpha_8_SkColorType == bitmap.colorType() && paint.getShader()) { |
1357 paintRect); | 1381 // We don't have local coords in this case and have previously set the t
ransform |
| 1382 // matrices directly on the texture processor. |
| 1383 fDrawContext->drawRect(fRenderTarget, fClip, grPaint, viewMatrix, dstRec
t); |
| 1384 } else { |
| 1385 fDrawContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, viewMat
rix, dstRect, |
| 1386 paintRect); |
| 1387 } |
1358 } | 1388 } |
1359 | 1389 |
1360 bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, | 1390 bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, |
1361 int width, int height, | 1391 int width, int height, |
1362 const SkImageFilter* filter, | 1392 const SkImageFilter* filter, |
1363 const SkImageFilter::Context& ctx, | 1393 const SkImageFilter::Context& ctx, |
1364 SkBitmap* result, SkIPoint* offset) { | 1394 SkBitmap* result, SkIPoint* offset) { |
1365 SkASSERT(filter); | 1395 SkASSERT(filter); |
1366 | 1396 |
1367 SkImageFilter::Proxy proxy(this); | 1397 SkImageFilter::Proxy proxy(this); |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1994 #endif | 2024 #endif |
1995 } | 2025 } |
1996 | 2026 |
1997 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 2027 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
1998 // We always return a transient cache, so it is freed after each | 2028 // We always return a transient cache, so it is freed after each |
1999 // filter traversal. | 2029 // filter traversal. |
2000 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); | 2030 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); |
2001 } | 2031 } |
2002 | 2032 |
2003 #endif | 2033 #endif |
OLD | NEW |