|  | /* | 
|  | * Copyright 2019 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | #include "src/gpu/dawn/GrDawnCaps.h" | 
|  |  | 
|  | GrDawnCaps::GrDawnCaps(const GrContextOptions& contextOptions) : INHERITED(contextOptions) { | 
|  | fMipMapSupport = true; | 
|  | fBufferMapThreshold = SK_MaxS32;  // FIXME: get this from Dawn? | 
|  | fShaderCaps.reset(new GrShaderCaps(contextOptions)); | 
|  | fMaxTextureSize = fMaxRenderTargetSize = 4096; // FIXME | 
|  | fMaxVertexAttributes = 16; // FIXME | 
|  | fClampToBorderSupport = false; | 
|  | fPerformPartialClearsAsDraws = true; | 
|  |  | 
|  | fShaderCaps->fFlatInterpolationSupport = true; | 
|  | fShaderCaps->fIntegerSupport = true; | 
|  | // FIXME: each fragment sampler takes two binding slots in Dawn (sampler + texture). Limit to | 
|  | // 6 * 2 = 12, since kMaxBindingsPerGroup is 16 in Dawn, and we need to keep a few for | 
|  | // non-texture bindings. Eventually, we may be able to increase kMaxBindingsPerGroup in Dawn. | 
|  | fShaderCaps->fMaxFragmentSamplers = 6; | 
|  | fShaderCaps->fShaderDerivativeSupport = true; | 
|  |  | 
|  | this->applyOptionsOverrides(contextOptions); | 
|  | fShaderCaps->applyOptionsOverrides(contextOptions); | 
|  | } | 
|  |  | 
|  | bool GrDawnCaps::isFormatSRGB(const GrBackendFormat& format) const { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool GrDawnCaps::isFormatCompressed(const GrBackendFormat& format, | 
|  | SkImage::CompressionType* compressionType) const { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool GrDawnCaps::isFormatTexturable(const GrBackendFormat& format) const { | 
|  | // Currently, all the formats in GrDawnFormatToPixelConfig are texturable. | 
|  | dawn::TextureFormat dawnFormat; | 
|  | return format.asDawnFormat(&dawnFormat); | 
|  | } | 
|  |  | 
|  | GrPixelConfig GrDawnCaps::onGetConfigFromBackendFormat(const GrBackendFormat& format, | 
|  | GrColorType colorType) const { | 
|  | dawn::TextureFormat dawnFormat; | 
|  | if (!format.asDawnFormat(&dawnFormat)) { | 
|  | return kUnknown_GrPixelConfig; | 
|  | } | 
|  | switch (colorType) { | 
|  | case GrColorType::kUnknown: | 
|  | return kUnknown_GrPixelConfig; | 
|  | case GrColorType::kAlpha_8: | 
|  | if (dawn::TextureFormat::R8Unorm == dawnFormat) { | 
|  | return kAlpha_8_as_Red_GrPixelConfig; | 
|  | } | 
|  | break; | 
|  | case GrColorType::kRGBA_8888: | 
|  | if (dawn::TextureFormat::RGBA8Unorm == dawnFormat) { | 
|  | return kRGBA_8888_GrPixelConfig; | 
|  | } else if (dawn::TextureFormat::BGRA8Unorm == dawnFormat) { | 
|  | // FIXME: This shouldn't be necessary, but on some platforms (Mac) | 
|  | // Skia byte order is RGBA, while preferred swap format is BGRA. | 
|  | return kBGRA_8888_GrPixelConfig; | 
|  | } | 
|  | break; | 
|  | case GrColorType::kRGB_888x: | 
|  | break; | 
|  | case GrColorType::kBGRA_8888: | 
|  | if (dawn::TextureFormat::BGRA8Unorm == dawnFormat) { | 
|  | return kBGRA_8888_GrPixelConfig; | 
|  | } else if (dawn::TextureFormat::RGBA8Unorm == dawnFormat) { | 
|  | return kRGBA_8888_GrPixelConfig; | 
|  | } | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | return kUnknown_GrPixelConfig; | 
|  | } | 
|  |  | 
|  | static GrSwizzle get_swizzle(const GrBackendFormat& format, GrColorType colorType, | 
|  | bool forOutput) { | 
|  | switch (colorType) { | 
|  | case GrColorType::kAlpha_8: // fall through | 
|  | case GrColorType::kAlpha_F16: | 
|  | if (forOutput) { | 
|  | return GrSwizzle::AAAA(); | 
|  | } else { | 
|  | return GrSwizzle::RRRR(); | 
|  | } | 
|  | case GrColorType::kGray_8: | 
|  | if (!forOutput) { | 
|  | return GrSwizzle::RRRA(); | 
|  | } | 
|  | break; | 
|  | case GrColorType::kRGB_888x: | 
|  | if (!forOutput) { | 
|  | return GrSwizzle::RGB1(); | 
|  | } | 
|  | default: | 
|  | return GrSwizzle::RGBA(); | 
|  | } | 
|  | return GrSwizzle::RGBA(); | 
|  | } | 
|  |  | 
|  | bool GrDawnCaps::isFormatTexturableAndUploadable(GrColorType ct, | 
|  | const GrBackendFormat& format) const { | 
|  | dawn::TextureFormat dawnFormat; | 
|  | if (!format.asDawnFormat(&dawnFormat)) { | 
|  | return false; | 
|  | } | 
|  | switch (ct) { | 
|  | case GrColorType::kAlpha_8: | 
|  | return dawn::TextureFormat::R8Unorm == dawnFormat; | 
|  | case GrColorType::kRGBA_8888: | 
|  | case GrColorType::kRGB_888x: | 
|  | case GrColorType::kBGRA_8888: | 
|  | return dawn::TextureFormat::RGBA8Unorm == dawnFormat || | 
|  | dawn::TextureFormat::BGRA8Unorm == dawnFormat; | 
|  | default: | 
|  | return false; | 
|  | } | 
|  | } | 
|  |  | 
|  | bool GrDawnCaps::isFormatRenderable(const GrBackendFormat& format, | 
|  | int sampleCount) const { | 
|  | dawn::TextureFormat dawnFormat; | 
|  | if (!format.isValid() || sampleCount > 1 || !format.asDawnFormat(&dawnFormat)) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | return GrDawnFormatIsRenderable(dawnFormat); | 
|  | } | 
|  |  | 
|  | bool GrDawnCaps::isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, | 
|  | int sampleCount) const { | 
|  | return isFormatRenderable(format, sampleCount); | 
|  | } | 
|  |  | 
|  | size_t GrDawnCaps::bytesPerPixel(const GrBackendFormat& backendFormat) const { | 
|  | dawn::TextureFormat dawnFormat; | 
|  | if (!backendFormat.asDawnFormat(&dawnFormat)) { | 
|  | return 0; | 
|  | } | 
|  | return GrDawnBytesPerPixel(dawnFormat); | 
|  | } | 
|  |  | 
|  | int GrDawnCaps::getRenderTargetSampleCount(int requestedCount, | 
|  | const GrBackendFormat& backendFormat) const { | 
|  | dawn::TextureFormat dawnFormat; | 
|  | if (!backendFormat.asDawnFormat(&dawnFormat)) { | 
|  | return 0; | 
|  | } | 
|  | return GrDawnFormatIsRenderable(dawnFormat) ? 1 : 0; | 
|  | } | 
|  |  | 
|  | int GrDawnCaps::maxRenderTargetSampleCount(const GrBackendFormat& format) const { | 
|  | return format.isValid() ? 1 : 0; | 
|  | } | 
|  |  | 
|  | GrBackendFormat GrDawnCaps::onGetDefaultBackendFormat(GrColorType ct, | 
|  | GrRenderable renderable) const { | 
|  | GrPixelConfig config = GrColorTypeToPixelConfig(ct); | 
|  | if (config == kUnknown_GrPixelConfig) { | 
|  | return GrBackendFormat(); | 
|  | } | 
|  | dawn::TextureFormat format; | 
|  | if (!GrPixelConfigToDawnFormat(config, &format)) { | 
|  | return GrBackendFormat(); | 
|  | } | 
|  | return GrBackendFormat::MakeDawn(format); | 
|  | } | 
|  |  | 
|  | GrBackendFormat GrDawnCaps::getBackendFormatFromCompressionType(SkImage::CompressionType type) const | 
|  | { | 
|  | return GrBackendFormat(); | 
|  | } | 
|  |  | 
|  | GrSwizzle GrDawnCaps::getTextureSwizzle(const GrBackendFormat& format, GrColorType colorType) const | 
|  | { | 
|  | return get_swizzle(format, colorType, false); | 
|  | } | 
|  |  | 
|  | GrSwizzle GrDawnCaps::getOutputSwizzle(const GrBackendFormat& format, GrColorType colorType) const | 
|  | { | 
|  | return get_swizzle(format, colorType, true); | 
|  | } | 
|  |  | 
|  | bool GrDawnCaps::onAreColorTypeAndFormatCompatible(GrColorType ct, | 
|  | const GrBackendFormat& format) const { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | GrColorType GrDawnCaps::getYUVAColorTypeFromBackendFormat(const GrBackendFormat& backendFormat, | 
|  | bool isAlphaChannel) const { | 
|  | dawn::TextureFormat textureFormat; | 
|  | if (!backendFormat.asDawnFormat(&textureFormat)) { | 
|  | return GrColorType::kUnknown; | 
|  | } | 
|  | switch (textureFormat) { | 
|  | case dawn::TextureFormat::R8Unorm:     return isAlphaChannel ? GrColorType::kAlpha_8 | 
|  | : GrColorType::kGray_8; | 
|  | case dawn::TextureFormat::RGBA8Unorm:  return GrColorType::kRGBA_8888; | 
|  | case dawn::TextureFormat::BGRA8Unorm:  return GrColorType::kBGRA_8888; | 
|  | default:                               return GrColorType::kUnknown; | 
|  | } | 
|  | } | 
|  |  | 
|  | #if GR_TEST_UTILS | 
|  | std::vector<GrCaps::TestFormatColorTypeCombination> GrDawnCaps::getTestingCombinations() const { | 
|  | std::vector<GrCaps::TestFormatColorTypeCombination> combos = { | 
|  | { GrColorType::kAlpha_8,   GrBackendFormat::MakeDawn(dawn::TextureFormat::R8Unorm)    }, | 
|  | { GrColorType::kRGBA_8888, GrBackendFormat::MakeDawn(dawn::TextureFormat::RGBA8Unorm) }, | 
|  | { GrColorType::kRGBA_8888, GrBackendFormat::MakeDawn(dawn::TextureFormat::BGRA8Unorm) }, | 
|  | { GrColorType::kRGB_888x,  GrBackendFormat::MakeDawn(dawn::TextureFormat::RGBA8Unorm) }, | 
|  | { GrColorType::kRGB_888x,  GrBackendFormat::MakeDawn(dawn::TextureFormat::BGRA8Unorm) }, | 
|  | { GrColorType::kBGRA_8888, GrBackendFormat::MakeDawn(dawn::TextureFormat::BGRA8Unorm) }, | 
|  | { GrColorType::kBGRA_8888, GrBackendFormat::MakeDawn(dawn::TextureFormat::RGBA8Unorm) }, | 
|  | }; | 
|  |  | 
|  | #ifdef SK_DEBUG | 
|  | for (auto combo : combos) { | 
|  | SkASSERT(this->onAreColorTypeAndFormatCompatible(combo.fColorType, combo.fFormat)); | 
|  | } | 
|  | #endif | 
|  | return combos; | 
|  | } | 
|  | #endif |