| 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 "SkCanvas.h" | 8 #include "SkCanvas.h" |
| 9 #include "SkCanvasPriv.h" | 9 #include "SkCanvasPriv.h" |
| 10 #include "SkBitmapDevice.h" | 10 #include "SkBitmapDevice.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 The clip/matrix/proc are fields that reflect the top of the save/restore | 104 The clip/matrix/proc are fields that reflect the top of the save/restore |
| 105 stack. Whenever the canvas changes, it marks a dirty flag, and then before | 105 stack. Whenever the canvas changes, it marks a dirty flag, and then before |
| 106 these are used (assuming we're not on a layer) we rebuild these cache | 106 these are used (assuming we're not on a layer) we rebuild these cache |
| 107 values: they reflect the top of the save stack, but translated and clipped | 107 values: they reflect the top of the save stack, but translated and clipped |
| 108 by the device's XY offset and bitmap-bounds. | 108 by the device's XY offset and bitmap-bounds. |
| 109 */ | 109 */ |
| 110 struct DeviceCM { | 110 struct DeviceCM { |
| 111 DeviceCM* fNext; | 111 DeviceCM* fNext; |
| 112 SkBaseDevice* fDevice; | 112 SkBaseDevice* fDevice; |
| 113 SkRasterClip fClip; | 113 SkRasterClip fClip; |
| 114 SkPaint* fPaint; // may be null (in the future) |
| 114 const SkMatrix* fMatrix; | 115 const SkMatrix* fMatrix; |
| 115 SkPaint* fPaint; // may be null (in the future) | 116 SkMatrix fMatrixStorage; |
| 117 const bool fDeviceIsBitmapDevice; |
| 116 | 118 |
| 117 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, | 119 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, |
| 118 bool conservativeRasterClip) | 120 bool conservativeRasterClip, bool deviceIsBitmapDevice) |
| 119 : fNext(NULL) | 121 : fNext(NULL) |
| 120 , fClip(conservativeRasterClip) | 122 , fClip(conservativeRasterClip) |
| 123 , fDeviceIsBitmapDevice(deviceIsBitmapDevice) |
| 121 { | 124 { |
| 122 if (NULL != device) { | 125 if (NULL != device) { |
| 123 device->ref(); | 126 device->ref(); |
| 124 device->onAttachToCanvas(canvas); | 127 device->onAttachToCanvas(canvas); |
| 125 } | 128 } |
| 126 fDevice = device; | 129 fDevice = device; |
| 127 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; | 130 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; |
| 128 } | 131 } |
| 129 | 132 |
| 130 ~DeviceCM() { | 133 ~DeviceCM() { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); | 176 fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); |
| 174 | 177 |
| 175 #ifdef SK_DEBUG | 178 #ifdef SK_DEBUG |
| 176 if (!fClip.isEmpty()) { | 179 if (!fClip.isEmpty()) { |
| 177 SkIRect deviceR; | 180 SkIRect deviceR; |
| 178 deviceR.set(0, 0, width, height); | 181 deviceR.set(0, 0, width, height); |
| 179 SkASSERT(deviceR.contains(fClip.getBounds())); | 182 SkASSERT(deviceR.contains(fClip.getBounds())); |
| 180 } | 183 } |
| 181 #endif | 184 #endif |
| 182 } | 185 } |
| 183 | |
| 184 private: | |
| 185 SkMatrix fMatrixStorage; | |
| 186 }; | 186 }; |
| 187 | 187 |
| 188 /* This is the record we keep for each save/restore level in the stack. | 188 /* This is the record we keep for each save/restore level in the stack. |
| 189 Since a level optionally copies the matrix and/or stack, we have pointers | 189 Since a level optionally copies the matrix and/or stack, we have pointers |
| 190 for these fields. If the value is copied for this level, the copy is | 190 for these fields. If the value is copied for this level, the copy is |
| 191 stored in the ...Storage field, and the pointer points to that. If the | 191 stored in the ...Storage field, and the pointer points to that. If the |
| 192 value is not copied for this level, we ignore ...Storage, and just point | 192 value is not copied for this level, we ignore ...Storage, and just point |
| 193 at the corresponding value in the previous level in the stack. | 193 at the corresponding value in the previous level in the stack. |
| 194 */ | 194 */ |
| 195 class SkCanvas::MCRec { | 195 class SkCanvas::MCRec { |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 fSaveCount = 1; | 479 fSaveCount = 1; |
| 480 fMetaData = NULL; | 480 fMetaData = NULL; |
| 481 | 481 |
| 482 fClipStack.reset(SkNEW(SkClipStack)); | 482 fClipStack.reset(SkNEW(SkClipStack)); |
| 483 | 483 |
| 484 fMCRec = (MCRec*)fMCStack.push_back(); | 484 fMCRec = (MCRec*)fMCStack.push_back(); |
| 485 new (fMCRec) MCRec(fConservativeRasterClip); | 485 new (fMCRec) MCRec(fConservativeRasterClip); |
| 486 | 486 |
| 487 SkASSERT(sizeof(DeviceCM) <= sizeof(fBaseLayerStorage)); | 487 SkASSERT(sizeof(DeviceCM) <= sizeof(fBaseLayerStorage)); |
| 488 fMCRec->fLayer = (DeviceCM*)fBaseLayerStorage; | 488 fMCRec->fLayer = (DeviceCM*)fBaseLayerStorage; |
| 489 new (fBaseLayerStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip); | 489 new (fBaseLayerStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip,
false); |
| 490 | 490 |
| 491 fMCRec->fTopLayer = fMCRec->fLayer; | 491 fMCRec->fTopLayer = fMCRec->fLayer; |
| 492 | 492 |
| 493 fSurfaceBase = NULL; | 493 fSurfaceBase = NULL; |
| 494 | 494 |
| 495 if (device) { | 495 if (device) { |
| 496 device->initForRootLayer(fProps.pixelGeometry()); | 496 device->initForRootLayer(fProps.pixelGeometry()); |
| 497 if (device->forceConservativeRasterClip()) { | 497 if (device->forceConservativeRasterClip()) { |
| 498 fConservativeRasterClip = true; | 498 fConservativeRasterClip = true; |
| 499 } | 499 } |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 } | 978 } |
| 979 SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), | 979 SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), |
| 980 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); | 980 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); |
| 981 | 981 |
| 982 SkBaseDevice* device = this->getTopDevice(); | 982 SkBaseDevice* device = this->getTopDevice(); |
| 983 if (NULL == device) { | 983 if (NULL == device) { |
| 984 SkDebugf("Unable to find device for layer."); | 984 SkDebugf("Unable to find device for layer."); |
| 985 return; | 985 return; |
| 986 } | 986 } |
| 987 | 987 |
| 988 SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; | 988 bool forceSpriteOnRestore = false; |
| 989 device = device->onCreateDevice(SkBaseDevice::CreateInfo(info, usage, geo),
paint); | 989 { |
| 990 if (NULL == device) { | 990 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; |
| 991 SkErrorInternals::SetError( kInternalError_SkError, | 991 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf
o, usage, geo); |
| 992 "Unable to create device for layer."); | 992 SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); |
| 993 return; | 993 if (NULL == newDev) { |
| 994 // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't h
andle the paint) |
| 995 newDev = SkBitmapDevice::Create(createInfo.fInfo); |
| 996 if (NULL == newDev) { |
| 997 SkErrorInternals::SetError(kInternalError_SkError, |
| 998 "Unable to create device for layer.")
; |
| 999 return; |
| 1000 } |
| 1001 forceSpriteOnRestore = true; |
| 1002 } |
| 1003 device = newDev; |
| 994 } | 1004 } |
| 995 | 1005 |
| 996 device->setOrigin(ir.fLeft, ir.fTop); | 1006 device->setOrigin(ir.fLeft, ir.fTop); |
| 997 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa
sterClip)); | 1007 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa
sterClip, |
| 1008 forceSpriteOnRestore)); |
| 998 device->unref(); | 1009 device->unref(); |
| 999 | 1010 |
| 1000 layer->fNext = fMCRec->fTopLayer; | 1011 layer->fNext = fMCRec->fTopLayer; |
| 1001 fMCRec->fLayer = layer; | 1012 fMCRec->fLayer = layer; |
| 1002 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer | 1013 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer |
| 1003 } | 1014 } |
| 1004 | 1015 |
| 1005 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { | 1016 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { |
| 1006 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); | 1017 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); |
| 1007 } | 1018 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1036 fMCRec = (MCRec*)fMCStack.back(); | 1047 fMCRec = (MCRec*)fMCStack.back(); |
| 1037 | 1048 |
| 1038 /* Time to draw the layer's offscreen. We can't call the public drawSprite, | 1049 /* Time to draw the layer's offscreen. We can't call the public drawSprite, |
| 1039 since if we're being recorded, we don't want to record this (the | 1050 since if we're being recorded, we don't want to record this (the |
| 1040 recorder will have already recorded the restore). | 1051 recorder will have already recorded the restore). |
| 1041 */ | 1052 */ |
| 1042 if (layer) { | 1053 if (layer) { |
| 1043 if (layer->fNext) { | 1054 if (layer->fNext) { |
| 1044 const SkIPoint& origin = layer->fDevice->getOrigin(); | 1055 const SkIPoint& origin = layer->fDevice->getOrigin(); |
| 1045 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), | 1056 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), |
| 1046 layer->fPaint); | 1057 layer->fPaint, layer->fDeviceIsBitmapDevice
); |
| 1047 // reset this, since internalDrawDevice will have set it to true | 1058 // reset this, since internalDrawDevice will have set it to true |
| 1048 fDeviceCMDirty = true; | 1059 fDeviceCMDirty = true; |
| 1049 SkDELETE(layer); | 1060 SkDELETE(layer); |
| 1050 } else { | 1061 } else { |
| 1051 // we're at the root | 1062 // we're at the root |
| 1052 SkASSERT(layer == (void*)fBaseLayerStorage); | 1063 SkASSERT(layer == (void*)fBaseLayerStorage); |
| 1053 layer->~DeviceCM(); | 1064 layer->~DeviceCM(); |
| 1054 } | 1065 } |
| 1055 } | 1066 } |
| 1056 } | 1067 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1148 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 1159 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
| 1149 | 1160 |
| 1150 while (iter.next()) { | 1161 while (iter.next()) { |
| 1151 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); | 1162 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); |
| 1152 } | 1163 } |
| 1153 | 1164 |
| 1154 LOOPER_END | 1165 LOOPER_END |
| 1155 } | 1166 } |
| 1156 | 1167 |
| 1157 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, | 1168 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, |
| 1158 const SkPaint* paint) { | 1169 const SkPaint* paint, bool deviceIsBitmapDevic
e) { |
| 1159 SkPaint tmp; | 1170 SkPaint tmp; |
| 1160 if (NULL == paint) { | 1171 if (NULL == paint) { |
| 1161 paint = &tmp; | 1172 paint = &tmp; |
| 1162 } | 1173 } |
| 1163 | 1174 |
| 1164 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) | 1175 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) |
| 1165 while (iter.next()) { | 1176 while (iter.next()) { |
| 1166 SkBaseDevice* dstDev = iter.fDevice; | 1177 SkBaseDevice* dstDev = iter.fDevice; |
| 1167 paint = &looper.paint(); | 1178 paint = &looper.paint(); |
| 1168 SkImageFilter* filter = paint->getImageFilter(); | 1179 SkImageFilter* filter = paint->getImageFilter(); |
| 1169 SkIPoint pos = { x - iter.getX(), y - iter.getY() }; | 1180 SkIPoint pos = { x - iter.getX(), y - iter.getY() }; |
| 1170 if (filter && !dstDev->canHandleImageFilter(filter)) { | 1181 if (filter && !dstDev->canHandleImageFilter(filter)) { |
| 1171 SkDeviceImageFilterProxy proxy(dstDev, fProps); | 1182 SkDeviceImageFilterProxy proxy(dstDev, fProps); |
| 1172 SkBitmap dst; | 1183 SkBitmap dst; |
| 1173 SkIPoint offset = SkIPoint::Make(0, 0); | 1184 SkIPoint offset = SkIPoint::Make(0, 0); |
| 1174 const SkBitmap& src = srcDev->accessBitmap(false); | 1185 const SkBitmap& src = srcDev->accessBitmap(false); |
| 1175 SkMatrix matrix = *iter.fMatrix; | 1186 SkMatrix matrix = *iter.fMatrix; |
| 1176 matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y()
)); | 1187 matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y()
)); |
| 1177 SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height
()); | 1188 SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height
()); |
| 1178 SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache
()); | 1189 SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache
()); |
| 1179 SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); | 1190 SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); |
| 1180 if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { | 1191 if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { |
| 1181 SkPaint tmpUnfiltered(*paint); | 1192 SkPaint tmpUnfiltered(*paint); |
| 1182 tmpUnfiltered.setImageFilter(NULL); | 1193 tmpUnfiltered.setImageFilter(NULL); |
| 1183 dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + of
fset.y(), | 1194 dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + of
fset.y(), |
| 1184 tmpUnfiltered); | 1195 tmpUnfiltered); |
| 1185 } | 1196 } |
| 1197 } else if (deviceIsBitmapDevice) { |
| 1198 const SkBitmap& src = srcDev->accessBitmap(false); |
| 1199 dstDev->drawSprite(iter, src, pos.x(), pos.y(), *paint); |
| 1186 } else { | 1200 } else { |
| 1187 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); | 1201 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); |
| 1188 } | 1202 } |
| 1189 } | 1203 } |
| 1190 LOOPER_END | 1204 LOOPER_END |
| 1191 } | 1205 } |
| 1192 | 1206 |
| 1193 void SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint*
paint) { | 1207 void SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint*
paint) { |
| 1194 if (gTreatSpriteAsBitmap) { | 1208 if (gTreatSpriteAsBitmap) { |
| 1195 this->save(); | 1209 this->save(); |
| (...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2578 } | 2592 } |
| 2579 | 2593 |
| 2580 if (matrix) { | 2594 if (matrix) { |
| 2581 canvas->concat(*matrix); | 2595 canvas->concat(*matrix); |
| 2582 } | 2596 } |
| 2583 } | 2597 } |
| 2584 | 2598 |
| 2585 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2599 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
| 2586 fCanvas->restoreToCount(fSaveCount); | 2600 fCanvas->restoreToCount(fSaveCount); |
| 2587 } | 2601 } |
| OLD | NEW |