diff options
-rw-r--r-- | src/gpu/GrSWMaskHelper.cpp | 41 | ||||
-rw-r--r-- | src/gpu/GrSWMaskHelper.h | 5 | ||||
-rw-r--r-- | src/opts/SkTextureCompression_opts.h | 4 | ||||
-rw-r--r-- | src/opts/SkTextureCompression_opts_arm.cpp | 21 | ||||
-rw-r--r-- | src/opts/SkTextureCompression_opts_none.cpp | 4 | ||||
-rw-r--r-- | src/utils/SkTextureCompressor.cpp | 39 | ||||
-rw-r--r-- | src/utils/SkTextureCompressor.h | 6 |
7 files changed, 104 insertions, 16 deletions
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index 547a05e79b..ba62858cb7 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -13,7 +13,6 @@ #include "SkData.h" #include "SkStrokeRec.h" -#include "SkTextureCompressor.h" // TODO: try to remove this #include #include "GrContext.h" @@ -37,6 +36,20 @@ SkXfermode::Mode op_to_mode(SkRegion::Op op) { return modeMap[op]; } +static inline GrPixelConfig fmt_to_config(SkTextureCompressor::Format fmt) { + static const GrPixelConfig configMap[] = { + kLATC_GrPixelConfig, // kLATC_Format, + kR11_EAC_GrPixelConfig, // kR11_EAC_Format, + kASTC_12x12_GrPixelConfig // kASTC_12x12_Format, + }; + GR_STATIC_ASSERT(0 == SkTextureCompressor::kLATC_Format); + GR_STATIC_ASSERT(1 == SkTextureCompressor::kR11_EAC_Format); + GR_STATIC_ASSERT(2 == SkTextureCompressor::kASTC_12x12_Format); + GR_STATIC_ASSERT(SK_ARRAY_COUNT(configMap) == SkTextureCompressor::kFormatCnt); + + return configMap[fmt]; +} + } /** @@ -102,11 +115,16 @@ bool GrSWMaskHelper::init(const SkIRect& resultBounds, -resultBounds.fTop * SK_Scalar1); SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), resultBounds.height()); + #if GR_COMPRESS_ALPHA_MASK + fCompressedFormat = SkTextureCompressor::kR11_EAC_Format; + // 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. - const int cmpWidth = (bounds.fRight + 15) & ~15; - const int cmpHeight = (bounds.fBottom + 3) & ~3; + int dimX, dimY; + SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY); + const int cmpWidth = dimX * ((bounds.fRight + (dimX - 1)) / dimX); + const int cmpHeight = dimY * ((bounds.fRight + (dimY - 1)) / dimY); #else const int cmpWidth = bounds.fRight; const int cmpHeight = bounds.fBottom; @@ -135,21 +153,24 @@ 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 - static const int kCompressedBlockSize = 4; - static const GrPixelConfig kCompressedConfig = kR11_EAC_GrPixelConfig; - if (desc.fWidth % kCompressedBlockSize == 0 && - desc.fHeight % kCompressedBlockSize == 0) { - desc.fConfig = kCompressedConfig; - } +#ifdef SK_DEBUG + 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); // 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; } +#else + desc.fConfig = kAlpha_8_GrPixelConfig; #endif texture->set(fContext, desc); diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h index 340b1a3829..ad1d432ea6 100644 --- a/src/gpu/GrSWMaskHelper.h +++ b/src/gpu/GrSWMaskHelper.h @@ -15,6 +15,7 @@ #include "SkMatrix.h" #include "SkRasterClip.h" #include "SkRegion.h" +#include "SkTextureCompressor.h" #include "SkTypes.h" class GrAutoScratchTexture; @@ -101,6 +102,10 @@ private: SkDraw fDraw; SkRasterClip fRasterClip; +#if GR_COMPRESS_ALPHA_MASK + 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. void sendTextureData(GrTexture *texture, const GrTextureDesc& desc, diff --git a/src/opts/SkTextureCompression_opts.h b/src/opts/SkTextureCompression_opts.h index e618280835..07d645f0ed 100644 --- a/src/opts/SkTextureCompression_opts.h +++ b/src/opts/SkTextureCompression_opts.h @@ -14,4 +14,8 @@ SkTextureCompressor::CompressionProc SkTextureCompressorGetPlatformProc(SkColorType colorType, SkTextureCompressor::Format fmt); +// Returns true if dimX and dimY are set to the block size of the supplied +// compression format according to how the platform can consume them. Returns false otherwise. +bool SkTextureCompressorGetPlatformDims(SkTextureCompressor::Format fmt, int* dimX, int* dimY); + #endif // SkTextureCompression_opts_DEFINED diff --git a/src/opts/SkTextureCompression_opts_arm.cpp b/src/opts/SkTextureCompression_opts_arm.cpp index 3a97a5ed9a..36ff15c1d1 100644 --- a/src/opts/SkTextureCompression_opts_arm.cpp +++ b/src/opts/SkTextureCompression_opts_arm.cpp @@ -36,3 +36,24 @@ SkTextureCompressorGetPlatformProc(SkColorType colorType, SkTextureCompressor::F } #endif } + +bool SkTextureCompressorGetPlatformDims(SkTextureCompressor::Format fmt, int* dimX, int* dimY) { +#if SK_ARM_NEON_IS_NONE + return false; +#else +#if SK_ARM_NEON_IS_DYNAMIC + if (!sk_cpu_arm_has_neon()) { + return false; + } +#endif + switch (fmt) { + case SkTextureCompressor::kR11_EAC_Format: + *dimX = 16; + *dimY = 4; + return true; + default: + return false; + } + return false; +#endif +} diff --git a/src/opts/SkTextureCompression_opts_none.cpp b/src/opts/SkTextureCompression_opts_none.cpp index f86fbf5f29..caa211859a 100644 --- a/src/opts/SkTextureCompression_opts_none.cpp +++ b/src/opts/SkTextureCompression_opts_none.cpp @@ -11,3 +11,7 @@ SkTextureCompressor::CompressionProc SkTextureCompressorGetPlatformProc(SkColorType colorType, SkTextureCompressor::Format fmt) { return NULL; } + +bool SkTextureCompressorGetPlatformDims(SkTextureCompressor::Format fmt, int* dimX, int* dimY) { + return false; +} diff --git a/src/utils/SkTextureCompressor.cpp b/src/utils/SkTextureCompressor.cpp index 43d906aea5..30fd3072d5 100644 --- a/src/utils/SkTextureCompressor.cpp +++ b/src/utils/SkTextureCompressor.cpp @@ -20,21 +20,48 @@ namespace SkTextureCompressor { +void GetBlockDimensions(Format format, int* dimX, int* dimY) { + if (NULL == dimX || NULL == dimY) { + return; + } + + if (SkTextureCompressorGetPlatformDims(format, dimX, dimY)) { + return; + } + + switch(format) { + // These formats are 64 bits per 4x4 block. + default: + SkDEBUGFAIL("Unknown compression format!"); + // fall through + case kR11_EAC_Format: + case kLATC_Format: + *dimX = 4; + *dimY = 4; + break; + + // This format is 12x12 blocks to 128 bits. + case kASTC_12x12_Format: + *dimX = 12; + *dimY = 12; + break; + } +} + int GetCompressedDataSize(Format fmt, int width, int height) { - int blockDimension = 0; + int dimX, dimY; + GetBlockDimensions(fmt, &dimX, &dimY); int encodedBlockSize = 0; switch (fmt) { // These formats are 64 bits per 4x4 block. case kR11_EAC_Format: case kLATC_Format: - blockDimension = 4; encodedBlockSize = 8; break; // This format is 12x12 blocks to 128 bits. case kASTC_12x12_Format: - blockDimension = 12; encodedBlockSize = 16; break; @@ -43,9 +70,9 @@ int GetCompressedDataSize(Format fmt, int width, int height) { return -1; } - if(((width % blockDimension) == 0) && ((height % blockDimension) == 0)) { - const int blocksX = width / blockDimension; - const int blocksY = height / blockDimension; + if(((width % dimX) == 0) && ((height % dimY) == 0)) { + const int blocksX = width / dimX; + const int blocksY = height / dimY; return blocksX * blocksY * encodedBlockSize; } diff --git a/src/utils/SkTextureCompressor.h b/src/utils/SkTextureCompressor.h index 5238ba221b..c6305bab45 100644 --- a/src/utils/SkTextureCompressor.h +++ b/src/utils/SkTextureCompressor.h @@ -55,6 +55,12 @@ namespace SkTextureCompressor { // RGB source data into an R11 EAC texture, you're gonna have a bad time. SkBlitter* CreateBlitterForFormat(int width, int height, void* compressedBuffer, Format format); + + // Returns the desired dimensions of the block size for the given format. These dimensions + // don't necessarily correspond to the hardware-specified dimensions, since there may + // be specialized algorithms that operate on multiple blocks at once. These dimensions + // reflect that optimization and return the appropriate operable dimensions. + void GetBlockDimensions(Format format, int* dimX, int* dimY); } #endif |