| 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 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 DeviceCM* fLayer; | 191 DeviceCM* fLayer; |
| 192 /* If there are any layers in the stack, this points to the top-most | 192 /* If there are any layers in the stack, this points to the top-most |
| 193 one that is at or below this level in the stack (so we know what | 193 one that is at or below this level in the stack (so we know what |
| 194 bitmap/device to draw into from this level. This value is NOT | 194 bitmap/device to draw into from this level. This value is NOT |
| 195 reference counted, since the real owner is either our fLayer field, | 195 reference counted, since the real owner is either our fLayer field, |
| 196 or a previous one in a lower level.) | 196 or a previous one in a lower level.) |
| 197 */ | 197 */ |
| 198 DeviceCM* fTopLayer; | 198 DeviceCM* fTopLayer; |
| 199 SkRasterClip fRasterClip; | 199 SkRasterClip fRasterClip; |
| 200 SkMatrix fMatrix; | 200 SkMatrix fMatrix; |
| 201 int fDeferredSaveCount; | 201 int fSaveCount; // The count of SkCanvas::save() calls when thi
s rec was created. |
| 202 | 202 |
| 203 MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { | 203 MCRec(bool conservativeRasterClip, int saveCount) |
| 204 : fRasterClip(conservativeRasterClip) |
| 205 , fSaveCount(saveCount) { |
| 204 fFilter = NULL; | 206 fFilter = NULL; |
| 205 fLayer = NULL; | 207 fLayer = NULL; |
| 206 fTopLayer = NULL; | 208 fTopLayer = NULL; |
| 207 fMatrix.reset(); | 209 fMatrix.reset(); |
| 208 fDeferredSaveCount = 0; | |
| 209 | 210 |
| 210 // don't bother initializing fNext | 211 // don't bother initializing fNext |
| 211 inc_rec(); | 212 inc_rec(); |
| 212 } | 213 } |
| 213 MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatr
ix) { | 214 MCRec(const MCRec& prev, int saveCount) |
| 215 : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) |
| 216 , fSaveCount(saveCount) { |
| 214 fFilter = SkSafeRef(prev.fFilter); | 217 fFilter = SkSafeRef(prev.fFilter); |
| 215 fLayer = NULL; | 218 fLayer = NULL; |
| 216 fTopLayer = prev.fTopLayer; | 219 fTopLayer = prev.fTopLayer; |
| 217 fDeferredSaveCount = 0; | |
| 218 | 220 |
| 219 // don't bother initializing fNext | 221 // don't bother initializing fNext |
| 220 inc_rec(); | 222 inc_rec(); |
| 221 } | 223 } |
| 222 ~MCRec() { | 224 ~MCRec() { |
| 223 SkSafeUnref(fFilter); | 225 SkSafeUnref(fFilter); |
| 224 SkDELETE(fLayer); | 226 SkDELETE(fLayer); |
| 225 dec_rec(); | 227 dec_rec(); |
| 226 } | 228 } |
| 227 }; | 229 }; |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag)
; | 431 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag)
; |
| 430 fCachedLocalClipBounds.setEmpty(); | 432 fCachedLocalClipBounds.setEmpty(); |
| 431 fCachedLocalClipBoundsDirty = true; | 433 fCachedLocalClipBoundsDirty = true; |
| 432 fAllowSoftClip = true; | 434 fAllowSoftClip = true; |
| 433 fAllowSimplifyClip = false; | 435 fAllowSimplifyClip = false; |
| 434 fDeviceCMDirty = true; | 436 fDeviceCMDirty = true; |
| 435 fSaveCount = 1; | 437 fSaveCount = 1; |
| 436 fMetaData = NULL; | 438 fMetaData = NULL; |
| 437 | 439 |
| 438 fMCRec = (MCRec*)fMCStack.push_back(); | 440 fMCRec = (MCRec*)fMCStack.push_back(); |
| 439 new (fMCRec) MCRec(fConservativeRasterClip); | 441 new (fMCRec) MCRec(fConservativeRasterClip, fSaveCount); |
| 440 | 442 |
| 441 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRaster
Clip)); | 443 fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, NULL, NULL, fConservativeRaster
Clip)); |
| 442 fMCRec->fTopLayer = fMCRec->fLayer; | 444 fMCRec->fTopLayer = fMCRec->fLayer; |
| 443 | 445 |
| 444 fSurfaceBase = NULL; | 446 fSurfaceBase = NULL; |
| 445 | 447 |
| 446 fClipStack.reset(SkNEW(SkClipStack)); | 448 fClipStack.reset(SkNEW(SkClipStack)); |
| 447 | 449 |
| 448 if (device) { | 450 if (device) { |
| 449 device->initForRootLayer(fProps.pixelGeometry()); | 451 device->initForRootLayer(fProps.pixelGeometry()); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 { | 540 { |
| 539 inc_canvas(); | 541 inc_canvas(); |
| 540 | 542 |
| 541 SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); | 543 SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); |
| 542 this->init(device, kDefault_InitFlags); | 544 this->init(device, kDefault_InitFlags); |
| 543 } | 545 } |
| 544 | 546 |
| 545 SkCanvas::~SkCanvas() { | 547 SkCanvas::~SkCanvas() { |
| 546 // free up the contents of our deque | 548 // free up the contents of our deque |
| 547 this->restoreToCount(1); // restore everything but the last | 549 this->restoreToCount(1); // restore everything but the last |
| 548 | |
| 549 this->internalRestore(); // restore the last, since we're going away | 550 this->internalRestore(); // restore the last, since we're going away |
| 550 | 551 |
| 551 SkDELETE(fMetaData); | 552 SkDELETE(fMetaData); |
| 552 | 553 |
| 553 dec_canvas(); | 554 dec_canvas(); |
| 554 } | 555 } |
| 555 | 556 |
| 556 SkDrawFilter* SkCanvas::getDrawFilter() const { | 557 SkDrawFilter* SkCanvas::getDrawFilter() const { |
| 557 return fMCRec->fFilter; | 558 return fMCRec->fFilter; |
| 558 } | 559 } |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 layer->updateMC(totalMatrix, clip, *fClipStack, &clip); | 746 layer->updateMC(totalMatrix, clip, *fClipStack, &clip); |
| 746 } while ((layer = layer->fNext) != NULL); | 747 } while ((layer = layer->fNext) != NULL); |
| 747 } | 748 } |
| 748 fDeviceCMDirty = false; | 749 fDeviceCMDirty = false; |
| 749 } | 750 } |
| 750 } | 751 } |
| 751 | 752 |
| 752 /////////////////////////////////////////////////////////////////////////////// | 753 /////////////////////////////////////////////////////////////////////////////// |
| 753 | 754 |
| 754 void SkCanvas::checkForDeferredSave() { | 755 void SkCanvas::checkForDeferredSave() { |
| 755 if (fMCRec->fDeferredSaveCount > 0) { | 756 if (fMCRec->fSaveCount < fSaveCount) { |
| 756 fMCRec->fDeferredSaveCount -= 1; | |
| 757 this->doSave(); | 757 this->doSave(); |
| 758 } | 758 } |
| 759 } | 759 } |
| 760 | 760 |
| 761 int SkCanvas::getSaveCount() const { | 761 int SkCanvas::getSaveCount() const { |
| 762 #ifdef SK_DEBUG | |
| 763 int count = 0; | |
| 764 SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); | |
| 765 for (;;) { | |
| 766 const MCRec* rec = (const MCRec*)iter.next(); | |
| 767 if (!rec) { | |
| 768 break; | |
| 769 } | |
| 770 count += 1 + rec->fDeferredSaveCount; | |
| 771 } | |
| 772 SkASSERT(count == fSaveCount); | |
| 773 #endif | |
| 774 return fSaveCount; | 762 return fSaveCount; |
| 775 } | 763 } |
| 776 | 764 |
| 777 int SkCanvas::save() { | 765 int SkCanvas::save() { |
| 778 fSaveCount += 1; | 766 fSaveCount += 1; |
| 779 fMCRec->fDeferredSaveCount += 1; | |
| 780 return this->getSaveCount() - 1; // return our prev value | 767 return this->getSaveCount() - 1; // return our prev value |
| 781 } | 768 } |
| 782 | 769 |
| 783 void SkCanvas::doSave() { | 770 void SkCanvas::doSave() { |
| 784 this->willSave(); | 771 this->willSave(); |
| 785 this->internalSave(); | 772 this->internalSave(); |
| 786 } | 773 } |
| 787 | 774 |
| 788 void SkCanvas::restore() { | 775 void SkCanvas::restore() { |
| 789 if (fMCRec->fDeferredSaveCount > 0) { | 776 int deferredSaveCount = fSaveCount - fMCRec->fSaveCount; |
| 790 SkASSERT(fSaveCount > 1); | 777 SkASSERT(deferredSaveCount >= 0); |
| 791 fSaveCount -= 1; | 778 if (deferredSaveCount == 0) { |
| 792 fMCRec->fDeferredSaveCount -= 1; | 779 // Check if the client tried to restore() too many times. |
| 793 } else { | |
| 794 // check for underflow | |
| 795 if (fMCStack.count() > 1) { | 780 if (fMCStack.count() > 1) { |
| 796 this->willRestore(); | 781 this->willRestore(); |
| 797 SkASSERT(fSaveCount > 1); | 782 this->internalRestore(); |
| 798 fSaveCount -= 1; | 783 fSaveCount -= 1; |
| 799 this->internalRestore(); | |
| 800 this->didRestore(); | 784 this->didRestore(); |
| 801 } | 785 } |
| 786 } else { |
| 787 // The topmost save was deferred. |
| 788 fSaveCount -= 1; |
| 802 } | 789 } |
| 790 |
| 791 // Note: we can not detect the case where errorneous SkCanvas::restore() |
| 792 // is called within the SkDrawLooper callback. |
| 803 } | 793 } |
| 804 | 794 |
| 805 void SkCanvas::restoreToCount(int count) { | 795 void SkCanvas::restoreToCount(int count) { |
| 806 // sanity check | 796 // sanity check |
| 807 if (count < 1) { | 797 if (count < 1) { |
| 808 count = 1; | 798 count = 1; |
| 809 } | 799 } |
| 810 | 800 |
| 811 int n = this->getSaveCount() - count; | 801 int n = this->getSaveCount() - count; |
| 812 for (int i = 0; i < n; ++i) { | 802 for (int i = 0; i < n; ++i) { |
| 813 this->restore(); | 803 this->restore(); |
| 814 } | 804 } |
| 815 } | 805 } |
| 816 | 806 |
| 817 void SkCanvas::internalSave() { | 807 void SkCanvas::internalSave() { |
| 818 MCRec* newTop = (MCRec*)fMCStack.push_back(); | 808 MCRec* newTop = (MCRec*)fMCStack.push_back(); |
| 819 new (newTop) MCRec(*fMCRec); // balanced in restore() | 809 new (newTop) MCRec(*fMCRec, fSaveCount); // balanced in restore() |
| 820 fMCRec = newTop; | 810 fMCRec = newTop; |
| 821 | |
| 822 fClipStack->save(); | 811 fClipStack->save(); |
| 823 } | 812 } |
| 824 | 813 |
| 825 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) { | 814 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) { |
| 826 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG | 815 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG |
| 827 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; | 816 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; |
| 828 #else | 817 #else |
| 829 return true; | 818 return true; |
| 830 #endif | 819 #endif |
| 831 } | 820 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 *intersection = ir; | 861 *intersection = ir; |
| 873 } | 862 } |
| 874 return true; | 863 return true; |
| 875 } | 864 } |
| 876 | 865 |
| 877 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { | 866 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { |
| 878 if (gIgnoreSaveLayerBounds) { | 867 if (gIgnoreSaveLayerBounds) { |
| 879 bounds = NULL; | 868 bounds = NULL; |
| 880 } | 869 } |
| 881 SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLa
yer_SaveFlag); | 870 SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLa
yer_SaveFlag); |
| 882 fSaveCount += 1; | 871 fSaveCount++; |
| 883 this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, strategy); | 872 this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, strategy); |
| 884 return this->getSaveCount() - 1; | 873 return this->getSaveCount() - 1; |
| 885 } | 874 } |
| 886 | 875 |
| 887 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags fl
ags) { | 876 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags fl
ags) { |
| 888 if (gIgnoreSaveLayerBounds) { | 877 if (gIgnoreSaveLayerBounds) { |
| 889 bounds = NULL; | 878 bounds = NULL; |
| 890 } | 879 } |
| 891 SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); | 880 SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); |
| 892 fSaveCount += 1; | 881 fSaveCount++; |
| 893 this->internalSaveLayer(bounds, paint, flags, strategy); | 882 this->internalSaveLayer(bounds, paint, flags, strategy); |
| 894 return this->getSaveCount() - 1; | 883 return this->getSaveCount() - 1; |
| 895 } | 884 } |
| 896 | 885 |
| 897 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav
eFlags flags, | 886 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav
eFlags flags, |
| 898 SaveLayerStrategy strategy) { | 887 SaveLayerStrategy strategy) { |
| 899 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG | 888 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG |
| 900 flags |= kClipToLayer_SaveFlag; | 889 flags |= kClipToLayer_SaveFlag; |
| 901 #endif | 890 #endif |
| 902 | 891 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 return this->saveLayer(bounds, NULL, flags); | 959 return this->saveLayer(bounds, NULL, flags); |
| 971 } else { | 960 } else { |
| 972 SkPaint tmpPaint; | 961 SkPaint tmpPaint; |
| 973 tmpPaint.setAlpha(alpha); | 962 tmpPaint.setAlpha(alpha); |
| 974 return this->saveLayer(bounds, &tmpPaint, flags); | 963 return this->saveLayer(bounds, &tmpPaint, flags); |
| 975 } | 964 } |
| 976 } | 965 } |
| 977 | 966 |
| 978 void SkCanvas::internalRestore() { | 967 void SkCanvas::internalRestore() { |
| 979 SkASSERT(fMCStack.count() != 0); | 968 SkASSERT(fMCStack.count() != 0); |
| 969 SkASSERT(fMCRec->fSaveCount == fSaveCount); |
| 980 | 970 |
| 981 fDeviceCMDirty = true; | 971 fDeviceCMDirty = true; |
| 982 fCachedLocalClipBoundsDirty = true; | 972 fCachedLocalClipBoundsDirty = true; |
| 983 | 973 |
| 984 fClipStack->restore(); | 974 fClipStack->restore(); |
| 985 | 975 |
| 986 // reserve our layer (if any) | 976 // reserve our layer (if any) |
| 987 DeviceCM* layer = fMCRec->fLayer; // may be null | 977 DeviceCM* layer = fMCRec->fLayer; // may be null |
| 988 // now detach it from fMCRec so we can pop(). Gets freed after its drawn | 978 // now detach it from fMCRec so we can pop(). Gets freed after its drawn |
| 989 fMCRec->fLayer = NULL; | 979 fMCRec->fLayer = NULL; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1000 if (layer) { | 990 if (layer) { |
| 1001 if (layer->fNext) { | 991 if (layer->fNext) { |
| 1002 const SkIPoint& origin = layer->fDevice->getOrigin(); | 992 const SkIPoint& origin = layer->fDevice->getOrigin(); |
| 1003 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), | 993 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), |
| 1004 layer->fPaint); | 994 layer->fPaint); |
| 1005 // reset this, since internalDrawDevice will have set it to true | 995 // reset this, since internalDrawDevice will have set it to true |
| 1006 fDeviceCMDirty = true; | 996 fDeviceCMDirty = true; |
| 1007 } | 997 } |
| 1008 SkDELETE(layer); | 998 SkDELETE(layer); |
| 1009 } | 999 } |
| 1000 SkASSERT(fMCStack.count() == 0 || fMCRec->fSaveCount <= fSaveCount); |
| 1010 } | 1001 } |
| 1011 | 1002 |
| 1012 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { | 1003 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { |
| 1013 if (NULL == props) { | 1004 if (NULL == props) { |
| 1014 props = &fProps; | 1005 props = &fProps; |
| 1015 } | 1006 } |
| 1016 return this->onNewSurface(info, *props); | 1007 return this->onNewSurface(info, *props); |
| 1017 } | 1008 } |
| 1018 | 1009 |
| 1019 SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&
props) { | 1010 SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&
props) { |
| (...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2520 } | 2511 } |
| 2521 | 2512 |
| 2522 if (matrix) { | 2513 if (matrix) { |
| 2523 canvas->concat(*matrix); | 2514 canvas->concat(*matrix); |
| 2524 } | 2515 } |
| 2525 } | 2516 } |
| 2526 | 2517 |
| 2527 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2518 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
| 2528 fCanvas->restoreToCount(fSaveCount); | 2519 fCanvas->restoreToCount(fSaveCount); |
| 2529 } | 2520 } |
| OLD | NEW |