Add query for block dimensions of a given format

R=robertphillips@google.com

Author: krajcevski@google.com

Review URL: https://codereview.chromium.org/422023006
This commit is contained in:
krajcevski 2014-07-29 11:44:26 -07:00 committed by Commit bot
parent a8f8da0500
commit 25a67bcb7a
7 changed files with 104 additions and 16 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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