Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Side by Side Diff: src/gpu/SkGpuDevice.cpp

Issue 30593003: Apply matrix early in draw bitmap (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/gpu/SkGpuDevice.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 // also affect the behavior of the mask filter. 1160 // also affect the behavior of the mask filter.
1161 SkMatrix drawMatrix; 1161 SkMatrix drawMatrix;
1162 drawMatrix.setConcat(fContext->getMatrix(), newM); 1162 drawMatrix.setConcat(fContext->getMatrix(), newM);
1163 SkDraw transformedDraw(draw); 1163 SkDraw transformedDraw(draw);
1164 transformedDraw.fMatrix = &drawMatrix; 1164 transformedDraw.fMatrix = &drawMatrix;
1165 1165
1166 this->drawRect(transformedDraw, srcRect, paintWithTexture); 1166 this->drawRect(transformedDraw, srcRect, paintWithTexture);
1167 1167
1168 return; 1168 return;
1169 } 1169 }
1170
robertphillips 2013/10/20 21:21:39 How does this get undone?
bsalomon 2013/10/21 13:19:10 It doesn't :) But SkGpuDevice sets the canvas matr
1171 fContext->concatMatrix(m);
1170 1172
1171 GrTextureParams params; 1173 GrTextureParams params;
1172 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); 1174 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel();
1173 GrTextureParams::FilterMode textureFilterMode; 1175 GrTextureParams::FilterMode textureFilterMode;
1174 switch(paintFilterLevel) { 1176 switch(paintFilterLevel) {
1175 case SkPaint::kNone_FilterLevel: 1177 case SkPaint::kNone_FilterLevel:
1176 textureFilterMode = GrTextureParams::kNone_FilterMode; 1178 textureFilterMode = GrTextureParams::kNone_FilterMode;
1177 break; 1179 break;
1178 case SkPaint::kLow_FilterLevel: 1180 case SkPaint::kLow_FilterLevel:
1179 textureFilterMode = GrTextureParams::kBilerp_FilterMode; 1181 textureFilterMode = GrTextureParams::kBilerp_FilterMode;
(...skipping 12 matching lines...) Expand all
1192 "MIPMaps."); 1194 "MIPMaps.");
1193 textureFilterMode = GrTextureParams::kMipMap_FilterMode; 1195 textureFilterMode = GrTextureParams::kMipMap_FilterMode;
1194 break; 1196 break;
1195 1197
1196 } 1198 }
1197 1199
1198 params.setFilterMode(textureFilterMode); 1200 params.setFilterMode(textureFilterMode);
1199 1201
1200 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { 1202 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) {
1201 // take the simple case 1203 // take the simple case
1202 this->internalDrawBitmap(bitmap, srcRect, m, params, paint, flags); 1204 this->internalDrawBitmap(bitmap, srcRect, params, paint, flags);
1203 } else { 1205 } else {
1204 this->drawTiledBitmap(bitmap, srcRect, m, params, paint, flags); 1206 this->drawTiledBitmap(bitmap, srcRect, params, paint, flags);
1205 } 1207 }
1206 } 1208 }
1207 1209
1208 // Break 'bitmap' into several tiles to draw it since it has already 1210 // Break 'bitmap' into several tiles to draw it since it has already
1209 // been determined to be too large to fit in VRAM 1211 // been determined to be too large to fit in VRAM
1210 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, 1212 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
1211 const SkRect& srcRect, 1213 const SkRect& srcRect,
1212 const SkMatrix& m,
1213 const GrTextureParams& params, 1214 const GrTextureParams& params,
1214 const SkPaint& paint, 1215 const SkPaint& paint,
1215 SkCanvas::DrawBitmapRectFlags flags) { 1216 SkCanvas::DrawBitmapRectFlags flags) {
1216 int maxTextureSize = fContext->getMaxTextureSize(); 1217 int maxTextureSize = fContext->getMaxTextureSize();
1217 if (SkPaint::kNone_FilterLevel != paint.getFilterLevel()) { 1218 if (SkPaint::kNone_FilterLevel != paint.getFilterLevel()) {
1218 // We may need a skosh more room if we have to bump out the tile 1219 // We may need a skosh more room if we have to bump out the tile
1219 // by 1 pixel all around 1220 // by 1 pixel all around
1220 maxTextureSize -= 2; 1221 maxTextureSize -= 2;
1221 } 1222 }
1222 1223
1223 int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize); 1224 int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize);
1224 1225
1225 // compute clip bounds in local coordinates 1226 // compute clip bounds in local coordinates
1226 SkRect clipRect; 1227 SkRect clipRect;
1227 { 1228 {
1228 const GrRenderTarget* rt = fContext->getRenderTarget(); 1229 const GrRenderTarget* rt = fContext->getRenderTarget();
1229 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); 1230 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height()));
1230 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect)) { 1231 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect)) {
1231 return; 1232 return;
1232 } 1233 }
1233 SkMatrix matrix, inverse; 1234 SkMatrix inverse;
1234 matrix.setConcat(fContext->getMatrix(), m); 1235 if (!fContext->getMatrix().invert(&inverse)) {
1235 if (!matrix.invert(&inverse)) {
1236 return; 1236 return;
1237 } 1237 }
1238 inverse.mapRect(&clipRect); 1238 inverse.mapRect(&clipRect);
1239 } 1239 }
1240 1240
1241 int nx = bitmap.width() / tileSize; 1241 int nx = bitmap.width() / tileSize;
1242 int ny = bitmap.height() / tileSize; 1242 int ny = bitmap.height() / tileSize;
1243 for (int x = 0; x <= nx; x++) { 1243 for (int x = 0; x <= nx; x++) {
1244 for (int y = 0; y <= ny; y++) { 1244 for (int y = 0; y <= ny; y++) {
1245 SkRect tileR; 1245 SkRect tileR;
(...skipping 29 matching lines...) Expand all
1275 // not bleed across the original clamped edges) 1275 // not bleed across the original clamped edges)
1276 srcRect.roundOut(&iClampRect); 1276 srcRect.roundOut(&iClampRect);
1277 } 1277 }
1278 1278
1279 clamped_unit_outset_with_offset(&iTileR, &offset, iClampRect); 1279 clamped_unit_outset_with_offset(&iTileR, &offset, iClampRect);
1280 } 1280 }
1281 1281
1282 if (bitmap.extractSubset(&tmpB, iTileR)) { 1282 if (bitmap.extractSubset(&tmpB, iTileR)) {
1283 // now offset it to make it "local" to our tmp bitmap 1283 // now offset it to make it "local" to our tmp bitmap
1284 tileR.offset(-offset.fX, -offset.fY); 1284 tileR.offset(-offset.fX, -offset.fY);
1285 SkMatrix tmpM(m); 1285 SkMatrix tmpM;
1286 tmpM.preTranslate(offset.fX, offset.fY); 1286 tmpM.setTranslate(offset.fX, offset.fY);
1287 1287 GrContext::AutoMatrix am;
1288 this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint, flags ); 1288 am.setPreConcat(fContext, tmpM);
1289 this->internalDrawBitmap(tmpB, tileR, params, paint, flags);
1289 } 1290 }
1290 } 1291 }
1291 } 1292 }
1292 } 1293 }
1293 1294
1294 static bool has_aligned_samples(const SkRect& srcRect, 1295 static bool has_aligned_samples(const SkRect& srcRect,
1295 const SkRect& transformedRect) { 1296 const SkRect& transformedRect) {
1296 // detect pixel disalignment 1297 // detect pixel disalignment
1297 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - 1298 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) -
1298 transformedRect.left()) < COLOR_BLEED_TOLERANCE && 1299 transformedRect.left()) < COLOR_BLEED_TOLERANCE &&
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 1336
1336 /* 1337 /*
1337 * This is called by drawBitmap(), which has to handle images that may be too 1338 * This is called by drawBitmap(), which has to handle images that may be too
1338 * large to be represented by a single texture. 1339 * large to be represented by a single texture.
1339 * 1340 *
1340 * internalDrawBitmap assumes that the specified bitmap will fit in a texture 1341 * internalDrawBitmap assumes that the specified bitmap will fit in a texture
1341 * and that non-texture portion of the GrPaint has already been setup. 1342 * and that non-texture portion of the GrPaint has already been setup.
1342 */ 1343 */
1343 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, 1344 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
1344 const SkRect& srcRect, 1345 const SkRect& srcRect,
1345 const SkMatrix& m,
1346 const GrTextureParams& params, 1346 const GrTextureParams& params,
1347 const SkPaint& paint, 1347 const SkPaint& paint,
1348 SkCanvas::DrawBitmapRectFlags flags) { 1348 SkCanvas::DrawBitmapRectFlags flags) {
1349 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && 1349 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
1350 bitmap.height() <= fContext->getMaxTextureSize()); 1350 bitmap.height() <= fContext->getMaxTextureSize());
1351 1351
1352 GrTexture* texture; 1352 GrTexture* texture;
1353 SkAutoCachedTexture act(this, bitmap, &params, &texture); 1353 SkAutoCachedTexture act(this, bitmap, &params, &texture);
1354 if (NULL == texture) { 1354 if (NULL == texture) {
1355 return; 1355 return;
1356 } 1356 }
1357 1357
1358 SkRect dstRect(srcRect); 1358 SkRect dstRect(srcRect);
1359 SkRect paintRect; 1359 SkRect paintRect;
1360 SkScalar wInv = SkScalarInvert(SkIntToScalar(bitmap.width())); 1360 SkScalar wInv = SkScalarInvert(SkIntToScalar(bitmap.width()));
1361 SkScalar hInv = SkScalarInvert(SkIntToScalar(bitmap.height())); 1361 SkScalar hInv = SkScalarInvert(SkIntToScalar(bitmap.height()));
1362 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), 1362 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv),
1363 SkScalarMul(srcRect.fTop, hInv), 1363 SkScalarMul(srcRect.fTop, hInv),
1364 SkScalarMul(srcRect.fRight, wInv), 1364 SkScalarMul(srcRect.fRight, wInv),
1365 SkScalarMul(srcRect.fBottom, hInv)); 1365 SkScalarMul(srcRect.fBottom, hInv));
1366 1366
1367 bool needsTextureDomain = false; 1367 bool needsTextureDomain = false;
1368 if (!(flags & SkCanvas::kBleed_DrawBitmapRectFlag) && 1368 if (!(flags & SkCanvas::kBleed_DrawBitmapRectFlag) &&
1369 params.filterMode() != GrTextureParams::kNone_FilterMode) { 1369 params.filterMode() != GrTextureParams::kNone_FilterMode) {
1370 // Need texture domain if drawing a sub rect. 1370 // Need texture domain if drawing a sub rect.
1371 needsTextureDomain = srcRect.width() < bitmap.width() || 1371 needsTextureDomain = srcRect.width() < bitmap.width() ||
1372 srcRect.height() < bitmap.height(); 1372 srcRect.height() < bitmap.height();
1373 if (needsTextureDomain && m.rectStaysRect() && fContext->getMatrix().rec tStaysRect()) { 1373 if (needsTextureDomain && fContext->getMatrix().rectStaysRect()) {
1374 const SkMatrix& matrix = fContext->getMatrix();
1374 // sampling is axis-aligned 1375 // sampling is axis-aligned
1375 SkRect transformedRect; 1376 SkRect transformedRect;
1376 SkMatrix srcToDeviceMatrix(m); 1377 matrix.mapRect(&transformedRect, srcRect);
1377 srcToDeviceMatrix.postConcat(fContext->getMatrix()); 1378
1378 srcToDeviceMatrix.mapRect(&transformedRect, srcRect);
1379
1380 if (has_aligned_samples(srcRect, transformedRect)) { 1379 if (has_aligned_samples(srcRect, transformedRect)) {
1381 // We could also turn off filtering here (but we already did a c ache lookup with 1380 // We could also turn off filtering here (but we already did a c ache lookup with
1382 // params). 1381 // params).
1383 needsTextureDomain = false; 1382 needsTextureDomain = false;
1384 } else { 1383 } else {
1385 needsTextureDomain = may_color_bleed(srcRect, transformedRect, m ); 1384 needsTextureDomain = may_color_bleed(srcRect, transformedRect, m atrix);
bsalomon 2013/10/20 14:14:18 I think this was supposed take the full matrix and
robertphillips 2013/10/20 21:21:39 I agree
1386 } 1385 }
1387 } 1386 }
1388 } 1387 }
1389 1388
1390 SkRect textureDomain = SkRect::MakeEmpty(); 1389 SkRect textureDomain = SkRect::MakeEmpty();
1391 SkAutoTUnref<GrEffectRef> effect; 1390 SkAutoTUnref<GrEffectRef> effect;
1392 if (needsTextureDomain) { 1391 if (needsTextureDomain) {
1393 // Use a constrained texture domain to avoid color bleeding 1392 // Use a constrained texture domain to avoid color bleeding
1394 SkScalar left, top, right, bottom; 1393 SkScalar left, top, right, bottom;
1395 if (srcRect.width() > SK_Scalar1) { 1394 if (srcRect.width() > SK_Scalar1) {
(...skipping 22 matching lines...) Expand all
1418 1417
1419 // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring 1418 // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
1420 // the rest from the SkPaint. 1419 // the rest from the SkPaint.
1421 GrPaint grPaint; 1420 GrPaint grPaint;
1422 grPaint.addColorEffect(effect); 1421 grPaint.addColorEffect(effect);
1423 bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config()); 1422 bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config());
1424 if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) { 1423 if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) {
1425 return; 1424 return;
1426 } 1425 }
1427 1426
1428 fContext->drawRectToRect(grPaint, dstRect, paintRect, &m); 1427 fContext->drawRectToRect(grPaint, dstRect, paintRect, NULL);
1429 } 1428 }
1430 1429
1431 static bool filter_texture(SkBaseDevice* device, GrContext* context, 1430 static bool filter_texture(SkBaseDevice* device, GrContext* context,
1432 GrTexture* texture, SkImageFilter* filter, 1431 GrTexture* texture, SkImageFilter* filter,
1433 int w, int h, const SkMatrix& ctm, SkBitmap* result, 1432 int w, int h, const SkMatrix& ctm, SkBitmap* result,
1434 SkIPoint* offset) { 1433 SkIPoint* offset) {
1435 SkASSERT(filter); 1434 SkASSERT(filter);
1436 SkDeviceImageFilterProxy proxy(device); 1435 SkDeviceImageFilterProxy proxy(device);
1437 1436
1438 if (filter->canFilterImageGPU()) { 1437 if (filter->canFilterImageGPU()) {
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1851 GrTexture* texture, 1850 GrTexture* texture,
1852 bool needClear) 1851 bool needClear)
1853 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { 1852 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) {
1854 1853
1855 SkASSERT(texture && texture->asRenderTarget()); 1854 SkASSERT(texture && texture->asRenderTarget());
1856 // 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
1857 // 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.
1858 this->initFromRenderTarget(context, texture->asRenderTarget(), true); 1857 this->initFromRenderTarget(context, texture->asRenderTarget(), true);
1859 fNeedClear = needClear; 1858 fNeedClear = needClear;
1860 } 1859 }
OLDNEW
« no previous file with comments | « include/gpu/SkGpuDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698