Index: src/gpu/SkGr.cpp |
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp |
index 1813433b300c2e3b003ec8172eeb66ecd095acd4..d8444968da6ea2e788b16900fc80af3e314a1243 100644 |
--- a/src/gpu/SkGr.cpp |
+++ b/src/gpu/SkGr.cpp |
@@ -38,6 +38,118 @@ |
# include "etc1.h" |
#endif |
+GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) { |
+ GrSurfaceDesc desc; |
+ desc.fFlags = kNone_GrSurfaceFlags; |
+ desc.fWidth = info.width(); |
+ desc.fHeight = info.height(); |
+ desc.fConfig = SkImageInfo2GrPixelConfig(info); |
+ desc.fSampleCnt = 0; |
+ return desc; |
+} |
+ |
+static void get_stretch(const GrCaps& caps, int width, int height, |
+ const GrTextureParams& params, SkGrStretch* stretch) { |
+ stretch->fType = SkGrStretch::kNone_Type; |
+ bool doStretch = false; |
+ if (params.isTiled() && !caps.npotTextureTileSupport() && |
+ (!SkIsPow2(width) || !SkIsPow2(height))) { |
+ doStretch = true; |
+ stretch->fWidth = GrNextPow2(SkTMax(width, caps.minTextureSize())); |
+ stretch->fHeight = GrNextPow2(SkTMax(height, caps.minTextureSize())); |
+ } else if (width < caps.minTextureSize() || height < caps.minTextureSize()) { |
+ // The small texture issues appear to be with tiling. Hence it seems ok to scale them |
+ // up using the GPU. If issues persist we may need to CPU-stretch. |
+ doStretch = true; |
+ stretch->fWidth = SkTMax(width, caps.minTextureSize()); |
+ stretch->fHeight = SkTMax(height, caps.minTextureSize()); |
+ } |
+ if (doStretch) { |
+ switch (params.filterMode()) { |
+ case GrTextureParams::kNone_FilterMode: |
+ stretch->fType = SkGrStretch::kNearest_Type; |
+ break; |
+ case GrTextureParams::kBilerp_FilterMode: |
+ case GrTextureParams::kMipMap_FilterMode: |
+ stretch->fType = SkGrStretch::kBilerp_Type; |
+ break; |
+ } |
+ } else { |
+ stretch->fWidth = -1; |
+ stretch->fHeight = -1; |
+ stretch->fType = SkGrStretch::kNone_Type; |
+ } |
+} |
+ |
+static void make_unstretched_key(GrUniqueKey* key, uint32_t imageID, const SkIRect& subset) { |
+ SkASSERT(SkIsU16(subset.width())); |
+ SkASSERT(SkIsU16(subset.height())); |
+ |
+ static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
+ GrUniqueKey::Builder builder(key, kDomain, 4); |
+ builder[0] = imageID; |
+ builder[1] = subset.x(); |
+ builder[2] = subset.y(); |
+ builder[3] = subset.width() | (subset.height() << 16); |
+} |
+ |
+void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& subset, |
+ const GrCaps& caps, const GrTextureParams& params) { |
+ SkGrStretch stretch; |
+ get_stretch(caps, subset.width(), subset.height(), params, &stretch); |
+ if (SkGrStretch::kNone_Type != stretch.fType) { |
+ GrUniqueKey tmpKey; |
+ make_unstretched_key(&tmpKey, imageID, subset); |
+ if (!GrMakeStretchedKey(tmpKey, stretch, key)) { |
+ *key = tmpKey; |
+ } |
+ } else { |
+ make_unstretched_key(key, imageID, subset); |
+ } |
+} |
+ |
+GrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data, |
+ int expectedW, int expectedH, |
+ const void** outStartOfDataToUpload) { |
+ *outStartOfDataToUpload = nullptr; |
+#ifndef SK_IGNORE_ETC1_SUPPORT |
+ if (!ctx->caps()->isConfigTexturable(kETC1_GrPixelConfig)) { |
+ return kUnknown_GrPixelConfig; |
+ } |
+ |
+ const uint8_t* bytes = data->bytes(); |
+ if (data->size() > ETC_PKM_HEADER_SIZE && etc1_pkm_is_valid(bytes)) { |
+ // Does the data match the dimensions of the bitmap? If not, |
+ // then we don't know how to scale the image to match it... |
+ if (etc1_pkm_get_width(bytes) != (unsigned)expectedW || |
+ etc1_pkm_get_height(bytes) != (unsigned)expectedH) |
+ { |
+ return kUnknown_GrPixelConfig; |
+ } |
+ |
+ *outStartOfDataToUpload = bytes + ETC_PKM_HEADER_SIZE; |
+ return kETC1_GrPixelConfig; |
+ } else if (SkKTXFile::is_ktx(bytes)) { |
+ SkKTXFile ktx(data); |
+ |
+ // Is it actually an ETC1 texture? |
+ if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) { |
+ return kUnknown_GrPixelConfig; |
+ } |
+ |
+ // Does the data match the dimensions of the bitmap? If not, |
+ // then we don't know how to scale the image to match it... |
+ if (ktx.width() != expectedW || ktx.height() != expectedH) { |
+ return kUnknown_GrPixelConfig; |
+ } |
+ |
+ *outStartOfDataToUpload = ktx.pixelData(); |
+ return kETC1_GrPixelConfig; |
+ } |
+#endif |
+ return kUnknown_GrPixelConfig; |
+} |
+ |
/* Fill out buffer with the compressed format Ganesh expects from a colortable |
based bitmap. [palette (colortable) + indices]. |
@@ -97,38 +209,6 @@ static void build_index8_data(void* buffer, const SkBitmap& bitmap) { |
//////////////////////////////////////////////////////////////////////////////// |
-static void get_stretch(const GrCaps& caps, int width, int height, |
- const GrTextureParams& params, SkGrStretch* stretch) { |
- stretch->fType = SkGrStretch::kNone_Type; |
- bool doStretch = false; |
- if (params.isTiled() && !caps.npotTextureTileSupport() && |
- (!SkIsPow2(width) || !SkIsPow2(height))) { |
- doStretch = true; |
- stretch->fWidth = GrNextPow2(SkTMax(width, caps.minTextureSize())); |
- stretch->fHeight = GrNextPow2(SkTMax(height, caps.minTextureSize())); |
- } else if (width < caps.minTextureSize() || height < caps.minTextureSize()) { |
- // The small texture issues appear to be with tiling. Hence it seems ok to scale them |
- // up using the GPU. If issues persist we may need to CPU-stretch. |
- doStretch = true; |
- stretch->fWidth = SkTMax(width, caps.minTextureSize()); |
- stretch->fHeight = SkTMax(height, caps.minTextureSize()); |
- } |
- if (doStretch) { |
- switch(params.filterMode()) { |
- case GrTextureParams::kNone_FilterMode: |
- stretch->fType = SkGrStretch::kNearest_Type; |
- break; |
- case GrTextureParams::kBilerp_FilterMode: |
- case GrTextureParams::kMipMap_FilterMode: |
- stretch->fType = SkGrStretch::kBilerp_Type; |
- break; |
- } |
- } else { |
- stretch->fWidth = -1; |
- stretch->fHeight = -1; |
- stretch->fType = SkGrStretch::kNone_Type; |
- } |
-} |
bool GrMakeStretchedKey(const GrUniqueKey& origKey, const SkGrStretch& stretch, |
GrUniqueKey* stretchedKey) { |
@@ -146,43 +226,6 @@ bool GrMakeStretchedKey(const GrUniqueKey& origKey, const SkGrStretch& stretch, |
return false; |
} |
-static void make_unstretched_key(GrUniqueKey* key, uint32_t imageID, const SkIRect& subset) { |
- SkASSERT(SkIsU16(subset.width())); |
- SkASSERT(SkIsU16(subset.height())); |
- |
- static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
- GrUniqueKey::Builder builder(key, kDomain, 4); |
- builder[0] = imageID; |
- builder[1] = subset.x(); |
- builder[2] = subset.y(); |
- builder[3] = subset.width() | (subset.height() << 16); |
-} |
- |
-void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& subset, |
- const GrCaps& caps, const GrTextureParams& params) { |
- SkGrStretch stretch; |
- get_stretch(caps, subset.width(), subset.height(), params, &stretch); |
- if (SkGrStretch::kNone_Type != stretch.fType) { |
- GrUniqueKey tmpKey; |
- make_unstretched_key(&tmpKey, imageID, subset); |
- if (!GrMakeStretchedKey(tmpKey, stretch, key)) { |
- *key = tmpKey; |
- } |
- } else { |
- make_unstretched_key(key, imageID, subset); |
- } |
-} |
- |
-GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) { |
- GrSurfaceDesc desc; |
- desc.fFlags = kNone_GrSurfaceFlags; |
- desc.fWidth = info.width(); |
- desc.fHeight = info.height(); |
- desc.fConfig = SkImageInfo2GrPixelConfig(info); |
- desc.fSampleCnt = 0; |
- return desc; |
-} |
- |
namespace { |
// When the SkPixelRef genID changes, invalidate a corresponding GrResource described by key. |
@@ -287,65 +330,6 @@ GrTexture* stretch_texture(GrTexture* inputTexture, const SkGrStretch& stretch, |
return stretched.detach(); |
} |
-GrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data, |
- int expectedW, int expectedH, |
- const void** outStartOfDataToUpload) { |
- *outStartOfDataToUpload = nullptr; |
-#ifndef SK_IGNORE_ETC1_SUPPORT |
- if (!ctx->caps()->isConfigTexturable(kETC1_GrPixelConfig)) { |
- return kUnknown_GrPixelConfig; |
- } |
- |
- const uint8_t* bytes = data->bytes(); |
- if (data->size() > ETC_PKM_HEADER_SIZE && etc1_pkm_is_valid(bytes)) { |
- // Does the data match the dimensions of the bitmap? If not, |
- // then we don't know how to scale the image to match it... |
- if (etc1_pkm_get_width(bytes) != (unsigned)expectedW || |
- etc1_pkm_get_height(bytes) != (unsigned)expectedH) |
- { |
- return kUnknown_GrPixelConfig; |
- } |
- |
- *outStartOfDataToUpload = bytes + ETC_PKM_HEADER_SIZE; |
- return kETC1_GrPixelConfig; |
- } else if (SkKTXFile::is_ktx(bytes)) { |
- SkKTXFile ktx(data); |
- |
- // Is it actually an ETC1 texture? |
- if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) { |
- return kUnknown_GrPixelConfig; |
- } |
- |
- // Does the data match the dimensions of the bitmap? If not, |
- // then we don't know how to scale the image to match it... |
- if (ktx.width() != expectedW || ktx.height() != expectedH) { |
- return kUnknown_GrPixelConfig; |
- } |
- |
- *outStartOfDataToUpload = ktx.pixelData(); |
- return kETC1_GrPixelConfig; |
- } |
-#endif |
- return kUnknown_GrPixelConfig; |
-} |
- |
-static GrTexture* load_etc1_texture(GrContext* ctx, const GrUniqueKey& optionalKey, |
- const SkBitmap &bm, GrSurfaceDesc desc) { |
- SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); |
- if (!data) { |
- return nullptr; |
- } |
- |
- const void* startOfTexData; |
- desc.fConfig = GrIsCompressedTextureDataSupported(ctx, data, bm.width(), bm.height(), |
- &startOfTexData); |
- if (kUnknown_GrPixelConfig == desc.fConfig) { |
- return nullptr; |
- } |
- |
- return GrCreateTextureForPixels(ctx, optionalKey, desc, bm.pixelRef(), startOfTexData, 0); |
-} |
- |
/* |
* Once we have made SkImages handle all lazy/deferred/generated content, the YUV apis will |
* be gone from SkPixelRef, and we can remove this subclass entirely. |
@@ -391,6 +375,23 @@ static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKe |
return texture; |
} |
+static GrTexture* load_etc1_texture(GrContext* ctx, const GrUniqueKey& optionalKey, |
+ const SkBitmap &bm, GrSurfaceDesc desc) { |
+ SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); |
+ if (!data) { |
+ return nullptr; |
+ } |
+ |
+ const void* startOfTexData; |
+ desc.fConfig = GrIsCompressedTextureDataSupported(ctx, data, bm.width(), bm.height(), |
+ &startOfTexData); |
+ if (kUnknown_GrPixelConfig == desc.fConfig) { |
+ return nullptr; |
+ } |
+ |
+ return GrCreateTextureForPixels(ctx, optionalKey, desc, bm.pixelRef(), startOfTexData, 0); |
+} |
+ |
static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, |
const SkBitmap& origBitmap, |
const GrUniqueKey& optionalKey) { |