- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / image / SkSurface.cpp
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 SkImageInfo& 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 }