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

Side by Side Diff: src/core/SkCanvas.cpp

Issue 2155063002: use special-image for imagefilters and save/restore layer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: address comments Created 4 years, 5 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
« no previous file with comments | « include/core/SkCanvas.h ('k') | src/core/SkSpecialImage.cpp » ('j') | 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 2008 The Android Open Source Project 2 * Copyright 2008 The Android Open Source Project
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 "SkBitmapDevice.h" 8 #include "SkBitmapDevice.h"
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkCanvasPriv.h" 10 #include "SkCanvasPriv.h"
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 SaveLayerRec rec(origRec); 1139 SaveLayerRec rec(origRec);
1140 if (gIgnoreSaveLayerBounds) { 1140 if (gIgnoreSaveLayerBounds) {
1141 rec.fBounds = nullptr; 1141 rec.fBounds = nullptr;
1142 } 1142 }
1143 SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec); 1143 SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec);
1144 fSaveCount += 1; 1144 fSaveCount += 1;
1145 this->internalSaveLayer(rec, strategy); 1145 this->internalSaveLayer(rec, strategy);
1146 return this->getSaveCount() - 1; 1146 return this->getSaveCount() - 1;
1147 } 1147 }
1148 1148
1149 static void draw_filter_into_device(SkBaseDevice* src, const SkImageFilter* filt er, 1149 void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt er,
1150 SkBaseDevice* dst, const SkMatrix& ctm) { 1150 SkBaseDevice* dst, const SkMatrix& ctm,
1151 1151 const SkClipStack* clipStack) {
1152 SkBitmap srcBM; 1152 SkDraw draw;
1153 1153 SkRasterClip rc;
1154 #if SK_SUPPORT_GPU 1154 rc.setRect(SkIRect::MakeWH(dst->width(), dst->height()));
1155 // TODO: remove this virtual usage of accessRenderTarget! It is preventing 1155 if (!dst->accessPixels(&draw.fDst)) {
1156 // removal of the virtual on SkBaseDevice. 1156 draw.fDst.reset(dst->imageInfo(), nullptr, 0);
1157 GrRenderTarget* srcRT = src->accessRenderTarget();
1158 if (srcRT && !srcRT->asTexture() && dst->accessRenderTarget()) {
1159 // When both the src & the dst are on the gpu but the src doesn't have a texture,
1160 // we create a temporary texture for the draw.
1161 // TODO: we should actually only copy the portion of the source needed t o apply the image
1162 // filter
1163 GrContext* context = srcRT->getContext();
1164 SkAutoTUnref<GrTexture> tex(context->textureProvider()->createTexture(sr cRT->desc(),
1165 Sk Budgeted::kYes));
1166
1167 context->copySurface(tex, srcRT);
1168
1169 GrWrapTextureInBitmap(tex, src->width(), src->height(), src->isOpaque(), &srcBM);
1170 } else
1171 #endif
1172 {
1173 srcBM = src->accessBitmap(false);
1174 } 1157 }
1175 1158 draw.fMatrix = &SkMatrix::I();
1176 SkCanvas c(dst); 1159 draw.fRC = &rc;
1160 draw.fClipStack = clipStack;
1161 draw.fDevice = dst;
1177 1162
1178 SkPaint p; 1163 SkPaint p;
1179 p.setImageFilter(filter->makeWithLocalMatrix(ctm)); 1164 p.setImageFilter(filter->makeWithLocalMatrix(ctm));
1180 const SkScalar x = SkIntToScalar(src->getOrigin().x()); 1165
1181 const SkScalar y = SkIntToScalar(src->getOrigin().y()); 1166 int x = src->getOrigin().x() - dst->getOrigin().x();
1182 c.drawBitmap(srcBM, x, y, &p); 1167 int y = src->getOrigin().y() - dst->getOrigin().y();
1168 auto special = src->snapSpecial();
1169 if (special) {
1170 dst->drawSpecial(draw, special.get(), x, y, p);
1171 }
1183 } 1172 }
1184 1173
1185 static SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, bool i sOpaque, 1174 static SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, bool i sOpaque,
1186 const SkPaint* paint) { 1175 const SkPaint* paint) {
1187 // need to force L32 for now if we have an image filter. Once filters suppor t other colortypes 1176 // need to force L32 for now if we have an image filter. Once filters suppor t other colortypes
1188 // e.g. sRGB or F16, we can remove this check 1177 // e.g. sRGB or F16, we can remove this check
1189 // SRGBTODO: Can we remove this check now? 1178 // SRGBTODO: Can we remove this check now?
1190 const bool hasImageFilter = paint && paint->getImageFilter(); 1179 const bool hasImageFilter = paint && paint->getImageFilter();
1191 1180
1192 SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType ; 1181 SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType ;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 SkPixelGeometry geo = fProps.pixelGeometry(); 1252 SkPixelGeometry geo = fProps.pixelGeometry();
1264 if (paint) { 1253 if (paint) {
1265 // TODO: perhaps add a query to filters so we might preserve opaqueness. .. 1254 // TODO: perhaps add a query to filters so we might preserve opaqueness. ..
1266 if (paint->getImageFilter() || paint->getColorFilter()) { 1255 if (paint->getImageFilter() || paint->getColorFilter()) {
1267 isOpaque = false; 1256 isOpaque = false;
1268 geo = kUnknown_SkPixelGeometry; 1257 geo = kUnknown_SkPixelGeometry;
1269 } 1258 }
1270 } 1259 }
1271 1260
1272 SkBaseDevice* priorDevice = this->getTopDevice(); 1261 SkBaseDevice* priorDevice = this->getTopDevice();
1273 if (!priorDevice) { 1262 if (nullptr == priorDevice) {
1274 SkDebugf("Unable to find device for layer."); 1263 SkDebugf("Unable to find device for layer.");
1275 return; 1264 return;
1276 } 1265 }
1277 1266
1278 SkImageInfo info = make_layer_info(priorDevice->imageInfo(), ir.width(), ir. height(), isOpaque, 1267 SkImageInfo info = make_layer_info(priorDevice->imageInfo(), ir.width(), ir. height(), isOpaque,
1279 paint); 1268 paint);
1280 1269
1281 SkAutoTUnref<SkBaseDevice> newDevice; 1270 SkAutoTUnref<SkBaseDevice> newDevice;
1282 { 1271 {
1283 const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 1272 const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() ||
1284 (saveLayerFlags & kPreserveLCDText_SaveLaye rFlag); 1273 (saveLayerFlags & kPreserveLCDText_SaveLaye rFlag);
1285 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 1274 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage;
1286 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf o, usage, geo, 1275 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf o, usage, geo,
1287 pre serveLCDText); 1276 pre serveLCDText);
1288 newDevice.reset(priorDevice->onCreateDevice(createInfo, paint)); 1277 newDevice.reset(priorDevice->onCreateDevice(createInfo, paint));
1289 if (!newDevice) { 1278 if (!newDevice) {
1290 SkErrorInternals::SetError(kInternalError_SkError, 1279 SkErrorInternals::SetError(kInternalError_SkError,
1291 "Unable to create device for layer."); 1280 "Unable to create device for layer.");
1292 return; 1281 return;
1293 } 1282 }
1294 } 1283 }
1295 newDevice->setOrigin(ir.fLeft, ir.fTop); 1284 newDevice->setOrigin(ir.fLeft, ir.fTop);
1296 1285
1297 if (rec.fBackdrop) {
1298 draw_filter_into_device(priorDevice, rec.fBackdrop, newDevice, fMCRec->f Matrix);
1299 }
1300
1301 DeviceCM* layer = new DeviceCM(newDevice, paint, this, fConservativeRasterCl ip, stashedMatrix); 1286 DeviceCM* layer = new DeviceCM(newDevice, paint, this, fConservativeRasterCl ip, stashedMatrix);
1302 1287
1303 layer->fNext = fMCRec->fTopLayer; 1288 layer->fNext = fMCRec->fTopLayer;
1304 fMCRec->fLayer = layer; 1289 fMCRec->fLayer = layer;
1305 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1290 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer
1291
1292 if (rec.fBackdrop) {
1293 DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice,
1294 fMCRec->fMatrix, this->getClipStack());
1295 }
1306 } 1296 }
1307 1297
1308 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1298 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
1309 if (0xFF == alpha) { 1299 if (0xFF == alpha) {
1310 return this->saveLayer(bounds, nullptr); 1300 return this->saveLayer(bounds, nullptr);
1311 } else { 1301 } else {
1312 SkPaint tmpPaint; 1302 SkPaint tmpPaint;
1313 tmpPaint.setAlpha(alpha); 1303 tmpPaint.setAlpha(alpha);
1314 return this->saveLayer(bounds, &tmpPaint); 1304 return this->saveLayer(bounds, &tmpPaint);
1315 } 1305 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 1435
1446 ///////////////////////////////////////////////////////////////////////////// 1436 /////////////////////////////////////////////////////////////////////////////
1447 1437
1448 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa int* paint) { 1438 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa int* paint) {
1449 SkPaint tmp; 1439 SkPaint tmp;
1450 if (nullptr == paint) { 1440 if (nullptr == paint) {
1451 paint = &tmp; 1441 paint = &tmp;
1452 } 1442 }
1453 1443
1454 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1444 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type)
1445
1455 while (iter.next()) { 1446 while (iter.next()) {
1456 SkBaseDevice* dstDev = iter.fDevice; 1447 SkBaseDevice* dstDev = iter.fDevice;
1457 paint = &looper.paint(); 1448 paint = &looper.paint();
1458 SkImageFilter* filter = paint->getImageFilter(); 1449 SkImageFilter* filter = paint->getImageFilter();
1459 SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 1450 SkIPoint pos = { x - iter.getX(), y - iter.getY() };
1460 if (filter) { 1451 if (filter) {
1461 const SkBitmap& srcBM = srcDev->accessBitmap(false); 1452 dstDev->drawSpecial(iter, srcDev->snapSpecial().get(), pos.x(), pos. y(), *paint);
1462 dstDev->drawSpriteWithFilter(iter, srcBM, pos.x(), pos.y(), *paint);
1463 } else { 1453 } else {
1464 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 1454 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint);
1465 } 1455 }
1466 } 1456 }
1457
1467 LOOPER_END 1458 LOOPER_END
1468 } 1459 }
1469 1460
1470 ///////////////////////////////////////////////////////////////////////////// 1461 /////////////////////////////////////////////////////////////////////////////
1471 1462
1472 void SkCanvas::translate(SkScalar dx, SkScalar dy) { 1463 void SkCanvas::translate(SkScalar dx, SkScalar dy) {
1473 SkMatrix m; 1464 SkMatrix m;
1474 m.setTranslate(dx, dy); 1465 m.setTranslate(dx, dy);
1475 this->concat(m); 1466 this->concat(m);
1476 } 1467 }
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after
2304 if (this->quickReject(tmp)) { 2295 if (this->quickReject(tmp)) {
2305 return; 2296 return;
2306 } 2297 }
2307 } 2298 }
2308 2299
2309 SkLazyPaint lazy; 2300 SkLazyPaint lazy;
2310 if (nullptr == paint) { 2301 if (nullptr == paint) {
2311 paint = lazy.init(); 2302 paint = lazy.init();
2312 } 2303 }
2313 2304
2305 sk_sp<SkSpecialImage> special;
2314 bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image- >height(), 2306 bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image- >height(),
2315 *paint); 2307 *paint);
2316 if (drawAsSprite && paint->getImageFilter()) { 2308 if (drawAsSprite && paint->getImageFilter()) {
2317 SkBitmap bitmap; 2309 special = this->getDevice()->makeSpecial(image);
2318 if (!as_IB(image)->asBitmapForImageFilters(&bitmap)) { 2310 if (!special) {
2319 drawAsSprite = false; 2311 drawAsSprite = false;
2320 } else{
2321 // Until imagefilters are updated, they cannot handle any src type b ut N32...
2322 if (bitmap.info().colorType() != kN32_SkColorType || bitmap.info().g ammaCloseToSRGB()) {
2323 drawAsSprite = false;
2324 }
2325 } 2312 }
2326 } 2313 }
2327 2314
2328 LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 2315 LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds)
2329 2316
2330 while (iter.next()) { 2317 while (iter.next()) {
2331 const SkPaint& pnt = looper.paint(); 2318 const SkPaint& pnt = looper.paint();
2332 if (drawAsSprite && pnt.getImageFilter()) { 2319 if (special) {
2333 SkBitmap bitmap; 2320 SkPoint pt;
2334 if (as_IB(image)->asBitmapForImageFilters(&bitmap)) { 2321 iter.fMatrix->mapXY(x, y, &pt);
2335 SkPoint pt; 2322 iter.fDevice->drawSpecial(iter, special.get(),
2336 iter.fMatrix->mapXY(x, y, &pt); 2323 SkScalarRoundToInt(pt.fX),
2337 iter.fDevice->drawSpriteWithFilter(iter, bitmap, 2324 SkScalarRoundToInt(pt.fY), pnt);
2338 SkScalarRoundToInt(pt.fX),
2339 SkScalarRoundToInt(pt.fY), pn t);
2340 }
2341 } else { 2325 } else {
2342 iter.fDevice->drawImage(iter, image, x, y, pnt); 2326 iter.fDevice->drawImage(iter, image, x, y, pnt);
2343 } 2327 }
2344 } 2328 }
2345 2329
2346 LOOPER_END 2330 LOOPER_END
2347 } 2331 }
2348 2332
2349 void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk Rect& dst, 2333 void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk Rect& dst,
2350 const SkPaint* paint, SrcRectConstraint constrain t) { 2334 const SkPaint* paint, SrcRectConstraint constrain t) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2393 if (paint->canComputeFastBounds()) { 2377 if (paint->canComputeFastBounds()) {
2394 bitmap.getBounds(&storage); 2378 bitmap.getBounds(&storage);
2395 matrix.mapRect(&storage); 2379 matrix.mapRect(&storage);
2396 SkRect tmp = storage; 2380 SkRect tmp = storage;
2397 if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { 2381 if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) {
2398 return; 2382 return;
2399 } 2383 }
2400 bounds = &storage; 2384 bounds = &storage;
2401 } 2385 }
2402 2386
2387 sk_sp<SkSpecialImage> special;
2403 bool drawAsSprite = bounds && this->canDrawBitmapAsSprite(x, y, bitmap.width (), bitmap.height(), 2388 bool drawAsSprite = bounds && this->canDrawBitmapAsSprite(x, y, bitmap.width (), bitmap.height(),
2404 *paint); 2389 *paint);
2405 if (drawAsSprite && paint->getImageFilter()) { 2390 if (drawAsSprite && paint->getImageFilter()) {
2406 // Until imagefilters are updated, they cannot handle any src type but N 32... 2391 special = this->getDevice()->makeSpecial(bitmap);
2407 if (bitmap.info().colorType() != kN32_SkColorType || bitmap.info().gamma CloseToSRGB()) { 2392 if (!special) {
2408 drawAsSprite = false; 2393 drawAsSprite = false;
2409 } 2394 }
2410 } 2395 }
2411 2396
2412 LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, bounds) 2397 LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, bounds)
2413 2398
2414 while (iter.next()) { 2399 while (iter.next()) {
2415 const SkPaint& pnt = looper.paint(); 2400 const SkPaint& pnt = looper.paint();
2416 if (drawAsSprite && pnt.getImageFilter()) { 2401 if (special) {
2417 SkPoint pt; 2402 SkPoint pt;
2418 iter.fMatrix->mapXY(x, y, &pt); 2403 iter.fMatrix->mapXY(x, y, &pt);
2419 iter.fDevice->drawSpriteWithFilter(iter, bitmap, 2404 iter.fDevice->drawSpecial(iter, special.get(),
2420 SkScalarRoundToInt(pt.fX), 2405 SkScalarRoundToInt(pt.fX),
2421 SkScalarRoundToInt(pt.fY), pnt); 2406 SkScalarRoundToInt(pt.fY), pnt);
2422 } else { 2407 } else {
2423 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 2408 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint());
2424 } 2409 }
2425 } 2410 }
2426 2411
2427 LOOPER_END 2412 LOOPER_END
2428 } 2413 }
2429 2414
2430 // this one is non-virtual, so it can be called safely by other canvas apis 2415 // this one is non-virtual, so it can be called safely by other canvas apis
2431 void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2416 void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
2432 const SkRect& dst, const SkPaint* paint, 2417 const SkRect& dst, const SkPaint* paint,
2433 SrcRectConstraint constraint) { 2418 SrcRectConstraint constraint) {
2434 if (bitmap.drawsNothing() || dst.isEmpty()) { 2419 if (bitmap.drawsNothing() || dst.isEmpty()) {
2435 return; 2420 return;
2436 } 2421 }
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
3118 3103
3119 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3104 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
3120 fCanvas->restoreToCount(fSaveCount); 3105 fCanvas->restoreToCount(fSaveCount);
3121 } 3106 }
3122 3107
3123 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API 3108 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API
3124 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) { 3109 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) {
3125 return this->makeSurface(info, props).release(); 3110 return this->makeSurface(info, props).release();
3126 } 3111 }
3127 #endif 3112 #endif
OLDNEW
« no previous file with comments | « include/core/SkCanvas.h ('k') | src/core/SkSpecialImage.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698