From b3abe90145b988883c9882de1ac42da963adbf67 Mon Sep 17 00:00:00 2001 From: krajcevski Date: Wed, 30 Jul 2014 13:08:11 -0700 Subject: Start the process of choosing the correct compression format R=robertphillips@google.com Author: krajcevski@google.com Review URL: https://codereview.chromium.org/427093004 --- src/gpu/GrSWMaskHelper.cpp | 98 ++++++++++++++++++++++++++++------------------ src/gpu/GrSWMaskHelper.h | 10 +++-- src/gpu/gl/GrGLCaps.cpp | 9 ++--- 3 files changed, 71 insertions(+), 46 deletions(-) (limited to 'src/gpu') diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index 2e68b7829b..be6eb034b4 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. diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h index ad1d432ea6..4c06786280 100644 --- a/src/gpu/GrSWMaskHelper.h +++ b/src/gpu/GrSWMaskHelper.h @@ -42,7 +42,7 @@ class GrDrawTarget; class GrSWMaskHelper : SkNoncopyable { public: GrSWMaskHelper(GrContext* context) - : fContext(context) { + : fContext(context), fCompressMask(false) { } // set up the internal state in preparation for draws. Since many masks @@ -102,9 +102,13 @@ private: SkDraw fDraw; SkRasterClip fRasterClip; -#if GR_COMPRESS_ALPHA_MASK + // This flag says whether or not we should compress the mask. If + // it is true, then fCompressedFormat is always valid. + bool fCompressMask; + + // This is the desired format within which to compress the + // texture. This value is only valid if fCompressMask is true. SkTextureCompressor::Format fCompressedFormat; -#endif // Actually sends the texture data to the GPU. This is called from // toTexture with the data filled in depending on the texture config. diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index f3329578ce..7dee3de4b1 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -558,11 +558,10 @@ void GrGLCaps::initConfigTexturableTable(const GrGLContextInfo& ctxInfo, const G fConfigTextureSupport[kLATC_GrPixelConfig] = hasLATC; fLATCAlias = alias; - // Check for R11_EAC - if (kGL_GrGLStandard == standard) { - fConfigTextureSupport[kR11_EAC_GrPixelConfig] = - version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility"); - } else { + // Check for R11_EAC ... We don't support R11_EAC on desktop, as most + // cards default to decompressing the textures in the driver, and is + // generally slower. + if (kGL_GrGLStandard != standard) { fConfigTextureSupport[kR11_EAC_GrPixelConfig] = version >= GR_GL_VER(3, 0); } -- cgit v1.2.3