Expand texturability testing to cover mip-mapped textures, and fix iOS

Don't allow creation of mip-mapped textures when caps says we don't
support mip-mapping.

Skip testing of mip-mapped resources in the resource size test,
when creation will fail.

For iOS devices with ES2, the APPLE BGRA8888 extension is more
trouble than it's worth. Even though it lets the internal and
external formats not match, it appears that the driver remembers
the first external format, so subsequent attempts to upload with
the other swizzle will fail. Up until now, creation of these
textures was failing anyway, so now just make it more explicit
that we don't support BGRA in this situation.

BUG=skia:

Change-Id: Ic2e3ba1673398d542edd46a555ef47b5d0979c01
Reviewed-on: https://skia-review.googlesource.com/18261
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Brian Osman 2017-06-01 11:01:33 -04:00 committed by Skia Commit-Bot
parent 48567ac8ae
commit 9f6f41b01b
4 changed files with 35 additions and 10 deletions

View File

@ -65,7 +65,7 @@ bool validate_desc(const GrSurfaceDesc& desc, const GrCaps& caps, int levelCount
return false; return false;
} }
} }
if (levelCount > 1 && GrPixelConfigIsSint(desc.fConfig)) { if (levelCount > 1 && (GrPixelConfigIsSint(desc.fConfig) || !caps.mipMapSupport())) {
return false; return false;
} }
return true; return true;

View File

@ -1571,14 +1571,16 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA; fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8; fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) { if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
// The APPLE extension doesn't make this renderable. // This APPLE extension introduces complexity on ES2. It leaves the internal format
fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag; // as RGBA, but allows BGRA as the external format. From testing, it appears that the
if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) { // driver remembers the external format when the texture is created (with TexImage).
// On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension. // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
// Though, that seems to not be the case if the texture storage extension is // We could work around this, but it adds even more state tracking to code that is
// present. The specs don't exactly make that clear. // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA; // This also side-steps some ambiguous interactions with the texture storage extension.
fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8; if (version >= GR_GL_VER(3,0)) {
// The APPLE extension doesn't make this renderable.
fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
} }
} else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) { } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag | fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |

View File

@ -17,6 +17,7 @@
#include "GrTest.h" #include "GrTest.h"
#include "GrTexture.h" #include "GrTexture.h"
#include "GrSurfacePriv.h" #include "GrSurfacePriv.h"
#include "SkMipMap.h"
#include "Test.h" #include "Test.h"
// Tests that GrSurface::asTexture(), GrSurface::asRenderTarget(), and static upcasting of texture // Tests that GrSurface::asTexture(), GrSurface::asRenderTarget(), and static upcasting of texture
@ -99,6 +100,16 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(GrSurfaceRenderability, reporter, ctxInfo) {
desc.fWidth = 64; desc.fWidth = 64;
desc.fHeight = 64; desc.fHeight = 64;
// Enough space for the first mip of our largest pixel config
const size_t pixelBufferSize = desc.fWidth * desc.fHeight *
GrBytesPerPixel(kRGBA_float_GrPixelConfig);
std::unique_ptr<char[]> pixelData(new char[pixelBufferSize]);
memset(pixelData.get(), 0, pixelBufferSize);
// We re-use the same mip level objects (with updated pointers and rowBytes) for each config
const int levelCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight);
std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[levelCount]);
for (GrPixelConfig config : configs) { for (GrPixelConfig config : configs) {
for (GrSurfaceOrigin origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) { for (GrSurfaceOrigin origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
desc.fFlags = kNone_GrSurfaceFlags; desc.fFlags = kNone_GrSurfaceFlags;
@ -109,6 +120,18 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(GrSurfaceRenderability, reporter, ctxInfo) {
sk_sp<GrSurface> tex = resourceProvider->createTexture(desc, SkBudgeted::kNo); sk_sp<GrSurface> tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigTexturable(desc.fConfig)); REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigTexturable(desc.fConfig));
size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
for (int i = 0; i < levelCount; ++i) {
texels[i].fPixels = pixelData.get();
texels[i].fRowBytes = rowBytes >> i;
}
sk_sp<GrTextureProxy> proxy = resourceProvider->createMipMappedTexture(
desc, SkBudgeted::kNo, texels.get(), levelCount);
REPORTER_ASSERT(reporter, SkToBool(proxy.get()) ==
(caps->isConfigTexturable(desc.fConfig) &&
caps->mipMapSupport() &&
!GrPixelConfigIsSint(desc.fConfig)));
desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fFlags = kRenderTarget_GrSurfaceFlag;
tex = resourceProvider->createTexture(desc, SkBudgeted::kNo); tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigRenderable(config, false)); REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigRenderable(config, false));

View File

@ -1714,7 +1714,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GPUMemorySize, reporter, ctxInfo) {
// Mipmapped versions // Mipmapped versions
{ if (context->caps()->mipMapSupport()) {
sk_sp<GrTextureProxy> proxy; sk_sp<GrTextureProxy> proxy;
proxy = make_mipmap_proxy(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 0); proxy = make_mipmap_proxy(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 0);