OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "SkGpuDevice.h" | 8 #include "SkGpuDevice.h" |
9 | 9 |
10 #include "effects/GrBicubicEffect.h" | 10 #include "effects/GrBicubicEffect.h" |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 | 123 |
124 /////////////////////////////////////////////////////////////////////////////// | 124 /////////////////////////////////////////////////////////////////////////////// |
125 | 125 |
126 SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props
, unsigned flags) { | 126 SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props
, unsigned flags) { |
127 if (!rt || rt->wasDestroyed()) { | 127 if (!rt || rt->wasDestroyed()) { |
128 return NULL; | 128 return NULL; |
129 } | 129 } |
130 return SkNEW_ARGS(SkGpuDevice, (rt, props, flags)); | 130 return SkNEW_ARGS(SkGpuDevice, (rt, props, flags)); |
131 } | 131 } |
132 | 132 |
| 133 SkGpuDevice* SkGpuDevice::CreateWithReverseOwnershipDeprecated(GrRenderTarget* r
t, |
| 134 const SkSurfacePr
ops* props, |
| 135 unsigned flags) { |
| 136 SkGpuDevice* device = SkGpuDevice::Create(rt, props, flags); |
| 137 if (NULL == device) { |
| 138 return device; |
| 139 } |
| 140 device->fDeviceOwnsSurface = true; |
| 141 return device; |
| 142 } |
| 143 |
133 static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps* prop
s) { | 144 static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps* prop
s) { |
134 if (props) { | 145 if (props) { |
135 return SkDeviceProperties(props->pixelGeometry()); | 146 return SkDeviceProperties(props->pixelGeometry()); |
136 } else { | 147 } else { |
137 return SkDeviceProperties(SkDeviceProperties::kLegacyLCD_InitType); | 148 return SkDeviceProperties(SkDeviceProperties::kLegacyLCD_InitType); |
138 } | 149 } |
139 } | 150 } |
140 | 151 |
141 static SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) { | 152 static SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) { |
142 if (props) { | 153 if (props) { |
143 return SkSurfaceProps(*props); | 154 return SkSurfaceProps(*props); |
144 } else { | 155 } else { |
145 return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType); | 156 return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType); |
146 } | 157 } |
147 } | 158 } |
148 | 159 |
149 SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsign
ed flags) | 160 SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsign
ed flags) |
150 : INHERITED(surfaceprops_to_deviceprops(props)) | 161 : INHERITED(surfaceprops_to_deviceprops(props)) |
151 , fSurfaceProps(copy_or_default_props(props)) | 162 , fSurfaceProps(copy_or_default_props(props)) |
| 163 , fSurface(NULL) |
| 164 , fDeviceOwnsSurface(false) |
152 { | 165 { |
153 fDrawProcs = NULL; | 166 fDrawProcs = NULL; |
154 | 167 |
155 fContext = SkRef(rt->getContext()); | 168 fContext = SkRef(rt->getContext()); |
156 fNeedClear = flags & kNeedClear_Flag; | 169 fNeedClear = flags & kNeedClear_Flag; |
157 | 170 |
158 fRenderTarget = SkRef(rt); | 171 fRenderTarget = SkRef(rt); |
159 | 172 |
160 SkImageInfo info = rt->surfacePriv().info(); | 173 SkImageInfo info = rt->surfacePriv().info(); |
161 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt)); | 174 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt)); |
162 fLegacyBitmap.setInfo(info); | 175 fLegacyBitmap.setInfo(info); |
163 fLegacyBitmap.setPixelRef(pr)->unref(); | 176 fLegacyBitmap.setPixelRef(pr)->unref(); |
164 | 177 |
165 bool useDFT = fSurfaceProps.isUseDistanceFieldFonts(); | 178 bool useDFT = fSurfaceProps.isUseDistanceFieldFonts(); |
166 fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProp
erties(), useDFT); | 179 fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProp
erties(), useDFT); |
167 } | 180 } |
168 | 181 |
| 182 void SkGpuDevice::setSurface(SkSurface_Gpu* surface) { |
| 183 if (fDeviceOwnsSurface) { |
| 184 SkRefCnt_SafeAssign(fSurface, surface); |
| 185 } else { |
| 186 fSurface = surface; |
| 187 } |
| 188 } |
| 189 |
169 SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgete
d, | 190 SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgete
d, |
170 const SkImageInfo& info, int sampleCount, | 191 const SkImageInfo& info, int sampleCount, |
171 const SkSurfaceProps* props, unsigned flags) { | 192 const SkSurfaceProps* props, unsigned flags) { |
172 | 193 |
173 SkAutoTUnref<GrRenderTarget> rt(SkSurface_Gpu::CreateRenderTarget(context, b
udgeted, info, | 194 SkAutoTUnref<GrRenderTarget> rt(SkSurface_Gpu::CreateRenderTarget(context, b
udgeted, info, |
174 sampleCoun
t)); | 195 sampleCoun
t)); |
175 if (!rt) { | 196 if (!rt) { |
176 return NULL; | 197 return NULL; |
177 } | 198 } |
178 | 199 |
(...skipping 10 matching lines...) Expand all Loading... |
189 // The GrContext takes a ref on the target. We don't want to cause the rende
r | 210 // The GrContext takes a ref on the target. We don't want to cause the rende
r |
190 // target to be unnecessarily kept alive. | 211 // target to be unnecessarily kept alive. |
191 if (fContext->getRenderTarget() == fRenderTarget) { | 212 if (fContext->getRenderTarget() == fRenderTarget) { |
192 fContext->setRenderTarget(NULL); | 213 fContext->setRenderTarget(NULL); |
193 } | 214 } |
194 | 215 |
195 if (fContext->getClip() == &fClipData) { | 216 if (fContext->getClip() == &fClipData) { |
196 fContext->setClip(NULL); | 217 fContext->setClip(NULL); |
197 } | 218 } |
198 | 219 |
199 fRenderTarget->unref(); | 220 this->setSurface(NULL); |
200 fContext->unref(); | 221 fContext->unref(); |
201 } | 222 } |
202 | 223 |
203 /////////////////////////////////////////////////////////////////////////////// | 224 /////////////////////////////////////////////////////////////////////////////// |
204 | 225 |
| 226 void SkGpuDevice::discard() { |
| 227 if (fSurface) { |
| 228 fSurface->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); |
| 229 } |
| 230 } |
| 231 |
205 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
_t dstRowBytes, | 232 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
_t dstRowBytes, |
206 int x, int y) { | 233 int x, int y) { |
207 DO_DEFERRED_CLEAR(); | 234 DO_DEFERRED_CLEAR(); |
208 | 235 |
209 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels | 236 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels |
210 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo); | 237 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo); |
211 if (kUnknown_GrPixelConfig == config) { | 238 if (kUnknown_GrPixelConfig == config) { |
212 return false; | 239 return false; |
213 } | 240 } |
214 | 241 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 void SkGpuDevice::onDetachFromCanvas() { | 281 void SkGpuDevice::onDetachFromCanvas() { |
255 INHERITED::onDetachFromCanvas(); | 282 INHERITED::onDetachFromCanvas(); |
256 fClipData.fClipStack.reset(NULL); | 283 fClipData.fClipStack.reset(NULL); |
257 } | 284 } |
258 | 285 |
259 // call this every draw call, to ensure that the context reflects our state, | 286 // call this every draw call, to ensure that the context reflects our state, |
260 // and not the state from some other canvas/device | 287 // and not the state from some other canvas/device |
261 void SkGpuDevice::prepareDraw(const SkDraw& draw) { | 288 void SkGpuDevice::prepareDraw(const SkDraw& draw) { |
262 SkASSERT(fClipData.fClipStack); | 289 SkASSERT(fClipData.fClipStack); |
263 | 290 |
| 291 if (fSurface) { |
| 292 fSurface->aboutToDraw(SkSurface::kRetain_ContentChangeMode); |
| 293 } |
| 294 |
264 fContext->setRenderTarget(fRenderTarget); | 295 fContext->setRenderTarget(fRenderTarget); |
265 | 296 |
266 SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack); | 297 SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack); |
267 | 298 |
268 fClipData.fOrigin = this->getOrigin(); | 299 fClipData.fOrigin = this->getOrigin(); |
269 | 300 |
270 fContext->setClip(&fClipData); | 301 fContext->setClip(&fClipData); |
271 | 302 |
272 DO_DEFERRED_CLEAR(); | 303 DO_DEFERRED_CLEAR(); |
273 } | 304 } |
(...skipping 1515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1789 } | 1820 } |
1790 | 1821 |
1791 void SkGpuDevice::flush() { | 1822 void SkGpuDevice::flush() { |
1792 DO_DEFERRED_CLEAR(); | 1823 DO_DEFERRED_CLEAR(); |
1793 fRenderTarget->prepareForExternalRead(); | 1824 fRenderTarget->prepareForExternalRead(); |
1794 } | 1825 } |
1795 | 1826 |
1796 /////////////////////////////////////////////////////////////////////////////// | 1827 /////////////////////////////////////////////////////////////////////////////// |
1797 | 1828 |
1798 SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) { | 1829 SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) { |
1799 GrSurfaceDesc desc; | 1830 return fSurface->createCompatibleDeviceDeprecated(cinfo); |
1800 desc.fConfig = fRenderTarget->config(); | |
1801 desc.fFlags = kRenderTarget_GrSurfaceFlag; | |
1802 desc.fWidth = cinfo.fInfo.width(); | |
1803 desc.fHeight = cinfo.fInfo.height(); | |
1804 desc.fSampleCnt = fRenderTarget->numSamples(); | |
1805 | |
1806 SkAutoTUnref<GrTexture> texture; | |
1807 // Skia's convention is to only clear a device if it is non-opaque. | |
1808 unsigned flags = cinfo.fInfo.isOpaque() ? 0 : kNeedClear_Flag; | |
1809 | |
1810 // layers are never draw in repeat modes, so we can request an approx | |
1811 // match and ignore any padding. | |
1812 const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == cinfo.fUsage)
? | |
1813 GrContext::kApprox_ScratchTexMat
ch : | |
1814 GrContext::kExact_ScratchTexMatc
h; | |
1815 texture.reset(fContext->refScratchTexture(desc, match)); | |
1816 | |
1817 if (texture) { | |
1818 SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry); | |
1819 return SkGpuDevice::Create(texture->asRenderTarget(), &props, flags); | |
1820 } else { | |
1821 SkDebugf("---- failed to create compatible device texture [%d %d]\n", | |
1822 cinfo.fInfo.width(), cinfo.fInfo.height()); | |
1823 return NULL; | |
1824 } | |
1825 } | 1831 } |
1826 | 1832 |
1827 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps
& props) { | 1833 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps
& props) { |
1828 // TODO: Change the signature of newSurface to take a budgeted parameter. | 1834 // TODO: Change the signature of newSurface to take a budgeted parameter. |
1829 static const SkSurface::Budgeted kBudgeted = SkSurface::kNo_Budgeted; | 1835 static const SkSurface::Budgeted kBudgeted = SkSurface::kNo_Budgeted; |
1830 return SkSurface::NewRenderTarget(fContext, kBudgeted, info, fRenderTarget->
numSamples(), | 1836 return SkSurface::NewRenderTarget(fContext, kBudgeted, info, fRenderTarget->
numSamples(), |
1831 &props); | 1837 &props); |
1832 } | 1838 } |
1833 | 1839 |
1834 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
* mainPicture, | 1840 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
* mainPicture, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1890 #endif | 1896 #endif |
1891 } | 1897 } |
1892 | 1898 |
1893 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 1899 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
1894 // We always return a transient cache, so it is freed after each | 1900 // We always return a transient cache, so it is freed after each |
1895 // filter traversal. | 1901 // filter traversal. |
1896 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); | 1902 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); |
1897 } | 1903 } |
1898 | 1904 |
1899 #endif | 1905 #endif |
OLD | NEW |