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 "SkBitmapDevice.h" |
| 10 #include "SkCanvas.h" |
| 11 #include "SkDeviceProperties.h" |
9 #include "SkImagePriv.h" | 12 #include "SkImagePriv.h" |
10 #include "SkCanvas.h" | |
11 #include "SkDevice.h" | |
12 #include "SkMallocPixelRef.h" | 13 #include "SkMallocPixelRef.h" |
13 | 14 |
14 static const size_t kIgnoreRowBytesValue = (size_t)~0; | 15 static const size_t kIgnoreRowBytesValue = (size_t)~0; |
| 16 class SkRasterDevice; |
15 | 17 |
16 class SkSurface_Raster : public SkSurface_Base { | 18 class SkSurface_Raster : public SkSurface_Base { |
17 public: | 19 public: |
18 static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue); | 20 static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue); |
19 | 21 |
20 SkSurface_Raster(const SkImageInfo&, void*, size_t rb, | 22 SkSurface_Raster(const SkImageInfo&, void*, size_t rb, |
21 void (*releaseProc)(void* pixels, void* context), void* con
text, | 23 void (*releaseProc)(void* pixels, void* context), void* con
text, |
22 const SkSurfaceProps*); | 24 const SkSurfaceProps*); |
23 SkSurface_Raster(SkPixelRef*, const SkSurfaceProps*); | 25 SkSurface_Raster(SkPixelRef*, const SkSurfaceProps*); |
24 | 26 ~SkSurface_Raster(); |
25 SkCanvas* onNewCanvas() SK_OVERRIDE; | 27 SkCanvas* onNewCanvas() SK_OVERRIDE; |
26 SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; | 28 SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; |
27 SkImage* onNewImageSnapshot(Budgeted) SK_OVERRIDE; | 29 SkImage* onNewImageSnapshot(Budgeted) SK_OVERRIDE; |
28 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, | 30 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, |
29 const SkPaint*) SK_OVERRIDE; | 31 const SkPaint*) SK_OVERRIDE; |
30 void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE; | 32 void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE; |
31 | 33 |
32 private: | 34 private: |
33 SkBitmap fBitmap; | 35 SkRasterDevice* fDevice; |
34 bool fWeOwnThePixels; | |
35 | 36 |
36 typedef SkSurface_Base INHERITED; | 37 typedef SkSurface_Base INHERITED; |
37 }; | 38 }; |
38 | 39 |
| 40 /** A bitmap device that is used by SkSurface_Raster. */ |
| 41 class SkRasterDevice : public SkBitmapDevice { |
| 42 public: |
| 43 SkRasterDevice(const SkBitmap& bitmap); |
| 44 enum Direct { kDirect }; |
| 45 SkRasterDevice(const SkBitmap& bitmap, Direct); |
| 46 SkRasterDevice(const SkBitmap& bitmap, const SkDeviceProperties& props); |
| 47 void setSurface(SkSurface_Raster* surface) { fSurface = surface; } |
| 48 |
| 49 void discard() SK_OVERRIDE; |
| 50 SkImage* newImageSnapshot(const SkSurfaceProps* props); |
| 51 |
| 52 bool backendUsesPixelRef(const SkPixelRef* other) { |
| 53 return this->getBackendBitmap().pixelRef() == other; |
| 54 } |
| 55 |
| 56 void discardOnWrite(); |
| 57 void copyOnWrite(); |
| 58 private: |
| 59 SkBaseDevice* onCreateCompatibleDevice(const CreateInfo& cinfo) SK_OVERRIDE; |
| 60 const SkBitmap& onAccessBitmap() SK_OVERRIDE; |
| 61 SkBitmap& getBackendBitmap() { |
| 62 return fBitmap; // Note: accessing private SkBitmapDevice::fBitmap |
| 63 } |
| 64 |
| 65 bool fWeOwnThePixels; |
| 66 SkSurface_Raster* fSurface; |
| 67 |
| 68 typedef SkBitmapDevice INHERITED; |
| 69 }; |
| 70 |
| 71 SkRasterDevice::SkRasterDevice(const SkBitmap& bitmap) |
| 72 : INHERITED(bitmap) |
| 73 , fWeOwnThePixels(true) |
| 74 , fSurface(NULL) { |
| 75 } |
| 76 |
| 77 SkRasterDevice::SkRasterDevice(const SkBitmap& bitmap, Direct) |
| 78 : INHERITED(bitmap) |
| 79 , fWeOwnThePixels(false) |
| 80 , fSurface(NULL) { |
| 81 |
| 82 } |
| 83 SkRasterDevice::SkRasterDevice(const SkBitmap& bitmap, const SkDeviceProperties&
props) |
| 84 : INHERITED(bitmap, props) |
| 85 , fWeOwnThePixels(true) |
| 86 , fSurface(NULL) { |
| 87 } |
| 88 |
| 89 SkBaseDevice* SkRasterDevice::onCreateCompatibleDevice(const CreateInfo& cinfo)
{ |
| 90 SkDeviceProperties leaky(cinfo.fPixelGeometry); |
| 91 SkBitmap bitmap; |
| 92 if (!CreateBackendBitmap(cinfo.fInfo, &bitmap)) { |
| 93 return NULL; |
| 94 } |
| 95 return SkNEW_ARGS(SkRasterDevice, (bitmap, leaky)); |
| 96 } |
| 97 |
| 98 const SkBitmap& SkRasterDevice::onAccessBitmap() { |
| 99 if (fSurface) { |
| 100 fSurface->aboutToDraw(SkSurface::kRetain_ContentChangeMode); |
| 101 } |
| 102 return this->INHERITED::onAccessBitmap(); |
| 103 } |
| 104 |
| 105 SkImage* SkRasterDevice::newImageSnapshot(const SkSurfaceProps* props) { |
| 106 return SkNewImageFromBitmap(this->getBackendBitmap(), fWeOwnThePixels, props
); |
| 107 } |
| 108 |
| 109 void SkRasterDevice::discard() { |
| 110 if (fSurface) { |
| 111 fSurface->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); |
| 112 } |
| 113 } |
| 114 |
| 115 void SkRasterDevice::discardOnWrite() { |
| 116 SkASSERT(fWeOwnThePixels); |
| 117 SkBitmap bitmap(this->getBackendBitmap()); |
| 118 bitmap.setPixelRef(NULL); |
| 119 bitmap.allocPixels(); |
| 120 this->replaceBitmapBackend(bitmap); |
| 121 } |
| 122 |
| 123 void SkRasterDevice::copyOnWrite() { |
| 124 SkASSERT(fWeOwnThePixels); |
| 125 SkBitmap bitmap; |
| 126 SkBitmap prev(this->getBackendBitmap()); |
| 127 prev.deepCopyTo(&bitmap); |
| 128 this->replaceBitmapBackend(bitmap); |
| 129 } |
| 130 |
39 /////////////////////////////////////////////////////////////////////////////// | 131 /////////////////////////////////////////////////////////////////////////////// |
40 | 132 |
41 bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) { | 133 bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) { |
42 if (info.isEmpty()) { | 134 if (info.isEmpty()) { |
43 return false; | 135 return false; |
44 } | 136 } |
45 | 137 |
46 static const size_t kMaxTotalSize = SK_MaxS32; | 138 static const size_t kMaxTotalSize = SK_MaxS32; |
47 | 139 |
48 int shift = 0; | 140 int shift = 0; |
(...skipping 29 matching lines...) Expand all Loading... |
78 if (size > kMaxTotalSize) { | 170 if (size > kMaxTotalSize) { |
79 return false; | 171 return false; |
80 } | 172 } |
81 | 173 |
82 return true; | 174 return true; |
83 } | 175 } |
84 | 176 |
85 SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t
rb, | 177 SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t
rb, |
86 void (*releaseProc)(void* pixels, void* conte
xt), void* context, | 178 void (*releaseProc)(void* pixels, void* conte
xt), void* context, |
87 const SkSurfaceProps* props) | 179 const SkSurfaceProps* props) |
88 : INHERITED(info, props) | 180 : INHERITED(info, props) { |
89 { | 181 SkBitmap bitmap; |
90 fBitmap.installPixels(info, pixels, rb, NULL, releaseProc, context); | 182 bitmap.installPixels(info, pixels, rb, NULL, releaseProc, context); |
91 fWeOwnThePixels = false; // We are "Direct" | 183 fDevice = SkNEW_ARGS(SkRasterDevice, (bitmap, SkRasterDevice::kDirect)); |
| 184 fDevice->setSurface(this); |
92 } | 185 } |
93 | 186 |
94 SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props) | 187 SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props) |
95 : INHERITED(pr->info().width(), pr->info().height(), props) | 188 : INHERITED(pr->info().width(), pr->info().height(), props) |
96 { | 189 { |
97 const SkImageInfo& info = pr->info(); | 190 const SkImageInfo& info = pr->info(); |
98 | 191 |
99 fBitmap.setInfo(info, info.minRowBytes()); | 192 SkBitmap bitmap; |
100 fBitmap.setPixelRef(pr); | 193 bitmap.setInfo(info, info.minRowBytes()); |
101 fWeOwnThePixels = true; | 194 bitmap.setPixelRef(pr); |
| 195 if (!info.isOpaque()) { |
| 196 bitmap.eraseColor(SK_ColorTRANSPARENT); |
| 197 } |
| 198 fDevice = SkNEW_ARGS(SkRasterDevice, (bitmap)); |
| 199 fDevice->setSurface(this); |
| 200 } |
102 | 201 |
103 if (!info.isOpaque()) { | 202 SkSurface_Raster::~SkSurface_Raster() { |
104 fBitmap.eraseColor(SK_ColorTRANSPARENT); | 203 fDevice->setSurface(NULL); |
105 } | 204 SkSafeUnref(fDevice); |
106 } | 205 } |
107 | 206 |
108 SkCanvas* SkSurface_Raster::onNewCanvas() { | 207 SkCanvas* SkSurface_Raster::onNewCanvas() { |
109 return SkNEW_ARGS(SkCanvas, (fBitmap, this->props())); | 208 return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), SkCanvas::kDefault_Ini
tFlags)); |
110 } | 209 } |
111 | 210 |
112 SkSurface* SkSurface_Raster::onNewSurface(const SkImageInfo& info) { | 211 SkSurface* SkSurface_Raster::onNewSurface(const SkImageInfo& info) { |
113 return SkSurface::NewRaster(info); | 212 return SkSurface::NewRaster(info); |
114 } | 213 } |
115 | 214 |
116 void SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, | 215 void SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, |
117 const SkPaint* paint) { | 216 const SkPaint* paint) { |
118 canvas->drawBitmap(fBitmap, x, y, paint); | 217 canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint); |
119 } | 218 } |
120 | 219 |
121 SkImage* SkSurface_Raster::onNewImageSnapshot(Budgeted) { | 220 SkImage* SkSurface_Raster::onNewImageSnapshot(Budgeted) { |
122 return SkNewImageFromBitmap(fBitmap, fWeOwnThePixels, &this->props()); | 221 return fDevice->newImageSnapshot(&this->props()); |
123 } | 222 } |
124 | 223 |
125 void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) { | 224 void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) { |
126 // are we sharing pixelrefs with the image? | 225 // Is the device sharing pixelrefs with the image? |
127 SkASSERT(this->getCachedImage(kNo_Budgeted)); | 226 SkImage* image = this->getCachedImage(kNo_Budgeted); |
128 if (SkBitmapImageGetPixelRef(this->getCachedImage(kNo_Budgeted)) == fBitmap.
pixelRef()) { | 227 SkASSERT(image); |
129 SkASSERT(fWeOwnThePixels); | 228 if (fDevice->backendUsesPixelRef(SkBitmapImageGetPixelRef(image))) { |
130 if (kDiscard_ContentChangeMode == mode) { | 229 if (kDiscard_ContentChangeMode == mode) { |
131 fBitmap.setPixelRef(NULL); | 230 fDevice->discardOnWrite(); |
132 fBitmap.allocPixels(); | |
133 } else { | 231 } else { |
134 SkBitmap prev(fBitmap); | 232 fDevice->copyOnWrite(); |
135 prev.deepCopyTo(&fBitmap); | |
136 } | 233 } |
137 // Now fBitmap is a deep copy of itself (and therefore different from | |
138 // what is being used by the image. Next we update the canvas to use | |
139 // this as its backend, so we can't modify the image's pixels anymore. | |
140 SkASSERT(this->getCachedCanvas()); | |
141 this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurfa
ce(fBitmap); | |
142 } | 234 } |
143 } | 235 } |
144 | 236 |
145 /////////////////////////////////////////////////////////////////////////////// | 237 /////////////////////////////////////////////////////////////////////////////// |
146 | 238 |
147 SkSurface* SkSurface::NewRasterDirectReleaseProc(const SkImageInfo& info, void*
pixels, size_t rb, | 239 SkSurface* SkSurface::NewRasterDirectReleaseProc(const SkImageInfo& info, void*
pixels, size_t rb, |
148 void (*releaseProc)(void* pixel
s, void* context), | 240 void (*releaseProc)(void* pixel
s, void* context), |
149 void* context, const SkSurfaceP
rops* props) { | 241 void* context, const SkSurfaceP
rops* props) { |
150 if (NULL == releaseProc) { | 242 if (NULL == releaseProc) { |
151 context = NULL; | 243 context = NULL; |
(...skipping 17 matching lines...) Expand all Loading... |
169 if (!SkSurface_Raster::Valid(info)) { | 261 if (!SkSurface_Raster::Valid(info)) { |
170 return NULL; | 262 return NULL; |
171 } | 263 } |
172 | 264 |
173 SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewAllocate(info, 0, NULL)); | 265 SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewAllocate(info, 0, NULL)); |
174 if (NULL == pr.get()) { | 266 if (NULL == pr.get()) { |
175 return NULL; | 267 return NULL; |
176 } | 268 } |
177 return SkNEW_ARGS(SkSurface_Raster, (pr, props)); | 269 return SkNEW_ARGS(SkSurface_Raster, (pr, props)); |
178 } | 270 } |
OLD | NEW |