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 ///////////////////////////////////////////////////////////////////////////////
14 SkSurface_Base::SkSurface_Base(int width, int height) : INHERITED(width, height) {
19 SkSurface_Base::SkSurface_Base(const SkImageInfo& info) : INHERITED(info) {
24 SkSurface_Base::~SkSurface_Base() {
25 // in case the canvas outsurvives us, we null the callback
27 fCachedCanvas->setSurfaceBase(NULL);
30 SkSafeUnref(fCachedImage);
31 SkSafeUnref(fCachedCanvas);
34 void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
35 const SkPaint* paint) {
36 SkImage* image = this->newImageSnapshot();
38 image->draw(canvas, x, y, paint);
43 void SkSurface_Base::aboutToDraw(ContentChangeMode mode) {
44 this->dirtyGenerationID();
46 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
48 if (NULL != fCachedImage) {
49 // the surface may need to fork its backend, if its sharing it with
50 // the cached image. Note: we only call if there is an outstanding owner
51 // on the image (besides us).
52 if (!fCachedImage->unique()) {
53 this->onCopyOnWrite(mode);
56 // regardless of copy-on-write, we must drop our cached image now, so
57 // that the next request will get our new contents.
58 fCachedImage->unref();
60 } else if (kDiscard_ContentChangeMode == mode) {
65 uint32_t SkSurface_Base::newGenerationID() {
66 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
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) {
78 SkASSERT(fWidth >= 0);
79 SkASSERT(fHeight >= 0);
83 SkSurface::SkSurface(const SkImageInfo& info)
85 , fHeight(info.fHeight)
87 SkASSERT(fWidth >= 0);
88 SkASSERT(fHeight >= 0);
92 uint32_t SkSurface::generationID() {
93 if (0 == fGenerationID) {
94 fGenerationID = asSB(this)->newGenerationID();
99 void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
100 asSB(this)->aboutToDraw(mode);
103 SkCanvas* SkSurface::getCanvas() {
104 return asSB(this)->getCachedCanvas();
107 SkImage* SkSurface::newImageSnapshot() {
108 SkImage* image = asSB(this)->getCachedImage();
109 SkSafeRef(image); // the caller will call unref() to balance this
113 SkSurface* SkSurface::newSurface(const SkImageInfo& info) {
114 return asSB(this)->onNewSurface(info);
117 void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
118 const SkPaint* paint) {
119 return asSB(this)->onDraw(canvas, x, y, paint);
122 const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) {
123 return this->getCanvas()->peekPixels(info, rowBytes);