2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "SkSurface_Base.h"
9 #include "SkImagePriv.h"
12 SK_DEFINE_INST_COUNT(SkSurface)
14 ///////////////////////////////////////////////////////////////////////////////
16 SkSurface_Base::SkSurface_Base(int width, int height) : INHERITED(width, height) {
21 SkSurface_Base::~SkSurface_Base() {
22 // in case the canvas outsurvives us, we null the callback
24 fCachedCanvas->setSurfaceBase(NULL);
27 SkSafeUnref(fCachedImage);
28 SkSafeUnref(fCachedCanvas);
31 void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
32 const SkPaint* paint) {
33 SkImage* image = this->newImageSnapshot();
35 image->draw(canvas, x, y, paint);
40 void SkSurface_Base::aboutToDraw(ContentChangeMode mode) {
41 this->dirtyGenerationID();
43 if (NULL != fCachedCanvas) {
44 SkASSERT(fCachedCanvas->getSurfaceBase() == this || \
45 NULL == fCachedCanvas->getSurfaceBase());
46 fCachedCanvas->setSurfaceBase(NULL);
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);
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();
64 uint32_t SkSurface_Base::newGenerationID() {
65 this->installIntoCanvasForDirtyNotification();
68 return sk_atomic_inc(&gID) + 1;
71 static SkSurface_Base* asSB(SkSurface* surface) {
72 return static_cast<SkSurface_Base*>(surface);
75 ///////////////////////////////////////////////////////////////////////////////
77 SkSurface::SkSurface(int width, int height) : fWidth(width), fHeight(height) {
79 SkASSERT(height >= 0);
83 uint32_t SkSurface::generationID() {
84 if (0 == fGenerationID) {
85 fGenerationID = asSB(this)->newGenerationID();
90 void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
91 asSB(this)->aboutToDraw(mode);
94 SkCanvas* SkSurface::getCanvas() {
95 return asSB(this)->getCachedCanvas();
98 SkImage* SkSurface::newImageSnapshot() {
99 SkImage* image = asSB(this)->getCachedImage();
100 SkSafeRef(image); // the caller will call unref() to balance this
104 SkSurface* SkSurface::newSurface(const SkImageInfo& info) {
105 return asSB(this)->onNewSurface(info);
108 void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
109 const SkPaint* paint) {
110 return asSB(this)->onDraw(canvas, x, y, paint);