Add mipmap support to SkPixmap flavor of createBackendTexture

Change-Id: I7a2dea9b0b8e6b985f2d56e587939266022c19e1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/234664
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2019-09-26 14:01:36 -04:00 committed by Skia Commit-Bot
parent 798a31dd8a
commit 7f367983b5
9 changed files with 283 additions and 103 deletions

View File

@ -341,9 +341,9 @@ SkColor SkPixmap::getColor(int x, int y) const {
b = ((value >> 20) & 0x3ff) * (1/1023.0f),
a = ((value >> 30) & 0x3 ) * (1/ 3.0f);
if (a != 0 && needsUnpremul) {
r *= (1.0f/a);
g *= (1.0f/a);
b *= (1.0f/a);
r = SkTPin(r/a, 0.0f, 1.0f);
g = SkTPin(g/a, 0.0f, 1.0f);
b = SkTPin(b/a, 0.0f, 1.0f);
}
return (uint32_t)( r * 255.0f ) << 16
| (uint32_t)( g * 255.0f ) << 8

View File

@ -267,6 +267,9 @@ public:
// pixmap(s).
// If numLevels is 1 a non-mipMapped texture will result. If a mipMapped texture is desired
// the data for all the mipmap levels must be provided.
// For the Vulkan backend the layout of the created VkImage will be:
// VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
// regardless of the renderability setting
GrBackendTexture createBackendTexture(const SkPixmap srcData[], int numLevels,
GrRenderable, GrProtected);

View File

@ -3553,11 +3553,6 @@ GrBackendTexture GrGLGpu::onCreateBackendTexture(int w, int h,
return GrBackendTexture(); // invalid
}
// Currently we don't support uploading pixel data when mipped.
if (srcData && GrMipMapped::kYes == mipMapped) {
return GrBackendTexture(); // invalid
}
GrGLTextureInfo info;
GrGLTextureParameters::SamplerOverriddenState initialState;
@ -3596,6 +3591,7 @@ GrBackendTexture GrGLGpu::onCreateBackendTexture(int w, int h,
texels[i] = {&(tmpPixels[offset]), currentWidth * bytesPerPixel};
}
}
GrSurfaceDesc desc;
desc.fWidth = w;
desc.fHeight = h;

View File

@ -16,6 +16,7 @@ GrMTLPixelFormat GrGetMTLPixelFormatFromMtlTextureInfo(const GrMtlTextureInfo&);
#if GR_TEST_UTILS
const char* GrMtlFormatToStr(GrMTLPixelFormat mtlFormat);
bool GrMtlFormatIsBGRA(GrMTLPixelFormat mtlFormat);
#endif
#endif

View File

