OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkSurface_Base.h" | 8 #include "SkSurface_Base.h" |
9 #include "SkImagePriv.h" | 9 #include "SkImagePriv.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 : fFlags(other.fFlags) | 51 : fFlags(other.fFlags) |
52 , fPixelGeometry(other.fPixelGeometry) | 52 , fPixelGeometry(other.fPixelGeometry) |
53 {} | 53 {} |
54 | 54 |
55 /////////////////////////////////////////////////////////////////////////////// | 55 /////////////////////////////////////////////////////////////////////////////// |
56 | 56 |
57 SkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* prop
s) | 57 SkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* prop
s) |
58 : INHERITED(width, height, props) | 58 : INHERITED(width, height, props) |
59 { | 59 { |
60 fCachedCanvas = NULL; | 60 fCachedCanvas = NULL; |
61 fCachedImage = NULL; | |
62 } | 61 } |
63 | 62 |
64 SkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* pr
ops) | 63 SkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* pr
ops) |
65 : INHERITED(info, props) | 64 : INHERITED(info, props) |
66 { | 65 { |
67 fCachedCanvas = NULL; | 66 fCachedCanvas = NULL; |
68 fCachedImage = NULL; | |
69 } | 67 } |
70 | 68 |
71 SkSurface_Base::~SkSurface_Base() { | 69 SkSurface_Base::~SkSurface_Base() { |
72 // in case the canvas outsurvives us, we null the callback | |
73 if (fCachedCanvas) { | |
74 fCachedCanvas->setSurfaceBase(NULL); | |
75 } | |
76 | |
77 SkSafeUnref(fCachedImage); | |
78 SkSafeUnref(fCachedCanvas); | 70 SkSafeUnref(fCachedCanvas); |
79 } | 71 } |
80 | 72 |
81 void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPa
int* paint) { | 73 void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPa
int* paint) { |
82 SkImage* image = this->newImageSnapshot(kYes_Budgeted); | 74 SkImage* image = this->newImageSnapshot(kYes_Budgeted); |
83 if (image) { | 75 if (image) { |
84 canvas->drawImage(image, x, y, paint); | 76 canvas->drawImage(image, x, y, paint); |
85 image->unref(); | 77 image->unref(); |
86 } | 78 } |
87 } | 79 } |
88 | 80 |
89 void SkSurface_Base::aboutToDraw(ContentChangeMode mode) { | |
90 this->dirtyGenerationID(); | |
91 | |
92 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this); | |
93 | |
94 if (fCachedImage) { | |
95 // the surface may need to fork its backend, if its sharing it with | |
96 // the cached image. Note: we only call if there is an outstanding owner | |
97 // on the image (besides us). | |
98 if (!fCachedImage->unique()) { | |
99 this->onCopyOnWrite(mode); | |
100 } | |
101 | |
102 // regardless of copy-on-write, we must drop our cached image now, so | |
103 // that the next request will get our new contents. | |
104 fCachedImage->unref(); | |
105 fCachedImage = NULL; | |
106 } else if (kDiscard_ContentChangeMode == mode) { | |
107 this->onDiscard(); | |
108 } | |
109 } | |
110 | |
111 uint32_t SkSurface_Base::newGenerationID() { | 81 uint32_t SkSurface_Base::newGenerationID() { |
112 SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this); | |
113 static int32_t gID; | 82 static int32_t gID; |
114 return sk_atomic_inc(&gID) + 1; | 83 return sk_atomic_inc(&gID) + 1; |
115 } | 84 } |
116 | 85 |
117 static SkSurface_Base* asSB(SkSurface* surface) { | 86 static SkSurface_Base* asSB(SkSurface* surface) { |
118 return static_cast<SkSurface_Base*>(surface); | 87 return static_cast<SkSurface_Base*>(surface); |
119 } | 88 } |
120 | 89 |
121 /////////////////////////////////////////////////////////////////////////////// | 90 /////////////////////////////////////////////////////////////////////////////// |
122 | 91 |
123 SkSurface::SkSurface(int width, int height, const SkSurfaceProps* props) | 92 SkSurface::SkSurface(int width, int height, const SkSurfaceProps* props) |
124 : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height) | 93 : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height) |
125 { | 94 { |
126 SkASSERT(fWidth > 0); | 95 SkASSERT(fWidth > 0); |
127 SkASSERT(fHeight > 0); | 96 SkASSERT(fHeight > 0); |
128 fGenerationID = 0; | |
129 } | 97 } |
130 | 98 |
131 SkSurface::SkSurface(const SkImageInfo& info, const SkSurfaceProps* props) | 99 SkSurface::SkSurface(const SkImageInfo& info, const SkSurfaceProps* props) |
132 : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(info.width()), fHeight(
info.height()) | 100 : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(info.width()), fHeight(
info.height()) |
133 { | 101 { |
134 SkASSERT(fWidth > 0); | 102 SkASSERT(fWidth > 0); |
135 SkASSERT(fHeight > 0); | 103 SkASSERT(fHeight > 0); |
136 fGenerationID = 0; | |
137 } | |
138 | |
139 uint32_t SkSurface::generationID() { | |
140 if (0 == fGenerationID) { | |
141 fGenerationID = asSB(this)->newGenerationID(); | |
142 } | |
143 return fGenerationID; | |
144 } | |
145 | |
146 void SkSurface::notifyContentWillChange(ContentChangeMode mode) { | |
147 asSB(this)->aboutToDraw(mode); | |
148 } | 104 } |
149 | 105 |
150 SkCanvas* SkSurface::getCanvas() { | 106 SkCanvas* SkSurface::getCanvas() { |
151 return asSB(this)->getCachedCanvas(); | 107 return asSB(this)->getCachedCanvas(); |
152 } | 108 } |
153 | 109 |
154 SkImage* SkSurface::newImageSnapshot(Budgeted budgeted) { | 110 SkImage* SkSurface::newImageSnapshot(Budgeted budgeted) { |
155 SkImage* image = asSB(this)->getCachedImage(budgeted); | 111 return asSB(this)->onNewImageSnapshot(budgeted); |
156 SkSafeRef(image); // the caller will call unref() to balance this | |
157 return image; | |
158 } | 112 } |
159 | 113 |
160 SkSurface* SkSurface::newSurface(const SkImageInfo& info) { | 114 SkSurface* SkSurface::newSurface(const SkImageInfo& info) { |
161 return asSB(this)->onNewSurface(info); | 115 return asSB(this)->onNewSurface(info); |
162 } | 116 } |
163 | 117 |
164 void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y, | 118 void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y, |
165 const SkPaint* paint) { | 119 const SkPaint* paint) { |
166 return asSB(this)->onDraw(canvas, x, y, paint); | 120 return asSB(this)->onDraw(canvas, x, y, paint); |
167 } | 121 } |
(...skipping 15 matching lines...) Expand all Loading... |
183 return NULL; | 137 return NULL; |
184 } | 138 } |
185 | 139 |
186 SkSurface* SkSurface::NewRenderTarget(GrContext*, Budgeted, const SkImageInfo&,
int, | 140 SkSurface* SkSurface::NewRenderTarget(GrContext*, Budgeted, const SkImageInfo&,
int, |
187 const SkSurfaceProps*) { | 141 const SkSurfaceProps*) { |
188 return NULL; | 142 return NULL; |
189 } | 143 } |
190 | 144 |
191 | 145 |
192 #endif | 146 #endif |
OLD | NEW |