aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/GrSWMaskHelper.cpp41
-rw-r--r--src/gpu/GrSWMaskHelper.h5
-rw-r--r--src/opts/SkTextureCompression_opts.h4
-rw-r--r--src/opts/SkTextureCompression_opts_arm.cpp21
-rw-r--r--src/opts/SkTextureCompression_opts_none.cpp4
-rw-r--r--src/utils/SkTextureCompressor.cpp39
-rw-r--r--src/utils/SkTextureCompressor.h6
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