| 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 "effects/GrTextureDomainEffect.h" | 10 #include "effects/GrTextureDomainEffect.h" |
| (...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 } else { | 1075 } else { |
| 1076 return false; | 1076 return false; |
| 1077 } | 1077 } |
| 1078 } | 1078 } |
| 1079 | 1079 |
| 1080 void SkGpuDevice::drawBitmap(const SkDraw& draw, | 1080 void SkGpuDevice::drawBitmap(const SkDraw& draw, |
| 1081 const SkBitmap& bitmap, | 1081 const SkBitmap& bitmap, |
| 1082 const SkMatrix& m, | 1082 const SkMatrix& m, |
| 1083 const SkPaint& paint) { | 1083 const SkPaint& paint) { |
| 1084 // We cannot call drawBitmapRect here since 'm' could be anything | 1084 // We cannot call drawBitmapRect here since 'm' could be anything |
| 1085 this->drawBitmapCommon(draw, bitmap, NULL, m, paint); | 1085 this->drawBitmapCommon(draw, bitmap, NULL, m, paint, |
| 1086 SkCanvas::kNone_DrawBitmapRectflag); |
| 1086 } | 1087 } |
| 1087 | 1088 |
| 1088 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, | 1089 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
| 1089 const SkBitmap& bitmap, | 1090 const SkBitmap& bitmap, |
| 1090 const SkRect* srcRectPtr, | 1091 const SkRect* srcRectPtr, |
| 1091 const SkMatrix& m, | 1092 const SkMatrix& m, |
| 1092 const SkPaint& paint) { | 1093 const SkPaint& paint, |
| 1094 SkCanvas::DrawBitmapRectFlags flags) { |
| 1093 CHECK_SHOULD_DRAW(draw, false); | 1095 CHECK_SHOULD_DRAW(draw, false); |
| 1094 | 1096 |
| 1095 SkRect srcRect; | 1097 SkRect srcRect; |
| 1096 if (NULL == srcRectPtr) { | 1098 if (NULL == srcRectPtr) { |
| 1097 srcRect.set(0, 0, SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.he
ight())); | 1099 srcRect.set(0, 0, SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.he
ight())); |
| 1098 } else { | 1100 } else { |
| 1099 srcRect = *srcRectPtr; | 1101 srcRect = *srcRectPtr; |
| 1100 } | 1102 } |
| 1101 | 1103 |
| 1102 if (paint.getMaskFilter()){ | 1104 if (paint.getMaskFilter()){ |
| 1105 // TODO: this path needs to be updated to respect the bleed flag |
| 1106 |
| 1103 // Convert the bitmap to a shader so that the rect can be drawn | 1107 // Convert the bitmap to a shader so that the rect can be drawn |
| 1104 // through drawRect, which supports mask filters. | 1108 // through drawRect, which supports mask filters. |
| 1105 SkMatrix newM(m); | 1109 SkMatrix newM(m); |
| 1106 SkBitmap tmp; // subset of bitmap, if necessary | 1110 SkBitmap tmp; // subset of bitmap, if necessary |
| 1107 const SkBitmap* bitmapPtr = &bitmap; | 1111 const SkBitmap* bitmapPtr = &bitmap; |
| 1108 if (NULL != srcRectPtr) { | 1112 if (NULL != srcRectPtr) { |
| 1109 SkIRect iSrc; | 1113 SkIRect iSrc; |
| 1110 srcRect.roundOut(&iSrc); | 1114 srcRect.roundOut(&iSrc); |
| 1111 if (!bitmap.extractSubset(&tmp, iSrc)) { | 1115 if (!bitmap.extractSubset(&tmp, iSrc)) { |
| 1112 return; // extraction failed | 1116 return; // extraction failed |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1161 "MIPMaps."); | 1165 "MIPMaps."); |
| 1162 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 1166 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
| 1163 break; | 1167 break; |
| 1164 | 1168 |
| 1165 } | 1169 } |
| 1166 | 1170 |
| 1167 params.setFilterMode(textureFilterMode); | 1171 params.setFilterMode(textureFilterMode); |
| 1168 | 1172 |
| 1169 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { | 1173 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { |
| 1170 // take the simple case | 1174 // take the simple case |
| 1171 this->internalDrawBitmap(bitmap, srcRect, m, params, paint); | 1175 this->internalDrawBitmap(bitmap, srcRect, m, params, paint, flags); |
| 1172 } else { | 1176 } else { |
| 1173 this->drawTiledBitmap(bitmap, srcRect, m, params, paint); | 1177 this->drawTiledBitmap(bitmap, srcRect, m, params, paint, flags); |
| 1174 } | 1178 } |
| 1175 } | 1179 } |
| 1176 | 1180 |
| 1177 // Break 'bitmap' into several tiles to draw it since it has already | 1181 // Break 'bitmap' into several tiles to draw it since it has already |
| 1178 // been determined to be too large to fit in VRAM | 1182 // been determined to be too large to fit in VRAM |
| 1179 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, | 1183 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, |
| 1180 const SkRect& srcRect, | 1184 const SkRect& srcRect, |
| 1181 const SkMatrix& m, | 1185 const SkMatrix& m, |
| 1182 const GrTextureParams& params, | 1186 const GrTextureParams& params, |
| 1183 const SkPaint& paint) { | 1187 const SkPaint& paint, |
| 1188 SkCanvas::DrawBitmapRectFlags flags) { |
| 1189 // TODO: this method needs to be updated to respect the bleed flag |
| 1184 const int maxTextureSize = fContext->getMaxTextureSize(); | 1190 const int maxTextureSize = fContext->getMaxTextureSize(); |
| 1185 | 1191 |
| 1186 int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize); | 1192 int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize); |
| 1187 | 1193 |
| 1188 // compute clip bounds in local coordinates | 1194 // compute clip bounds in local coordinates |
| 1189 SkRect clipRect; | 1195 SkRect clipRect; |
| 1190 { | 1196 { |
| 1191 const GrRenderTarget* rt = fContext->getRenderTarget(); | 1197 const GrRenderTarget* rt = fContext->getRenderTarget(); |
| 1192 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); | 1198 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); |
| 1193 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect))
{ | 1199 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect))
{ |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1222 SkBitmap tmpB; | 1228 SkBitmap tmpB; |
| 1223 SkIRect iTileR; | 1229 SkIRect iTileR; |
| 1224 tileR.roundOut(&iTileR); | 1230 tileR.roundOut(&iTileR); |
| 1225 if (bitmap.extractSubset(&tmpB, iTileR)) { | 1231 if (bitmap.extractSubset(&tmpB, iTileR)) { |
| 1226 // now offset it to make it "local" to our tmp bitmap | 1232 // now offset it to make it "local" to our tmp bitmap |
| 1227 tileR.offset(SkIntToScalar(-iTileR.fLeft), SkIntToScalar(-iTileR
.fTop)); | 1233 tileR.offset(SkIntToScalar(-iTileR.fLeft), SkIntToScalar(-iTileR
.fTop)); |
| 1228 SkMatrix tmpM(m); | 1234 SkMatrix tmpM(m); |
| 1229 tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), | 1235 tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), |
| 1230 SkIntToScalar(iTileR.fTop)); | 1236 SkIntToScalar(iTileR.fTop)); |
| 1231 | 1237 |
| 1232 this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint); | 1238 this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint, flags
); |
| 1233 } | 1239 } |
| 1234 } | 1240 } |
| 1235 } | 1241 } |
| 1236 } | 1242 } |
| 1237 | 1243 |
| 1238 static bool has_aligned_samples(const SkRect& srcRect, | 1244 static bool has_aligned_samples(const SkRect& srcRect, |
| 1239 const SkRect& transformedRect) { | 1245 const SkRect& transformedRect) { |
| 1240 // detect pixel disalignment | 1246 // detect pixel disalignment |
| 1241 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - | 1247 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - |
| 1242 transformedRect.left()) < COLOR_BLEED_TOLERANCE && | 1248 transformedRect.left()) < COLOR_BLEED_TOLERANCE && |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1281 * This is called by drawBitmap(), which has to handle images that may be too | 1287 * This is called by drawBitmap(), which has to handle images that may be too |
| 1282 * large to be represented by a single texture. | 1288 * large to be represented by a single texture. |
| 1283 * | 1289 * |
| 1284 * internalDrawBitmap assumes that the specified bitmap will fit in a texture | 1290 * internalDrawBitmap assumes that the specified bitmap will fit in a texture |
| 1285 * and that non-texture portion of the GrPaint has already been setup. | 1291 * and that non-texture portion of the GrPaint has already been setup. |
| 1286 */ | 1292 */ |
| 1287 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, | 1293 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, |
| 1288 const SkRect& srcRect, | 1294 const SkRect& srcRect, |
| 1289 const SkMatrix& m, | 1295 const SkMatrix& m, |
| 1290 const GrTextureParams& params, | 1296 const GrTextureParams& params, |
| 1291 const SkPaint& paint) { | 1297 const SkPaint& paint, |
| 1298 SkCanvas::DrawBitmapRectFlags flags) { |
| 1292 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && | 1299 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && |
| 1293 bitmap.height() <= fContext->getMaxTextureSize()); | 1300 bitmap.height() <= fContext->getMaxTextureSize()); |
| 1294 | 1301 |
| 1295 GrTexture* texture; | 1302 GrTexture* texture; |
| 1296 SkAutoCachedTexture act(this, bitmap, ¶ms, &texture); | 1303 SkAutoCachedTexture act(this, bitmap, ¶ms, &texture); |
| 1297 if (NULL == texture) { | 1304 if (NULL == texture) { |
| 1298 return; | 1305 return; |
| 1299 } | 1306 } |
| 1300 | 1307 |
| 1301 SkRect dstRect(srcRect); | 1308 SkRect dstRect(srcRect); |
| 1302 SkRect paintRect; | 1309 SkRect paintRect; |
| 1303 SkScalar wInv = SkScalarInvert(SkIntToScalar(bitmap.width())); | 1310 SkScalar wInv = SkScalarInvert(SkIntToScalar(bitmap.width())); |
| 1304 SkScalar hInv = SkScalarInvert(SkIntToScalar(bitmap.height())); | 1311 SkScalar hInv = SkScalarInvert(SkIntToScalar(bitmap.height())); |
| 1305 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), | 1312 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), |
| 1306 SkScalarMul(srcRect.fTop, hInv), | 1313 SkScalarMul(srcRect.fTop, hInv), |
| 1307 SkScalarMul(srcRect.fRight, wInv), | 1314 SkScalarMul(srcRect.fRight, wInv), |
| 1308 SkScalarMul(srcRect.fBottom, hInv)); | 1315 SkScalarMul(srcRect.fBottom, hInv)); |
| 1309 | 1316 |
| 1310 bool needsTextureDomain = false; | 1317 bool needsTextureDomain = false; |
| 1311 if (params.filterMode() != GrTextureParams::kNone_FilterMode) { | 1318 if (!(flags & SkCanvas::kBleed_DrawBitmapRectFlag) && |
| 1319 params.filterMode() != GrTextureParams::kNone_FilterMode) { |
| 1312 // Need texture domain if drawing a sub rect. | 1320 // Need texture domain if drawing a sub rect. |
| 1313 needsTextureDomain = srcRect.width() < bitmap.width() || | 1321 needsTextureDomain = srcRect.width() < bitmap.width() || |
| 1314 srcRect.height() < bitmap.height(); | 1322 srcRect.height() < bitmap.height(); |
| 1315 if (needsTextureDomain && m.rectStaysRect() && fContext->getMatrix().rec
tStaysRect()) { | 1323 if (needsTextureDomain && m.rectStaysRect() && fContext->getMatrix().rec
tStaysRect()) { |
| 1316 // sampling is axis-aligned | 1324 // sampling is axis-aligned |
| 1317 SkRect transformedRect; | 1325 SkRect transformedRect; |
| 1318 SkMatrix srcToDeviceMatrix(m); | 1326 SkMatrix srcToDeviceMatrix(m); |
| 1319 srcToDeviceMatrix.postConcat(fContext->getMatrix()); | 1327 srcToDeviceMatrix.postConcat(fContext->getMatrix()); |
| 1320 srcToDeviceMatrix.mapRect(&transformedRect, srcRect); | 1328 srcToDeviceMatrix.mapRect(&transformedRect, srcRect); |
| 1321 | 1329 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1433 SkIntToScalar(w), | 1441 SkIntToScalar(w), |
| 1434 SkIntToScalar(h)), | 1442 SkIntToScalar(h)), |
| 1435 SkRect::MakeXYWH(0, | 1443 SkRect::MakeXYWH(0, |
| 1436 0, | 1444 0, |
| 1437 SK_Scalar1 * w / texture->width(), | 1445 SK_Scalar1 * w / texture->width(), |
| 1438 SK_Scalar1 * h / texture->height()
)); | 1446 SK_Scalar1 * h / texture->height()
)); |
| 1439 } | 1447 } |
| 1440 | 1448 |
| 1441 void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, | 1449 void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, |
| 1442 const SkRect* src, const SkRect& dst, | 1450 const SkRect* src, const SkRect& dst, |
| 1443 const SkPaint& paint) { | 1451 const SkPaint& paint, |
| 1452 SkCanvas::DrawBitmapRectFlags flags) { |
| 1444 SkMatrix matrix; | 1453 SkMatrix matrix; |
| 1445 SkRect bitmapBounds, tmpSrc; | 1454 SkRect bitmapBounds, tmpSrc; |
| 1446 | 1455 |
| 1447 bitmapBounds.set(0, 0, | 1456 bitmapBounds.set(0, 0, |
| 1448 SkIntToScalar(bitmap.width()), | 1457 SkIntToScalar(bitmap.width()), |
| 1449 SkIntToScalar(bitmap.height())); | 1458 SkIntToScalar(bitmap.height())); |
| 1450 | 1459 |
| 1451 // Compute matrix from the two rectangles | 1460 // Compute matrix from the two rectangles |
| 1452 if (NULL != src) { | 1461 if (NULL != src) { |
| 1453 tmpSrc = *src; | 1462 tmpSrc = *src; |
| 1454 } else { | 1463 } else { |
| 1455 tmpSrc = bitmapBounds; | 1464 tmpSrc = bitmapBounds; |
| 1456 } | 1465 } |
| 1457 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); | 1466 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); |
| 1458 | 1467 |
| 1459 // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null
. | 1468 // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null
. |
| 1460 if (NULL != src) { | 1469 if (NULL != src) { |
| 1461 if (!bitmapBounds.contains(tmpSrc)) { | 1470 if (!bitmapBounds.contains(tmpSrc)) { |
| 1462 if (!tmpSrc.intersect(bitmapBounds)) { | 1471 if (!tmpSrc.intersect(bitmapBounds)) { |
| 1463 return; // nothing to draw | 1472 return; // nothing to draw |
| 1464 } | 1473 } |
| 1465 } | 1474 } |
| 1466 } | 1475 } |
| 1467 | 1476 |
| 1468 this->drawBitmapCommon(draw, bitmap, &tmpSrc, matrix, paint); | 1477 this->drawBitmapCommon(draw, bitmap, &tmpSrc, matrix, paint, flags); |
| 1469 } | 1478 } |
| 1470 | 1479 |
| 1471 void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, | 1480 void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, |
| 1472 int x, int y, const SkPaint& paint) { | 1481 int x, int y, const SkPaint& paint) { |
| 1473 // clear of the source device must occur before CHECK_SHOULD_DRAW | 1482 // clear of the source device must occur before CHECK_SHOULD_DRAW |
| 1474 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); | 1483 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); |
| 1475 if (dev->fNeedClear) { | 1484 if (dev->fNeedClear) { |
| 1476 // TODO: could check here whether we really need to draw at all | 1485 // TODO: could check here whether we really need to draw at all |
| 1477 dev->clear(0x0); | 1486 dev->clear(0x0); |
| 1478 } | 1487 } |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1788 GrTexture* texture, | 1797 GrTexture* texture, |
| 1789 bool needClear) | 1798 bool needClear) |
| 1790 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { | 1799 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { |
| 1791 | 1800 |
| 1792 GrAssert(texture && texture->asRenderTarget()); | 1801 GrAssert(texture && texture->asRenderTarget()); |
| 1793 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1802 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture |
| 1794 // cache. We pass true for the third argument so that it will get unlocked. | 1803 // cache. We pass true for the third argument so that it will get unlocked. |
| 1795 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1804 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
| 1796 fNeedClear = needClear; | 1805 fNeedClear = needClear; |
| 1797 } | 1806 } |
| OLD | NEW |