| 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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 by the device's XY offset and bitmap-bounds. | 193 by the device's XY offset and bitmap-bounds. |
| 194 */ | 194 */ |
| 195 struct DeviceCM { | 195 struct DeviceCM { |
| 196 DeviceCM* fNext; | 196 DeviceCM* fNext; |
| 197 SkBaseDevice* fDevice; | 197 SkBaseDevice* fDevice; |
| 198 SkRasterClip fClip; | 198 SkRasterClip fClip; |
| 199 SkPaint* fPaint; // may be null (in the future) | 199 SkPaint* fPaint; // may be null (in the future) |
| 200 const SkMatrix* fMatrix; | 200 const SkMatrix* fMatrix; |
| 201 SkMatrix fMatrixStorage; | 201 SkMatrix fMatrixStorage; |
| 202 SkMatrix fStashedMatrix; // original CTM; used by imagefilter in
saveLayer | 202 SkMatrix fStashedMatrix; // original CTM; used by imagefilter in
saveLayer |
| 203 const bool fDeviceIsBitmapDevice; | |
| 204 | 203 |
| 205 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, | 204 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, |
| 206 bool conservativeRasterClip, bool deviceIsBitmapDevice, const SkMat
rix& stashed) | 205 bool conservativeRasterClip, const SkMatrix& stashed) |
| 207 : fNext(nullptr) | 206 : fNext(nullptr) |
| 208 , fClip(conservativeRasterClip) | 207 , fClip(conservativeRasterClip) |
| 209 , fStashedMatrix(stashed) | 208 , fStashedMatrix(stashed) |
| 210 , fDeviceIsBitmapDevice(deviceIsBitmapDevice) | |
| 211 { | 209 { |
| 212 if (nullptr != device) { | 210 if (nullptr != device) { |
| 213 device->ref(); | 211 device->ref(); |
| 214 device->onAttachToCanvas(canvas); | 212 device->onAttachToCanvas(canvas); |
| 215 } | 213 } |
| 216 fDevice = device; | 214 fDevice = device; |
| 217 fPaint = paint ? new SkPaint(*paint) : nullptr; | 215 fPaint = paint ? new SkPaint(*paint) : nullptr; |
| 218 } | 216 } |
| 219 | 217 |
| 220 ~DeviceCM() { | 218 ~DeviceCM() { |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 fSaveCount = 1; | 664 fSaveCount = 1; |
| 667 fMetaData = nullptr; | 665 fMetaData = nullptr; |
| 668 | 666 |
| 669 fClipStack.reset(new SkClipStack); | 667 fClipStack.reset(new SkClipStack); |
| 670 | 668 |
| 671 fMCRec = (MCRec*)fMCStack.push_back(); | 669 fMCRec = (MCRec*)fMCStack.push_back(); |
| 672 new (fMCRec) MCRec(fConservativeRasterClip); | 670 new (fMCRec) MCRec(fConservativeRasterClip); |
| 673 | 671 |
| 674 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); | 672 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); |
| 675 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; | 673 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; |
| 676 new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRast
erClip, false, | 674 new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRast
erClip, |
| 677 fMCRec->fMatrix); | 675 fMCRec->fMatrix); |
| 678 | 676 |
| 679 fMCRec->fTopLayer = fMCRec->fLayer; | 677 fMCRec->fTopLayer = fMCRec->fLayer; |
| 680 | 678 |
| 681 fSurfaceBase = nullptr; | 679 fSurfaceBase = nullptr; |
| 682 | 680 |
| 683 if (device) { | 681 if (device) { |
| 684 // The root device and the canvas should always have the same pixel geom
etry | 682 // The root device and the canvas should always have the same pixel geom
etry |
| 685 SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry(
)); | 683 SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry(
)); |
| 686 device->onAttachToCanvas(this); | 684 device->onAttachToCanvas(this); |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1273 | 1271 |
| 1274 SkBaseDevice* device = this->getTopDevice(); | 1272 SkBaseDevice* device = this->getTopDevice(); |
| 1275 if (nullptr == device) { | 1273 if (nullptr == device) { |
| 1276 SkDebugf("Unable to find device for layer."); | 1274 SkDebugf("Unable to find device for layer."); |
| 1277 return; | 1275 return; |
| 1278 } | 1276 } |
| 1279 | 1277 |
| 1280 SkImageInfo info = make_layer_info(device->imageInfo(), ir.width(), ir.heigh
t(), isOpaque, | 1278 SkImageInfo info = make_layer_info(device->imageInfo(), ir.width(), ir.heigh
t(), isOpaque, |
| 1281 paint); | 1279 paint); |
| 1282 | 1280 |
| 1283 bool forceSpriteOnRestore = false; | |
| 1284 { | 1281 { |
| 1285 const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || | 1282 const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || |
| 1286 (saveLayerFlags & kPreserveLCDText_SaveLaye
rFlag); | 1283 (saveLayerFlags & kPreserveLCDText_SaveLaye
rFlag); |
| 1287 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; | 1284 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; |
| 1288 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf
o, usage, geo, | 1285 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf
o, usage, geo, |
| 1289 pre
serveLCDText); | 1286 pre
serveLCDText); |
| 1290 SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); | 1287 SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); |
| 1291 if (nullptr == newDev) { | 1288 if (nullptr == newDev) { |
| 1292 // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't h
andle the paint) | 1289 SkErrorInternals::SetError(kInternalError_SkError, |
| 1293 const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelG
eometry); | 1290 "Unable to create device for layer."); |
| 1294 newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps); | 1291 return; |
| 1295 if (nullptr == newDev) { | |
| 1296 SkErrorInternals::SetError(kInternalError_SkError, | |
| 1297 "Unable to create device for layer.")
; | |
| 1298 return; | |
| 1299 } | |
| 1300 forceSpriteOnRestore = true; | |
| 1301 } | 1292 } |
| 1302 device = newDev; | 1293 device = newDev; |
| 1303 } | 1294 } |
| 1304 device->setOrigin(ir.fLeft, ir.fTop); | 1295 device->setOrigin(ir.fLeft, ir.fTop); |
| 1305 | 1296 |
| 1306 if (rec.fBackdrop) { | 1297 if (rec.fBackdrop) { |
| 1307 draw_filter_into_device(fMCRec->fTopLayer->fDevice, rec.fBackdrop, devic
e, fMCRec->fMatrix); | 1298 draw_filter_into_device(fMCRec->fTopLayer->fDevice, rec.fBackdrop, devic
e, fMCRec->fMatrix); |
| 1308 } | 1299 } |
| 1309 | 1300 |
| 1310 DeviceCM* layer = new DeviceCM(device, paint, this, fConservativeRasterClip, | 1301 DeviceCM* layer = new DeviceCM(device, paint, this, fConservativeRasterClip,
stashedMatrix); |
| 1311 forceSpriteOnRestore, stashedMatrix); | |
| 1312 device->unref(); | 1302 device->unref(); |
| 1313 | 1303 |
| 1314 layer->fNext = fMCRec->fTopLayer; | 1304 layer->fNext = fMCRec->fTopLayer; |
| 1315 fMCRec->fLayer = layer; | 1305 fMCRec->fLayer = layer; |
| 1316 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer | 1306 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer |
| 1317 } | 1307 } |
| 1318 | 1308 |
| 1319 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { | 1309 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { |
| 1320 if (0xFF == alpha) { | 1310 if (0xFF == alpha) { |
| 1321 return this->saveLayer(bounds, nullptr); | 1311 return this->saveLayer(bounds, nullptr); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1344 fMCStack.pop_back(); | 1334 fMCStack.pop_back(); |
| 1345 fMCRec = (MCRec*)fMCStack.back(); | 1335 fMCRec = (MCRec*)fMCStack.back(); |
| 1346 | 1336 |
| 1347 /* Time to draw the layer's offscreen. We can't call the public drawSprite, | 1337 /* Time to draw the layer's offscreen. We can't call the public drawSprite, |
| 1348 since if we're being recorded, we don't want to record this (the | 1338 since if we're being recorded, we don't want to record this (the |
| 1349 recorder will have already recorded the restore). | 1339 recorder will have already recorded the restore). |
| 1350 */ | 1340 */ |
| 1351 if (layer) { | 1341 if (layer) { |
| 1352 if (layer->fNext) { | 1342 if (layer->fNext) { |
| 1353 const SkIPoint& origin = layer->fDevice->getOrigin(); | 1343 const SkIPoint& origin = layer->fDevice->getOrigin(); |
| 1354 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), | 1344 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), lay
er->fPaint); |
| 1355 layer->fPaint, layer->fDeviceIsBitmapDevice
); | |
| 1356 // restore what we smashed in internalSaveLayer | 1345 // restore what we smashed in internalSaveLayer |
| 1357 fMCRec->fMatrix = layer->fStashedMatrix; | 1346 fMCRec->fMatrix = layer->fStashedMatrix; |
| 1358 // reset this, since internalDrawDevice will have set it to true | 1347 // reset this, since internalDrawDevice will have set it to true |
| 1359 fDeviceCMDirty = true; | 1348 fDeviceCMDirty = true; |
| 1360 delete layer; | 1349 delete layer; |
| 1361 } else { | 1350 } else { |
| 1362 // we're at the root | 1351 // we're at the root |
| 1363 SkASSERT(layer == (void*)fDeviceCMStorage); | 1352 SkASSERT(layer == (void*)fDeviceCMStorage); |
| 1364 layer->~DeviceCM(); | 1353 layer->~DeviceCM(); |
| 1365 // no need to update fMCRec, 'cause we're killing the canvas | 1354 // no need to update fMCRec, 'cause we're killing the canvas |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1450 return pmap.writable_addr(); | 1439 return pmap.writable_addr(); |
| 1451 } | 1440 } |
| 1452 | 1441 |
| 1453 bool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { | 1442 bool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { |
| 1454 SkBaseDevice* dev = this->getTopDevice(); | 1443 SkBaseDevice* dev = this->getTopDevice(); |
| 1455 return dev && dev->accessPixels(pmap); | 1444 return dev && dev->accessPixels(pmap); |
| 1456 } | 1445 } |
| 1457 | 1446 |
| 1458 ///////////////////////////////////////////////////////////////////////////// | 1447 ///////////////////////////////////////////////////////////////////////////// |
| 1459 | 1448 |
| 1460 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, | 1449 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa
int* paint) { |
| 1461 const SkPaint* paint, bool deviceIsBitmapDevic
e) { | |
| 1462 SkPaint tmp; | 1450 SkPaint tmp; |
| 1463 if (nullptr == paint) { | 1451 if (nullptr == paint) { |
| 1464 paint = &tmp; | 1452 paint = &tmp; |
| 1465 } | 1453 } |
| 1466 | 1454 |
| 1467 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) | 1455 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) |
| 1468 while (iter.next()) { | 1456 while (iter.next()) { |
| 1469 SkBaseDevice* dstDev = iter.fDevice; | 1457 SkBaseDevice* dstDev = iter.fDevice; |
| 1470 paint = &looper.paint(); | 1458 paint = &looper.paint(); |
| 1471 SkImageFilter* filter = paint->getImageFilter(); | 1459 SkImageFilter* filter = paint->getImageFilter(); |
| 1472 SkIPoint pos = { x - iter.getX(), y - iter.getY() }; | 1460 SkIPoint pos = { x - iter.getX(), y - iter.getY() }; |
| 1473 if (filter) { | 1461 if (filter) { |
| 1474 const SkBitmap& srcBM = srcDev->accessBitmap(false); | 1462 const SkBitmap& srcBM = srcDev->accessBitmap(false); |
| 1475 dstDev->drawSpriteWithFilter(iter, srcBM, pos.x(), pos.y(), *paint); | 1463 dstDev->drawSpriteWithFilter(iter, srcBM, pos.x(), pos.y(), *paint); |
| 1476 } else if (deviceIsBitmapDevice) { | |
| 1477 const SkBitmap& src = static_cast<SkBitmapDevice*>(srcDev)->fBitmap; | |
| 1478 dstDev->drawSprite(iter, src, pos.x(), pos.y(), *paint); | |
| 1479 } else { | 1464 } else { |
| 1480 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); | 1465 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); |
| 1481 } | 1466 } |
| 1482 } | 1467 } |
| 1483 LOOPER_END | 1468 LOOPER_END |
| 1484 } | 1469 } |
| 1485 | 1470 |
| 1486 ///////////////////////////////////////////////////////////////////////////// | 1471 ///////////////////////////////////////////////////////////////////////////// |
| 1487 | 1472 |
| 1488 void SkCanvas::translate(SkScalar dx, SkScalar dy) { | 1473 void SkCanvas::translate(SkScalar dx, SkScalar dy) { |
| (...skipping 1645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3134 | 3119 |
| 3135 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 3120 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
| 3136 fCanvas->restoreToCount(fSaveCount); | 3121 fCanvas->restoreToCount(fSaveCount); |
| 3137 } | 3122 } |
| 3138 | 3123 |
| 3139 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API | 3124 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API |
| 3140 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { | 3125 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { |
| 3141 return this->makeSurface(info, props).release(); | 3126 return this->makeSurface(info, props).release(); |
| 3142 } | 3127 } |
| 3143 #endif | 3128 #endif |
| OLD | NEW |