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

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: Add flattenable registration for local image filter subclass to fix GM serialization failure 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 | « src/core/SkImageFilterUtils.cpp ('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 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 SkMatrix drawMatrix; 1157 SkMatrix drawMatrix;
1158 drawMatrix.setConcat(fContext->getMatrix(), newM); 1158 drawMatrix.setConcat(fContext->getMatrix(), newM);
1159 SkDraw transformedDraw(draw); 1159 SkDraw transformedDraw(draw);
1160 transformedDraw.fMatrix = &drawMatrix; 1160 transformedDraw.fMatrix = &drawMatrix;
1161 1161
1162 this->drawRect(transformedDraw, srcRect, paintWithTexture); 1162 this->drawRect(transformedDraw, srcRect, paintWithTexture);
1163 1163
1164 return; 1164 return;
1165 } 1165 }
1166 1166
1167 fContext->concatMatrix(m);
1168
1167 GrTextureParams params; 1169 GrTextureParams params;
1168 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); 1170 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel();
1169 GrTextureParams::FilterMode textureFilterMode; 1171 GrTextureParams::FilterMode textureFilterMode;
1170 switch(paintFilterLevel) { 1172 switch(paintFilterLevel) {
1171 case SkPaint::kNone_FilterLevel: 1173 case SkPaint::kNone_FilterLevel:
1172 textureFilterMode = GrTextureParams::kNone_FilterMode; 1174 textureFilterMode = GrTextureParams::kNone_FilterMode;
1173 break; 1175 break;
1174 case SkPaint::kLow_FilterLevel: 1176 case SkPaint::kLow_FilterLevel:
1175 textureFilterMode = GrTextureParams::kBilerp_FilterMode; 1177 textureFilterMode = GrTextureParams::kBilerp_FilterMode;
1176 break; 1178 break;
(...skipping 11 matching lines...) Expand all
1188 "MIPMaps."); 1190 "MIPMaps.");
1189 textureFilterMode = GrTextureParams::kMipMap_FilterMode; 1191 textureFilterMode = GrTextureParams::kMipMap_FilterMode;
1190 break; 1192 break;
1191 1193
1192 } 1194 }
1193 1195
1194 params.setFilterMode(textureFilterMode); 1196 params.setFilterMode(textureFilterMode);
1195 1197
1196 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { 1198 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) {
1197 // take the simple case 1199 // take the simple case
1198 this->internalDrawBitmap(bitmap, srcRect, m, params, paint, flags); 1200 this->internalDrawBitmap(bitmap, srcRect, params, paint, flags);
1199 } else { 1201 } else {
1200 this->drawTiledBitmap(bitmap, srcRect, m, params, paint, flags); 1202 this->drawTiledBitmap(bitmap, srcRect, params, paint, flags);
1201 } 1203 }
1202 } 1204 }
1203 1205
1204 // Break 'bitmap' into several tiles to draw it since it has already 1206 // Break 'bitmap' into several tiles to draw it since it has already
1205 // been determined to be too large to fit in VRAM 1207 // been determined to be too large to fit in VRAM
1206 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, 1208 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
1207 const SkRect& srcRect, 1209 const SkRect& srcRect,
1208 const SkMatrix& m,
1209 const GrTextureParams& params, 1210 const GrTextureParams& params,
1210 const SkPaint& paint, 1211 const SkPaint& paint,
1211 SkCanvas::DrawBitmapRectFlags flags) { 1212 SkCanvas::DrawBitmapRectFlags flags) {
1212 int maxTextureSize = fContext->getMaxTextureSize(); 1213 int maxTextureSize = fContext->getMaxTextureSize();
1213 if (SkPaint::kNone_FilterLevel != paint.getFilterLevel()) { 1214 if (SkPaint::kNone_FilterLevel != paint.getFilterLevel()) {
1214 // We may need a skosh more room if we have to bump out the tile 1215 // We may need a skosh more room if we have to bump out the tile
1215 // by 1 pixel all around 1216 // by 1 pixel all around
1216 maxTextureSize -= 2; 1217 maxTextureSize -= 2;
1217 } 1218 }
1218 1219
1219 int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize); 1220 int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize);
1220 1221
1221 // compute clip bounds in local coordinates 1222 // compute clip bounds in local coordinates
1222 SkRect clipRect; 1223 SkRect clipRect;
1223 { 1224 {
1224 const GrRenderTarget* rt = fContext->getRenderTarget(); 1225 const GrRenderTarget* rt = fContext->getRenderTarget();
1225 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); 1226 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height()));
1226 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect)) { 1227 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect)) {
1227 return; 1228 return;
1228 } 1229 }
1229 SkMatrix matrix, inverse; 1230 SkMatrix inverse;
1230 matrix.setConcat(fContext->getMatrix(), m); 1231 if (!fContext->getMatrix().invert(&inverse)) {
1231 if (!matrix.invert(&inverse)) {
1232 return; 1232 return;
1233 } 1233 }
1234 inverse.mapRect(&clipRect); 1234 inverse.mapRect(&clipRect);
1235 } 1235 }
1236 1236
1237 int nx = bitmap.width() / tileSize; 1237 int nx = bitmap.width() / tileSize;
1238 int ny = bitmap.height() / tileSize; 1238 int ny = bitmap.height() / tileSize;
1239 for (int x = 0; x <= nx; x++) { 1239 for (int x = 0; x <= nx; x++) {
1240 for (int y = 0; y <= ny; y++) { 1240 for (int y = 0; y <= ny; y++) {
1241 SkRect tileR; 1241 SkRect tileR;
(...skipping 29 matching lines...) Expand all
1271 // not bleed across the original clamped edges) 1271 // not bleed across the original clamped edges)
1272 srcRect.roundOut(&iClampRect); 1272 srcRect.roundOut(&iClampRect);
1273 } 1273 }
1274 1274
1275 clamped_unit_outset_with_offset(&iTileR, &offset, iClampRect); 1275 clamped_unit_outset_with_offset(&iTileR, &offset, iClampRect);
1276 } 1276 }
1277 1277
1278 if (bitmap.extractSubset(&tmpB, iTileR)) { 1278 if (bitmap.extractSubset(&tmpB, iTileR)) {
1279 // now offset it to make it "local" to our tmp bitmap 1279 // now offset it to make it "local" to our tmp bitmap
1280 tileR.offset(-offset.fX, -offset.fY); 1280 tileR.offset(-offset.fX, -offset.fY);
1281 SkMatrix tmpM(m); 1281 SkMatrix tmpM;
1282 tmpM.preTranslate(offset.fX, offset.fY); 1282 tmpM.setTranslate(offset.fX, offset.fY);
1283 1283 GrContext::AutoMatrix am;
1284 this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint, flags ); 1284 am.setPreConcat(fContext, tmpM);
1285 this->internalDrawBitmap(tmpB, tileR, params, paint, flags);
1285 } 1286 }
1286 } 1287 }
1287 } 1288 }
1288 } 1289 }
1289 1290
1290 static bool has_aligned_samples(const SkRect& srcRect, 1291 static bool has_aligned_samples(const SkRect& srcRect,
1291 const SkRect& transformedRect) { 1292 const SkRect& transformedRect) {
1292 // detect pixel disalignment 1293 // detect pixel disalignment
1293 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - 1294 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) -
1294 transformedRect.left()) < COLOR_BLEED_TOLERANCE && 1295 transformedRect.left()) < COLOR_BLEED_TOLERANCE &&
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 1332
1332 /* 1333 /*
1333 * This is called by drawBitmap(), which has to handle images that may be too 1334 * This is called by drawBitmap(), which has to handle images that may be too
1334 * large to be represented by a single texture. 1335 * large to be represented by a single texture.
1335 * 1336 *
1336 * internalDrawBitmap assumes that the specified bitmap will fit in a texture 1337 * internalDrawBitmap assumes that the specified bitmap will fit in a texture
1337 * and that non-texture portion of the GrPaint has already been setup. 1338 * and that non-texture portion of the GrPaint has already been setup.
1338 */ 1339 */
1339 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, 1340 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
1340 const SkRect& srcRect, 1341 const SkRect& srcRect,
1341 const SkMatrix& m,
1342 const GrTextureParams& params, 1342 const GrTextureParams& params,
1343 const SkPaint& paint, 1343 const SkPaint& paint,
1344 SkCanvas::DrawBitmapRectFlags flags) { 1344 SkCanvas::DrawBitmapRectFlags flags) {
1345 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && 1345 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
1346 bitmap.height() <= fContext->getMaxTextureSize()); 1346 bitmap.height() <= fContext->getMaxTextureSize());
1347 1347
1348 GrTexture* texture; 1348 GrTexture* texture;
1349 SkAutoCachedTexture act(this, bitmap, &params, &texture); 1349 SkAutoCachedTexture act(this, bitmap, &params, &texture);
1350 if (NULL == texture) { 1350 if (NULL == texture) {
1351 return; 1351 return;
1352 } 1352 }
1353 1353
1354 SkRect dstRect(srcRect); 1354 SkRect dstRect(srcRect);
1355 SkRect paintRect; 1355 SkRect paintRect;
1356 SkScalar wInv = SkScalarInvert(SkIntToScalar(bitmap.width())); 1356 SkScalar wInv = SkScalarInvert(SkIntToScalar(bitmap.width()));
1357 SkScalar hInv = SkScalarInvert(SkIntToScalar(bitmap.height())); 1357 SkScalar hInv = SkScalarInvert(SkIntToScalar(bitmap.height()));
1358 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), 1358 paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv),
1359 SkScalarMul(srcRect.fTop, hInv), 1359 SkScalarMul(srcRect.fTop, hInv),
1360 SkScalarMul(srcRect.fRight, wInv), 1360 SkScalarMul(srcRect.fRight, wInv),
1361 SkScalarMul(srcRect.fBottom, hInv)); 1361 SkScalarMul(srcRect.fBottom, hInv));
1362 1362
1363 bool needsTextureDomain = false; 1363 bool needsTextureDomain = false;
1364 if (!(flags & SkCanvas::kBleed_DrawBitmapRectFlag) && 1364 if (!(flags & SkCanvas::kBleed_DrawBitmapRectFlag) &&
1365 params.filterMode() != GrTextureParams::kNone_FilterMode) { 1365 params.filterMode() != GrTextureParams::kNone_FilterMode) {
1366 // Need texture domain if drawing a sub rect. 1366 // Need texture domain if drawing a sub rect.
1367 needsTextureDomain = srcRect.width() < bitmap.width() || 1367 needsTextureDomain = srcRect.width() < bitmap.width() ||
1368 srcRect.height() < bitmap.height(); 1368 srcRect.height() < bitmap.height();
1369 if (needsTextureDomain && m.rectStaysRect() && fContext->getMatrix().rec tStaysRect()) { 1369 if (needsTextureDomain && fContext->getMatrix().rectStaysRect()) {
1370 const SkMatrix& matrix = fContext->getMatrix();
1370 // sampling is axis-aligned 1371 // sampling is axis-aligned
1371 SkRect transformedRect; 1372 SkRect transformedRect;
1372 SkMatrix srcToDeviceMatrix(m); 1373 matrix.mapRect(&transformedRect, srcRect);
1373 srcToDeviceMatrix.postConcat(fContext->getMatrix()); 1374
1374 srcToDeviceMatrix.mapRect(&transformedRect, srcRect);
1375
1376 if (has_aligned_samples(srcRect, transformedRect)) { 1375 if (has_aligned_samples(srcRect, transformedRect)) {
1377 // We could also turn off filtering here (but we already did a c ache lookup with 1376 // We could also turn off filtering here (but we already did a c ache lookup with
1378 // params). 1377 // params).
1379 needsTextureDomain = false; 1378 needsTextureDomain = false;
1380 } else { 1379 } else {
1381 needsTextureDomain = may_color_bleed(srcRect, transformedRect, m ); 1380 needsTextureDomain = may_color_bleed(srcRect, transformedRect, m atrix);
1382 } 1381 }
1383 } 1382 }
1384 } 1383 }
1385 1384
1386 SkRect textureDomain = SkRect::MakeEmpty(); 1385 SkRect textureDomain = SkRect::MakeEmpty();
1387 SkAutoTUnref<GrEffectRef> effect; 1386 SkAutoTUnref<GrEffectRef> effect;
1388 if (needsTextureDomain) { 1387 if (needsTextureDomain) {
1389 // Use a constrained texture domain to avoid color bleeding 1388 // Use a constrained texture domain to avoid color bleeding
1390 SkScalar left, top, right, bottom; 1389 SkScalar left, top, right, bottom;
1391 if (srcRect.width() > SK_Scalar1) { 1390 if (srcRect.width() > SK_Scalar1) {
(...skipping 22 matching lines...) Expand all
1414 1413
1415 // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring 1414 // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
1416 // the rest from the SkPaint. 1415 // the rest from the SkPaint.
1417 GrPaint grPaint; 1416 GrPaint grPaint;
1418 grPaint.addColorEffect(effect); 1417 grPaint.addColorEffect(effect);
1419 bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config()); 1418 bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config());
1420 if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) { 1419 if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) {
1421 return; 1420 return;
1422 } 1421 }
1423 1422
1424 fContext->drawRectToRect(grPaint, dstRect, paintRect, &m); 1423 fContext->drawRectToRect(grPaint, dstRect, paintRect, NULL);
1425 } 1424 }
1426 1425
1427 static bool filter_texture(SkBaseDevice* device, GrContext* context, 1426 static bool filter_texture(SkBaseDevice* device, GrContext* context,
1428 GrTexture* texture, SkImageFilter* filter, 1427 GrTexture* texture, SkImageFilter* filter,
1429 int w, int h, const SkMatrix& ctm, SkBitmap* result, 1428 int w, int h, const SkMatrix& ctm, SkBitmap* result,
1430 SkIPoint* offset) { 1429 SkIPoint* offset) {
1431 SkASSERT(filter); 1430 SkASSERT(filter);
1432 SkDeviceImageFilterProxy proxy(device); 1431 SkDeviceImageFilterProxy proxy(device);
1433 1432
1434 if (filter->canFilterImageGPU()) { 1433 if (filter->canFilterImageGPU()) {
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 GrTexture* texture, 1846 GrTexture* texture,
1848 bool needClear) 1847 bool needClear)
1849 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { 1848 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) {
1850 1849
1851 SkASSERT(texture && texture->asRenderTarget()); 1850 SkASSERT(texture && texture->asRenderTarget());
1852 // This constructor is called from onCreateCompatibleDevice. It has locked t he RT in the texture 1851 // This constructor is called from onCreateCompatibleDevice. It has locked t he RT in the texture
1853 // cache. We pass true for the third argument so that it will get unlocked. 1852 // cache. We pass true for the third argument so that it will get unlocked.
1854 this->initFromRenderTarget(context, texture->asRenderTarget(), true); 1853 this->initFromRenderTarget(context, texture->asRenderTarget(), true);
1855 fNeedClear = needClear; 1854 fNeedClear = needClear;
1856 } 1855 }
OLDNEW
« no previous file with comments | « src/core/SkImageFilterUtils.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698