OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |