OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrContext.h" | 9 #include "GrContext.h" |
10 #include "GrContextOptions.h" | 10 #include "GrContextOptions.h" |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 // Stack frame size is limited in GOOGLE3. | 291 // Stack frame size is limited in GOOGLE3. |
292 SkAutoSTMalloc<48 * 48, uint32_t> tmpPixels(0); | 292 SkAutoSTMalloc<48 * 48, uint32_t> tmpPixels(0); |
293 #else | 293 #else |
294 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); | 294 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); |
295 #endif | 295 #endif |
296 if (tempTexture) { | 296 if (tempTexture) { |
297 SkAutoTUnref<const GrFragmentProcessor> fp; | 297 SkAutoTUnref<const GrFragmentProcessor> fp; |
298 SkMatrix textureMatrix; | 298 SkMatrix textureMatrix; |
299 textureMatrix.setIDiv(tempTexture->width(), tempTexture->height()); | 299 textureMatrix.setIDiv(tempTexture->width(), tempTexture->height()); |
300 if (applyPremulToSrc) { | 300 if (applyPremulToSrc) { |
301 fp.reset(this->createUPMToPMEffect(tempTexture, tempDrawInfo.fSwapRA
ndB, | 301 fp.reset(this->createUPMToPMEffect(tempTexture, tempDrawInfo.fSwizzl
e, |
302 textureMatrix)); | 302 textureMatrix)); |
303 // If premultiplying was the only reason for the draw, fall back to
a straight write. | 303 // If premultiplying was the only reason for the draw, fall back to
a straight write. |
304 if (!fp) { | 304 if (!fp) { |
305 if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference)
{ | 305 if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference)
{ |
306 tempTexture.reset(nullptr); | 306 tempTexture.reset(nullptr); |
307 } | 307 } |
308 } else { | 308 } else { |
309 applyPremulToSrc = false; | 309 applyPremulToSrc = false; |
310 } | 310 } |
311 } | 311 } |
312 if (tempTexture) { | 312 if (tempTexture) { |
313 if (!fp) { | 313 if (!fp) { |
314 fp.reset(GrConfigConversionEffect::Create(tempTexture, tempDrawI
nfo.fSwapRAndB, | 314 fp.reset(GrConfigConversionEffect::Create(tempTexture, tempDrawI
nfo.fSwizzle, |
315 GrConfigConversionEffect::kNone_PMConversion, textureMatrix)
); | 315 GrConfigConversionEffect::kNone_PMConversion, textureMatrix)
); |
316 if (!fp) { | 316 if (!fp) { |
317 return false; | 317 return false; |
318 } | 318 } |
319 } | 319 } |
320 GrRenderTarget* renderTarget = surface->asRenderTarget(); | 320 GrRenderTarget* renderTarget = surface->asRenderTarget(); |
321 SkASSERT(renderTarget); | 321 SkASSERT(renderTarget); |
322 if (tempTexture->surfacePriv().hasPendingIO()) { | 322 if (tempTexture->surfacePriv().hasPendingIO()) { |
323 this->flush(); | 323 this->flush(); |
324 } | 324 } |
325 if (applyPremulToSrc) { | 325 if (applyPremulToSrc) { |
326 size_t tmpRowBytes = 4 * width; | 326 size_t tmpRowBytes = 4 * width; |
327 tmpPixels.reset(width * height); | 327 tmpPixels.reset(width * height); |
328 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, bu
ffer, tmpRowBytes, | 328 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, bu
ffer, tmpRowBytes, |
329 tmpPixels.get())) { | 329 tmpPixels.get())) { |
330 return false; | 330 return false; |
331 } | 331 } |
332 rowBytes = tmpRowBytes; | 332 rowBytes = tmpRowBytes; |
333 buffer = tmpPixels.get(); | 333 buffer = tmpPixels.get(); |
334 applyPremulToSrc = false; | 334 applyPremulToSrc = false; |
335 } | 335 } |
336 if (!fGpu->writePixels(tempTexture, 0, 0, width, height, | 336 if (!fGpu->writePixels(tempTexture, 0, 0, width, height, |
337 tempDrawInfo.fTempSurfaceDesc.fConfig, buffer
, | 337 tempDrawInfo.fWriteConfig, buffer, |
338 rowBytes)) { | 338 rowBytes)) { |
339 return false; | 339 return false; |
340 } | 340 } |
341 SkMatrix matrix; | 341 SkMatrix matrix; |
342 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); | 342 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); |
343 SkAutoTUnref<GrDrawContext> drawContext(this->drawContext(renderTarg
et)); | 343 SkAutoTUnref<GrDrawContext> drawContext(this->drawContext(renderTarg
et)); |
344 if (!drawContext) { | 344 if (!drawContext) { |
345 return false; | 345 return false; |
346 } | 346 } |
347 GrPaint paint; | 347 GrPaint paint; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 temp.reset(this->textureProvider()->createTexture(tempDrawInfo.fTemp
SurfaceDesc, true)); | 431 temp.reset(this->textureProvider()->createTexture(tempDrawInfo.fTemp
SurfaceDesc, true)); |
432 } else { | 432 } else { |
433 temp.reset(this->textureProvider()->createApproxTexture(tempDrawInfo
.fTempSurfaceDesc)); | 433 temp.reset(this->textureProvider()->createApproxTexture(tempDrawInfo
.fTempSurfaceDesc)); |
434 } | 434 } |
435 if (temp) { | 435 if (temp) { |
436 SkMatrix textureMatrix; | 436 SkMatrix textureMatrix; |
437 textureMatrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); | 437 textureMatrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); |
438 textureMatrix.postIDiv(src->width(), src->height()); | 438 textureMatrix.postIDiv(src->width(), src->height()); |
439 SkAutoTUnref<const GrFragmentProcessor> fp; | 439 SkAutoTUnref<const GrFragmentProcessor> fp; |
440 if (unpremul) { | 440 if (unpremul) { |
441 fp.reset(this->createPMToUPMEffect(src->asTexture(), tempDrawInf
o.fSwapRAndB, | 441 fp.reset(this->createPMToUPMEffect(src->asTexture(), tempDrawInf
o.fSwizzle, |
442 textureMatrix)); | 442 textureMatrix)); |
443 if (fp) { | 443 if (fp) { |
444 unpremul = false; // we no longer need to do this on CPU aft
er the read back. | 444 unpremul = false; // we no longer need to do this on CPU aft
er the read back. |
445 } else if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPrefe
rence) { | 445 } else if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPrefe
rence) { |
446 // We only wanted to do the draw in order to perform the unp
remul so don't | 446 // We only wanted to do the draw in order to perform the unp
remul so don't |
447 // bother. | 447 // bother. |
448 temp.reset(nullptr); | 448 temp.reset(nullptr); |
449 } | 449 } |
450 } | 450 } |
451 if (!fp && temp) { | 451 if (!fp && temp) { |
452 fp.reset(GrConfigConversionEffect::Create(src->asTexture(), temp
DrawInfo.fSwapRAndB, | 452 fp.reset(GrConfigConversionEffect::Create(src->asTexture(), temp
DrawInfo.fSwizzle, |
453 GrConfigConversionEffect::kNone_PMConversion, textureMatrix)
); | 453 GrConfigConversionEffect::kNone_PMConversion, textureMatrix)
); |
454 } | 454 } |
455 if (fp) { | 455 if (fp) { |
456 GrPaint paint; | 456 GrPaint paint; |
457 paint.addColorFragmentProcessor(fp); | 457 paint.addColorFragmentProcessor(fp); |
458 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); | 458 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); |
459 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar
(height)); | 459 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar
(height)); |
460 SkAutoTUnref<GrDrawContext> drawContext(this->drawContext(temp->
asRenderTarget())); | 460 SkAutoTUnref<GrDrawContext> drawContext(this->drawContext(temp->
asRenderTarget())); |
461 drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(),
rect, nullptr); | 461 drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(),
rect, nullptr); |
462 surfaceToRead.reset(SkRef(temp.get())); | 462 surfaceToRead.reset(SkRef(temp.get())); |
463 left = 0; | 463 left = 0; |
464 top = 0; | 464 top = 0; |
465 didTempDraw = true; | 465 didTempDraw = true; |
466 } | 466 } |
467 } | 467 } |
468 } | 468 } |
469 | 469 |
470 if (GrGpu::kRequireDraw_DrawPreference == drawPreference && !didTempDraw) { | 470 if (GrGpu::kRequireDraw_DrawPreference == drawPreference && !didTempDraw) { |
471 return false; | 471 return false; |
472 } | 472 } |
473 GrPixelConfig configToRead = dstConfig; | 473 GrPixelConfig configToRead = dstConfig; |
474 if (didTempDraw) { | 474 if (didTempDraw) { |
475 this->flushSurfaceWrites(surfaceToRead); | 475 this->flushSurfaceWrites(surfaceToRead); |
476 // We swapped R and B while doing the temp draw. Swap back on the read. | 476 configToRead = tempDrawInfo.fReadConfig; |
477 if (tempDrawInfo.fSwapRAndB) { | |
478 configToRead = GrPixelConfigSwapRAndB(dstConfig); | |
479 } | |
480 } | 477 } |
481 if (!fGpu->readPixels(surfaceToRead, left, top, width, height, configToRead,
buffer, | 478 if (!fGpu->readPixels(surfaceToRead, left, top, width, height, configToRead,
buffer, |
482 rowBytes)) { | 479 rowBytes)) { |
483 return false; | 480 return false; |
484 } | 481 } |
485 | 482 |
486 // Perform umpremul conversion if we weren't able to perform it as a draw. | 483 // Perform umpremul conversion if we weren't able to perform it as a draw. |
487 if (unpremul) { | 484 if (unpremul) { |
488 SkDstPixelInfo dstPI; | 485 SkDstPixelInfo dstPI; |
489 if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, nul
lptr)) { | 486 if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, nul
lptr)) { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 if (SkToBool(kUnpremul_PixelOpsFlag & flags)) { | 598 if (SkToBool(kUnpremul_PixelOpsFlag & flags)) { |
602 SkAutoMutexAcquire ama(fTestPMConversionsMutex); | 599 SkAutoMutexAcquire ama(fTestPMConversionsMutex); |
603 if (!fDidTestPMConversions) { | 600 if (!fDidTestPMConversions) { |
604 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); | 601 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); |
605 fDidTestPMConversions = true; | 602 fDidTestPMConversions = true; |
606 } | 603 } |
607 } | 604 } |
608 } | 605 } |
609 | 606 |
610 const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture, | 607 const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture, |
611 bool swapRAndB, | 608 const GrSwizzle& swizz
le, |
612 const SkMatrix& matrix
) const { | 609 const SkMatrix& matrix
) const { |
613 ASSERT_SINGLE_OWNER | 610 ASSERT_SINGLE_OWNER |
614 // We should have already called this->testPMConversionsIfNecessary(). | 611 // We should have already called this->testPMConversionsIfNecessary(). |
615 SkASSERT(fDidTestPMConversions); | 612 SkASSERT(fDidTestPMConversions); |
616 GrConfigConversionEffect::PMConversion pmToUPM = | 613 GrConfigConversionEffect::PMConversion pmToUPM = |
617 static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); | 614 static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); |
618 if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) { | 615 if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) { |
619 return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, mat
rix); | 616 return GrConfigConversionEffect::Create(texture, swizzle, pmToUPM, matri
x); |
620 } else { | 617 } else { |
621 return nullptr; | 618 return nullptr; |
622 } | 619 } |
623 } | 620 } |
624 | 621 |
625 const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture, | 622 const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture, |
626 bool swapRAndB, | 623 const GrSwizzle& swizz
le, |
627 const SkMatrix& matrix
) const { | 624 const SkMatrix& matrix
) const { |
628 ASSERT_SINGLE_OWNER | 625 ASSERT_SINGLE_OWNER |
629 // We should have already called this->testPMConversionsIfNecessary(). | 626 // We should have already called this->testPMConversionsIfNecessary(). |
630 SkASSERT(fDidTestPMConversions); | 627 SkASSERT(fDidTestPMConversions); |
631 GrConfigConversionEffect::PMConversion upmToPM = | 628 GrConfigConversionEffect::PMConversion upmToPM = |
632 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); | 629 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); |
633 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { | 630 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { |
634 return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, mat
rix); | 631 return GrConfigConversionEffect::Create(texture, swizzle, upmToPM, matri
x); |
635 } else { | 632 } else { |
636 return nullptr; | 633 return nullptr; |
637 } | 634 } |
638 } | 635 } |
639 | 636 |
640 bool GrContext::didFailPMUPMConversionTest() const { | 637 bool GrContext::didFailPMUPMConversionTest() const { |
641 ASSERT_SINGLE_OWNER | 638 ASSERT_SINGLE_OWNER |
642 // We should have already called this->testPMConversionsIfNecessary(). | 639 // We should have already called this->testPMConversionsIfNecessary(). |
643 SkASSERT(fDidTestPMConversions); | 640 SkASSERT(fDidTestPMConversions); |
644 // The PM<->UPM tests fail or succeed together so we only need to check one. | 641 // The PM<->UPM tests fail or succeed together so we only need to check one. |
(...skipping 16 matching lines...) Expand all Loading... |
661 ASSERT_SINGLE_OWNER | 658 ASSERT_SINGLE_OWNER |
662 fResourceCache->setLimits(maxTextures, maxTextureBytes); | 659 fResourceCache->setLimits(maxTextures, maxTextureBytes); |
663 } | 660 } |
664 | 661 |
665 ////////////////////////////////////////////////////////////////////////////// | 662 ////////////////////////////////////////////////////////////////////////////// |
666 | 663 |
667 void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { | 664 void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { |
668 ASSERT_SINGLE_OWNER | 665 ASSERT_SINGLE_OWNER |
669 fResourceCache->dumpMemoryStatistics(traceMemoryDump); | 666 fResourceCache->dumpMemoryStatistics(traceMemoryDump); |
670 } | 667 } |
OLD | NEW |