@ -712,6 +712,20 @@ static GrPixelConfig mtl_format_to_pixelconfig(MTLPixelFormat format) {
SkUNREACHABLE;
}
void copy_src_data(char* dst, size_t bytesPerPixel, const SkTArray<size_t>& individualMipOffsets,
const SkPixmap srcData[], int numMipLevels, size_t bufferSize) {
SkASSERT(srcData && numMipLevels);
SkASSERT(individualMipOffsets.count() == numMipLevels);
for (int level = 0; level < numMipLevels; ++level) {
const size_t trimRB = srcData[level].width() * bytesPerPixel;
SkASSERT(individualMipOffsets[level] + trimRB * srcData[level].height() <= bufferSize);
SkRectMemcpy(dst + individualMipOffsets[level], trimRB,
srcData[level].addr(), srcData[level].rowBytes(),
trimRB, srcData[level].height());
}
}
bool GrMtlGpu::createMtlTextureForBackendSurface(MTLPixelFormat format,
int w, int h, bool texturable,
bool renderable, GrMipMapped mipMapped,
@ -734,11 +748,8 @@ bool GrMtlGpu::createMtlTextureForBackendSurface(MTLPixelFormat format,
if (renderable && !fMtlCaps->isFormatRenderable(format, 1)) {
return false;
}
// Currently we don't support uploading pixel data when mipped.
if (srcData && GrMipMapped::kYes == mipMapped) {
return false;
}
if(!check_max_blit_width(w)) {
if (!check_max_blit_width(w)) {
return false;
}
@ -793,14 +804,8 @@ bool GrMtlGpu::createMtlTextureForBackendSurface(MTLPixelFormat format,
// Fill buffer with data
if (srcData) {
const size_t trimRowBytes = w * bytesPerPixel;
// TODO: support mipmapping
SkASSERT(1 == mipLevelCount);
// copy data into the buffer, skipping the trailing bytes
const char* src = (const char*) srcData->addr();
SkRectMemcpy(buffer, trimRowBytes, src, srcData->rowBytes(), trimRowBytes, h);
copy_src_data(buffer, bytesPerPixel, individualMipOffsets,
srcData, numMipLevels, combinedBufferSize);
} else if (color) {
GrPixelConfig config = mtl_format_to_pixelconfig(format);
SkASSERT(kUnknown_GrPixelConfig != config);

View File

@ -353,6 +353,10 @@ bool GrMtlFormatToCompressionType(MTLPixelFormat mtlFormat,
}
#if GR_TEST_UTILS
bool GrMtlFormatIsBGRA(GrMTLPixelFormat mtlFormat) {
return mtlFormat == MTLPixelFormatBGRA8Unorm;
}
const char* GrMtlFormatToStr(GrMTLPixelFormat mtlFormat) {
switch (mtlFormat) {
case MTLPixelFormatInvalid: return "Invalid";

View File

@ -1448,23 +1448,26 @@ GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(
////////////////////////////////////////////////////////////////////////////////
bool copy_src_data(GrVkGpu* gpu, const GrVkAlloc& alloc, VkFormat vkFormat,
int width, int height,
const void* srcData, size_t srcRowBytes) {
SkASSERT(srcData);
const SkTArray<size_t>& individualMipOffsets,
const SkPixmap srcData[], int numMipLevels) {
SkASSERT(srcData && numMipLevels);
SkASSERT(!GrVkFormatIsCompressed(vkFormat));
SkASSERT(individualMipOffsets.count() == numMipLevels);
void* mapPtr = GrVkMemory::MapAlloc(gpu, alloc);
char* mapPtr = (char*) GrVkMemory::MapAlloc(gpu, alloc);
if (!mapPtr) {
return false;
}
size_t bytesPerPixel = GrVkBytesPerFormat(vkFormat);
const size_t trimRowBytes = width * bytesPerPixel;
if (!srcRowBytes) {
srcRowBytes = trimRowBytes;
}
SkASSERT(trimRowBytes * height <= alloc.fSize);
SkRectMemcpy(mapPtr, trimRowBytes, srcData, srcRowBytes, trimRowBytes, height);
for (int level = 0; level < numMipLevels; ++level) {
const size_t trimRB = srcData[level].width() * bytesPerPixel;
SkASSERT(individualMipOffsets[level] + trimRB * srcData[level].height() <= alloc.fSize);
SkRectMemcpy(mapPtr + individualMipOffsets[level], trimRB,
srcData[level].addr(), srcData[level].rowBytes(),
trimRB, srcData[level].height());
}
GrVkMemory::FlushMappedAlloc(gpu, alloc, 0, alloc.fSize);
GrVkMemory::UnmapAlloc(gpu, alloc);
@ -1527,11 +1530,6 @@ bool GrVkGpu::createVkImageForBackendSurface(VkFormat vkFormat, int w, int h, bo
return false;
}
// Currently we don't support uploading pixel data when mipped.
if (srcData && GrMipMapped::kYes == mipMapped) {
return false;
}
VkImageUsageFlags usageFlags = 0;
usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
@ -1644,9 +1642,8 @@ bool GrVkGpu::createVkImageForBackendSurface(VkFormat vkFormat, int w, int h, bo
return false;
}
SkASSERT(1 == mipLevelCount);
bool result = copy_src_data(this, bufferAlloc, vkFormat, w, h,
srcData->addr(), srcData->rowBytes());
bool result = copy_src_data(this, bufferAlloc, vkFormat, individualMipOffsets,
srcData, numMipLevels);
if (!result) {
GrVkImage::DestroyImageInfo(this, info);
GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);

View File

@ -20,6 +20,11 @@
#include "src/gpu/gl/GrGLUtil.h"
#endif
#ifdef SK_METAL
#include "include/gpu/mtl/GrMtlTypes.h"
#include "src/gpu/mtl/GrMtlCppUtil.h"
#endif
// Test wrapping of GrBackendObjects in SkSurfaces and SkImages (non-static since used in Mtl test)
void test_wrapping(GrContext* context, skiatest::Reporter* reporter,
std::function<GrBackendTexture (GrContext*,
@ -93,60 +98,113 @@ void test_wrapping(GrContext* context, skiatest::Reporter* reporter,
context->deleteBackendTexture(backendTex);
}
static bool isBGRA(const GrBackendFormat& format) {
switch (format.backend()) {
case GrBackendApi::kMetal:
#ifdef SK_METAL
return GrMtlFormatIsBGRA(format.asMtlFormat());
#else
return false;
#endif
case GrBackendApi::kDawn:
return false;
case GrBackendApi::kOpenGL:
#ifdef SK_GL
return format.asGLFormat() == GrGLFormat::kBGRA8;
#else
return false;
#endif
case GrBackendApi::kVulkan: {
#ifdef SK_VULKAN
VkFormat vkFormat;
format.asVkFormat(&vkFormat);
return vkFormat == VK_FORMAT_B8G8R8A8_UNORM;
#else
return false;
#endif
}
case GrBackendApi::kMock:
return format.asMockColorType() == GrColorType::kBGRA_8888;
}
SkUNREACHABLE;
}
static bool isRGB(const GrBackendFormat& format) {
switch (format.backend()) {
case GrBackendApi::kMetal:
return false; // Metal doesn't even pretend to support this
case GrBackendApi::kDawn:
return false;
case GrBackendApi::kOpenGL:
#ifdef SK_GL
return format.asGLFormat() == GrGLFormat::kRGB8;
#else
return false;
#endif
case GrBackendApi::kVulkan: {
#ifdef SK_VULKAN
VkFormat vkFormat;
format.asVkFormat(&vkFormat);
return vkFormat == VK_FORMAT_R8G8B8_UNORM;
#else
return false;
#endif
}
case GrBackendApi::kMock:
return false; // No GrColorType::kRGB_888
}
SkUNREACHABLE;
}
static void check_solid_pixmap(skiatest::Reporter* reporter,
const SkColor4f& expected, const SkPixmap& actual,
SkColorType ct, const char* label) {
SkColorType ct, const char* label1, const char* label2) {
// we need 0.001f across the board just for noise
// we need 0.01f across the board for 1010102
const float tols[4] = {0.01f, 0.01f, 0.01f, 0.01f};
const float tols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
auto error = std::function<ComparePixmapsErrorReporter>(
[reporter, ct, label](int x, int y, const float diffs[4]) {
[reporter, ct, label1, label2](int x, int y, const float diffs[4]) {
SkASSERT(x >= 0 && y >= 0);
ERRORF(reporter, "%s %s - mismatch at %d, %d (%f, %f, %f %f)",
ToolUtils::colortype_name(ct), label, x, y,
ERRORF(reporter, "%s %s %s - mismatch at %d, %d (%f, %f, %f %f)",
ToolUtils::colortype_name(ct), label1, label2, x, y,
diffs[0], diffs[1], diffs[2], diffs[3]);
});
check_solid_pixels(expected, actual, tols, error);
}
// What would raster do?
static SkColor4f get_expected_color(SkColor4f orig, SkColorType ct) {
uint32_t components = SkColorTypeComponentFlags(ct);
if (components & kGray_SkColorTypeComponentFlag) {
// For the GPU backends, gray implies a single channel which is opaque.
return { orig.fA, orig.fA, orig.fA, 1 };
if (ct == kGray_8_SkColorType) {
// Prevent the premul raster graciously applies in this case
orig.fA = 1.0;
}
float r = orig.fR, g = orig.fG, b = orig.fB, a = orig.fA;
SkAlphaType at = SkColorTypeIsAlwaysOpaque(ct) ? kOpaque_SkAlphaType
: kPremul_SkAlphaType;
// Missing channels are set to 0
if (!(components & kRed_SkColorTypeComponentFlag)) {
r = 0;
}
if (!(components & kGreen_SkColorTypeComponentFlag)) {
g = 0;
}
if (!(components & kBlue_SkColorTypeComponentFlag)) {
b = 0;
}
// except for missing alpha - which gets set to 1
if (!(components & kAlpha_SkColorTypeComponentFlag)) {
a = 1;
}
return { r, g, b, a };
SkImageInfo ii = SkImageInfo::Make(2, 2, ct, at);
SkAutoPixmapStorage pm;
pm.alloc(ii);
pm.erase(orig);
SkColor tmp = pm.getColor(0, 0);
return SkColor4f::FromColor(tmp);
}
static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
SkColorType skColorType, const SkColor4f expectedColors[6],
skiatest::Reporter* reporter);
skiatest::Reporter* reporter, const char* label);
static void check_base_readbacks(GrContext* context, const GrBackendTexture& backendTex,
SkColorType skColorType, GrRenderable renderable,
const SkColor4f& color, skiatest::Reporter* reporter) {
const SkColor4f& color, skiatest::Reporter* reporter,
const char* label) {
if (isRGB(backendTex.getBackendFormat())) {
// readPixels is busted for the RGB backend format (skbug.com/8862)
// TODO: add a GrColorType::kRGB_888 to fix the situation
return;
}
SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
: kPremul_SkAlphaType;
@ -157,28 +215,11 @@ static void check_base_readbacks(GrContext* context, const GrBackendTexture& bac
{
SkImageInfo readBackII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
kPremul_SkAlphaType);
kUnpremul_SkAlphaType);
SkAssertResult(actual.tryAlloc(readBackII));
}
if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
backendTex,
kTopLeft_GrSurfaceOrigin,
0,
skColorType,
nullptr, nullptr);
if (surf) {
actual.erase(SkColors::kTransparent);
bool result = surf->readPixels(actual, 0, 0);
REPORTER_ASSERT(reporter, result);
check_solid_pixmap(reporter, expectedColor, actual, skColorType,
"SkSurface::readPixels");
}
}
{
sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
backendTex,
@ -197,10 +238,29 @@ static void check_base_readbacks(GrContext* context, const GrBackendTexture& bac
#endif
} else {
check_solid_pixmap(reporter, expectedColor, actual, skColorType,
"SkImage::readPixels");
label, "SkImage::readPixels");
}
}
}
// This will mark any mipmaps as dirty (bc that is what we do when we wrap a renderable
// backend texture) so it must be done last!
if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
backendTex,
kTopLeft_GrSurfaceOrigin,
0,
skColorType,
nullptr, nullptr);
if (surf) {
actual.erase(SkColors::kTransparent);
bool result = surf->readPixels(actual, 0, 0);
REPORTER_ASSERT(reporter, result);
check_solid_pixmap(reporter, expectedColor, actual, skColorType,
label, "SkSurface::readPixels");
}
}
}
// Test initialization of GrBackendObjects to a specific color (non-static since used in Mtl test)
@ -226,15 +286,16 @@ void test_color_init(GrContext* context, skiatest::Reporter* reporter,
return;
}
check_base_readbacks(context, backendTex, skColorType, renderable, color, reporter);
if (mipMapped == GrMipMapped::kYes) {
SkColor4f expectedColor = get_expected_color(color, skColorType);
SkColor4f expectedColors[6] = { expectedColor, expectedColor, expectedColor,
expectedColor, expectedColor, expectedColor };
check_mipmaps(context, backendTex, skColorType, expectedColors, reporter);
check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "colorinit");
}
// The last step in this test will dirty the mipmaps so do it last
check_base_readbacks(context, backendTex, skColorType, renderable, color,
reporter, "colorinit");
context->deleteBackendTexture(backendTex);
}
@ -242,7 +303,7 @@ void test_color_init(GrContext* context, skiatest::Reporter* reporter,
// all the mipMap levels.
static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
SkColorType skColorType, const SkColor4f expectedColors[6],
skiatest::Reporter* reporter) {
skiatest::Reporter* reporter, const char* label) {
#ifdef SK_GL
// skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
@ -256,8 +317,15 @@ static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex
}
#endif
if (isRGB(backendTex.getBackendFormat())) {
// readPixels is busted for the RGB backend format (skbug.com/8862)
// TODO: add a GrColorType::kRGB_888 to fix the situation
return;
}
SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
: kPremul_SkAlphaType;
sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
backendTex,
kTopLeft_GrSurfaceOrigin,
@ -268,11 +336,12 @@ static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex
return;
}
SkImageInfo newII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
SkImageInfo readbackSurfaceII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
kPremul_SkAlphaType);
sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context,
SkBudgeted::kNo,
newII, 1,
readbackSurfaceII, 1,
kTopLeft_GrSurfaceOrigin,
nullptr);
if (!surf) {
@ -295,7 +364,7 @@ static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex
SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
kRGBA_8888_SkColorType,
kPremul_SkAlphaType);
kUnpremul_SkAlphaType);
SkAutoPixmapStorage actual2;
SkAssertResult(actual2.tryAlloc(readbackII));
actual2.erase(SkColors::kTransparent);
@ -303,10 +372,83 @@ static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex
bool result = surf->readPixels(actual2, 0, 0);
REPORTER_ASSERT(reporter, result);
check_solid_pixmap(reporter, expectedColors[i], actual2, skColorType, "mip-level failure");
check_solid_pixmap(reporter, expectedColors[i], actual2, skColorType,
label, "mip-level failure");
}
}
static int make_pixmaps(SkColorType skColorType, GrMipMapped mipMapped,
const SkColor4f colors[6], SkAutoPixmapStorage pixmaps[6]) {
int levelSize = 32;
int numMipLevels = mipMapped == GrMipMapped::kYes ? 6 : 1;
SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
: kPremul_SkAlphaType;
for (int level = 0; level < numMipLevels; ++level) {
SkImageInfo ii = SkImageInfo::Make(levelSize, levelSize, skColorType, at);
pixmaps[level].alloc(ii);
pixmaps[level].erase(colors[level]);
levelSize /= 2;
}
return numMipLevels;
}
// Test initialization of GrBackendObjects using SkPixmaps
static void test_pixmap_init(GrContext* context, skiatest::Reporter* reporter,
std::function<GrBackendTexture (GrContext*,
const SkPixmap srcData[],
int numLevels,
GrRenderable)> create,
SkColorType skColorType, GrMipMapped mipMapped,
GrRenderable renderable) {
SkAutoPixmapStorage pixmapMem[6];
SkColor4f colors[6] = {
{ 1.0f, 0.0f, 0.0f, 1.0f }, // R
{ 0.0f, 1.0f, 0.0f, 0.9f }, // G
{ 0.0f, 0.0f, 1.0f, 0.7f }, // B
{ 0.0f, 1.0f, 1.0f, 0.5f }, // C
{ 1.0f, 0.0f, 1.0f, 0.3f }, // M
{ 1.0f, 1.0f, 0.0f, 0.2f }, // Y
};
int numMipLevels = make_pixmaps(skColorType, mipMapped, colors, pixmapMem);
SkASSERT(numMipLevels);
// TODO: this is tedious. Should we pass in an array of SkBitmaps instead?
SkPixmap pixmaps[6];
for (int i = 0; i < numMipLevels; ++i) {
pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
}
GrBackendTexture backendTex = create(context, pixmaps, numMipLevels, renderable);
if (!backendTex.isValid()) {
// errors here should be reported by the test_wrapping test
return;
}
if (skColorType == kBGRA_8888_SkColorType && !isBGRA(backendTex.getBackendFormat())) {
// When kBGRA is backed by an RGBA something goes wrong in the swizzling
return;
}
if (mipMapped == GrMipMapped::kYes) {
SkColor4f expectedColors[6] = {
get_expected_color(colors[0], skColorType),
get_expected_color(colors[1], skColorType),
get_expected_color(colors[2], skColorType),
get_expected_color(colors[3], skColorType),
get_expected_color(colors[4], skColorType),
get_expected_color(colors[5], skColorType),
};
check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "pixmap");
}
// The last step in this test will dirty the mipmaps so do it last
check_base_readbacks(context, backendTex, skColorType, renderable, colors[0],
reporter, "pixmap");
context->deleteBackendTexture(backendTex);
}
enum class VkLayout {
kUndefined,
kReadOnlyOptimal,
@ -452,11 +594,11 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctx
{ kRGBA_F16Norm_SkColorType, SkColors::kLtGray },
{ kRGBA_F16_SkColorType, SkColors::kYellow },
{ kRGBA_F32_SkColorType, SkColors::kGray },
{ kR8G8_unorm_SkColorType, { .25f, .75f, 0, 0 } },
{ kR8G8_unorm_SkColorType, { .25f, .75f, 0, 1 } },
{ kR16G16_unorm_SkColorType, SkColors::kGreen },
{ kA16_unorm_SkColorType, kTransCol },
{ kA16_float_SkColorType, kTransCol },
{ kR16G16_float_SkColorType, { .25f, .75f, 0, 0 } },
{ kR16G16_float_SkColorType, { .25f, .75f, 0, 1 } },
{ kR16G16B16A16_unorm_SkColorType,{ .25f, .5f, .75f, 1 } },
};
@ -482,6 +624,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctx
renderable).isValid()) {
continue;
}
if (GrRenderable::kYes == renderable) {
if (kRGB_888x_SkColorType == combo.fColorType) {
// Ganesh can't perform the blends correctly when rendering this format
@ -549,10 +692,41 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctx
SkColorTypeToGrColorType(colorType),
combo.fColor, mipMapped, renderable);
}
// Gray_8 is problematic. In the colorInit tests there is ambiguity when
// mapping from format to colorType (since R8 or A8 could be either Alpha_8
// or Gray_8). To compensate for this ambiguity we feed in colors with
// R==G==B==A. If we actually do know the colorType (as is the case
// in the SkPixmap case, there is no ambiguity but the two test expectations
// now collide.
// For now, skip the SkPixmap tests. The real answer is to plumb the
// SkColorType down further in the color-init case.
if (colorType != kGray_8_SkColorType) {
auto createWithSrcDataMtd = [](GrContext* context,
const SkPixmap srcData[],
int numLevels,
GrRenderable renderable) {
SkASSERT(srcData && numLevels);
auto result = context->priv().createBackendTexture(srcData, numLevels,
renderable,
GrProtected::kNo);
check_vk_layout(result, VkLayout::kReadOnlyOptimal);
#ifdef SK_DEBUG
{
auto format = context->defaultBackendFormat(srcData[0].colorType(),
renderable);
SkASSERT(format == result.getBackendFormat());
}
#endif
return result;
};
test_pixmap_init(context, reporter, createWithSrcDataMtd, colorType,
mipMapped, renderable);
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
@ -692,7 +866,7 @@ DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest, reporter, ctxInfo) {
const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1 };
struct {
GrColorType fColorType;

View File

@ -32,10 +32,11 @@ DEF_GPUTEST_FOR_METAL_CONTEXT(MtlBackendAllocationTest, reporter, ctxInfo) {
const GrMtlCaps* mtlCaps = static_cast<const GrMtlCaps*>(context->priv().caps());
constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
struct {
GrColorType fColorType;
MTLPixelFormat fFormat;
MTLPixelFormat fFormat;
SkColor4f fColor;
} combinations[] = {
{ GrColorType::kRGBA_8888, MTLPixelFormatRGBA8Unorm, SkColors::kRed },
@ -56,7 +57,7 @@ DEF_GPUTEST_FOR_METAL_CONTEXT(MtlBackendAllocationTest, reporter, ctxInfo) {
{ GrColorType::kAlpha_8, MTLPixelFormatA8Unorm, kTransCol },
{ GrColorType::kAlpha_8, MTLPixelFormatR8Unorm, kTransCol },
{ GrColorType::kGray_8, MTLPixelFormatR8Unorm, SkColors::kDkGray },
{ GrColorType::kGray_8, MTLPixelFormatR8Unorm, kGrayCol },
{ GrColorType::kRGBA_F32, MTLPixelFormatRGBA32Float, SkColors::kRed },
@ -114,7 +115,6 @@ DEF_GPUTEST_FOR_METAL_CONTEXT(MtlBackendAllocationTest, reporter, ctxInfo) {
combo.fColorType, mipMapped, renderable);
}
// Not implemented for Metal yet
{
auto createWithColorMtd = [format](GrContext* context,
const SkColor4f& color,