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 |