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" |
| 12 #include "SkImage_Base.h" |
9 #include "SkImagePriv.h" | 13 #include "SkImagePriv.h" |
10 #include "SkCanvas.h" | |
11 #include "SkDevice.h" | |
12 #include "SkMallocPixelRef.h" | 14 #include "SkMallocPixelRef.h" |
13 | 15 |
14 static const size_t kIgnoreRowBytesValue = (size_t)~0; | 16 static const size_t kIgnoreRowBytesValue = (size_t)~0; |
| 17 class SkRasterDevice; |
15 | 18 |
16 class SkSurface_Raster : public SkSurface_Base { | 19 class SkSurface_Raster : public SkSurface_Base { |
17 public: | 20 public: |
18 static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue); | 21 static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue); |
19 | 22 |
20 SkSurface_Raster(const SkImageInfo&, void*, size_t rb, | 23 SkSurface_Raster(const SkImageInfo&, void*, size_t rb, |
21 void (*releaseProc)(void* pixels, void* context), void* con
text, | 24 void (*releaseProc)(void* pixels, void* context), void* con
text, |
22 const SkSurfaceProps*); | 25 const SkSurfaceProps*); |
23 SkSurface_Raster(SkPixelRef*, const SkSurfaceProps*); | 26 SkSurface_Raster(SkPixelRef*, const SkSurfaceProps*); |
24 | 27 ~SkSurface_Raster(); |
25 SkCanvas* onNewCanvas() SK_OVERRIDE; | 28 SkCanvas* onNewCanvas() SK_OVERRIDE; |
26 SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; | 29 SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; |
27 SkImage* onNewImageSnapshot(Budgeted) SK_OVERRIDE; | 30 SkImage* onNewImageSnapshot(Budgeted) SK_OVERRIDE; |
28 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, | 31 uint32_t generationID() SK_OVERRIDE; |
29 const SkPaint*) SK_OVERRIDE; | |
30 void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE; | |
31 | 32 |
32 private: | 33 private: |
33 SkBitmap fBitmap; | 34 SkRasterDevice* fDevice; |
| 35 uint32_t fLastDeviceGenerationID; |
| 36 uint32_t fGenerationID; |
34 | 37 |
35 typedef SkSurface_Base INHERITED; | 38 typedef SkSurface_Base INHERITED; |
36 }; | 39 }; |
37 | 40 |
| 41 /** A bitmap device that is used by SkSurface_Raster. */ |
| 42 class SkRasterDevice : public SkBitmapDevice { |
| 43 public: |
| 44 SkRasterDevice(const SkBitmap& bitmap); |
| 45 |
| 46 void setSurface(SkSurface_Raster* surface) { |
| 47 fSurface = surface; |
| 48 if (NULL != fSurface) { |
| 49 fSurfaceProps = fSurface->props(); |
| 50 } |
| 51 } |
| 52 |
| 53 uint32_t generationID() { return this->getBackendBitmap().getGenerationID();
} |
| 54 |
| 55 private: |
| 56 SkImage* onNewImageSnapshot() SK_OVERRIDE; |
| 57 |
| 58 SkBitmap& getBackendBitmap() { |
| 59 return fBitmap; // Note: accessing private SkBitmapDevice::fBitmap |
| 60 } |
| 61 |
| 62 SkSurface_Raster* fSurface; |
| 63 SkSurfaceProps fSurfaceProps; |
| 64 |
| 65 typedef SkBitmapDevice INHERITED; |
| 66 }; |
| 67 |
| 68 SkRasterDevice::SkRasterDevice(const SkBitmap& bitmap) |
| 69 : INHERITED(bitmap) |
| 70 , fSurface(NULL) |
| 71 , fSurfaceProps(0, kUnknown_SkPixelGeometry) { |
| 72 } |
| 73 |
| 74 SkImage* SkRasterDevice::onNewImageSnapshot() { |
| 75 // Override the SkImage creation to set the correct surface properties. |
| 76 return SkNewImageFromBitmap(fBitmap, &fSurfaceProps); |
| 77 } |
| 78 |
38 /////////////////////////////////////////////////////////////////////////////// | 79 /////////////////////////////////////////////////////////////////////////////// |
39 | 80 |
40 bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) { | 81 bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) { |
41 if (info.isEmpty()) { | 82 if (info.isEmpty()) { |
42 return false; | 83 return false; |
43 } | 84 } |
44 | 85 |
45 static const size_t kMaxTotalSize = SK_MaxS32; | 86 static const size_t kMaxTotalSize = SK_MaxS32; |
46 | 87 |
47 int shift = 0; | 88 int shift = 0; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 } | 120 } |
80 | 121 |
81 return true; | 122 return true; |
82 } | 123 } |
83 | 124 |
84 SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t
rb, | 125 SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t
rb, |
85 void (*releaseProc)(void* pixels, void* conte
xt), void* context, | 126 void (*releaseProc)(void* pixels, void* conte
xt), void* context, |
86 const SkSurfaceProps* props) | 127 const SkSurfaceProps* props) |
87 : INHERITED(info, props) | 128 : INHERITED(info, props) |
88 { | 129 { |
89 fBitmap.installPixels(info, pixels, rb, NULL, releaseProc, context); | 130 SkBitmap bitmap; |
| 131 bitmap.installPixels(info, pixels, rb, NULL, releaseProc, context); |
| 132 fDevice = SkNEW_ARGS(SkRasterDevice, (bitmap)); |
| 133 fDevice->setSurface(this); |
| 134 fLastDeviceGenerationID = fDevice->generationID(); |
| 135 fGenerationID = this->newGenerationID(); |
90 } | 136 } |
91 | 137 |
92 SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props) | 138 SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props) |
93 : INHERITED(pr->info().width(), pr->info().height(), props) | 139 : INHERITED(pr->info().width(), pr->info().height(), props) |
94 { | 140 { |
95 const SkImageInfo& info = pr->info(); | 141 const SkImageInfo& info = pr->info(); |
| 142 SkBitmap bitmap; |
| 143 bitmap.setInfo(info, info.minRowBytes()); |
| 144 bitmap.setPixelRef(pr); |
| 145 if (!info.isOpaque()) { |
| 146 bitmap.eraseColor(SK_ColorTRANSPARENT); |
| 147 } |
| 148 fDevice = SkNEW_ARGS(SkRasterDevice, (bitmap)); |
| 149 fDevice->setSurface(this); |
| 150 fLastDeviceGenerationID = fDevice->generationID(); |
| 151 fGenerationID = this->newGenerationID(); |
| 152 } |
96 | 153 |
97 fBitmap.setInfo(info, info.minRowBytes()); | 154 SkSurface_Raster::~SkSurface_Raster() { |
98 fBitmap.setPixelRef(pr); | 155 fDevice->setSurface(NULL); |
99 | 156 fDevice->unref(); |
100 if (!info.isOpaque()) { | |
101 fBitmap.eraseColor(SK_ColorTRANSPARENT); | |
102 } | |
103 } | 157 } |
104 | 158 |
105 SkCanvas* SkSurface_Raster::onNewCanvas() { | 159 SkCanvas* SkSurface_Raster::onNewCanvas() { |
106 return SkNEW_ARGS(SkCanvas, (fBitmap, this->props())); | 160 return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), SkCanvas::kDefault_Ini
tFlags)); |
107 } | 161 } |
108 | 162 |
109 SkSurface* SkSurface_Raster::onNewSurface(const SkImageInfo& info) { | 163 SkSurface* SkSurface_Raster::onNewSurface(const SkImageInfo& info) { |
110 return SkSurface::NewRaster(info); | 164 return SkSurface::NewRaster(info); |
111 } | 165 } |
112 | 166 |
113 void SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, | 167 SkImage* SkSurface_Raster::onNewImageSnapshot(Budgeted) { |
114 const SkPaint* paint) { | 168 return fDevice->newImageSnapshot(); |
115 canvas->drawBitmap(fBitmap, x, y, paint); | |
116 } | 169 } |
117 | 170 |
118 SkImage* SkSurface_Raster::onNewImageSnapshot(Budgeted) { | 171 uint32_t SkSurface_Raster::generationID() { |
119 return SkNewImageFromBitmap(fBitmap, &this->props()); | 172 uint32_t deviceGenerationID = fDevice->generationID(); |
| 173 if (fLastDeviceGenerationID != deviceGenerationID) { |
| 174 fLastDeviceGenerationID = deviceGenerationID; |
| 175 // We do not return the device generation id, as that might clash with a
nother |
| 176 // SkSurface::generationID() generated by other SkSurface subclass. |
| 177 fGenerationID = this->newGenerationID(); |
| 178 } |
| 179 // The SkSurface API mandates that empty surfaces return zero. However, thos
e are not valid by |
| 180 // SkSurface_Raster::Valid, so currently this is not taken into account. |
| 181 return fGenerationID; |
120 } | 182 } |
121 | |
122 void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) { | |
123 // are we sharing pixelrefs with the image? | |
124 SkASSERT(this->getCachedImage(kNo_Budgeted)); | |
125 if (SkBitmapImageGetPixelRef(this->getCachedImage(kNo_Budgeted)) == fBitmap.
pixelRef()) { | |
126 if (kDiscard_ContentChangeMode == mode) { | |
127 fBitmap.setPixelRef(NULL); | |
128 fBitmap.allocPixels(); | |
129 } else { | |
130 SkBitmap prev(fBitmap); | |
131 prev.deepCopyTo(&fBitmap); | |
132 } | |
133 // Now fBitmap is a deep copy of itself (and therefore different from | |
134 // what is being used by the image. Next we update the canvas to use | |
135 // this as its backend, so we can't modify the image's pixels anymore. | |
136 SkASSERT(this->getCachedCanvas()); | |
137 this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurfa
ce(fBitmap); | |
138 } | |
139 } | |
140 | |
141 /////////////////////////////////////////////////////////////////////////////// | 183 /////////////////////////////////////////////////////////////////////////////// |
142 | 184 |
143 SkSurface* SkSurface::NewRasterDirectReleaseProc(const SkImageInfo& info, void*
pixels, size_t rb, | 185 SkSurface* SkSurface::NewRasterDirectReleaseProc(const SkImageInfo& info, void*
pixels, size_t rb, |
144 void (*releaseProc)(void* pixel
s, void* context), | 186 void (*releaseProc)(void* pixel
s, void* context), |
145 void* context, const SkSurfaceP
rops* props) { | 187 void* context, const SkSurfaceP
rops* props) { |
146 if (NULL == releaseProc) { | 188 if (NULL == releaseProc) { |
147 context = NULL; | 189 context = NULL; |
148 } | 190 } |
149 if (!SkSurface_Raster::Valid(info, rb)) { | 191 if (!SkSurface_Raster::Valid(info, rb)) { |
150 return NULL; | 192 return NULL; |
(...skipping 14 matching lines...) Expand all Loading... |
165 if (!SkSurface_Raster::Valid(info)) { | 207 if (!SkSurface_Raster::Valid(info)) { |
166 return NULL; | 208 return NULL; |
167 } | 209 } |
168 | 210 |
169 SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewAllocate(info, 0, NULL)); | 211 SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewAllocate(info, 0, NULL)); |
170 if (NULL == pr.get()) { | 212 if (NULL == pr.get()) { |
171 return NULL; | 213 return NULL; |
172 } | 214 } |
173 return SkNEW_ARGS(SkSurface_Raster, (pr, props)); | 215 return SkNEW_ARGS(SkSurface_Raster, (pr, props)); |
174 } | 216 } |
OLD | NEW |