Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Side by Side Diff: src/core/SkCanvas.cpp

Issue 1116453002: onCreateDevice -> NULL now means the caller should create its own (bitmap) device (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698