Index: src/gpu/GrSWMaskHelper.cpp |
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp |
index 2e68b7829b4bde6f044b055df014cc94fd97d81f..be6eb034b432a15432444408b124589b6fbd465f 100644 |
--- a/src/gpu/GrSWMaskHelper.cpp |
+++ b/src/gpu/GrSWMaskHelper.cpp |
@@ -50,6 +50,37 @@ static inline GrPixelConfig fmt_to_config(SkTextureCompressor::Format fmt) { |
return configMap[fmt]; |
} |
+#if GR_COMPRESS_ALPHA_MASK |
+static bool choose_compressed_fmt(const GrDrawTargetCaps* caps, |
+ SkTextureCompressor::Format *fmt) { |
+ if (NULL == fmt) { |
+ return false; |
+ } |
+ |
+ // We can't use scratch textures without the ability to update |
+ // compressed textures... |
+ if (!(caps->compressedTexSubImageSupport())) { |
+ return false; |
+ } |
+ |
+ // Figure out what our preferred texture type is. If ASTC is available, that always |
+ // gives the biggest win. Otherwise, in terms of compression speed and accuracy, |
+ // LATC has a slight edge over R11 EAC. |
+ if (caps->isConfigTexturable(kASTC_12x12_GrPixelConfig)) { |
+ *fmt = SkTextureCompressor::kASTC_12x12_Format; |
+ return true; |
+ } else if (caps->isConfigTexturable(kLATC_GrPixelConfig)) { |
+ *fmt = SkTextureCompressor::kLATC_Format; |
+ return true; |
+ } else if (caps->isConfigTexturable(kR11_EAC_GrPixelConfig)) { |
+ *fmt = SkTextureCompressor::kR11_EAC_Format; |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+#endif |
+ |
} |
/** |
@@ -117,18 +148,23 @@ bool GrSWMaskHelper::init(const SkIRect& resultBounds, |
resultBounds.height()); |
#if GR_COMPRESS_ALPHA_MASK |
- fCompressedFormat = SkTextureCompressor::kR11_EAC_Format; |
+ fCompressMask = choose_compressed_fmt(fContext->getGpu()->caps(), &fCompressedFormat); |
+#else |
+ fCompressMask = false; |
+#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 dimX, dimY; |
- SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY); |
- const int cmpWidth = dimX * ((bounds.fRight + (dimX - 1)) / dimX); |
- const int cmpHeight = dimY * ((bounds.fBottom + (dimY - 1)) / dimY); |
-#else |
- const int cmpWidth = bounds.fRight; |
- const int cmpHeight = bounds.fBottom; |
-#endif |
+ int cmpWidth, cmpHeight; |
+ if (fCompressMask) { |
+ 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; |
+ } |
if (!fBM.allocPixels(SkImageInfo::MakeA8(cmpWidth, cmpHeight))) { |
return false; |
@@ -153,25 +189,25 @@ bool GrSWMaskHelper::getTexture(GrAutoScratchTexture* texture) { |
GrTextureDesc desc; |
desc.fWidth = fBM.width(); |
desc.fHeight = fBM.height(); |
+ desc.fConfig = kAlpha_8_GrPixelConfig; |
-#if GR_COMPRESS_ALPHA_MASK |
+ if (fCompressMask) { |
#ifdef SK_DEBUG |
- int dimX, dimY; |
- SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY); |
- SkASSERT((desc.fWidth % dimX) == 0); |
- SkASSERT((desc.fHeight % dimY) == 0); |
+ int dimX, dimY; |
+ SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY); |
+ SkASSERT((desc.fWidth % dimX) == 0); |
+ SkASSERT((desc.fHeight % dimY) == 0); |
#endif |
- desc.fConfig = fmt_to_config(fCompressedFormat); |
+ 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))) { |
- desc.fConfig = kAlpha_8_GrPixelConfig; |
+ // 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; |
+ } |
} |
-#else |
- desc.fConfig = kAlpha_8_GrPixelConfig; |
-#endif |
texture->set(fContext, desc); |
return NULL != texture->texture(); |
@@ -195,23 +231,9 @@ void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& de |
void GrSWMaskHelper::compressTextureData(GrTexture *texture, const GrTextureDesc& desc) { |
SkASSERT(GrPixelConfigIsCompressed(desc.fConfig)); |
+ SkASSERT(fmt_to_config(fCompressedFormat) == desc.fConfig); |
- SkTextureCompressor::Format format = SkTextureCompressor::kLATC_Format; |
- |
- // Choose the format required by the texture descriptor. |
- switch(desc.fConfig) { |
- case kLATC_GrPixelConfig: |
- format = SkTextureCompressor::kLATC_Format; |
- break; |
- case kR11_EAC_GrPixelConfig: |
- format = SkTextureCompressor::kR11_EAC_Format; |
- break; |
- default: |
- SkFAIL("Unrecognized texture compression format."); |
- break; |
- } |
- |
- SkAutoDataUnref cmpData(SkTextureCompressor::CompressBitmapToFormat(fBM, format)); |
+ SkAutoDataUnref cmpData(SkTextureCompressor::CompressBitmapToFormat(fBM, fCompressedFormat)); |
SkASSERT(NULL != cmpData); |
this->sendTextureData(texture, desc, cmpData->data(), 0); |
@@ -229,7 +251,7 @@ void GrSWMaskHelper::toTexture(GrTexture *texture) { |
desc.fConfig = texture->config(); |
// First see if we should compress this texture before uploading. |
- if (GrPixelConfigIsCompressed(texture->config())) { |
+ if (fCompressMask) { |
this->compressTextureData(texture, desc); |
} else { |
// Looks like we have to send a full A8 texture. |