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