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 "GrBitmapTextContext.h" | 10 #include "GrBitmapTextContext.h" |
11 #include "GrContext.h" | 11 #include "GrContext.h" |
12 #include "GrDistanceFieldTextContext.h" | 12 #include "GrDistanceFieldTextContext.h" |
13 #include "GrGpu.h" | 13 #include "GrGpu.h" |
14 #include "GrGpuResourcePriv.h" | 14 #include "GrGpuResourcePriv.h" |
15 #include "GrLayerHoister.h" | 15 #include "GrLayerHoister.h" |
16 #include "GrRecordReplaceDraw.h" | 16 #include "GrRecordReplaceDraw.h" |
17 #include "GrStrokeInfo.h" | 17 #include "GrStrokeInfo.h" |
18 #include "GrTracing.h" | 18 #include "GrTracing.h" |
19 #include "SkCanvasPriv.h" | 19 #include "SkCanvasPriv.h" |
20 #include "SkDeviceImageFilterProxy.h" | 20 #include "SkDeviceImageFilterProxy.h" |
21 #include "SkDrawProcs.h" | 21 #include "SkDrawProcs.h" |
22 #include "SkErrorInternals.h" | 22 #include "SkErrorInternals.h" |
23 #include "SkGlyphCache.h" | 23 #include "SkGlyphCache.h" |
24 #include "SkGrTexturePixelRef.h" | 24 #include "SkGrTexturePixelRef.h" |
25 #include "SkImageFilter.h" | 25 #include "SkImageFilter.h" |
| 26 #include "SkImagePriv.h" |
26 #include "SkImage_Base.h" | 27 #include "SkImage_Base.h" |
27 #include "SkLayerInfo.h" | 28 #include "SkLayerInfo.h" |
28 #include "SkMaskFilter.h" | 29 #include "SkMaskFilter.h" |
29 #include "SkPathEffect.h" | 30 #include "SkPathEffect.h" |
30 #include "SkPicture.h" | 31 #include "SkPicture.h" |
31 #include "SkPictureData.h" | 32 #include "SkPictureData.h" |
32 #include "SkRRect.h" | 33 #include "SkRRect.h" |
33 #include "SkRecord.h" | 34 #include "SkRecord.h" |
34 #include "SkStroke.h" | 35 #include "SkStroke.h" |
35 #include "SkSurface.h" | 36 #include "SkSurface.h" |
36 #include "SkSurface_Gpu.h" | 37 #include "SkSurface_Gpu.h" |
37 #include "SkTLazy.h" | 38 #include "SkTLazy.h" |
38 #include "SkUtils.h" | 39 #include "SkUtils.h" |
39 #include "SkVertState.h" | 40 #include "SkVertState.h" |
40 #include "SkXfermode.h" | 41 #include "SkXfermode.h" |
41 #include "effects/GrBicubicEffect.h" | 42 #include "effects/GrBicubicEffect.h" |
42 #include "effects/GrDashingEffect.h" | 43 #include "effects/GrDashingEffect.h" |
43 #include "effects/GrSimpleTextureEffect.h" | 44 #include "effects/GrSimpleTextureEffect.h" |
44 #include "effects/GrTextureDomain.h" | 45 #include "effects/GrTextureDomain.h" |
45 | 46 |
46 #if SK_SUPPORT_GPU | 47 #if SK_SUPPORT_GPU |
47 | 48 |
48 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 }; | 49 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 }; |
49 | 50 |
50 #if 0 | 51 #if 0 |
51 extern bool (*gShouldDrawProc)(); | 52 extern bool (*gShouldDrawProc)(); |
52 #define CHECK_SHOULD_DRAW(draw) \ | 53 #define CHECK_SHOULD_DRAW(draw) \ |
53 do { \ | 54 do { \ |
54 if (gShouldDrawProc && !gShouldDrawProc()) return; \ | 55 if (gShouldDrawProc && !gShouldDrawProc()) return; \ |
55 this->prepareDraw(draw); \ | 56 if (!this->prepareDraw(draw)) return; \ |
56 } while (0) | 57 } while (0) |
57 #else | 58 #else |
58 #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw) | 59 #define CHECK_SHOULD_DRAW(draw) if (!this->prepareDraw(draw)) return; |
59 #endif | 60 #endif |
60 | 61 |
| 62 |
61 // This constant represents the screen alignment criterion in texels for | 63 // This constant represents the screen alignment criterion in texels for |
62 // requiring texture domain clamping to prevent color bleeding when drawing | 64 // requiring texture domain clamping to prevent color bleeding when drawing |
63 // a sub region of a larger source image. | 65 // a sub region of a larger source image. |
64 #define COLOR_BLEED_TOLERANCE 0.001f | 66 #define COLOR_BLEED_TOLERANCE 0.001f |
65 | 67 |
66 #define DO_DEFERRED_CLEAR() \ | 68 #define DO_DEFERRED_CLEAR() \ |
67 do { \ | 69 do { \ |
68 if (fNeedClear) { \ | 70 if (fNeedClear) { \ |
69 this->clearAll(); \ | 71 this->clearAll(); \ |
70 } \ | 72 } \ |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 } | 161 } |
160 | 162 |
161 static SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) { | 163 static SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) { |
162 if (props) { | 164 if (props) { |
163 return SkSurfaceProps(*props); | 165 return SkSurfaceProps(*props); |
164 } else { | 166 } else { |
165 return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType); | 167 return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType); |
166 } | 168 } |
167 } | 169 } |
168 | 170 |
| 171 namespace { |
| 172 |
| 173 void wrap_surface(GrSurface* rt, SkBitmap* bm) { |
| 174 bm->setInfo(rt->surfacePriv().info()); |
| 175 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (rt->surfacePriv().info(), rt)); |
| 176 bm->setPixelRef(pr)->unref(); |
| 177 } |
| 178 |
| 179 }; |
| 180 |
169 SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsign
ed flags) | 181 SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsign
ed flags) |
170 : INHERITED(surfaceprops_to_deviceprops(props)) | 182 : INHERITED(surfaceprops_to_deviceprops(props)) |
171 , fSurfaceProps(copy_or_default_props(props)) | 183 , fSurfaceProps(copy_or_default_props(props)) |
| 184 , fSurface(NULL) |
172 { | 185 { |
173 fDrawProcs = NULL; | 186 fDrawProcs = NULL; |
174 | 187 |
175 fContext = SkRef(rt->getContext()); | 188 fContext = SkRef(rt->getContext()); |
176 fNeedClear = flags & kNeedClear_Flag; | 189 fNeedClear = flags & kNeedClear_Flag; |
177 | 190 |
178 fRenderTarget = SkRef(rt); | 191 fRenderTarget = SkRef(rt); |
179 | 192 |
180 SkImageInfo info = rt->surfacePriv().info(); | 193 wrap_surface(fRenderTarget, &fLegacyBitmap); |
181 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt)); | |
182 fLegacyBitmap.setInfo(info); | |
183 fLegacyBitmap.setPixelRef(pr)->unref(); | |
184 | |
185 bool useDFT = fSurfaceProps.isUseDistanceFieldFonts(); | 194 bool useDFT = fSurfaceProps.isUseDistanceFieldFonts(); |
186 fTextContext = fContext->createTextContext(fRenderTarget, this, this->getLea
kyProperties(), | 195 fTextContext = fContext->createTextContext(fRenderTarget, this, this->getLea
kyProperties(), |
187 useDFT); | 196 useDFT); |
188 } | 197 } |
189 | 198 |
190 GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B
udgeted budgeted, | 199 GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B
udgeted budgeted, |
191 const SkImageInfo& origInfo, int
sampleCount) { | 200 const SkImageInfo& origInfo, int
sampleCount) { |
192 if (kUnknown_SkColorType == origInfo.colorType() || | 201 if (kUnknown_SkColorType == origInfo.colorType() || |
193 origInfo.width() < 0 || origInfo.height() < 0) { | 202 origInfo.width() < 0 || origInfo.height() < 0) { |
194 return NULL; | 203 return NULL; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 } | 252 } |
244 | 253 |
245 delete fTextContext; | 254 delete fTextContext; |
246 | 255 |
247 fRenderTarget->unref(); | 256 fRenderTarget->unref(); |
248 fContext->unref(); | 257 fContext->unref(); |
249 } | 258 } |
250 | 259 |
251 /////////////////////////////////////////////////////////////////////////////// | 260 /////////////////////////////////////////////////////////////////////////////// |
252 | 261 |
| 262 void SkGpuDevice::discard() { |
| 263 if (fSurface) { |
| 264 fSurface->notifyContentWillChange(); |
| 265 } |
| 266 this->prepareBackendRenderTarget(kDiscard_ModifyMode); |
| 267 } |
| 268 |
253 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
_t dstRowBytes, | 269 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
_t dstRowBytes, |
254 int x, int y) { | 270 int x, int y) { |
255 DO_DEFERRED_CLEAR(); | 271 DO_DEFERRED_CLEAR(); |
256 | 272 |
257 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels | 273 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels |
258 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo); | 274 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo); |
259 if (kUnknown_GrPixelConfig == config) { | 275 if (kUnknown_GrPixelConfig == config) { |
260 return false; | 276 return false; |
261 } | 277 } |
262 | 278 |
263 uint32_t flags = 0; | 279 uint32_t flags = 0; |
264 if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { | 280 if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { |
265 flags = GrContext::kUnpremul_PixelOpsFlag; | 281 flags = GrContext::kUnpremul_PixelOpsFlag; |
266 } | 282 } |
267 return fContext->readRenderTargetPixels(fRenderTarget, x, y, dstInfo.width()
, dstInfo.height(), | 283 return fContext->readRenderTargetPixels(fRenderTarget, x, y, dstInfo.width()
, dstInfo.height(), |
268 config, dstPixels, dstRowBytes, flag
s); | 284 config, dstPixels, dstRowBytes, flag
s); |
269 } | 285 } |
270 | 286 |
271 bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, siz
e_t rowBytes, | 287 bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, siz
e_t rowBytes, |
272 int x, int y) { | 288 int x, int y) { |
273 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels | 289 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels |
274 GrPixelConfig config = SkImageInfo2GrPixelConfig(info); | 290 GrPixelConfig config = SkImageInfo2GrPixelConfig(info); |
275 if (kUnknown_GrPixelConfig == config) { | 291 if (kUnknown_GrPixelConfig == config) { |
276 return false; | 292 return false; |
277 } | 293 } |
| 294 |
| 295 if (!this->prepareWrite()) { |
| 296 return false; |
| 297 } |
| 298 |
278 uint32_t flags = 0; | 299 uint32_t flags = 0; |
279 if (kUnpremul_SkAlphaType == info.alphaType()) { | 300 if (kUnpremul_SkAlphaType == info.alphaType()) { |
280 flags = GrContext::kUnpremul_PixelOpsFlag; | 301 flags = GrContext::kUnpremul_PixelOpsFlag; |
281 } | 302 } |
282 fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels
, rowBytes, flags); | 303 fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels
, rowBytes, flags); |
283 | 304 |
284 // need to bump our genID for compatibility with clients that "know" we have
a bitmap | 305 // need to bump our genID for compatibility with clients that "know" we have
a bitmap |
285 fLegacyBitmap.notifyPixelsChanged(); | 306 fLegacyBitmap.notifyPixelsChanged(); |
286 | 307 |
287 return true; | 308 return true; |
288 } | 309 } |
289 | 310 |
290 const SkBitmap& SkGpuDevice::onAccessBitmap() { | 311 const SkBitmap& SkGpuDevice::onAccessBitmap() { |
291 DO_DEFERRED_CLEAR(); | 312 // Must prepare for write because user might obtain the texture from the bit
map and then modify |
| 313 // it. |
| 314 this->prepareWrite(); |
292 return fLegacyBitmap; | 315 return fLegacyBitmap; |
293 } | 316 } |
294 | 317 |
295 void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) { | 318 void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) { |
296 INHERITED::onAttachToCanvas(canvas); | 319 INHERITED::onAttachToCanvas(canvas); |
297 | 320 |
298 // Canvas promises that this ptr is valid until onDetachFromCanvas is called | 321 // Canvas promises that this ptr is valid until onDetachFromCanvas is called |
299 fClipStack.reset(SkRef(canvas->getClipStack())); | 322 fClipStack.reset(SkRef(canvas->getClipStack())); |
300 } | 323 } |
301 | 324 |
302 void SkGpuDevice::onDetachFromCanvas() { | 325 void SkGpuDevice::onDetachFromCanvas() { |
303 INHERITED::onDetachFromCanvas(); | 326 INHERITED::onDetachFromCanvas(); |
304 fClip.reset(); | 327 fClip.reset(); |
305 fClipStack.reset(NULL); | 328 fClipStack.reset(NULL); |
306 } | 329 } |
307 | 330 |
308 // call this every draw call, to ensure that the context reflects our state, | 331 // call this every draw call, to ensure that the context reflects our state, |
309 // and not the state from some other canvas/device | 332 // and not the state from some other canvas/device |
310 void SkGpuDevice::prepareDraw(const SkDraw& draw) { | 333 bool SkGpuDevice::prepareDraw(const SkDraw& draw) { |
311 SkASSERT(fClipStack.get()); | 334 SkASSERT(fClipStack.get()); |
312 | 335 |
313 SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack); | 336 SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack); |
314 | 337 |
315 fClip.setClipStack(fClipStack, &this->getOrigin()); | 338 fClip.setClipStack(fClipStack, &this->getOrigin()); |
316 | 339 |
317 DO_DEFERRED_CLEAR(); | 340 if (!this->prepareBackendRenderTarget(kDrawContent_ModifyMode)) { |
| 341 return false; |
| 342 } |
| 343 |
| 344 if (fSurface) { |
| 345 fSurface->notifyContentWillChange(); |
| 346 } |
| 347 |
| 348 return true; |
| 349 } |
| 350 |
| 351 bool SkGpuDevice::prepareWrite() { |
| 352 if (!this->prepareBackendRenderTarget(kDrawContent_ModifyMode)) { |
| 353 return false; |
| 354 } |
| 355 if (fSurface) { |
| 356 fSurface->notifyContentWillChange(); |
| 357 } |
| 358 return true; |
318 } | 359 } |
319 | 360 |
320 GrRenderTarget* SkGpuDevice::accessRenderTarget() { | 361 GrRenderTarget* SkGpuDevice::accessRenderTarget() { |
321 DO_DEFERRED_CLEAR(); | 362 // The render target could be read through the ptr, so we must do deferred c
lear. The render |
| 363 // target could be written to through the ptr, so we must detach the snapsho
t. |
| 364 this->prepareWrite(); |
322 return fRenderTarget; | 365 return fRenderTarget; |
323 } | 366 } |
324 | 367 |
325 void SkGpuDevice::clearAll() { | 368 void SkGpuDevice::clearAll() { |
326 GrColor color = 0; | 369 GrColor color = 0; |
327 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::clearAll", fContext); | 370 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::clearAll", fContext); |
328 SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); | 371 SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); |
329 fContext->clear(&rect, color, true, fRenderTarget); | 372 fContext->clear(&rect, color, true, fRenderTarget); |
330 fNeedClear = false; | 373 fNeedClear = false; |
331 } | 374 } |
332 | 375 |
333 void SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) { | 376 bool SkGpuDevice::prepareBackendRenderTarget(ModifyMode writeMode) { |
334 // Caller must have accessed the render target, because it knows the rt must
be replaced. | 377 // We are preparing for modifying the render target. This will detach the sn
apshot in all |
335 SkASSERT(!fNeedClear); | 378 // cases, so do the detach right away. |
| 379 SkAutoTUnref<SkImage> snapshot; |
| 380 snapshot.swap(&fSnapshot); |
| 381 |
| 382 bool needNewRenderTarget = false; |
| 383 |
| 384 if (NULL != snapshot) { |
| 385 SkASSERT(!fNeedClear); |
| 386 needNewRenderTarget = fRenderTarget->asTexture() == SkTextureImageGetTex
ture(snapshot) && |
| 387 !snapshot->unique(); |
| 388 } |
| 389 |
| 390 if (!needNewRenderTarget) { |
| 391 if (writeMode == kDiscard_ModifyMode) { |
| 392 fRenderTarget->discard(); |
| 393 fNeedClear = false; |
| 394 } |
| 395 if (fRenderTarget->wasDestroyed()) { |
| 396 return false; |
| 397 } |
| 398 |
| 399 DO_DEFERRED_CLEAR(); |
| 400 return true; |
| 401 } |
336 | 402 |
337 SkSurface::Budgeted budgeted = | 403 SkSurface::Budgeted budgeted = |
338 fRenderTarget->resourcePriv().isBudgeted() ? SkSurface::kYes_Budgete
d | 404 fRenderTarget->resourcePriv().isBudgeted() ? SkSurface::kYes_Budgete
d |
339 : SkSurface::kNo_Budgeted
; | 405 : SkSurface::kNo_Budgeted
; |
340 | 406 |
341 SkAutoTUnref<GrRenderTarget> newRT(CreateRenderTarget( | 407 SkAutoTUnref<GrRenderTarget> newRT(CreateRenderTarget( |
342 fRenderTarget->getContext(), budgeted, this->imageInfo(), fRenderTarget-
>numSamples())); | 408 this->context(), budgeted, this->imageInfo(), fRenderTarget->numSamples(
))); |
343 | 409 |
344 if (NULL == newRT) { | 410 if (NULL == newRT) { |
345 return; | 411 return false; |
346 } | 412 } |
347 | 413 |
348 if (shouldRetainContent) { | 414 if (writeMode == kDrawContent_ModifyMode) { |
349 if (fRenderTarget->wasDestroyed()) { | 415 if (fRenderTarget->wasDestroyed()) { |
350 return; | 416 return false; |
351 } | 417 } |
352 this->context()->copySurface(newRT, fRenderTarget); | 418 |
| 419 if (fNeedClear) { |
| 420 // Clear the snapshot render target and clear the new render target. |
| 421 this->clearAll(); |
| 422 fNeedClear = true; // Clears the new render target. |
| 423 } else { |
| 424 this->context()->copySurface(newRT, fRenderTarget); |
| 425 } |
| 426 } else { |
| 427 fNeedClear = false; |
353 } | 428 } |
354 | 429 |
355 SkASSERT(fRenderTarget != newRT); | 430 SkASSERT(fRenderTarget != newRT); |
356 | |
357 fRenderTarget->unref(); | 431 fRenderTarget->unref(); |
358 fRenderTarget = newRT.detach(); | 432 fRenderTarget = newRT.detach(); |
359 | 433 |
360 SkASSERT(fRenderTarget->surfacePriv().info() == fLegacyBitmap.info()); | 434 SkASSERT(fRenderTarget->surfacePriv().info() == fLegacyBitmap.info()); |
361 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (fRenderTarget->surfacePriv().info
(), fRenderTarget)); | 435 wrap_surface(fRenderTarget, &fLegacyBitmap); |
362 fLegacyBitmap.setPixelRef(pr)->unref(); | 436 |
| 437 SkASSERT(!fRenderTarget->wasDestroyed()); |
| 438 |
| 439 DO_DEFERRED_CLEAR(); |
| 440 |
| 441 if (snapshot) { |
| 442 SkTextureImageApplyBudgetedDecision(snapshot); |
| 443 } |
| 444 |
| 445 return true; |
363 } | 446 } |
364 | 447 |
| 448 bool SkGpuDevice::isBackendBudgeted() const { |
| 449 return fRenderTarget->resourcePriv().isBudgeted(); |
| 450 } |
365 /////////////////////////////////////////////////////////////////////////////// | 451 /////////////////////////////////////////////////////////////////////////////// |
366 | 452 |
367 SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); | 453 SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); |
368 SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch); | 454 SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch); |
369 SK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch); | 455 SK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch); |
370 SK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch); | 456 SK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch); |
371 SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4, | 457 SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4, |
372 shader_type_mismatch); | 458 shader_type_mismatch); |
373 SK_COMPILE_ASSERT(SkShader::kTwoPointConical_BitmapType == 5, | 459 SK_COMPILE_ASSERT(SkShader::kTwoPointConical_BitmapType == 5, |
374 shader_type_mismatch); | 460 shader_type_mismatch); |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 // setup new clip | 838 // setup new clip |
753 GrClip clip(clipRect); | 839 GrClip clip(clipRect); |
754 | 840 |
755 // Draw the mask into maskTexture with the path's top-left at the origin usi
ng tempPaint. | 841 // Draw the mask into maskTexture with the path's top-left at the origin usi
ng tempPaint. |
756 SkMatrix translate; | 842 SkMatrix translate; |
757 translate.setTranslate(-maskRect.fLeft, -maskRect.fTop); | 843 translate.setTranslate(-maskRect.fLeft, -maskRect.fTop); |
758 context->drawPath(mask->asRenderTarget(), clip, tempPaint, translate, devPat
h, strokeInfo); | 844 context->drawPath(mask->asRenderTarget(), clip, tempPaint, translate, devPat
h, strokeInfo); |
759 return mask; | 845 return mask; |
760 } | 846 } |
761 | 847 |
762 SkBitmap wrap_texture(GrTexture* texture) { | |
763 SkBitmap result; | |
764 result.setInfo(texture->surfacePriv().info()); | |
765 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unre
f(); | |
766 return result; | |
767 } | |
768 | |
769 }; | 848 }; |
770 | 849 |
771 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, | 850 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, |
772 const SkPaint& paint, const SkMatrix* prePathMatrix, | 851 const SkPaint& paint, const SkMatrix* prePathMatrix, |
773 bool pathIsMutable) { | 852 bool pathIsMutable) { |
774 CHECK_FOR_ANNOTATION(paint); | 853 CHECK_FOR_ANNOTATION(paint); |
775 CHECK_SHOULD_DRAW(draw); | 854 CHECK_SHOULD_DRAW(draw); |
776 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext); | 855 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext); |
777 | 856 |
778 return this->internalDrawPath(origSrcPath, paint, *draw.fMatrix, prePathMatr
ix, | 857 return this->internalDrawPath(origSrcPath, paint, *draw.fMatrix, prePathMatr
ix, |
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1500 const SkImageFilter* filter, | 1579 const SkImageFilter* filter, |
1501 const SkImageFilter::Context& ctx, | 1580 const SkImageFilter::Context& ctx, |
1502 SkBitmap* result, SkIPoint* offset) { | 1581 SkBitmap* result, SkIPoint* offset) { |
1503 SkASSERT(filter); | 1582 SkASSERT(filter); |
1504 | 1583 |
1505 // FIXME: plumb actual surface props such that we don't have to lie about th
e flags here | 1584 // FIXME: plumb actual surface props such that we don't have to lie about th
e flags here |
1506 // (https://code.google.com/p/skia/issues/detail?id=3148). | 1585 // (https://code.google.com/p/skia/issues/detail?id=3148). |
1507 SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties().
pixelGeometry())); | 1586 SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties().
pixelGeometry())); |
1508 | 1587 |
1509 if (filter->canFilterImageGPU()) { | 1588 if (filter->canFilterImageGPU()) { |
1510 return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result
, offset); | 1589 SkBitmap filterInput; |
| 1590 wrap_surface(texture, &filterInput); |
| 1591 return filter->filterImageGPU(&proxy, filterInput, ctx, result, offset); |
1511 } else { | 1592 } else { |
1512 return false; | 1593 return false; |
1513 } | 1594 } |
1514 } | 1595 } |
1515 | 1596 |
1516 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, | 1597 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, |
1517 int left, int top, const SkPaint& paint) { | 1598 int left, int top, const SkPaint& paint) { |
1518 // drawSprite is defined to be in device coords. | 1599 // drawSprite is defined to be in device coords. |
1519 CHECK_SHOULD_DRAW(draw); | 1600 CHECK_SHOULD_DRAW(draw); |
1520 | 1601 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1636 dstSize.fWidth = tmpDst.width(); | 1717 dstSize.fWidth = tmpDst.width(); |
1637 dstSize.fHeight = tmpDst.height(); | 1718 dstSize.fHeight = tmpDst.height(); |
1638 | 1719 |
1639 this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, flags); | 1720 this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, flags); |
1640 } | 1721 } |
1641 | 1722 |
1642 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, | 1723 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, |
1643 int x, int y, const SkPaint& paint) { | 1724 int x, int y, const SkPaint& paint) { |
1644 // clear of the source device must occur before CHECK_SHOULD_DRAW | 1725 // clear of the source device must occur before CHECK_SHOULD_DRAW |
1645 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext); | 1726 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext); |
1646 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); | |
1647 | |
1648 // TODO: If the source device covers the whole of this device, we could | 1727 // TODO: If the source device covers the whole of this device, we could |
1649 // omit fNeedsClear -related flushing. | 1728 // omit fNeedsClear -related flushing. |
1650 // TODO: if source needs clear, we could maybe omit the draw fully. | 1729 // TODO: if source is a gpu device, we could inspect its fNeedsClear, |
| 1730 // and we could maybe omit the draw fully. |
1651 | 1731 |
1652 // drawDevice is defined to be in device coords. | 1732 SkAutoTUnref<SkImage> devImage(device->newImageSnapshot()); |
1653 CHECK_SHOULD_DRAW(draw); | 1733 if (NULL == devImage) { |
1654 | 1734 return; |
1655 GrRenderTarget* devRT = dev->accessRenderTarget(); | 1735 } |
1656 GrTexture* devTex; | 1736 GrTexture* devTex = devImage->getTexture(); |
1657 if (NULL == (devTex = devRT->asTexture())) { | 1737 if (NULL == devTex) { |
1658 return; | 1738 return; |
1659 } | 1739 } |
1660 | 1740 |
1661 const SkImageInfo ii = dev->imageInfo(); | 1741 int w = devImage->width(); |
1662 int w = ii.width(); | 1742 int h = devImage->height(); |
1663 int h = ii.height(); | |
1664 | 1743 |
1665 SkImageFilter* filter = paint.getImageFilter(); | 1744 SkImageFilter* filter = paint.getImageFilter(); |
1666 // This bitmap will own the filtered result as a texture. | 1745 // This bitmap will own the filtered result as a texture. |
1667 SkBitmap filteredBitmap; | 1746 SkBitmap filteredBitmap; |
1668 | 1747 |
1669 if (filter) { | 1748 if (filter) { |
1670 SkIPoint offset = SkIPoint::Make(0, 0); | 1749 SkIPoint offset = SkIPoint::Make(0, 0); |
1671 SkMatrix matrix(*draw.fMatrix); | 1750 SkMatrix matrix(*draw.fMatrix); |
1672 matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); | 1751 matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); |
1673 SkIRect clipBounds = SkIRect::MakeWH(devTex->width(), devTex->height()); | 1752 SkIRect clipBounds = SkIRect::MakeWH(devTex->width(), devTex->height()); |
1674 // This cache is transient, and is freed (along with all its contained | 1753 // This cache is transient, and is freed (along with all its contained |
1675 // textures) when it goes out of scope. | 1754 // textures) when it goes out of scope. |
1676 SkAutoTUnref<SkImageFilter::Cache> cache(getImageFilterCache()); | 1755 SkAutoTUnref<SkImageFilter::Cache> cache(getImageFilterCache()); |
1677 SkImageFilter::Context ctx(matrix, clipBounds, cache); | 1756 SkImageFilter::Context ctx(matrix, clipBounds, cache); |
1678 if (this->filterTexture(fContext, devTex, filter, ctx, &filteredBitmap, | 1757 if (this->filterTexture(fContext, devTex, filter, ctx, &filteredBitmap, |
1679 &offset)) { | 1758 &offset)) { |
1680 devTex = filteredBitmap.getTexture(); | 1759 devTex = filteredBitmap.getTexture(); |
1681 w = filteredBitmap.width(); | 1760 w = filteredBitmap.width(); |
1682 h = filteredBitmap.height(); | 1761 h = filteredBitmap.height(); |
1683 x += offset.fX; | 1762 x += offset.fX; |
1684 y += offset.fY; | 1763 y += offset.fY; |
1685 } else { | 1764 } else { |
1686 return; | 1765 return; |
1687 } | 1766 } |
1688 } | 1767 } |
| 1768 // drawDevice is defined to be in device coords. |
| 1769 CHECK_SHOULD_DRAW(draw); |
1689 | 1770 |
1690 GrPaint grPaint; | 1771 GrPaint grPaint; |
1691 grPaint.addColorTextureProcessor(devTex, SkMatrix::I()); | 1772 grPaint.addColorTextureProcessor(devTex, SkMatrix::I()); |
1692 | 1773 |
1693 SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, | 1774 SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, |
1694 SkColor2GrColorJustAlpha(paint.getColor()), false, &
grPaint); | 1775 SkColor2GrColorJustAlpha(paint.getColor()), false, &
grPaint); |
1695 | 1776 |
1696 SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x), | 1777 SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x), |
1697 SkIntToScalar(y), | 1778 SkIntToScalar(y), |
1698 SkIntToScalar(w), | 1779 SkIntToScalar(w), |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1898 return true; | 1979 return true; |
1899 } | 1980 } |
1900 return false; | 1981 return false; |
1901 } | 1982 } |
1902 | 1983 |
1903 void SkGpuDevice::flush() { | 1984 void SkGpuDevice::flush() { |
1904 DO_DEFERRED_CLEAR(); | 1985 DO_DEFERRED_CLEAR(); |
1905 fRenderTarget->prepareForExternalRead(); | 1986 fRenderTarget->prepareForExternalRead(); |
1906 } | 1987 } |
1907 | 1988 |
| 1989 SkImage* SkGpuDevice::newImageSnapshot() { |
| 1990 return this->newImageSnapshot(&fSurfaceProps, SkSurface::kYes_Budgeted); |
| 1991 } |
| 1992 |
| 1993 SkImage* SkGpuDevice::newImageSnapshot(const SkSurfaceProps* props, SkSurface::B
udgeted budgeted) { |
| 1994 if (NULL == fSnapshot) { |
| 1995 if (fRenderTarget->wasDestroyed()) { |
| 1996 return NULL; |
| 1997 } |
| 1998 DO_DEFERRED_CLEAR(); |
| 1999 const int sampleCount = fRenderTarget->numSamples(); |
| 2000 SkImage* image = SkNewImageFromBitmapTexture(fLegacyBitmap, sampleCount,
budgeted); |
| 2001 if (!image) { |
| 2002 return NULL; |
| 2003 } |
| 2004 if (props) { |
| 2005 as_IB(image)->initWithProps(*props); |
| 2006 } |
| 2007 fSnapshot.reset(image); |
| 2008 } |
| 2009 return SkRef(fSnapshot.get()); |
| 2010 } |
1908 /////////////////////////////////////////////////////////////////////////////// | 2011 /////////////////////////////////////////////////////////////////////////////// |
1909 | 2012 |
1910 SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
*) { | 2013 SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
*) { |
1911 GrSurfaceDesc desc; | 2014 GrSurfaceDesc desc; |
1912 desc.fConfig = fRenderTarget->config(); | 2015 desc.fConfig = fRenderTarget->config(); |
1913 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 2016 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
1914 desc.fWidth = cinfo.fInfo.width(); | 2017 desc.fWidth = cinfo.fInfo.width(); |
1915 desc.fHeight = cinfo.fInfo.height(); | 2018 desc.fHeight = cinfo.fInfo.height(); |
1916 desc.fSampleCnt = fRenderTarget->numSamples(); | 2019 desc.fSampleCnt = fRenderTarget->numSamples(); |
1917 | 2020 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2010 #endif | 2113 #endif |
2011 } | 2114 } |
2012 | 2115 |
2013 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 2116 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
2014 // We always return a transient cache, so it is freed after each | 2117 // We always return a transient cache, so it is freed after each |
2015 // filter traversal. | 2118 // filter traversal. |
2016 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); | 2119 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); |
2017 } | 2120 } |
2018 | 2121 |
2019 #endif | 2122 #endif |
OLD | NEW |