Chromium Code Reviews| 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 |