1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkSurface_Base.h" 9 #include "SkImagePriv.h" 10 #include "SkCanvas.h" 11 12 /////////////////////////////////////////////////////////////////////////////// 13 14 SkSurface_Base::SkSurface_Base(int width, int height) : INHERITED(width, height) { 15 fCachedCanvas = NULL; 16 fCachedImage = NULL; 17 } 18 19 SkSurface_Base::~SkSurface_Base() { 20 // in case the canvas outsurvives us, we null the callback 21 if (fCachedCanvas) { 22 fCachedCanvas->setSurfaceBase(NULL); 23 } 24 25 SkSafeUnref(fCachedImage); 26 SkSafeUnref(fCachedCanvas); 27 } 28 29 void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, 30 const SkPaint* paint) { 31 SkImage* image = this->newImageSnapshot(); 32 if (image) { 33 image->draw(canvas, x, y, paint); 34 image->unref(); 35 } 36 } 37 38 void SkSurface_Base::aboutToDraw(ContentChangeMode mode) { 39 this->dirtyGenerationID(); 40 41 if (NULL != fCachedCanvas) { 42 SkASSERT(fCachedCanvas->getSurfaceBase() == this || \ 43 NULL == fCachedCanvas->getSurfaceBase()); 44 fCachedCanvas->setSurfaceBase(NULL); 45 } 46 47 if (NULL != fCachedImage) { 48 // the surface may need to fork its backend, if its sharing it with 49 // the cached image. Note: we only call if there is an outstanding owner 50 // on the image (besides us). 51 if (!fCachedImage->unique()) { 52 this->onCopyOnWrite(mode); 53 } 54 55 // regardless of copy-on-write, we must drop our cached image now, so 56 // that the next request will get our new contents. 57 fCachedImage->unref(); 58 fCachedImage = NULL; 59 } 60 } 61 62 uint32_t SkSurface_Base::newGenerationID() { 63 this->installIntoCanvasForDirtyNotification(); 64 65 static int32_t gID; 66 return sk_atomic_inc(&gID) + 1; 67 } 68 69 static SkSurface_Base* asSB(SkSurface* surface) { 70 return static_cast<SkSurface_Base*>(surface); 71 } 72 73 /////////////////////////////////////////////////////////////////////////////// 74 75 SkSurface::SkSurface(int width, int height) : fWidth(width), fHeight(height) { 76 SkASSERT(width >= 0); 77 SkASSERT(height >= 0); 78 fGenerationID = 0; 79 } 80 81 uint32_t SkSurface::generationID() { 82 if (0 == fGenerationID) { 83 fGenerationID = asSB(this)->newGenerationID(); 84 } 85 return fGenerationID; 86 } 87 88 void SkSurface::notifyContentWillChange(ContentChangeMode mode) { 89 asSB(this)->aboutToDraw(mode); 90 } 91 92 SkCanvas* SkSurface::getCanvas() { 93 return asSB(this)->getCachedCanvas(); 94 } 95 96 SkImage* SkSurface::newImageSnapshot() { 97 SkImage* image = asSB(this)->getCachedImage(); 98 SkSafeRef(image); // the caller will call unref() to balance this 99 return image; 100 } 101 102 SkSurface* SkSurface::newSurface(const SkImageInfo& info) { 103 return asSB(this)->onNewSurface(info); 104 } 105 106 void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y, 107 const SkPaint* paint) { 108 return asSB(this)->onDraw(canvas, x, y, paint); 109 } 110