Reland "Add compressed data support for SkImage."
This is a reland of 57263c2e0ccddf4dd62814c427a39d9d615acbe5
Original change's description:
> Add compressed data support for SkImage.
>
> Adds a new SkImage::MakeFromCompressed method which takes raw data,
> a size, and a compression method, and returns a GPU-backed
> image.
>
> Bug: skia:8684
> Change-Id: I570c9dafce283bcd64dfbef4fbe1c4bfeac6ce2a
> Reviewed-on: https://skia-review.googlesource.com/c/184484
> Commit-Queue: Jim Van Verth <jvanverth@google.com>
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Reviewed-by: Robert Phillips <robertphillips@google.com>
Bug: skia:8684
Change-Id: I25fb320e8cc05e1c5afa6faa81e1a55ffd83a7a3
Reviewed-on: https://skia-review.googlesource.com/c/185200
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 657d607..3aa6262 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -412,6 +412,42 @@
fit, budgeted, surfaceFlags));
}
+sk_sp<GrTextureProxy> GrProxyProvider::createProxy(sk_sp<SkData> data, const GrSurfaceDesc& desc) {
+ if (!this->caps()->isConfigTexturable(desc.fConfig)) {
+ return nullptr;
+ }
+
+ const GrColorType ct = GrPixelConfigToColorType(desc.fConfig);
+ const GrBackendFormat format = fCaps->getBackendFormatFromGrColorType(ct, GrSRGBEncoded::kNo);
+
+ sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
+ [desc, data](GrResourceProvider* resourceProvider) {
+ if (!resourceProvider) {
+ return sk_sp<GrTexture>();
+ }
+
+ GrMipLevel texels;
+ texels.fPixels = data->data();
+ texels.fRowBytes = GrBytesPerPixel(desc.fConfig)*desc.fWidth;
+ return resourceProvider->createTexture(desc, SkBudgeted::kYes, &texels, 1);
+ },
+ format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
+ SkBudgeted::kYes);
+
+ if (!proxy) {
+ return nullptr;
+ }
+
+ if (fResourceProvider) {
+ // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however
+ // we're better off instantiating the proxy immediately here.
+ if (!proxy->priv().doLazyInstantiation(fResourceProvider)) {
+ return nullptr;
+ }
+ }
+ return proxy;
+}
+
sk_sp<GrTextureProxy> GrProxyProvider::wrapBackendTexture(const GrBackendTexture& backendTex,
GrSurfaceOrigin origin,
GrWrapOwnership ownership,
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 8e8c2e0..1abb49f 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -99,6 +99,11 @@
surfaceFlags);
}
+ /*
+ * Create a texture proxy with data. It's assumed that the data is packed tightly.
+ */
+ sk_sp<GrTextureProxy> createProxy(sk_sp<SkData>, const GrSurfaceDesc& desc);
+
// These match the definitions in SkImage & GrTexture.h, for whence they came
typedef void* ReleaseContext;
typedef void (*ReleaseProc)(ReleaseContext);
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index 6524bb6..a86804b 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -140,6 +140,7 @@
case VK_FORMAT_R5G6B5_UNORM_PACK16:
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
case VK_FORMAT_R8_UNORM:
+ case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
case VK_FORMAT_R32G32B32A32_SFLOAT:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R16G16B16A16_SFLOAT:
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 5bec1cd..a2a203e 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -153,6 +153,34 @@
kAdopt_GrWrapOwnership, nullptr, nullptr);
}
+sk_sp<SkImage> SkImage::MakeFromCompressed(GrContext* context, sk_sp<SkData> data,
+ int width, int height, CompressionType type) {
+ // create the backing texture
+ GrSurfaceDesc desc;
+ desc.fFlags = kNone_GrSurfaceFlags;
+ desc.fWidth = width;
+ desc.fHeight = height;
+ switch (type) {
+ case kETC1_CompressionType:
+ desc.fConfig = kRGB_ETC1_GrPixelConfig;
+ break;
+ default:
+ desc.fConfig = kUnknown_GrPixelConfig;
+ break;
+ }
+ desc.fSampleCnt = 1;
+
+ GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
+ sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(std::move(data), desc);
+
+ if (!proxy) {
+ return nullptr;
+ }
+
+ return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), kNeedNewImageUniqueID, kOpaque_SkAlphaType,
+ std::move(proxy), nullptr);
+}
+
sk_sp<SkImage> SkImage_Gpu::ConvertYUVATexturesToRGB(GrContext* ctx, SkYUVColorSpace yuvColorSpace,
const GrBackendTexture yuvaTextures[],
const SkYUVAIndex yuvaIndices[4], SkISize size,