| 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 |