OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "SkPictureShader.h" | 8 #include "SkPictureShader.h" |
9 | 9 |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 | 69 |
70 // Use a rotation-invariant scale | 70 // Use a rotation-invariant scale |
71 SkPoint scale; | 71 SkPoint scale; |
72 if (!SkDecomposeUpper2x2(m, NULL, &scale, NULL)) { | 72 if (!SkDecomposeUpper2x2(m, NULL, &scale, NULL)) { |
73 // Decomposition failed, use an approximation. | 73 // Decomposition failed, use an approximation. |
74 scale.set(SkScalarSqrt(m.getScaleX() * m.getScaleX() + m.getSkewX() * m.
getSkewX()), | 74 scale.set(SkScalarSqrt(m.getScaleX() * m.getScaleX() + m.getSkewX() * m.
getSkewX()), |
75 SkScalarSqrt(m.getScaleY() * m.getScaleY() + m.getSkewY() * m.
getSkewY())); | 75 SkScalarSqrt(m.getScaleY() * m.getScaleY() + m.getSkewY() * m.
getSkewY())); |
76 } | 76 } |
77 SkSize scaledSize = SkSize::Make(scale.x() * fTile.width(), scale.y() * fTil
e.height()); | 77 SkSize scaledSize = SkSize::Make(scale.x() * fTile.width(), scale.y() * fTil
e.height()); |
78 | 78 |
| 79 // Clamp the tile size to about 16M pixels |
| 80 static const SkScalar kMaxTileArea = 4096 * 4096; |
| 81 SkScalar tileArea = SkScalarMul(scaledSize.width(), scaledSize.height()); |
| 82 if (tileArea > kMaxTileArea) { |
| 83 SkScalar clampScale = SkScalarSqrt(SkScalarDiv(kMaxTileArea, tileArea)); |
| 84 scaledSize.set(SkScalarMul(scaledSize.width(), clampScale), |
| 85 SkScalarMul(scaledSize.height(), clampScale)); |
| 86 } |
| 87 |
79 SkISize tileSize = scaledSize.toRound(); | 88 SkISize tileSize = scaledSize.toRound(); |
80 if (tileSize.isEmpty()) { | 89 if (tileSize.isEmpty()) { |
81 return NULL; | 90 return NULL; |
82 } | 91 } |
83 | 92 |
84 // The actual scale, compensating for rounding. | 93 // The actual scale, compensating for rounding & clamping. |
85 SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fTile.widt
h(), | 94 SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fTile.widt
h(), |
86 SkIntToScalar(tileSize.height()) / fTile.hei
ght()); | 95 SkIntToScalar(tileSize.height()) / fTile.hei
ght()); |
87 | 96 |
88 SkAutoMutexAcquire ama(fCachedBitmapShaderMutex); | 97 SkAutoMutexAcquire ama(fCachedBitmapShaderMutex); |
89 | 98 |
90 if (!fCachedBitmapShader || tileScale != fCachedTileScale) { | 99 if (!fCachedBitmapShader || tileScale != fCachedTileScale) { |
91 SkBitmap bm; | 100 SkBitmap bm; |
92 if (!bm.allocN32Pixels(tileSize.width(), tileSize.height())) { | 101 if (!bm.allocN32Pixels(tileSize.width(), tileSize.height())) { |
93 return NULL; | 102 return NULL; |
94 } | 103 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 return bitmapShader->asNewEffect(context, paint, NULL, paintColor, effect); | 211 return bitmapShader->asNewEffect(context, paint, NULL, paintColor, effect); |
203 } | 212 } |
204 #else | 213 #else |
205 bool SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint, | 214 bool SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint, |
206 const SkMatrix* localMatrix, GrColor* paintCol
or, | 215 const SkMatrix* localMatrix, GrColor* paintCol
or, |
207 GrEffect** effect) const { | 216 GrEffect** effect) const { |
208 SkDEBUGFAIL("Should not call in GPU-less build"); | 217 SkDEBUGFAIL("Should not call in GPU-less build"); |
209 return false; | 218 return false; |
210 } | 219 } |
211 #endif | 220 #endif |
OLD | NEW |