Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/gpu/GrContext.cpp

Issue 1234313002: Make readpixels work on GrTextures (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix and more kRT removal Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/gpu/GrContext.h ('k') | src/gpu/GrSurface.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 10
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 surface->surfacePriv().hasPendingIO()) { 340 surface->surfacePriv().hasPendingIO()) {
341 this->flush(); 341 this->flush();
342 } 342 }
343 return fGpu->writeTexturePixels(texture, left, top, width, height, 343 return fGpu->writeTexturePixels(texture, left, top, width, height,
344 srcConfig, buffer, rowBytes); 344 srcConfig, buffer, rowBytes);
345 // Don't need to check kFlushWrites_PixelOp here, we just did a dire ct write so the 345 // Don't need to check kFlushWrites_PixelOp here, we just did a dire ct write so the
346 // upload is already flushed. 346 // upload is already flushed.
347 } 347 }
348 } 348 }
349 349
350 // Trim the params here so that if we wind up making a temporary surface it can be as small as
351 // necessary.
352 if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height (),
353 GrBytesPerPixel(srcConfig), &left , &top, &width,
354 &height, &buffer, &rowBytes)) {
355 return false;
356 }
357
350 // If we didn't do a direct texture write then we upload the pixels to a tex ture and draw. 358 // If we didn't do a direct texture write then we upload the pixels to a tex ture and draw.
351 GrRenderTarget* renderTarget = surface->asRenderTarget(); 359 GrRenderTarget* renderTarget = surface->asRenderTarget();
352 if (!renderTarget) { 360 if (!renderTarget) {
353 return false; 361 return false;
354 } 362 }
355 363
356 // We ignore the preferred config unless it is a R/B swap of the src config. In that case 364 // We ignore the preferred config unless it is a R/B swap of the src config. In that case
357 // we will upload the original src data to a scratch texture but we will spo of it as the swapped 365 // we will upload the original src data to a scratch texture but we will spo of it as the swapped
358 // config. This scratch will then have R and B swapped. We correct for this by swapping again 366 // config. This scratch will then have R and B swapped. We correct for this by swapping again
359 // when drawing the scratch to the dst using a conversion effect. 367 // when drawing the scratch to the dst using a conversion effect.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 // toggles between RGBA and BGRA 453 // toggles between RGBA and BGRA
446 static SkColorType toggle_colortype32(SkColorType ct) { 454 static SkColorType toggle_colortype32(SkColorType ct) {
447 if (kRGBA_8888_SkColorType == ct) { 455 if (kRGBA_8888_SkColorType == ct) {
448 return kBGRA_8888_SkColorType; 456 return kBGRA_8888_SkColorType;
449 } else { 457 } else {
450 SkASSERT(kBGRA_8888_SkColorType == ct); 458 SkASSERT(kBGRA_8888_SkColorType == ct);
451 return kRGBA_8888_SkColorType; 459 return kRGBA_8888_SkColorType;
452 } 460 }
453 } 461 }
454 462
455 bool GrContext::readRenderTargetPixels(GrRenderTarget* target, 463 bool GrContext::readSurfacePixels(GrSurface* src,
456 int left, int top, int width, int height, 464 int left, int top, int width, int height,
457 GrPixelConfig dstConfig, void* buffer, si ze_t rowBytes, 465 GrPixelConfig dstConfig, void* buffer, size_t rowBytes,
458 uint32_t flags) { 466 uint32_t flags) {
459 RETURN_FALSE_IF_ABANDONED 467 RETURN_FALSE_IF_ABANDONED
460 ASSERT_OWNED_RESOURCE(target); 468 ASSERT_OWNED_RESOURCE(src);
461 SkASSERT(target); 469 SkASSERT(src);
462 470
463 if (!(kDontFlush_PixelOpsFlag & flags) && target->surfacePriv().hasPendingWr ite()) { 471 // Adjust the params so that if we wind up using an intermediate surface we' ve already done
472 // all the trimming and the temporary can be the min size required.
473 if (!GrSurfacePriv::AdjustReadPixelParams(src->width(), src->height(),
474 GrBytesPerPixel(dstConfig), &left,
475 &top, &width, &height, &buffer, &r owBytes)) {
476 return false;
477 }
478
479 if (!(kDontFlush_PixelOpsFlag & flags) && src->surfacePriv().hasPendingWrite ()) {
464 this->flush(); 480 this->flush();
465 } 481 }
466 482
467 // Determine which conversions have to be applied: flipY, swapRAnd, and/or u npremul. 483 // Determine which conversions have to be applied: flipY, swapRAnd, and/or u npremul.
468 484
469 // If fGpu->readPixels would incur a y-flip cost then we will read the pixel s upside down. We'll
470 // either do the flipY by drawing into a scratch with a matrix or on the cpu after the read.
471 bool flipY = fGpu->readPixelsWillPayForYFlip(target, left, top,
472 width, height, dstConfig,
473 rowBytes);
474 // We ignore the preferred config if it is different than our config unless it is an R/B swap. 485 // We ignore the preferred config if it is different than our config unless it is an R/B swap.
475 // In that case we'll perform an R and B swap while drawing to a scratch tex ture of the swapped 486 // In that case we'll perform an R and B swap while drawing to a scratch tex ture of the swapped
476 // config. Then we will call readPixels on the scratch with the swapped conf ig. The swaps during 487 // config. Then we will call readPixels on the scratch with the swapped conf ig. The swaps during
477 // the draw cancels out the fact that we call readPixels with a config that is R/B swapped from 488 // the draw cancels out the fact that we call readPixels with a config that is R/B swapped from
478 // dstConfig. 489 // dstConfig.
479 GrPixelConfig readConfig = dstConfig; 490 GrPixelConfig readConfig = dstConfig;
480 bool swapRAndB = false; 491 bool swapRAndB = false;
481 if (GrPixelConfigSwapRAndB(dstConfig) == 492 if (GrPixelConfigSwapRAndB(dstConfig) ==
482 fGpu->preferredReadPixelsConfig(dstConfig, target->config())) { 493 fGpu->preferredReadPixelsConfig(dstConfig, src->config())) {
483 readConfig = GrPixelConfigSwapRAndB(readConfig); 494 readConfig = GrPixelConfigSwapRAndB(readConfig);
484 swapRAndB = true; 495 swapRAndB = true;
485 } 496 }
486 497
498 bool flipY = false;
499 GrRenderTarget* srcAsRT = src->asRenderTarget();
500 if (srcAsRT) {
501 // If fGpu->readPixels would incur a y-flip cost then we will read the p ixels upside down.
502 // We'll either do the flipY by drawing into a scratch with a matrix or on the cpu after the
503 // read.
504 flipY = fGpu->readPixelsWillPayForYFlip(srcAsRT, left, top,
505 width, height, dstConfig,
506 rowBytes);
507 }
508
487 bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); 509 bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
488
489 if (unpremul && !GrPixelConfigIs8888(dstConfig)) { 510 if (unpremul && !GrPixelConfigIs8888(dstConfig)) {
490 // The unpremul flag is only allowed for these two configs. 511 // The unpremul flag is only allowed for these two configs.
491 return false; 512 return false;
492 } 513 }
493 514
494 SkAutoTUnref<GrTexture> tempTexture; 515 SkAutoTUnref<GrTexture> tempTexture;
495 516
496 // If the src is a texture and we would have to do conversions after read pi xels, we instead 517 // If the src is a texture and we would have to do conversions after read pi xels, we instead
497 // do the conversions by drawing the src to a scratch texture. If we handle any of the 518 // do the conversions by drawing the src to a scratch texture. If we handle any of the
498 // conversions in the draw we set the corresponding bool to false so that we don't reapply it 519 // conversions in the draw we set the corresponding bool to false so that we don't reapply it
499 // on the read back pixels. 520 // on the read back pixels. We also do an intermediate draw if the src is no t a render target as
500 GrTexture* src = target->asTexture(); 521 // GrGpu currently supports reading from render targets but not textures.
501 if (src && (swapRAndB || unpremul || flipY)) { 522 GrTexture* srcAsTex = src->asTexture();
523 GrRenderTarget* rtToRead = srcAsRT;
524 if (srcAsTex && (swapRAndB || unpremul || flipY || !srcAsRT)) {
502 // Make the scratch a render so we can read its pixels. 525 // Make the scratch a render so we can read its pixels.
503 GrSurfaceDesc desc; 526 GrSurfaceDesc desc;
504 desc.fFlags = kRenderTarget_GrSurfaceFlag; 527 desc.fFlags = kRenderTarget_GrSurfaceFlag;
505 desc.fWidth = width; 528 desc.fWidth = width;
506 desc.fHeight = height; 529 desc.fHeight = height;
507 desc.fConfig = readConfig; 530 desc.fConfig = readConfig;
508 desc.fOrigin = kTopLeft_GrSurfaceOrigin; 531 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
509 532
510 // When a full read back is faster than a partial we could always make t he scratch exactly 533 // When a full read back is faster than a partial we could always make t he scratch exactly
511 // match the passed rect. However, if we see many different size rectang les we will trash 534 // match the passed rect. However, if we see many different size rectang les we will trash
512 // our texture cache and pay the cost of creating and destroying many te xtures. So, we only 535 // our texture cache and pay the cost of creating and destroying many te xtures. So, we only
513 // request an exact match when the caller is reading an entire RT. 536 // request an exact match when the caller is reading an entire RT.
514 GrTextureProvider::ScratchTexMatch match = GrTextureProvider::kApprox_Sc ratchTexMatch; 537 GrTextureProvider::ScratchTexMatch match = GrTextureProvider::kApprox_Sc ratchTexMatch;
515 if (0 == left && 538 if (0 == left &&
516 0 == top && 539 0 == top &&
517 target->width() == width && 540 src->width() == width &&
518 target->height() == height && 541 src->height() == height &&
519 fGpu->fullReadPixelsIsFasterThanPartial()) { 542 fGpu->fullReadPixelsIsFasterThanPartial()) {
520 match = GrTextureProvider::kExact_ScratchTexMatch; 543 match = GrTextureProvider::kExact_ScratchTexMatch;
521 } 544 }
522 tempTexture.reset(this->textureProvider()->refScratchTexture(desc, match )); 545 tempTexture.reset(this->textureProvider()->refScratchTexture(desc, match ));
523 if (tempTexture) { 546 if (tempTexture) {
524 // compute a matrix to perform the draw 547 // compute a matrix to perform the draw
525 SkMatrix textureMatrix; 548 SkMatrix textureMatrix;
526 textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 549 textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top);
527 textureMatrix.postIDiv(src->width(), src->height()); 550 textureMatrix.postIDiv(src->width(), src->height());
528 551
529 GrPaint paint; 552 GrPaint paint;
530 SkAutoTUnref<const GrFragmentProcessor> fp; 553 SkAutoTUnref<const GrFragmentProcessor> fp;
531 if (unpremul) { 554 if (unpremul) {
532 fp.reset(this->createPMToUPMEffect(paint.getProcessorDataManager (), src, swapRAndB, 555 fp.reset(this->createPMToUPMEffect(paint.getProcessorDataManager (), srcAsTex,
533 textureMatrix)); 556 swapRAndB, textureMatrix));
534 if (fp) { 557 if (fp) {
535 unpremul = false; // we no longer need to do this on CPU aft er the read back. 558 unpremul = false; // we no longer need to do this on CPU aft er the read back.
536 } 559 }
537 } 560 }
538 // If we failed to create a PM->UPM effect and have no other convers ions to perform then 561 // If we failed to create a PM->UPM effect and have no other convers ions to perform then
539 // there is no longer any point to using the scratch. 562 // there is no longer any point to using the scratch.
540 if (fp || flipY || swapRAndB) { 563 if (fp || flipY || swapRAndB || !srcAsRT) {
541 if (!fp) { 564 if (!fp) {
542 fp.reset(GrConfigConversionEffect::Create(paint.getProcessor DataManager(), 565 fp.reset(GrConfigConversionEffect::Create(paint.getProcessor DataManager(),
543 src, swapRAndB, GrConfigConversionEffect::kNone_PMCo nversion, 566 srcAsTex, swapRAndB, GrConfigConversionEffect::kNone _PMConversion,
544 textureMatrix)); 567 textureMatrix));
545 } 568 }
546 swapRAndB = false; // we will handle the swap in the draw. 569 swapRAndB = false; // we will handle the swap in the draw.
547 570
548 // We protect the existing geometry here since it may not be 571 // We protect the existing geometry here since it may not be
549 // clear to the caller that a draw operation (i.e., drawSimpleRe ct) 572 // clear to the caller that a draw operation (i.e., drawSimpleRe ct)
550 // can be invoked in this method 573 // can be invoked in this method
551 { 574 {
552 GrDrawContext* drawContext = this->drawContext(); 575 GrDrawContext* drawContext = this->drawContext();
553 if (!drawContext) { 576 if (!drawContext) {
554 return false; 577 return false;
555 } 578 }
556 579
557 paint.addColorProcessor(fp); 580 paint.addColorProcessor(fp);
558 581
559 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToSc alar(height)); 582 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToSc alar(height));
560 583
561 drawContext->drawRect(tempTexture->asRenderTarget(), GrClip: :WideOpen(), paint, 584 drawContext->drawRect(tempTexture->asRenderTarget(), GrClip: :WideOpen(), paint,
562 SkMatrix::I(), rect, NULL); 585 SkMatrix::I(), rect, NULL);
563 586
564 // we want to read back from the scratch's origin 587 // we want to read back from the scratch's origin
565 left = 0; 588 left = 0;
566 top = 0; 589 top = 0;
567 target = tempTexture->asRenderTarget(); 590 rtToRead = tempTexture->asRenderTarget();
568 } 591 }
569 this->flushSurfaceWrites(target); 592 this->flushSurfaceWrites(tempTexture);
570 } 593 }
571 } 594 }
572 } 595 }
573 596
574 if (!fGpu->readPixels(target, 597 if (!rtToRead ||
575 left, top, width, height, 598 !fGpu->readPixels(rtToRead, left, top, width, height, readConfig, buffer , rowBytes)) {
576 readConfig, buffer, rowBytes)) {
577 return false; 599 return false;
578 } 600 }
579 // Perform any conversions we weren't able to perform using a scratch textur e. 601 // Perform any conversions we weren't able to perform using a scratch textur e.
580 if (unpremul || swapRAndB) { 602 if (unpremul || swapRAndB) {
581 SkDstPixelInfo dstPI; 603 SkDstPixelInfo dstPI;
582 if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, NUL L)) { 604 if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, NUL L)) {
583 return false; 605 return false;
584 } 606 }
585 dstPI.fAlphaType = kUnpremul_SkAlphaType; 607 dstPI.fAlphaType = kUnpremul_SkAlphaType;
586 dstPI.fPixels = buffer; 608 dstPI.fPixels = buffer;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 ////////////////////////////////////////////////////////////////////////////// 785 //////////////////////////////////////////////////////////////////////////////
764 786
765 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { 787 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
766 fGpu->addGpuTraceMarker(marker); 788 fGpu->addGpuTraceMarker(marker);
767 } 789 }
768 790
769 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { 791 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
770 fGpu->removeGpuTraceMarker(marker); 792 fGpu->removeGpuTraceMarker(marker);
771 } 793 }
772 794
OLDNEW
« no previous file with comments | « include/gpu/GrContext.h ('k') | src/gpu/GrSurface.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698