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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
976 } | 976 } |
977 SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), | 977 SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), |
978 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); | 978 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); |
979 | 979 |
980 SkBaseDevice* device = this->getTopDevice(); | 980 SkBaseDevice* device = this->getTopDevice(); |
981 if (NULL == device) { | 981 if (NULL == device) { |
982 SkDebugf("Unable to find device for layer."); | 982 SkDebugf("Unable to find device for layer."); |
983 return; | 983 return; |
984 } | 984 } |
985 | 985 |
986 SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; | 986 bool forceSpriteOnRestore = false; |
987 device = device->onCreateDevice(SkBaseDevice::CreateInfo(info, usage, geo), paint); | 987 { |
988 if (NULL == device) { | 988 const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; |
989 SkErrorInternals::SetError( kInternalError_SkError, | 989 const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(inf o, usage, geo); |
990 "Unable to create device for layer."); | 990 SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); |
991 return; | 991 if (NULL == newDev) { |
robertphillips
2015/04/29 14:55:54
"If device creation didn't succeed," ?
"If device
reed1
2015/04/29 15:20:47
Done.
| |
992 // If the device didn't success, try raster (e.g. PDF perhaps couldn 't handle the paint) | |
993 newDev = SkBitmapDevice::Create(createInfo.fInfo); | |
994 if (NULL == newDev) { | |
995 SkErrorInternals::SetError(kInternalError_SkError, | |
996 "Unable to create device for layer.") ; | |
997 return; | |
998 } | |
999 forceSpriteOnRestore = true; | |
1000 } | |
1001 device = newDev; | |
992 } | 1002 } |
993 | 1003 |
994 device->setOrigin(ir.fLeft, ir.fTop); | 1004 device->setOrigin(ir.fLeft, ir.fTop); |
995 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa sterClip)); | 1005 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa sterClip, |
1006 forceSpriteOnRestore)); | |
996 device->unref(); | 1007 device->unref(); |
997 | 1008 |
998 layer->fNext = fMCRec->fTopLayer; | 1009 layer->fNext = fMCRec->fTopLayer; |
999 fMCRec->fLayer = layer; | 1010 fMCRec->fLayer = layer; |
1000 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer | 1011 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer |
1001 } | 1012 } |
1002 | 1013 |
1003 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { | 1014 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { |
1004 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); | 1015 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); |
1005 } | 1016 } |
(...skipping 28 matching lines...) Expand all Loading... | |
1034 fMCRec = (MCRec*)fMCStack.back(); | 1045 fMCRec = (MCRec*)fMCStack.back(); |
1035 | 1046 |
1036 /* Time to draw the layer's offscreen. We can't call the public drawSprite, | 1047 /* Time to draw the layer's offscreen. We can't call the public drawSprite, |
1037 since if we're being recorded, we don't want to record this (the | 1048 since if we're being recorded, we don't want to record this (the |
1038 recorder will have already recorded the restore). | 1049 recorder will have already recorded the restore). |
1039 */ | 1050 */ |
1040 if (layer) { | 1051 if (layer) { |
1041 if (layer->fNext) { | 1052 if (layer->fNext) { |
1042 const SkIPoint& origin = layer->fDevice->getOrigin(); | 1053 const SkIPoint& origin = layer->fDevice->getOrigin(); |
1043 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), | 1054 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), |
1044 layer->fPaint); | 1055 layer->fPaint, layer->fDeviceIsBitmapDevice ); |
1045 // reset this, since internalDrawDevice will have set it to true | 1056 // reset this, since internalDrawDevice will have set it to true |
1046 fDeviceCMDirty = true; | 1057 fDeviceCMDirty = true; |
1047 SkDELETE(layer); | 1058 SkDELETE(layer); |
1048 } else { | 1059 } else { |
1049 // we're at the root | 1060 // we're at the root |
1050 SkASSERT(layer == (void*)fBaseLayerStorage); | 1061 SkASSERT(layer == (void*)fBaseLayerStorage); |
1051 layer->~DeviceCM(); | 1062 layer->~DeviceCM(); |
1052 } | 1063 } |
1053 } | 1064 } |
1054 } | 1065 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1146 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 1157 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
1147 | 1158 |
1148 while (iter.next()) { | 1159 while (iter.next()) { |
1149 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); | 1160 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); |
1150 } | 1161 } |
1151 | 1162 |
1152 LOOPER_END | 1163 LOOPER_END |
1153 } | 1164 } |
1154 | 1165 |
1155 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, | 1166 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, |
1156 const SkPaint* paint) { | 1167 const SkPaint* paint, bool deviceIsBitmapDevic e) { |
1157 SkPaint tmp; | 1168 SkPaint tmp; |
1158 if (NULL == paint) { | 1169 if (NULL == paint) { |
1159 paint = &tmp; | 1170 paint = &tmp; |
1160 } | 1171 } |
1161 | 1172 |
1162 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) | 1173 LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) |
1163 while (iter.next()) { | 1174 while (iter.next()) { |
1164 SkBaseDevice* dstDev = iter.fDevice; | 1175 SkBaseDevice* dstDev = iter.fDevice; |
1165 paint = &looper.paint(); | 1176 paint = &looper.paint(); |
1166 SkImageFilter* filter = paint->getImageFilter(); | 1177 SkImageFilter* filter = paint->getImageFilter(); |
1167 SkIPoint pos = { x - iter.getX(), y - iter.getY() }; | 1178 SkIPoint pos = { x - iter.getX(), y - iter.getY() }; |
1168 if (filter && !dstDev->canHandleImageFilter(filter)) { | 1179 if (filter && !dstDev->canHandleImageFilter(filter)) { |
1169 SkDeviceImageFilterProxy proxy(dstDev, fProps); | 1180 SkDeviceImageFilterProxy proxy(dstDev, fProps); |
1170 SkBitmap dst; | 1181 SkBitmap dst; |
1171 SkIPoint offset = SkIPoint::Make(0, 0); | 1182 SkIPoint offset = SkIPoint::Make(0, 0); |
1172 const SkBitmap& src = srcDev->accessBitmap(false); | 1183 const SkBitmap& src = srcDev->accessBitmap(false); |
1173 SkMatrix matrix = *iter.fMatrix; | 1184 SkMatrix matrix = *iter.fMatrix; |
1174 matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y() )); | 1185 matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y() )); |
1175 SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height ()); | 1186 SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height ()); |
1176 SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache ()); | 1187 SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache ()); |
1177 SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); | 1188 SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); |
1178 if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { | 1189 if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { |
1179 SkPaint tmpUnfiltered(*paint); | 1190 SkPaint tmpUnfiltered(*paint); |
1180 tmpUnfiltered.setImageFilter(NULL); | 1191 tmpUnfiltered.setImageFilter(NULL); |
1181 dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + of fset.y(), | 1192 dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + of fset.y(), |
1182 tmpUnfiltered); | 1193 tmpUnfiltered); |
1183 } | 1194 } |
1195 } else if (deviceIsBitmapDevice) { | |
1196 const SkBitmap& src = srcDev->accessBitmap(false); | |
1197 dstDev->drawSprite(iter, src, pos.x(), pos.y(), *paint); | |
1184 } else { | 1198 } else { |
1185 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); | 1199 dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); |
1186 } | 1200 } |
1187 } | 1201 } |
1188 LOOPER_END | 1202 LOOPER_END |
1189 } | 1203 } |
1190 | 1204 |
1191 void SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint* paint) { | 1205 void SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint* paint) { |
1192 if (gTreatSpriteAsBitmap) { | 1206 if (gTreatSpriteAsBitmap) { |
1193 this->save(); | 1207 this->save(); |
(...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2576 } | 2590 } |
2577 | 2591 |
2578 if (matrix) { | 2592 if (matrix) { |
2579 canvas->concat(*matrix); | 2593 canvas->concat(*matrix); |
2580 } | 2594 } |
2581 } | 2595 } |
2582 | 2596 |
2583 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2597 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
2584 fCanvas->restoreToCount(fSaveCount); | 2598 fCanvas->restoreToCount(fSaveCount); |
2585 } | 2599 } |
OLD | NEW |