• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkSurface_Base(int width,int height)14 SkSurface_Base::SkSurface_Base(int width, int height) : INHERITED(width, height) {
15     fCachedCanvas = NULL;
16     fCachedImage = NULL;
17 }
18 
~SkSurface_Base()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 
onDraw(SkCanvas * canvas,SkScalar x,SkScalar y,const SkPaint * paint)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 
aboutToDraw(ContentChangeMode mode)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 
newGenerationID()62 uint32_t SkSurface_Base::newGenerationID() {
63     this->installIntoCanvasForDirtyNotification();
64 
65     static int32_t gID;
66     return sk_atomic_inc(&gID) + 1;
67 }
68 
asSB(SkSurface * surface)69 static SkSurface_Base* asSB(SkSurface* surface) {
70     return static_cast<SkSurface_Base*>(surface);
71 }
72 
73 ///////////////////////////////////////////////////////////////////////////////
74 
SkSurface(int width,int height)75 SkSurface::SkSurface(int width, int height) : fWidth(width), fHeight(height) {
76     SkASSERT(width >= 0);
77     SkASSERT(height >= 0);
78     fGenerationID = 0;
79 }
80 
generationID()81 uint32_t SkSurface::generationID() {
82     if (0 == fGenerationID) {
83         fGenerationID = asSB(this)->newGenerationID();
84     }
85     return fGenerationID;
86 }
87 
notifyContentWillChange(ContentChangeMode mode)88 void SkSurface::notifyContentWillChange(ContentChangeMode mode) {
89     asSB(this)->aboutToDraw(mode);
90 }
91 
getCanvas()92 SkCanvas* SkSurface::getCanvas() {
93     return asSB(this)->getCachedCanvas();
94 }
95 
newImageSnapshot()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 
newSurface(const SkImageInfo & info)102 SkSurface* SkSurface::newSurface(const SkImageInfo& info) {
103     return asSB(this)->onNewSurface(info);
104 }
105 
draw(SkCanvas * canvas,SkScalar x,SkScalar y,const SkPaint * paint)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