Revise GrDataUtils to be more self-contained (take 3)
This makes the GL and Vk backends share more code and sets up for the Metal implementation.
Change-Id: I781d5b6188fb2d46ae4ec48204fda74fe28b18c0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/218964
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index f344e2e..d2b18f1 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1589,50 +1589,6 @@
return state;
}
-size_t GLBytesPerPixel(GrGLenum glFormat) {
- switch (glFormat) {
- case GR_GL_LUMINANCE8:
- case GR_GL_ALPHA8:
- case GR_GL_R8:
- return 1;
-
- case GR_GL_RGB565:
- case GR_GL_RGBA4:
- case GR_GL_RG8:
- case GR_GL_R16F:
- return 2;
-
- case GR_GL_RGB8:
- return 3;
-
- case GR_GL_RGBA8:
- case GR_GL_SRGB8_ALPHA8:
- case GR_GL_BGRA8:
- case GR_GL_RGB10_A2:
- return 4;
-
- case GR_GL_RGBA16F:
- case GR_GL_RG32F:
- return 8;
-
- case GR_GL_RGBA32F:
- return 16;
-
- case GR_GL_COMPRESSED_RGB8_ETC2: // fall through
- case GR_GL_COMPRESSED_ETC1_RGB8:
- return 0;
-
- // Experimental (for P016 and P010)
- case GR_GL_R16:
- return 2;
- case GR_GL_RG16:
- return 4;
- }
-
- SK_ABORT("Invalid GL format");
- return 0;
-}
-
sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
SkBudgeted budgeted,
const GrMipLevel texels[],
@@ -1652,7 +1608,7 @@
std::unique_ptr<uint8_t[]> zeros;
if (performClear && !this->glCaps().clearTextureSupport() &&
!this->glCaps().canConfigBeFBOColorAttachment(desc.fConfig)) {
- size_t rowSize = GLBytesPerPixel(glFormat) * desc.fWidth;
+ size_t rowSize = GrGLBytesPerFormat(glFormat) * desc.fWidth;
size_t size = rowSize * desc.fHeight;
zeros.reset(new uint8_t[size]);
memset(zeros.get(), 0, size);
@@ -4050,7 +4006,7 @@
const GrBackendFormat& format,
GrMipMapped mipMapped,
GrRenderable renderable,
- const void* pixels, size_t rowBytes,
+ const void* srcPixels, size_t rowBytes,
const SkColor4f& colorf) {
this->handleDirtyContext();
@@ -4075,7 +4031,7 @@
}
// Currently we don't support uploading pixel data when mipped.
- if (pixels && GrMipMapped::kYes == mipMapped) {
+ if (srcPixels && GrMipMapped::kYes == mipMapped) {
return GrBackendTexture(); // invalid
}
@@ -4089,43 +4045,39 @@
mipLevelCount = SkMipMap::ComputeLevelCount(w, h) + 1;
}
- SkAutoMalloc pixelStorage;
-
- if (GrGLFormatIsCompressed(*glFormat)) {
- // we have to do something special for compressed textures
- SkASSERT(0 == rowBytes);
-
- if (!pixels) {
- size_t etc1Size = GrGLFormatCompressedDataSize(*glFormat, w, h);
- pixelStorage.reset(etc1Size);
- GrFillInETC1WithColor(w, h, colorf, pixelStorage.get());
- pixels = pixelStorage.get();
- rowBytes = 0;
- }
- } else {
- int bpp = GrBytesPerPixel(config);
- const size_t trimRowBytes = w * bpp;
- if (!rowBytes) {
- rowBytes = trimRowBytes;
- }
-
- if (!pixels) {
- size_t baseLayerSize = trimRowBytes * h;
- pixelStorage.reset(baseLayerSize);
- if (!GrFillBufferWithColor(config, w, h, colorf, pixelStorage.get())) {
- return GrBackendTexture(); // invalid
- }
-
- pixels = pixelStorage.get();
- rowBytes = trimRowBytes;
- }
- }
-
SkAutoTMalloc<GrMipLevel> texels(mipLevelCount);
- for (int i = 0; i < mipLevelCount; ++i) {
- // TODO: this isn't correct when pixels for additional mip levels are passed in
- texels.get()[i] = { pixels, rowBytes };
+ SkAutoMalloc pixelStorage;
+
+ if (!srcPixels) {
+ GrCompression compression = GrGLFormat2Compression(*glFormat);
+
+ SkTArray<size_t> individualMipOffsets(mipLevelCount);
+ size_t bytesPerPixel = GrBytesPerPixel(config);
+
+ size_t totalSize = GrComputeTightCombinedBufferSize(compression, bytesPerPixel, w, h,
+ &individualMipOffsets, mipLevelCount);
+
+ char* tmpPixels = (char *) pixelStorage.reset(totalSize);
+
+ GrFillInData(compression, config, w, h, individualMipOffsets, tmpPixels, colorf);
+
+ for (int i = 0; i < mipLevelCount; ++i) {
+ size_t offset = individualMipOffsets[i];
+
+ int twoToTheMipLevel = 1 << i;
+ int currentWidth = SkTMax(1, w / twoToTheMipLevel);
+
+ texels.get()[i] = { &(tmpPixels[offset]), currentWidth*bytesPerPixel };
+ }
+ } else {
+ SkASSERT(1 == mipLevelCount);
+
+ if (GrGLFormatIsCompressed(*glFormat)) {
+ SkASSERT(0 == rowBytes);
+ }
+
+ texels.get()[0] = { srcPixels, rowBytes };
}
GrSurfaceDesc desc;
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 8f67be7..f50932e 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -573,6 +573,18 @@
return false;
}
+GrCompression GrGLFormat2Compression(GrGLenum glFormat) {
+ switch (glFormat) {
+ case GR_GL_COMPRESSED_RGB8_ETC2: // fall through
+ case GR_GL_COMPRESSED_ETC1_RGB8:
+ return GrCompression::kETC1;
+ default:
+ return GrCompression::kNone;
+ }
+ SK_ABORT("Invalid format");
+ return GrCompression::kNone;
+}
+
size_t GrGLFormatCompressedDataSize(GrGLenum glFormat, int width, int height) {
SkASSERT(GrGLFormatIsCompressed(glFormat));
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index c9bd3c2..332cddd 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -10,6 +10,7 @@
#include "include/gpu/gl/GrGLInterface.h"
#include "include/private/GrTypesPriv.h"
+#include "src/gpu/GrDataUtils.h"
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/gl/GrGLDefines.h"
@@ -265,6 +266,11 @@
bool GrGLFormatIsCompressed(GrGLenum glFormat);
/**
+ * Maps a gl format into the GrCompressed enum.
+ */
+GrCompression GrGLFormat2Compression(GrGLenum glFormat);
+
+/**
* Returns the data size for the given compressed format
*/
size_t GrGLFormatCompressedDataSize(GrGLenum glFormat, int width, int height);