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 if (NULL != fCachedCanvas) {
47 SkASSERT(fCachedCanvas->getSurfaceBase() == this || \
48 NULL == fCachedCanvas->getSurfaceBase());
49 fCachedCanvas->setSurfaceBase(NULL);
52 if (NULL != fCachedImage) {
53 // the surface may need to fork its backend, if its sharing it with
54 // the cached image. Note: we only call if there is an outstanding owner
55 // on the image (besides us).
56 if (!fCachedImage->unique()) {
57 this->onCopyOnWrite(mode);
60 // regardless of copy-on-write, we must drop our cached image now, so
61 // that the next request will get our new contents.
62 fCachedImage->unref();
67 uint32_t SkSurface_Base::newGenerationID() {
68 this->installIntoCanvasForDirtyNotification();
71 return sk_atomic_inc(&gID) + 1;
74 static SkSurface_Base* asSB(SkSurface* surface) {
75 return static_cast<SkSurface_Base*>(surface);
78 ///////////////////////////////////////////////////////////////////////////////
80 SkSurface::SkSurface(int width, int height) : fWidth(width), fHeight(height) {
81 SkASSERT(fWidth >= 0);
82 SkASSERT(fHeight >= 0);
86 SkSurface::SkSurface(const SkImageInfo& info)
88 , fHeight(info.fHeight)
90 SkASSERT(fWidth >= 0);
91 SkASSERT(fHeight >= 0);
95 uint32_t SkSurface::generationID() {
96 if (0 == fGenerationID) {
97 fGenerationID = asSB(this)->newGenerationID();
102 void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
103 asSB(this)->aboutToDraw(mode);
106 SkCanvas* SkSurface::getCanvas() {
107 return asSB(this)->getCachedCanvas();
110 SkImage* SkSurface::newImageSnapshot() {
111 SkImage* image = asSB(this)->getCachedImage();
112 SkSafeRef(image); // the caller will call unref() to balance this
116 SkSurface* SkSurface::newSurface(const SkImageInfo& info) {
117 return asSB(this)->onNewSurface(info);
120 void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
121 const SkPaint* paint) {
122 return asSB(this)->onDraw(canvas, x, y, paint);
125 const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) {
126 return this->getCanvas()->peekPixels(info, rowBytes);