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 "GrBlurUtils.h" | 10 #include "GrBlurUtils.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 extern bool (*gShouldDrawProc)(); | 59 extern bool (*gShouldDrawProc)(); |
60 #define CHECK_SHOULD_DRAW(draw) \ | 60 #define CHECK_SHOULD_DRAW(draw) \ |
61 do { \ | 61 do { \ |
62 if (gShouldDrawProc && !gShouldDrawProc()) return; \ | 62 if (gShouldDrawProc && !gShouldDrawProc()) return; \ |
63 this->prepareDraw(draw); \ | 63 this->prepareDraw(draw); \ |
64 } while (0) | 64 } while (0) |
65 #else | 65 #else |
66 #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw) | 66 #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw) |
67 #endif | 67 #endif |
68 | 68 |
69 #define DO_DEFERRED_CLEAR() \ | |
70 do { \ | |
71 if (fNeedClear) { \ | |
72 this->clearAll(); \ | |
73 } \ | |
74 } while (false) \ | |
75 | |
76 /////////////////////////////////////////////////////////////////////////////// | 69 /////////////////////////////////////////////////////////////////////////////// |
77 | 70 |
78 #define CHECK_FOR_ANNOTATION(paint) \ | 71 #define CHECK_FOR_ANNOTATION(paint) \ |
79 do { if (paint.getAnnotation()) { return; } } while (0) | 72 do { if (paint.getAnnotation()) { return; } } while (0) |
80 | 73 |
81 /////////////////////////////////////////////////////////////////////////////// | 74 /////////////////////////////////////////////////////////////////////////////// |
82 | 75 |
83 // Helper for turning a bitmap into a texture. If the bitmap is GrTexture backed
this | 76 // Helper for turning a bitmap into a texture. If the bitmap is GrTexture backed
this |
84 // just accesses the backing GrTexture. Otherwise, it creates a cached texture | 77 // just accesses the backing GrTexture. Otherwise, it creates a cached texture |
85 // representation and releases it in the destructor. | 78 // representation and releases it in the destructor. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 } | 161 } |
169 | 162 |
170 return new SkGpuDevice(rt, info.width(), info.height(), props, flags); | 163 return new SkGpuDevice(rt, info.width(), info.height(), props, flags); |
171 } | 164 } |
172 | 165 |
173 SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height, | 166 SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height, |
174 const SkSurfaceProps* props, unsigned flags) | 167 const SkSurfaceProps* props, unsigned flags) |
175 : INHERITED(SkSurfacePropsCopyOrDefault(props)) | 168 : INHERITED(SkSurfacePropsCopyOrDefault(props)) |
176 , fContext(SkRef(rt->getContext())) | 169 , fContext(SkRef(rt->getContext())) |
177 , fRenderTarget(SkRef(rt)) { | 170 , fRenderTarget(SkRef(rt)) { |
178 fNeedClear = SkToBool(flags & kNeedClear_Flag); | |
179 fOpaque = SkToBool(flags & kIsOpaque_Flag); | 171 fOpaque = SkToBool(flags & kIsOpaque_Flag); |
180 | 172 |
181 SkAlphaType at = fOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; | 173 SkAlphaType at = fOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; |
182 SkImageInfo info = rt->surfacePriv().info(at).makeWH(width, height); | 174 SkImageInfo info = rt->surfacePriv().info(at).makeWH(width, height); |
183 SkPixelRef* pr = new SkGrPixelRef(info, rt); | 175 SkPixelRef* pr = new SkGrPixelRef(info, rt); |
184 fLegacyBitmap.setInfo(info); | 176 fLegacyBitmap.setInfo(info); |
185 fLegacyBitmap.setPixelRef(pr)->unref(); | 177 fLegacyBitmap.setPixelRef(pr)->unref(); |
186 | 178 |
187 fDrawContext.reset(this->context()->drawContext(rt, &this->surfaceProps())); | 179 fDrawContext.reset(this->context()->drawContext(rt, &this->surfaceProps())); |
| 180 if (flags & kNeedClear_Flag) { |
| 181 this->clearAll(); |
| 182 } |
188 } | 183 } |
189 | 184 |
190 GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B
udgeted budgeted, | 185 GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B
udgeted budgeted, |
191 const SkImageInfo& origInfo, int
sampleCount) { | 186 const SkImageInfo& origInfo, int
sampleCount) { |
192 if (kUnknown_SkColorType == origInfo.colorType() || | 187 if (kUnknown_SkColorType == origInfo.colorType() || |
193 origInfo.width() < 0 || origInfo.height() < 0) { | 188 origInfo.width() < 0 || origInfo.height() < 0) { |
194 return nullptr; | 189 return nullptr; |
195 } | 190 } |
196 | 191 |
197 if (!context) { | 192 if (!context) { |
(...skipping 26 matching lines...) Expand all Loading... |
224 } | 219 } |
225 SkASSERT(nullptr != texture->asRenderTarget()); | 220 SkASSERT(nullptr != texture->asRenderTarget()); |
226 return texture->asRenderTarget(); | 221 return texture->asRenderTarget(); |
227 } | 222 } |
228 | 223 |
229 /////////////////////////////////////////////////////////////////////////////// | 224 /////////////////////////////////////////////////////////////////////////////// |
230 | 225 |
231 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
_t dstRowBytes, | 226 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
_t dstRowBytes, |
232 int x, int y) { | 227 int x, int y) { |
233 ASSERT_SINGLE_OWNER | 228 ASSERT_SINGLE_OWNER |
234 DO_DEFERRED_CLEAR(); | |
235 | 229 |
236 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels | 230 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels |
237 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo); | 231 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo); |
238 if (kUnknown_GrPixelConfig == config) { | 232 if (kUnknown_GrPixelConfig == config) { |
239 return false; | 233 return false; |
240 } | 234 } |
241 | 235 |
242 uint32_t flags = 0; | 236 uint32_t flags = 0; |
243 if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { | 237 if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { |
244 flags = GrContext::kUnpremul_PixelOpsFlag; | 238 flags = GrContext::kUnpremul_PixelOpsFlag; |
(...skipping 17 matching lines...) Expand all Loading... |
262 fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels
, rowBytes, flags); | 256 fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels
, rowBytes, flags); |
263 | 257 |
264 // need to bump our genID for compatibility with clients that "know" we have
a bitmap | 258 // need to bump our genID for compatibility with clients that "know" we have
a bitmap |
265 fLegacyBitmap.notifyPixelsChanged(); | 259 fLegacyBitmap.notifyPixelsChanged(); |
266 | 260 |
267 return true; | 261 return true; |
268 } | 262 } |
269 | 263 |
270 const SkBitmap& SkGpuDevice::onAccessBitmap() { | 264 const SkBitmap& SkGpuDevice::onAccessBitmap() { |
271 ASSERT_SINGLE_OWNER | 265 ASSERT_SINGLE_OWNER |
272 DO_DEFERRED_CLEAR(); | |
273 return fLegacyBitmap; | 266 return fLegacyBitmap; |
274 } | 267 } |
275 | 268 |
276 bool SkGpuDevice::onAccessPixels(SkPixmap* pmap) { | 269 bool SkGpuDevice::onAccessPixels(SkPixmap* pmap) { |
277 ASSERT_SINGLE_OWNER | 270 ASSERT_SINGLE_OWNER |
278 DO_DEFERRED_CLEAR(); | |
279 // For compatibility with clients the know we're backed w/ a bitmap, and wan
t to inspect its | 271 // For compatibility with clients the know we're backed w/ a bitmap, and wan
t to inspect its |
280 // genID. When we can hide/remove that fact, we can eliminate this call to n
otify. | 272 // genID. When we can hide/remove that fact, we can eliminate this call to n
otify. |
281 // ... ugh. | 273 // ... ugh. |
282 fLegacyBitmap.notifyPixelsChanged(); | 274 fLegacyBitmap.notifyPixelsChanged(); |
283 return false; | 275 return false; |
284 } | 276 } |
285 | 277 |
286 void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) { | 278 void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) { |
287 ASSERT_SINGLE_OWNER | 279 ASSERT_SINGLE_OWNER |
288 INHERITED::onAttachToCanvas(canvas); | 280 INHERITED::onAttachToCanvas(canvas); |
(...skipping 11 matching lines...) Expand all Loading... |
300 | 292 |
301 // call this every draw call, to ensure that the context reflects our state, | 293 // call this every draw call, to ensure that the context reflects our state, |
302 // and not the state from some other canvas/device | 294 // and not the state from some other canvas/device |
303 void SkGpuDevice::prepareDraw(const SkDraw& draw) { | 295 void SkGpuDevice::prepareDraw(const SkDraw& draw) { |
304 ASSERT_SINGLE_OWNER | 296 ASSERT_SINGLE_OWNER |
305 SkASSERT(fClipStack.get()); | 297 SkASSERT(fClipStack.get()); |
306 | 298 |
307 SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack); | 299 SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack); |
308 | 300 |
309 fClip.setClipStack(fClipStack, &this->getOrigin()); | 301 fClip.setClipStack(fClipStack, &this->getOrigin()); |
310 | |
311 DO_DEFERRED_CLEAR(); | |
312 } | 302 } |
313 | 303 |
314 GrRenderTarget* SkGpuDevice::accessRenderTarget() { | 304 GrRenderTarget* SkGpuDevice::accessRenderTarget() { |
315 ASSERT_SINGLE_OWNER | 305 ASSERT_SINGLE_OWNER |
316 DO_DEFERRED_CLEAR(); | |
317 return fRenderTarget; | 306 return fRenderTarget; |
318 } | 307 } |
319 | 308 |
320 void SkGpuDevice::clearAll() { | 309 void SkGpuDevice::clearAll() { |
321 ASSERT_SINGLE_OWNER | 310 ASSERT_SINGLE_OWNER |
322 GrColor color = 0; | 311 GrColor color = 0; |
323 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "clearAll", fContext); | 312 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "clearAll", fContext); |
324 SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); | 313 SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); |
325 fDrawContext->clear(&rect, color, true); | 314 fDrawContext->clear(&rect, color, true); |
326 fNeedClear = false; | |
327 } | 315 } |
328 | 316 |
329 void SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) { | 317 void SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) { |
330 ASSERT_SINGLE_OWNER | 318 ASSERT_SINGLE_OWNER |
331 // Caller must have accessed the render target, because it knows the rt must
be replaced. | |
332 SkASSERT(!fNeedClear); | |
333 | 319 |
334 SkSurface::Budgeted budgeted = | 320 SkSurface::Budgeted budgeted = |
335 fRenderTarget->resourcePriv().isBudgeted() ? SkSurface::kYes_Budgete
d | 321 fRenderTarget->resourcePriv().isBudgeted() ? SkSurface::kYes_Budgete
d |
336 : SkSurface::kNo_Budgeted
; | 322 : SkSurface::kNo_Budgeted
; |
337 | 323 |
338 SkAutoTUnref<GrRenderTarget> newRT(CreateRenderTarget( | 324 SkAutoTUnref<GrRenderTarget> newRT(CreateRenderTarget( |
339 this->context(), budgeted, this->imageInfo(), fRenderTarget->desc().fSam
pleCnt)); | 325 this->context(), budgeted, this->imageInfo(), fRenderTarget->desc().fSam
pleCnt)); |
340 | 326 |
341 if (nullptr == newRT) { | 327 if (nullptr == newRT) { |
342 return; | 328 return; |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 this->drawTextureProducer(&maker, src, dst, constraint, *draw.fMatrix, fClip
, paint); | 1289 this->drawTextureProducer(&maker, src, dst, constraint, *draw.fMatrix, fClip
, paint); |
1304 } | 1290 } |
1305 | 1291 |
1306 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, | 1292 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, |
1307 int x, int y, const SkPaint& paint) { | 1293 int x, int y, const SkPaint& paint) { |
1308 ASSERT_SINGLE_OWNER | 1294 ASSERT_SINGLE_OWNER |
1309 // clear of the source device must occur before CHECK_SHOULD_DRAW | 1295 // clear of the source device must occur before CHECK_SHOULD_DRAW |
1310 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDevice", fContext); | 1296 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDevice", fContext); |
1311 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); | 1297 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); |
1312 | 1298 |
1313 // TODO: If the source device covers the whole of this device, we could | |
1314 // omit fNeedsClear -related flushing. | |
1315 // TODO: if source needs clear, we could maybe omit the draw fully. | |
1316 | |
1317 // drawDevice is defined to be in device coords. | 1299 // drawDevice is defined to be in device coords. |
1318 CHECK_SHOULD_DRAW(draw); | 1300 CHECK_SHOULD_DRAW(draw); |
1319 | 1301 |
1320 GrRenderTarget* devRT = dev->accessRenderTarget(); | 1302 GrRenderTarget* devRT = dev->accessRenderTarget(); |
1321 GrTexture* devTex; | 1303 GrTexture* devTex; |
1322 if (nullptr == (devTex = devRT->asTexture())) { | 1304 if (nullptr == (devTex = devRT->asTexture())) { |
1323 return; | 1305 return; |
1324 } | 1306 } |
1325 | 1307 |
1326 const SkImageInfo ii = dev->imageInfo(); | 1308 const SkImageInfo ii = dev->imageInfo(); |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1762 } | 1744 } |
1763 | 1745 |
1764 /////////////////////////////////////////////////////////////////////////////// | 1746 /////////////////////////////////////////////////////////////////////////////// |
1765 | 1747 |
1766 bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const { | 1748 bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const { |
1767 return GrTextContext::ShouldDisableLCD(paint); | 1749 return GrTextContext::ShouldDisableLCD(paint); |
1768 } | 1750 } |
1769 | 1751 |
1770 void SkGpuDevice::flush() { | 1752 void SkGpuDevice::flush() { |
1771 ASSERT_SINGLE_OWNER | 1753 ASSERT_SINGLE_OWNER |
1772 DO_DEFERRED_CLEAR(); | |
1773 | 1754 |
1774 // Clear batch debugging output | 1755 // Clear batch debugging output |
1775 // TODO not exactly sure where this should live | 1756 // TODO not exactly sure where this should live |
1776 if (GR_BATCH_DEBUGGING_OUTPUT) { | 1757 if (GR_BATCH_DEBUGGING_OUTPUT) { |
1777 SkDebugf("%s\n", fContext->getAuditTrail()->toJson().c_str()); | 1758 SkDebugf("%s\n", fContext->getAuditTrail()->toJson().c_str()); |
1778 // TODO This currently crashes because not all ops are accounted for | 1759 // TODO This currently crashes because not all ops are accounted for |
1779 GR_AUDIT_TRAIL_RESET(fContext->getAuditTrail()); | 1760 GR_AUDIT_TRAIL_RESET(fContext->getAuditTrail()); |
1780 } | 1761 } |
1781 fRenderTarget->prepareForExternalIO(); | 1762 fRenderTarget->prepareForExternalIO(); |
1782 } | 1763 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1900 } | 1881 } |
1901 | 1882 |
1902 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 1883 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
1903 ASSERT_SINGLE_OWNER | 1884 ASSERT_SINGLE_OWNER |
1904 // We always return a transient cache, so it is freed after each | 1885 // We always return a transient cache, so it is freed after each |
1905 // filter traversal. | 1886 // filter traversal. |
1906 return SkGpuDevice::NewImageFilterCache(); | 1887 return SkGpuDevice::NewImageFilterCache(); |
1907 } | 1888 } |
1908 | 1889 |
1909 #endif | 1890 #endif |
OLD | NEW |