Create a GrGpu::createBackendTexture choke point
This also makes createBackendTexture take SkPixmaps (instead of a raw pixels pointer)
Change-Id: I5d8a5a58fa7b15862fbf46a3c232cb6ea7f58976
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/243158
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index efc000f..0262554 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -12,6 +12,7 @@
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrContext.h"
#include "src/core/SkMathPriv.h"
+#include "src/core/SkMipMap.h"
#include "src/gpu/GrAuditTrail.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrContextPriv.h"
@@ -701,6 +702,73 @@
keys->push_back(SkString("shader_compilations")); values->push_back(fShaderCompilations);
}
-#endif
+#endif // GR_GPU_STATS
+#endif // GR_TEST_UTILS
-#endif
+
+bool GrGpu::MipMapsAreCorrect(int baseWidth, int baseHeight, GrMipMapped mipMapped,
+ const SkPixmap srcData[], int numMipLevels) {
+ if (!srcData) {
+ return true;
+ }
+
+ if (baseWidth != srcData[0].width() || baseHeight != srcData[0].height()) {
+ return false;
+ }
+
+ if (mipMapped == GrMipMapped::kYes) {
+ if (numMipLevels != SkMipMap::ComputeLevelCount(baseWidth, baseHeight) + 1) {
+ return false;
+ }
+
+ SkColorType colorType = srcData[0].colorType();
+
+ int currentWidth = baseWidth;
+ int currentHeight = baseHeight;
+ for (int i = 1; i < numMipLevels; ++i) {
+ currentWidth = SkTMax(1, currentWidth / 2);
+ currentHeight = SkTMax(1, currentHeight / 2);
+
+ if (srcData[i].colorType() != colorType) { // all levels must have same colorType
+ return false;
+ }
+
+ if (srcData[i].width() != currentWidth || srcData[i].height() != currentHeight) {
+ return false;
+ }
+ }
+ } else if (numMipLevels != 1) {
+ return false;
+ }
+
+ return true;
+}
+
+GrBackendTexture GrGpu::createBackendTexture(int w, int h, const GrBackendFormat& format,
+ GrMipMapped mipMapped, GrRenderable renderable,
+ const SkPixmap srcData[], int numMipLevels,
+ const SkColor4f* color, GrProtected isProtected) {
+ const GrCaps* caps = this->caps();
+
+ if (!format.isValid()) {
+ return {};
+ }
+
+ SkASSERT(!caps->isFormatCompressed(format) || !srcData); // There is no ETC1 SkColorType
+
+ if (w < 1 || w > caps->maxTextureSize() || h < 1 || h > caps->maxTextureSize()) {
+ return {};
+ }
+
+ // TODO: maybe just ignore the mipMapped parameter in this case
+ if (mipMapped == GrMipMapped::kYes && !this->caps()->mipMapSupport()) {
+ return {};
+ }
+
+ if (!MipMapsAreCorrect(w, h, mipMapped, srcData, numMipLevels)) {
+ return {};
+ }
+
+ return this->onCreateBackendTexture(w, h, format, mipMapped, renderable,
+ srcData, numMipLevels, color, isProtected);
+}