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

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: update dox 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
« no previous file with comments | « include/core/SkDevice.h ('k') | src/core/SkDeviceImageFilterProxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 }
OLDNEW
« no previous file with comments | « include/core/SkDevice.h ('k') | src/core/SkDeviceImageFilterProxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698