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 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 return; | 1025 return; |
1026 } | 1026 } |
1027 } | 1027 } |
1028 clippedSrcRect.roundOut(clippedSrcIRect); | 1028 clippedSrcRect.roundOut(clippedSrcIRect); |
1029 SkIRect bmpBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); | 1029 SkIRect bmpBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); |
1030 if (!clippedSrcIRect->intersect(bmpBounds)) { | 1030 if (!clippedSrcIRect->intersect(bmpBounds)) { |
1031 clippedSrcIRect->setEmpty(); | 1031 clippedSrcIRect->setEmpty(); |
1032 } | 1032 } |
1033 } | 1033 } |
1034 | 1034 |
1035 | |
1036 bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap, | 1035 bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap, |
1037 const GrTextureParams& params, | 1036 const GrTextureParams& params, |
1038 const SkRect* srcRectPtr, | 1037 const SkRect* srcRectPtr, |
1039 int maxTileSize, | 1038 int maxTileSize, |
1040 int* tileSize) const { | 1039 int* tileSize, |
| 1040 SkIRect* clippedSrcRect) const { |
1041 // if bitmap is explictly texture backed then just use the texture | 1041 // if bitmap is explictly texture backed then just use the texture |
1042 if (NULL != bitmap.getTexture()) { | 1042 if (NULL != bitmap.getTexture()) { |
1043 return false; | 1043 return false; |
1044 } | 1044 } |
1045 | 1045 |
1046 SkIRect clippedSrcRect; | |
1047 | |
1048 // if it's larger than the max tile size, then we have no choice but tiling. | 1046 // if it's larger than the max tile size, then we have no choice but tiling. |
1049 if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) { | 1047 if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) { |
1050 determine_clipped_src_rect(fContext, bitmap, srcRectPtr, &clippedSrcRect
); | 1048 determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect)
; |
1051 *tileSize = determine_tile_size(bitmap, clippedSrcRect, maxTileSize); | 1049 *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize); |
1052 return true; | 1050 return true; |
1053 } | 1051 } |
1054 | 1052 |
1055 if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTile
Size) { | 1053 if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTile
Size) { |
1056 return false; | 1054 return false; |
1057 } | 1055 } |
1058 | 1056 |
1059 // if the entire texture is already in our cache then no reason to tile it | 1057 // if the entire texture is already in our cache then no reason to tile it |
1060 if (GrIsBitmapInCache(fContext, bitmap, ¶ms)) { | 1058 if (GrIsBitmapInCache(fContext, bitmap, ¶ms)) { |
1061 return false; | 1059 return false; |
1062 } | 1060 } |
1063 | 1061 |
1064 // At this point we know we could do the draw by uploading the entire bitmap | 1062 // At this point we know we could do the draw by uploading the entire bitmap |
1065 // as a texture. However, if the texture would be large compared to the | 1063 // as a texture. However, if the texture would be large compared to the |
1066 // cache size and we don't require most of it for this draw then tile to | 1064 // cache size and we don't require most of it for this draw then tile to |
1067 // reduce the amount of upload and cache spill. | 1065 // reduce the amount of upload and cache spill. |
1068 | 1066 |
1069 // assumption here is that sw bitmap size is a good proxy for its size as | 1067 // assumption here is that sw bitmap size is a good proxy for its size as |
1070 // a texture | 1068 // a texture |
1071 size_t bmpSize = bitmap.getSize(); | 1069 size_t bmpSize = bitmap.getSize(); |
1072 size_t cacheSize; | 1070 size_t cacheSize; |
1073 fContext->getTextureCacheLimits(NULL, &cacheSize); | 1071 fContext->getTextureCacheLimits(NULL, &cacheSize); |
1074 if (bmpSize < cacheSize / 2) { | 1072 if (bmpSize < cacheSize / 2) { |
1075 return false; | 1073 return false; |
1076 } | 1074 } |
1077 | 1075 |
1078 // Figure out how much of the src we will need based on the src rect and cli
pping. | 1076 // Figure out how much of the src we will need based on the src rect and cli
pping. |
1079 determine_clipped_src_rect(fContext, bitmap, srcRectPtr, &clippedSrcRect); | 1077 determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect); |
1080 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max
sized tile. | 1078 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max
sized tile. |
1081 size_t usedTileBytes = get_tile_count(clippedSrcRect, kBmpSmallTileSize) * | 1079 size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) * |
1082 kBmpSmallTileSize * kBmpSmallTileSize; | 1080 kBmpSmallTileSize * kBmpSmallTileSize; |
1083 | 1081 |
1084 return usedTileBytes < 2 * bmpSize; | 1082 return usedTileBytes < 2 * bmpSize; |
1085 } | 1083 } |
1086 | 1084 |
1087 void SkGpuDevice::drawBitmap(const SkDraw& draw, | 1085 void SkGpuDevice::drawBitmap(const SkDraw& draw, |
1088 const SkBitmap& bitmap, | 1086 const SkBitmap& bitmap, |
1089 const SkMatrix& m, | 1087 const SkMatrix& m, |
1090 const SkPaint& paint) { | 1088 const SkPaint& paint) { |
1091 // We cannot call drawBitmapRect here since 'm' could be anything | 1089 // We cannot call drawBitmapRect here since 'm' could be anything |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1212 params.setFilterMode(textureFilterMode); | 1210 params.setFilterMode(textureFilterMode); |
1213 | 1211 |
1214 int maxTileSize = fContext->getMaxTextureSize(); | 1212 int maxTileSize = fContext->getMaxTextureSize(); |
1215 if (SkPaint::kNone_FilterLevel != paint.getFilterLevel()) { | 1213 if (SkPaint::kNone_FilterLevel != paint.getFilterLevel()) { |
1216 // We may need a skosh more room if we have to bump out the tile | 1214 // We may need a skosh more room if we have to bump out the tile |
1217 // by 1 pixel all around | 1215 // by 1 pixel all around |
1218 maxTileSize -= 2; | 1216 maxTileSize -= 2; |
1219 } | 1217 } |
1220 int tileSize; | 1218 int tileSize; |
1221 | 1219 |
1222 if (this->shouldTileBitmap(bitmap, params, srcRectPtr, maxTileSize, &tileSiz
e)) { | 1220 SkIRect clippedSrcRect; |
1223 this->drawTiledBitmap(bitmap, srcRect, params, paint, flags, tileSize); | 1221 if (this->shouldTileBitmap(bitmap, params, srcRectPtr, maxTileSize, &tileSiz
e, |
| 1222 &clippedSrcRect)) { |
| 1223 this->drawTiledBitmap(bitmap, srcRect, clippedSrcRect, params, paint, fl
ags, tileSize); |
1224 } else { | 1224 } else { |
1225 // take the simple case | 1225 // take the simple case |
1226 this->internalDrawBitmap(bitmap, srcRect, params, paint, flags); | 1226 this->internalDrawBitmap(bitmap, srcRect, params, paint, flags); |
1227 } | 1227 } |
1228 } | 1228 } |
1229 | 1229 |
1230 // Break 'bitmap' into several tiles to draw it since it has already | 1230 // Break 'bitmap' into several tiles to draw it since it has already |
1231 // been determined to be too large to fit in VRAM | 1231 // been determined to be too large to fit in VRAM |
1232 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, | 1232 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, |
1233 const SkRect& srcRect, | 1233 const SkRect& srcRect, |
| 1234 const SkIRect& clippedSrcIRect, |
1234 const GrTextureParams& params, | 1235 const GrTextureParams& params, |
1235 const SkPaint& paint, | 1236 const SkPaint& paint, |
1236 SkCanvas::DrawBitmapRectFlags flags, | 1237 SkCanvas::DrawBitmapRectFlags flags, |
1237 int tileSize) { | 1238 int tileSize) { |
1238 | 1239 SkRect clippedSrcRect = SkRect::MakeFromIRect(clippedSrcIRect); |
1239 // compute clip bounds in local coordinates | |
1240 SkRect clipRect; | |
1241 { | |
1242 const GrRenderTarget* rt = fContext->getRenderTarget(); | |
1243 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); | |
1244 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect))
{ | |
1245 return; | |
1246 } | |
1247 SkMatrix inverse; | |
1248 if (!fContext->getMatrix().invert(&inverse)) { | |
1249 return; | |
1250 } | |
1251 inverse.mapRect(&clipRect); | |
1252 } | |
1253 | 1240 |
1254 int nx = bitmap.width() / tileSize; | 1241 int nx = bitmap.width() / tileSize; |
1255 int ny = bitmap.height() / tileSize; | 1242 int ny = bitmap.height() / tileSize; |
1256 for (int x = 0; x <= nx; x++) { | 1243 for (int x = 0; x <= nx; x++) { |
1257 for (int y = 0; y <= ny; y++) { | 1244 for (int y = 0; y <= ny; y++) { |
1258 SkRect tileR; | 1245 SkRect tileR; |
1259 tileR.set(SkIntToScalar(x * tileSize), | 1246 tileR.set(SkIntToScalar(x * tileSize), |
1260 SkIntToScalar(y * tileSize), | 1247 SkIntToScalar(y * tileSize), |
1261 SkIntToScalar((x + 1) * tileSize), | 1248 SkIntToScalar((x + 1) * tileSize), |
1262 SkIntToScalar((y + 1) * tileSize)); | 1249 SkIntToScalar((y + 1) * tileSize)); |
1263 | 1250 |
1264 if (!SkRect::Intersects(tileR, clipRect)) { | 1251 if (!SkRect::Intersects(tileR, clippedSrcRect)) { |
1265 continue; | 1252 continue; |
1266 } | 1253 } |
1267 | 1254 |
1268 if (!tileR.intersect(srcRect)) { | 1255 if (!tileR.intersect(srcRect)) { |
1269 continue; | 1256 continue; |
1270 } | 1257 } |
1271 | 1258 |
1272 SkBitmap tmpB; | 1259 SkBitmap tmpB; |
1273 SkIRect iTileR; | 1260 SkIRect iTileR; |
1274 tileR.roundOut(&iTileR); | 1261 tileR.roundOut(&iTileR); |
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1863 GrTexture* texture, | 1850 GrTexture* texture, |
1864 bool needClear) | 1851 bool needClear) |
1865 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { | 1852 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { |
1866 | 1853 |
1867 SkASSERT(texture && texture->asRenderTarget()); | 1854 SkASSERT(texture && texture->asRenderTarget()); |
1868 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1855 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture |
1869 // cache. We pass true for the third argument so that it will get unlocked. | 1856 // cache. We pass true for the third argument so that it will get unlocked. |
1870 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1857 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
1871 fNeedClear = needClear; | 1858 fNeedClear = needClear; |
1872 } | 1859 } |
OLD | NEW |