Chromium Code Reviews| Index: src/gpu/GrSWMaskHelper.cpp |
| diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp |
| index 744fa1db8ffff2b192d63a2134927630cbed18a0..06f4e38bded3674f16b46a34f83bd9609ddc395e 100644 |
| --- a/src/gpu/GrSWMaskHelper.cpp |
| +++ b/src/gpu/GrSWMaskHelper.cpp |
| @@ -85,6 +85,18 @@ static bool choose_compressed_fmt(const GrDrawTargetCaps* caps, |
| } |
| +GrSWMaskHelper::~GrSWMaskHelper() { |
| + if (NULL != fCompressedBlitter) { |
| + delete fCompressedBlitter; |
| + fCompressedBlitter = NULL; |
| + } |
| + |
| + if (NULL != fCompressedBuffer) { |
| + sk_free(fCompressedBuffer); |
| + fCompressedBuffer = NULL; |
| + } |
| +} |
| + |
| /** |
| * Draw a single rect element of the clip stack into the accumulation bitmap |
| */ |
| @@ -125,13 +137,27 @@ void GrSWMaskHelper::draw(const SkPath& path, const SkStrokeRec& stroke, SkRegio |
| } |
| paint.setAntiAlias(antiAlias); |
| + SkBlitter* blitter = NULL; |
| + if (kBlitter_CompressionMode == fCompressionMode) { |
| + blitter = fCompressedBlitter; |
| + } |
| + |
| if (SkRegion::kReplace_Op == op && 0xFF == alpha) { |
| SkASSERT(0xFF == paint.getAlpha()); |
| - fDraw.drawPathCoverage(path, paint); |
| + fDraw.drawPathCoverage(path, paint, blitter); |
| } else { |
| paint.setXfermodeMode(op_to_mode(op)); |
| paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); |
| - fDraw.drawPath(path, paint); |
| + fDraw.drawPath(path, paint, blitter); |
| + } |
| + |
|
robertphillips
2014/08/06 20:54:49
Get reset -> Get rid of ?
krajcevski
2014/08/06 22:41:59
Done.
|
| + // Get reset the blitter, since we're done using it, and it might |
| + // need to do some final cleanup for its cached scanlines |
| + if (NULL != fCompressedBlitter) { |
| + SkASSERT(kBlitter_CompressionMode == fCompressionMode); |
| + SkASSERT(blitter == fCompressedBlitter); // we used the compressed blitter |
| + delete fCompressedBlitter; |
| + fCompressedBlitter = NULL; |
| } |
| } |
| @@ -150,31 +176,55 @@ bool GrSWMaskHelper::init(const SkIRect& resultBounds, |
| resultBounds.height()); |
| #if GR_COMPRESS_ALPHA_MASK |
| - fCompressMask = choose_compressed_fmt(fContext->getGpu()->caps(), &fCompressedFormat); |
| -#else |
| - fCompressMask = false; |
| + if (choose_compressed_fmt(fContext->getGpu()->caps(), &fCompressedFormat)) { |
| + fCompressionMode = kCompress_CompressionMode; |
| + } |
| #endif |
| // Make sure that the width is a multiple of 16 so that we can use |
| // specialized SIMD instructions that compress 4 blocks at a time. |
| - int cmpWidth, cmpHeight; |
| - if (fCompressMask) { |
| + int cmpWidth = bounds.fRight; |
| + int cmpHeight = bounds.fBottom; |
| + if (kCompress_CompressionMode == fCompressionMode) { |
| int dimX, dimY; |
| SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY); |
| - cmpWidth = dimX * ((bounds.fRight + (dimX - 1)) / dimX); |
| - cmpHeight = dimY * ((bounds.fBottom + (dimY - 1)) / dimY); |
| - } else { |
| - cmpWidth = bounds.fRight; |
| - cmpHeight = bounds.fBottom; |
| - } |
| + cmpWidth = dimX * ((cmpWidth + (dimX - 1)) / dimX); |
| + cmpHeight = dimY * ((cmpHeight + (dimY - 1)) / dimY); |
| + |
| + // Can we create a blitter? |
| + int cmpSz = SkTextureCompressor::GetCompressedDataSize( |
| + fCompressedFormat, cmpWidth, cmpHeight); |
| + |
| + if (cmpSz > 0) { |
| + fCompressedBuffer = sk_malloc_throw(cmpSz); |
| + fCompressedBlitter = SkTextureCompressor::CreateBlitterForFormat( |
| + cmpWidth, cmpHeight, fCompressedBuffer, fCompressedFormat); |
| + |
| + if (NULL != fCompressedBlitter) { |
| + fCompressionMode = kBlitter_CompressionMode; |
| + } else { |
| + fCompressionMode = kCompress_CompressionMode; |
| + sk_free(fCompressedBuffer); |
| + } |
| + } |
| + } |
| + |
|
robertphillips
2014/08/06 20:54:48
If blitter creation failed in the above couldn't w
krajcevski
2014/08/06 22:41:59
Yes, but the munged ones only happen if we have a
|
| + // If we don't have a custom blitter, then we need a bitmap |
| + // to compress into. |
| + const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(cmpWidth, cmpHeight); |
| + if (kBlitter_CompressionMode != fCompressionMode) { |
| + if (!fBM.allocPixels(bmImageInfo)) { |
| + return false; |
| + } |
| - if (!fBM.allocPixels(SkImageInfo::MakeA8(cmpWidth, cmpHeight))) { |
| - return false; |
| + sk_bzero(fBM.getPixels(), fBM.getSafeSize()); |
| + } else { |
| + // Otherwise, we just need to remember how big the buffer is... |
| + fBM.setInfo(bmImageInfo); |
| } |
| - sk_bzero(fBM.getPixels(), fBM.getSafeSize()); |
| - |
| sk_bzero(&fDraw, sizeof(fDraw)); |
| + |
| fRasterClip.setRect(bounds); |
| fDraw.fRC = &fRasterClip; |
| fDraw.fClip = &fRasterClip.bwRgn(); |
| @@ -193,7 +243,7 @@ bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { |
| desc.fHeight = fBM.height(); |
| desc.fConfig = kAlpha_8_GrPixelConfig; |
| - if (fCompressMask) { |
| + if (kNone_CompressionMode != fCompressionMode) { |
| #ifdef SK_DEBUG |
| int dimX, dimY; |
| @@ -203,12 +253,7 @@ bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { |
| #endif |
| desc.fConfig = fmt_to_config(fCompressedFormat); |
| - |
| - // If this config isn't supported then we should fall back to A8 |
| - if (!(fContext->getGpu()->caps()->isConfigTexturable(desc.fConfig))) { |
| - SkDEBUGFAIL("Determining compression should be set from choose_compressed_fmt"); |
| - desc.fConfig = kAlpha_8_GrPixelConfig; |
| - } |
| + SkASSERT(fContext->getGpu()->caps()->isConfigTexturable(desc.fConfig)); |
| } |
| texture->set(fContext, desc); |
| @@ -253,11 +298,18 @@ void GrSWMaskHelper::toTexture(GrTexture *texture) { |
| desc.fConfig = texture->config(); |
| // First see if we should compress this texture before uploading. |
| - if (fCompressMask) { |
| - this->compressTextureData(texture, desc); |
| - } else { |
| - // Looks like we have to send a full A8 texture. |
| - this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes()); |
| + switch (fCompressionMode) { |
| + case kNone_CompressionMode: |
| + this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes()); |
| + break; |
| + |
| + case kCompress_CompressionMode: |
| + this->compressTextureData(texture, desc); |
| + break; |
| + |
| + case kBlitter_CompressionMode: |
| + SkASSERT(NULL != fCompressedBuffer); |
| + this->sendTextureData(texture, desc, fCompressedBuffer, 0); |
|
robertphillips
2014/08/06 20:54:48
break; ? for consistency.
krajcevski
2014/08/06 22:41:59
Done.
|
| } |
| } |