| 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 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 #include "SkBounder.h" | 22 #include "SkBounder.h" |
| 23 #include "SkColorFilter.h" | 23 #include "SkColorFilter.h" |
| 24 #include "SkDeviceImageFilterProxy.h" | 24 #include "SkDeviceImageFilterProxy.h" |
| 25 #include "SkDrawProcs.h" | 25 #include "SkDrawProcs.h" |
| 26 #include "SkGlyphCache.h" | 26 #include "SkGlyphCache.h" |
| 27 #include "SkImageFilter.h" | 27 #include "SkImageFilter.h" |
| 28 #include "SkMaskFilter.h" | 28 #include "SkMaskFilter.h" |
| 29 #include "SkPathEffect.h" | 29 #include "SkPathEffect.h" |
| 30 #include "SkPicture.h" | 30 #include "SkPicture.h" |
| 31 #include "SkPicturePlayback.h" |
| 31 #include "SkRRect.h" | 32 #include "SkRRect.h" |
| 32 #include "SkStroke.h" | 33 #include "SkStroke.h" |
| 33 #include "SkSurface.h" | 34 #include "SkSurface.h" |
| 34 #include "SkTLazy.h" | 35 #include "SkTLazy.h" |
| 35 #include "SkUtils.h" | 36 #include "SkUtils.h" |
| 36 #include "SkErrorInternals.h" | 37 #include "SkErrorInternals.h" |
| 37 | 38 |
| 39 #define USE_SCRATCH 1 |
| 40 |
| 38 #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 | 41 #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 |
| 39 | 42 |
| 40 #if 0 | 43 #if 0 |
| 41 extern bool (*gShouldDrawProc)(); | 44 extern bool (*gShouldDrawProc)(); |
| 42 #define CHECK_SHOULD_DRAW(draw, forceI) \ | 45 #define CHECK_SHOULD_DRAW(draw, forceI) \ |
| 43 do { \ | 46 do { \ |
| 44 if (gShouldDrawProc && !gShouldDrawProc()) return; \ | 47 if (gShouldDrawProc && !gShouldDrawProc()) return; \ |
| 45 this->prepareDraw(draw, forceI); \ | 48 this->prepareDraw(draw, forceI); \ |
| 46 } while (0) | 49 } while (0) |
| 47 #else | 50 #else |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 GrRenderTarget* renderTarget, | 189 GrRenderTarget* renderTarget, |
| 187 unsigned flags) { | 190 unsigned flags) { |
| 188 fDrawProcs = NULL; | 191 fDrawProcs = NULL; |
| 189 | 192 |
| 190 fContext = context; | 193 fContext = context; |
| 191 fContext->ref(); | 194 fContext->ref(); |
| 192 | 195 |
| 193 fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyP
roperties)); | 196 fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyP
roperties)); |
| 194 fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProp
erties)); | 197 fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProp
erties)); |
| 195 | 198 |
| 196 fRenderTarget = NULL; | 199 fRenderTarget1 = NULL; |
| 197 fNeedClear = flags & kNeedClear_Flag; | 200 fNeedClear = flags & kNeedClear_Flag; |
| 198 | 201 |
| 199 SkASSERT(NULL != renderTarget); | 202 SkASSERT(NULL != renderTarget); |
| 200 fRenderTarget = renderTarget; | 203 // SkDebugf("initFromRenderTarget\n"); |
| 201 fRenderTarget->ref(); | 204 fRenderTarget1 = renderTarget; |
| 205 fRenderTarget1->ref(); |
| 202 | 206 |
| 203 // Hold onto to the texture in the pixel ref (if there is one) because the t
exture holds a ref | 207 // Hold onto to the texture in the pixel ref (if there is one) because the t
exture holds a ref |
| 204 // on the RT but not vice-versa. | 208 // on the RT but not vice-versa. |
| 205 // TODO: Remove this trickery once we figure out how to make SkGrPixelRef do
this without | 209 // TODO: Remove this trickery once we figure out how to make SkGrPixelRef do
this without |
| 206 // busting chrome (for a currently unknown reason). | 210 // busting chrome (for a currently unknown reason). |
| 207 GrSurface* surface = fRenderTarget->asTexture(); | 211 GrSurface* surface = fRenderTarget1->asTexture(); |
| 208 if (NULL == surface) { | 212 if (NULL == surface) { |
| 209 surface = fRenderTarget; | 213 surface = fRenderTarget1; |
| 210 } | 214 } |
| 211 | 215 |
| 212 SkImageInfo info; | 216 SkImageInfo info; |
| 213 surface->asImageInfo(&info); | 217 surface->asImageInfo(&info); |
| 214 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface, SkToBool(flags & k
Cached_Flag))); | 218 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface, SkToBool(flags & k
Cached_Flag))); |
| 215 | 219 |
| 216 this->setPixelRef(pr)->unref(); | 220 this->setPixelRef(pr)->unref(); |
| 217 } | 221 } |
| 218 | 222 |
| 219 SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo
, | 223 SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo
, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 SkGpuDevice::~SkGpuDevice() { | 321 SkGpuDevice::~SkGpuDevice() { |
| 318 if (fDrawProcs) { | 322 if (fDrawProcs) { |
| 319 delete fDrawProcs; | 323 delete fDrawProcs; |
| 320 } | 324 } |
| 321 | 325 |
| 322 delete fMainTextContext; | 326 delete fMainTextContext; |
| 323 delete fFallbackTextContext; | 327 delete fFallbackTextContext; |
| 324 | 328 |
| 325 // The GrContext takes a ref on the target. We don't want to cause the rende
r | 329 // The GrContext takes a ref on the target. We don't want to cause the rende
r |
| 326 // target to be unnecessarily kept alive. | 330 // target to be unnecessarily kept alive. |
| 327 if (fContext->getRenderTarget() == fRenderTarget) { | 331 if (fContext->getRenderTarget() == fRenderTarget1) { |
| 328 fContext->setRenderTarget(NULL); | 332 fContext->setRenderTarget(NULL); |
| 329 } | 333 } |
| 330 | 334 |
| 331 if (fContext->getClip() == &fClipData) { | 335 if (fContext->getClip() == &fClipData) { |
| 332 fContext->setClip(NULL); | 336 fContext->setClip(NULL); |
| 333 } | 337 } |
| 334 | 338 |
| 335 SkSafeUnref(fRenderTarget); | 339 SkSafeUnref(fRenderTarget1); |
| 336 fContext->unref(); | 340 fContext->unref(); |
| 337 } | 341 } |
| 338 | 342 |
| 339 /////////////////////////////////////////////////////////////////////////////// | 343 /////////////////////////////////////////////////////////////////////////////// |
| 340 | 344 |
| 341 void SkGpuDevice::makeRenderTargetCurrent() { | 345 void SkGpuDevice::makeRenderTargetCurrent() { |
| 342 DO_DEFERRED_CLEAR(); | 346 DO_DEFERRED_CLEAR(); |
| 343 fContext->setRenderTarget(fRenderTarget); | 347 fContext->setRenderTarget(fRenderTarget1); |
| 344 } | 348 } |
| 345 | 349 |
| 346 /////////////////////////////////////////////////////////////////////////////// | 350 /////////////////////////////////////////////////////////////////////////////// |
| 347 | 351 |
| 348 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
_t dstRowBytes, | 352 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
_t dstRowBytes, |
| 349 int x, int y) { | 353 int x, int y) { |
| 350 DO_DEFERRED_CLEAR(); | 354 DO_DEFERRED_CLEAR(); |
| 351 | 355 |
| 352 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels | 356 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels |
| 353 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo.colorType(), dstInf
o.alphaType()); | 357 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo.colorType(), dstInf
o.alphaType()); |
| 354 if (kUnknown_GrPixelConfig == config) { | 358 if (kUnknown_GrPixelConfig == config) { |
| 355 return false; | 359 return false; |
| 356 } | 360 } |
| 357 | 361 |
| 358 uint32_t flags = 0; | 362 uint32_t flags = 0; |
| 359 if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { | 363 if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { |
| 360 flags = GrContext::kUnpremul_PixelOpsFlag; | 364 flags = GrContext::kUnpremul_PixelOpsFlag; |
| 361 } | 365 } |
| 362 return fContext->readRenderTargetPixels(fRenderTarget, x, y, dstInfo.width()
, dstInfo.height(), | 366 return fContext->readRenderTargetPixels(fRenderTarget1, x, y, dstInfo.width(
), dstInfo.height(), |
| 363 config, dstPixels, dstRowBytes, flag
s); | 367 config, dstPixels, dstRowBytes, flag
s); |
| 364 } | 368 } |
| 365 | 369 |
| 366 bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, siz
e_t rowBytes, | 370 bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, siz
e_t rowBytes, |
| 367 int x, int y) { | 371 int x, int y) { |
| 368 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels | 372 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src p
ixels |
| 369 GrPixelConfig config = SkImageInfo2GrPixelConfig(info.colorType(), info.alph
aType()); | 373 GrPixelConfig config = SkImageInfo2GrPixelConfig(info.colorType(), info.alph
aType()); |
| 370 if (kUnknown_GrPixelConfig == config) { | 374 if (kUnknown_GrPixelConfig == config) { |
| 371 return false; | 375 return false; |
| 372 } | 376 } |
| 373 uint32_t flags = 0; | 377 uint32_t flags = 0; |
| 374 if (kUnpremul_SkAlphaType == info.alphaType()) { | 378 if (kUnpremul_SkAlphaType == info.alphaType()) { |
| 375 flags = GrContext::kUnpremul_PixelOpsFlag; | 379 flags = GrContext::kUnpremul_PixelOpsFlag; |
| 376 } | 380 } |
| 377 fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels
, rowBytes, flags); | 381 fRenderTarget1->writePixels(x, y, info.width(), info.height(), config, pixel
s, rowBytes, flags); |
| 378 | 382 |
| 379 // need to bump our genID for compatibility with clients that "know" we have
a bitmap | 383 // need to bump our genID for compatibility with clients that "know" we have
a bitmap |
| 380 this->onAccessBitmap().notifyPixelsChanged(); | 384 this->onAccessBitmap().notifyPixelsChanged(); |
| 381 | 385 |
| 382 return true; | 386 return true; |
| 383 } | 387 } |
| 384 | 388 |
| 385 const SkBitmap& SkGpuDevice::onAccessBitmap() { | 389 const SkBitmap& SkGpuDevice::onAccessBitmap() { |
| 386 DO_DEFERRED_CLEAR(); | 390 DO_DEFERRED_CLEAR(); |
| 387 return INHERITED::onAccessBitmap(); | 391 return INHERITED::onAccessBitmap(); |
| 388 } | 392 } |
| 389 | 393 |
| 390 void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) { | 394 void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) { |
| 391 INHERITED::onAttachToCanvas(canvas); | 395 INHERITED::onAttachToCanvas(canvas); |
| 392 | 396 |
| 393 // Canvas promises that this ptr is valid until onDetachFromCanvas is called | 397 // Canvas promises that this ptr is valid until onDetachFromCanvas is called |
| 394 fClipData.fClipStack = canvas->getClipStack(); | 398 fClipData.fClipStack = canvas->getClipStack(); |
| 395 } | 399 } |
| 396 | 400 |
| 397 void SkGpuDevice::onDetachFromCanvas() { | 401 void SkGpuDevice::onDetachFromCanvas() { |
| 398 INHERITED::onDetachFromCanvas(); | 402 INHERITED::onDetachFromCanvas(); |
| 399 fClipData.fClipStack = NULL; | 403 fClipData.fClipStack = NULL; |
| 400 } | 404 } |
| 401 | 405 |
| 402 // call this every draw call, to ensure that the context reflects our state, | 406 // call this every draw call, to ensure that the context reflects our state, |
| 403 // and not the state from some other canvas/device | 407 // and not the state from some other canvas/device |
| 404 void SkGpuDevice::prepareDraw(const SkDraw& draw, bool forceIdentity) { | 408 void SkGpuDevice::prepareDraw(const SkDraw& draw, bool forceIdentity) { |
| 405 SkASSERT(NULL != fClipData.fClipStack); | 409 SkASSERT(NULL != fClipData.fClipStack); |
| 406 | 410 |
| 407 fContext->setRenderTarget(fRenderTarget); | 411 fContext->setRenderTarget(fRenderTarget1); |
| 408 | 412 |
| 409 SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack); | 413 SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack); |
| 410 | 414 |
| 411 if (forceIdentity) { | 415 if (forceIdentity) { |
| 412 fContext->setIdentityMatrix(); | 416 fContext->setIdentityMatrix(); |
| 413 } else { | 417 } else { |
| 414 fContext->setMatrix(*draw.fMatrix); | 418 fContext->setMatrix(*draw.fMatrix); |
| 415 } | 419 } |
| 416 fClipData.fOrigin = this->getOrigin(); | 420 fClipData.fOrigin = this->getOrigin(); |
| 417 | 421 |
| 418 fContext->setClip(&fClipData); | 422 fContext->setClip(&fClipData); |
| 419 | 423 |
| 420 DO_DEFERRED_CLEAR(); | 424 DO_DEFERRED_CLEAR(); |
| 421 } | 425 } |
| 422 | 426 |
| 423 GrRenderTarget* SkGpuDevice::accessRenderTarget() { | 427 GrRenderTarget* SkGpuDevice::accessRenderTarget() { |
| 424 DO_DEFERRED_CLEAR(); | 428 DO_DEFERRED_CLEAR(); |
| 425 return fRenderTarget; | 429 return fRenderTarget1; |
| 426 } | 430 } |
| 427 | 431 |
| 428 /////////////////////////////////////////////////////////////////////////////// | 432 /////////////////////////////////////////////////////////////////////////////// |
| 429 | 433 |
| 430 SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); | 434 SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); |
| 431 SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch); | 435 SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch); |
| 432 SK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch); | 436 SK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch); |
| 433 SK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch); | 437 SK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch); |
| 434 SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4, | 438 SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4, |
| 435 shader_type_mismatch); | 439 shader_type_mismatch); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 } else { | 551 } else { |
| 548 return false; | 552 return false; |
| 549 } | 553 } |
| 550 } | 554 } |
| 551 } | 555 } |
| 552 } | 556 } |
| 553 | 557 |
| 554 /////////////////////////////////////////////////////////////////////////////// | 558 /////////////////////////////////////////////////////////////////////////////// |
| 555 | 559 |
| 556 SkBitmap::Config SkGpuDevice::config() const { | 560 SkBitmap::Config SkGpuDevice::config() const { |
| 557 if (NULL == fRenderTarget) { | 561 if (NULL == fRenderTarget1) { |
| 558 return SkBitmap::kNo_Config; | 562 return SkBitmap::kNo_Config; |
| 559 } | 563 } |
| 560 | 564 |
| 561 bool isOpaque; | 565 bool isOpaque; |
| 562 return grConfig2skConfig(fRenderTarget->config(), &isOpaque); | 566 return grConfig2skConfig(fRenderTarget1->config(), &isOpaque); |
| 563 } | 567 } |
| 564 | 568 |
| 565 void SkGpuDevice::clear(SkColor color) { | 569 void SkGpuDevice::clear(SkColor color) { |
| 566 SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); | 570 SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); |
| 567 fContext->clear(&rect, SkColor2GrColor(color), true, fRenderTarget); | 571 fContext->clear(&rect, SkColor2GrColor(color), true, fRenderTarget1); |
| 568 fNeedClear = false; | 572 fNeedClear = false; |
| 569 } | 573 } |
| 570 | 574 |
| 571 void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { | 575 void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { |
| 572 CHECK_SHOULD_DRAW(draw, false); | 576 CHECK_SHOULD_DRAW(draw, false); |
| 573 | 577 |
| 574 GrPaint grPaint; | 578 GrPaint grPaint; |
| 575 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { | 579 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { |
| 576 return; | 580 return; |
| 577 } | 581 } |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 const SkPaint& paint, const SkMatrix* prePathMatrix, | 915 const SkPaint& paint, const SkMatrix* prePathMatrix, |
| 912 bool pathIsMutable) { | 916 bool pathIsMutable) { |
| 913 CHECK_FOR_ANNOTATION(paint); | 917 CHECK_FOR_ANNOTATION(paint); |
| 914 CHECK_SHOULD_DRAW(draw, false); | 918 CHECK_SHOULD_DRAW(draw, false); |
| 915 | 919 |
| 916 GrPaint grPaint; | 920 GrPaint grPaint; |
| 917 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { | 921 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { |
| 918 return; | 922 return; |
| 919 } | 923 } |
| 920 | 924 |
| 925 // grPaint.setAntiAlias(false); |
| 926 |
| 921 // If we have a prematrix, apply it to the path, optimizing for the case | 927 // If we have a prematrix, apply it to the path, optimizing for the case |
| 922 // where the original path can in fact be modified in place (even though | 928 // where the original path can in fact be modified in place (even though |
| 923 // its parameter type is const). | 929 // its parameter type is const). |
| 924 SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath); | 930 SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath); |
| 925 SkTLazy<SkPath> tmpPath; | 931 SkTLazy<SkPath> tmpPath; |
| 926 SkTLazy<SkPath> effectPath; | 932 SkTLazy<SkPath> effectPath; |
| 927 | 933 |
| 928 if (prePathMatrix) { | 934 if (prePathMatrix) { |
| 929 SkPath* result = pathPtr; | 935 SkPath* result = pathPtr; |
| 930 | 936 |
| (...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1898 flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag; | 1904 flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag; |
| 1899 flags->fHinting = paint.getHinting(); | 1905 flags->fHinting = paint.getHinting(); |
| 1900 return true; | 1906 return true; |
| 1901 } | 1907 } |
| 1902 // we're cool with the paint as is | 1908 // we're cool with the paint as is |
| 1903 return false; | 1909 return false; |
| 1904 } | 1910 } |
| 1905 | 1911 |
| 1906 void SkGpuDevice::flush() { | 1912 void SkGpuDevice::flush() { |
| 1907 DO_DEFERRED_CLEAR(); | 1913 DO_DEFERRED_CLEAR(); |
| 1908 fContext->resolveRenderTarget(fRenderTarget); | 1914 fContext->resolveRenderTarget(fRenderTarget1); |
| 1909 } | 1915 } |
| 1910 | 1916 |
| 1911 /////////////////////////////////////////////////////////////////////////////// | 1917 /////////////////////////////////////////////////////////////////////////////// |
| 1912 | 1918 |
| 1913 SkBaseDevice* SkGpuDevice::onCreateDevice(const SkImageInfo& info, Usage usage)
{ | 1919 SkBaseDevice* SkGpuDevice::onCreateDevice(const SkImageInfo& info, Usage usage)
{ |
| 1914 GrTextureDesc desc; | 1920 GrTextureDesc desc; |
| 1915 desc.fConfig = fRenderTarget->config(); | 1921 desc.fConfig = fRenderTarget1->config(); |
| 1916 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 1922 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
| 1917 desc.fWidth = info.width(); | 1923 desc.fWidth = info.width(); |
| 1918 desc.fHeight = info.height(); | 1924 desc.fHeight = info.height(); |
| 1919 desc.fSampleCnt = fRenderTarget->numSamples(); | 1925 desc.fSampleCnt = fRenderTarget1->numSamples(); |
| 1920 | 1926 |
| 1921 SkAutoTUnref<GrTexture> texture; | 1927 SkAutoTUnref<GrTexture> texture; |
| 1922 // Skia's convention is to only clear a device if it is non-opaque. | 1928 // Skia's convention is to only clear a device if it is non-opaque. |
| 1923 unsigned flags = info.isOpaque() ? 0 : kNeedClear_Flag; | 1929 unsigned flags = info.isOpaque() ? 0 : kNeedClear_Flag; |
| 1924 | 1930 |
| 1925 #if CACHE_COMPATIBLE_DEVICE_TEXTURES | 1931 #if CACHE_COMPATIBLE_DEVICE_TEXTURES |
| 1926 // layers are never draw in repeat modes, so we can request an approx | 1932 // layers are never draw in repeat modes, so we can request an approx |
| 1927 // match and ignore any padding. | 1933 // match and ignore any padding. |
| 1928 flags |= kCached_Flag; | 1934 flags |= kCached_Flag; |
| 1929 const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == usage) ? | 1935 const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == usage) ? |
| 1930 GrContext::kApprox_ScratchTexMat
ch : | 1936 GrContext::kApprox_ScratchTexMat
ch : |
| 1931 GrContext::kExact_ScratchTexMatc
h; | 1937 GrContext::kExact_ScratchTexMatc
h; |
| 1932 texture.reset(fContext->lockAndRefScratchTexture(desc, match)); | 1938 texture.reset(fContext->lockAndRefScratchTexture(desc, match)); |
| 1933 #else | 1939 #else |
| 1934 texture.reset(fContext->createUncachedTexture(desc, NULL, 0)); | 1940 texture.reset(fContext->createUncachedTexture(desc, NULL, 0)); |
| 1935 #endif | 1941 #endif |
| 1936 if (NULL != texture.get()) { | 1942 if (NULL != texture.get()) { |
| 1937 return SkGpuDevice::Create(texture, flags); | 1943 return SkGpuDevice::Create(texture, flags); |
| 1938 } else { | 1944 } else { |
| 1939 GrPrintf("---- failed to create compatible device texture [%d %d]\n", | 1945 GrPrintf("---- failed to create compatible device texture [%d %d]\n", |
| 1940 info.width(), info.height()); | 1946 info.width(), info.height()); |
| 1941 return NULL; | 1947 return NULL; |
| 1942 } | 1948 } |
| 1943 } | 1949 } |
| 1944 | 1950 |
| 1945 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info) { | 1951 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info) { |
| 1946 return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples(
)); | 1952 return SkSurface::NewRenderTarget(fContext, info, fRenderTarget1->numSamples
()); |
| 1947 } | 1953 } |
| 1948 | 1954 |
| 1949 // In the future this may not be a static method if we need to incorporate the | 1955 // In the future this may not be a static method if we need to incorporate the |
| 1950 // clip and matrix state into the key | 1956 // clip and matrix state into the key |
| 1951 SkPicture::AccelData::Key SkGpuDevice::ComputeAccelDataKey() { | 1957 SkPicture::AccelData::Key SkGpuDevice::ComputeAccelDataKey() { |
| 1952 static const SkPicture::AccelData::Key gGPUID = SkPicture::AccelData::Genera
teDomain(); | 1958 static const SkPicture::AccelData::Key gGPUID = SkPicture::AccelData::Genera
teDomain(); |
| 1953 | 1959 |
| 1954 return gGPUID; | 1960 return gGPUID; |
| 1955 } | 1961 } |
| 1956 | 1962 |
| 1957 void SkGpuDevice::EXPERIMENTAL_optimize(SkPicture* picture) { | 1963 void SkGpuDevice::EXPERIMENTAL_optimize(SkPicture* picture) { |
| 1964 |
| 1958 SkPicture::AccelData::Key key = ComputeAccelDataKey(); | 1965 SkPicture::AccelData::Key key = ComputeAccelDataKey(); |
| 1959 | 1966 |
| 1960 GPUAccelData* data = SkNEW_ARGS(GPUAccelData, (key)); | 1967 GPUAccelData* data = SkNEW_ARGS(GPUAccelData, (key)); |
| 1961 | 1968 |
| 1962 picture->EXPERIMENTAL_addAccelData(data); | 1969 picture->EXPERIMENTAL_addAccelData(data); |
| 1963 | 1970 |
| 1964 GatherGPUInfo(picture, data); | 1971 GatherGPUInfo(picture, data); |
| 1965 } | 1972 } |
| 1966 | 1973 |
| 1967 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkPicture* picture) { | 1974 void SkGpuDevice::EXPERIMENTAL_purge() { |
| 1975 |
| 1976 } |
| 1977 |
| 1978 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
sult) { |
| 1979 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); |
| 1980 result->setConfig(info); |
| 1981 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); |
| 1982 } |
| 1983 |
| 1984 #ifndef USE_SCRATCH |
| 1985 |
| 1986 static void generate_layer_cache_id(const SkPicture& picture, int layerID, GrCac
heID* id) { |
| 1987 uint32_t genID = picture.uniqueID(); |
| 1988 |
| 1989 GrCacheID::Key key; |
| 1990 memcpy(key.fData8 + 0, &genID, 4); |
| 1991 memcpy(key.fData8 + 4, &layerID, 4); |
| 1992 static const size_t kKeyDataSize = 8; |
| 1993 memset(key.fData8 + kKeyDataSize, 0, sizeof(key) - kKeyDataSize); |
| 1994 GR_STATIC_ASSERT(sizeof(key) >= kKeyDataSize); |
| 1995 static const GrCacheID::Domain gLayerDomain = GrCacheID::GenerateDomain(); |
| 1996 id->reset(gLayerDomain, key); |
| 1997 } |
| 1998 #endif |
| 1999 |
| 2000 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas1, SkPicture* picture
) { |
| 1968 | 2001 |
| 1969 SkPicture::AccelData::Key key = ComputeAccelDataKey(); | 2002 SkPicture::AccelData::Key key = ComputeAccelDataKey(); |
| 1970 | 2003 |
| 1971 const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); | 2004 const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); |
| 1972 if (NULL == data) { | 2005 if (NULL == data) { |
| 1973 return false; | 2006 return false; |
| 1974 } | 2007 } |
| 1975 | 2008 |
| 1976 const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data); | 2009 const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data); |
| 1977 | 2010 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2013 SkRect r = SkRect::Make(clip); | 2046 SkRect r = SkRect::Make(clip); |
| 2014 inv.mapRect(&r); | 2047 inv.mapRect(&r); |
| 2015 r.roundOut(&clip); | 2048 r.roundOut(&clip); |
| 2016 | 2049 |
| 2017 const SkPicture::OperationList& ops = picture->EXPERIMENTAL_getActiveOps(cli
p); | 2050 const SkPicture::OperationList& ops = picture->EXPERIMENTAL_getActiveOps(cli
p); |
| 2018 | 2051 |
| 2019 #ifdef SK_PRINT_PULL_FORWARD_INFO | 2052 #ifdef SK_PRINT_PULL_FORWARD_INFO |
| 2020 SkDebugf("rect: %d %d %d %d\n", clip.fLeft, clip.fTop, clip.fRight, clip.fBo
ttom); | 2053 SkDebugf("rect: %d %d %d %d\n", clip.fLeft, clip.fTop, clip.fRight, clip.fBo
ttom); |
| 2021 #endif | 2054 #endif |
| 2022 | 2055 |
| 2023 for (int i = 0; i < ops.numOps(); ++i) { | 2056 if (ops.valid()) { |
| 2057 for (int i = 0; i < ops.numOps(); ++i) { |
| 2058 for (int j = 0; j < gpuData->numSaveLayers(); ++j) { |
| 2059 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo
(j); |
| 2060 |
| 2061 if (ops.offset(i) > info.fSaveLayerOpID && ops.offset(i) < info.
fRestoreOpID) { |
| 2062 pullForward[j] = true; |
| 2063 } |
| 2064 } |
| 2065 } |
| 2066 } else { |
| 2024 for (int j = 0; j < gpuData->numSaveLayers(); ++j) { | 2067 for (int j = 0; j < gpuData->numSaveLayers(); ++j) { |
| 2025 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j); | 2068 pullForward[j] = true; |
| 2069 } |
| 2070 } |
| 2026 | 2071 |
| 2027 if (ops.offset(i) > info.fSaveLayerOpID && ops.offset(i) < info.fRes
toreOpID) { | 2072 SkPicturePlayback::Bar bar; |
| 2028 pullForward[j] = true; | 2073 |
| 2074 #ifdef SK_PRINT_PULL_FORWARD_INFO |
| 2075 SkDebugf("Need SaveLayers: "); |
| 2076 #endif |
| 2077 |
| 2078 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { |
| 2079 if (pullForward[i]) { |
| 2080 GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(
picture, i); |
| 2081 |
| 2082 #ifdef SK_PRINT_PULL_FORWARD_INFO |
| 2083 SkDebugf("%d (%d), ", i, layer->layerID()); |
| 2084 #endif |
| 2085 |
| 2086 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); |
| 2087 |
| 2088 if (NULL != picture->fPlayback) { |
| 2089 SkPicturePlayback::Foo* temp = bar.push(); |
| 2090 |
| 2091 temp->fStart = info.fSaveLayerOpID; |
| 2092 temp->fStop = info.fRestoreOpID; |
| 2093 temp->fPos = info.fOrigin; |
| 2094 |
| 2095 GrTextureDesc desc; |
| 2096 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
| 2097 desc.fWidth = info.fSize.fWidth; |
| 2098 desc.fHeight = info.fSize.fHeight; |
| 2099 desc.fConfig = kSkia8888_GrPixelConfig; |
| 2100 // TODO: need to deal with sample count |
| 2101 |
| 2102 bool bNeedsRendering = true; |
| 2103 |
| 2104 #if USE_SCRATCH |
| 2105 // This path just uses scratch textures and doesn't cache the te
xture. |
| 2106 // This can yield a lot of re-rendering |
| 2107 if (NULL == layer->getTexture()) { |
| 2108 layer->setTexture(fContext->lockAndRefScratchTexture(desc, G
rContext::kApprox_ScratchTexMatch)); |
| 2109 if (NULL == layer->getTexture()) { |
| 2110 continue; |
| 2111 } |
| 2112 } else { |
| 2113 bNeedsRendering = false; |
| 2114 } |
| 2115 #else |
| 2116 // This path caches the rendering result |
| 2117 GrCacheID cacheID; |
| 2118 generate_layer_cache_id(*picture, i, &cacheID); |
| 2119 |
| 2120 layer->setTexture(fContext->findAndRefTexture(desc, cacheID, NUL
L)); |
| 2121 |
| 2122 if (NULL == layer->getTexture()) { |
| 2123 layer->setTexture(fContext->createTexture(NULL, desc, cacheI
D, NULL, 0)); |
| 2124 } else { |
| 2125 bNeedsRendering = false; |
| 2126 } |
| 2127 #endif |
| 2128 |
| 2129 temp->fBM = SkNEW(SkBitmap); |
| 2130 wrap_texture(layer->getTexture(), desc.fWidth, desc.fHeight, tem
p->fBM); |
| 2131 |
| 2132 temp->fPaint = info.fPaint; |
| 2133 |
| 2134 |
| 2135 if (bNeedsRendering) { |
| 2136 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDi
rect(layer->getTexture()->asRenderTarget())); |
| 2137 |
| 2138 SkCanvas* canvas = surface->getCanvas(); |
| 2139 |
| 2140 canvas->translate(SkIntToScalar(-info.fOrigin.fX), SkIntToSc
alar(-info.fOrigin.fY)); |
| 2141 canvas->clear(SK_ColorTRANSPARENT); |
| 2142 |
| 2143 picture->fPlayback->draw(*canvas, info.fSaveLayerOpID, info.
fRestoreOpID, NULL, NULL); |
| 2144 canvas->flush(); |
| 2145 } |
| 2029 } | 2146 } |
| 2030 } | 2147 } |
| 2031 } | 2148 } |
| 2032 | |
| 2033 #ifdef SK_PRINT_PULL_FORWARD_INFO | 2149 #ifdef SK_PRINT_PULL_FORWARD_INFO |
| 2034 SkDebugf("Need SaveLayers: "); | |
| 2035 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { | |
| 2036 if (pullForward[i]) { | |
| 2037 const GrAtlasedLayer* layer = fContext->getLayerCache()->findLayerOr
Create(picture, i); | |
| 2038 | |
| 2039 SkDebugf("%d (%d), ", i, layer->layerID()); | |
| 2040 } | |
| 2041 } | |
| 2042 SkDebugf("\n"); | 2150 SkDebugf("\n"); |
| 2043 #endif | 2151 #endif |
| 2044 | 2152 |
| 2045 return false; | 2153 // Playback using new layers |
| 2154 picture->fPlayback->draw(*canvas1, -1, -1, NULL, &bar); |
| 2155 |
| 2156 // playback normally |
| 2157 // picture->fPlayback->draw(*canvas1, -1, -1, NULL, NULL); |
| 2158 |
| 2159 bar.freeAll(); |
| 2160 |
| 2161 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { |
| 2162 // GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(pi
cture, i); |
| 2163 |
| 2164 #if USE_SCRATCH |
| 2165 // fContext->unlockScratchTexture(layer->getTexture()); |
| 2166 #endif |
| 2167 // layer->setTexture(NULL); |
| 2168 } |
| 2169 |
| 2170 return true; |
| 2046 } | 2171 } |
| OLD | NEW |