in src/gpu/ganesh/gl/GrGLCaps.cpp [1467:3568]
void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
const FormatWorkarounds& formatWorkarounds) {
GrGLStandard standard = ctxInfo.standard();
// standard can be unused (optimized away) if SK_ASSUME_GL_ES is set
sk_ignore_unused_variable(standard);
GrGLVersion version = ctxInfo.version();
uint32_t nonMSAARenderFlags = FormatInfo::kFBOColorAttachment_Flag;
uint32_t msaaRenderFlags = nonMSAARenderFlags;
if (kNone_MSFBOType != fMSFBOType) {
msaaRenderFlags |= FormatInfo::kFBOColorAttachmentWithMSAA_Flag;
}
bool texStorageSupported = false;
if (GR_IS_GR_GL(standard)) {
// The EXT version can apply to either GL or GLES.
texStorageSupported = version >= GR_GL_VER(4,2) ||
ctxInfo.hasExtension("GL_ARB_texture_storage") ||
ctxInfo.hasExtension("GL_EXT_texture_storage");
} else if (GR_IS_GR_GL_ES(standard)) {
texStorageSupported = version >= GR_GL_VER(3,0) ||
ctxInfo.hasExtension("GL_EXT_texture_storage");
} else if (GR_IS_GR_WEBGL(standard)) {
texStorageSupported = version >= GR_GL_VER(2,0);
}
if (fDriverBugWorkarounds.disable_texture_storage) {
texStorageSupported = false;
}
if (formatWorkarounds.fDisableTexStorage) {
texStorageSupported = false;
}
// ES 2.0 requires that the internal/external formats match so we can't use sized internal
// formats for glTexImage until ES 3.0. TODO: Support sized internal formats in WebGL2.
bool texImageSupportsSizedInternalFormat =
(GR_IS_GR_GL(standard) || (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3,0)));
// for now we don't support floating point MSAA on ES
uint32_t fpRenderFlags = (GR_IS_GR_GL(standard)) ? msaaRenderFlags : nonMSAARenderFlags;
for (int i = 0; i < kGrColorTypeCnt; ++i) {
fColorTypeToFormatTable[i] = GrGLFormat::kUnknown;
}
///////////////////////////////////////////////////////////////////////////
GrGLenum halfFloatType = GR_GL_HALF_FLOAT;
if ((GR_IS_GR_GL_ES(standard) && version < GR_GL_VER(3, 0)) ||
(GR_IS_GR_WEBGL(standard) && version < GR_GL_VER(2, 0))) {
halfFloatType = GR_GL_HALF_FLOAT_OES;
}
// Format: RGBA8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_RGBA8;
info.fDefaultExternalFormat = GR_GL_RGBA;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kRGBA_8888;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (GR_IS_GR_GL(standard)) {
info.fFlags |= msaaRenderFlags;
} else if (GR_IS_GR_GL_ES(standard)) {
if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
ctxInfo.hasExtension("GL_ARM_rgba8")) {
info.fFlags |= msaaRenderFlags;
}
} else if (GR_IS_GR_WEBGL(standard)) {
info.fFlags |= msaaRenderFlags;
}
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA8;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RGBA8 : GR_GL_RGBA;
}
bool supportsBGRAColorType = GR_IS_GR_GL(standard) &&
(version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra"));
info.fColorTypeInfoCount = supportsBGRAColorType ? 3 : 2;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: RGBA8, Surface: kRGBA_8888
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGBA_8888;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kRGBA_8888, GrGLFormat::kRGBA8);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGBA8, Surface: kRGBA_8888, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
// Format: RGBA8, Surface: kRGBA_8888, Data: kBGRA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kBGRA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0; // TODO: Enable this on non-ES GL
ioFormat.fExternalReadFormat =
formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
}
// Format: RGBA8, Surface: kBGRA_8888
if (supportsBGRAColorType) {
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kBGRA_8888;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kBGRA_8888, GrGLFormat::kRGBA8);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGBA8, Surface: kBGRA_8888, Data: kBGRA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kBGRA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
ioFormat.fExternalReadFormat =
formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: RGBA8, Surface: kBGRA_8888, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
// Format: RGBA8, Surface: kRGB_888x
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGB_888x;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 1;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGBA8, Surface: kRGB_888x, Data: kRGBA_888x
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGB_888x;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
// Format: R8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kR8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_R8;
info.fDefaultExternalFormat = GR_GL_RED;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kR_8;
bool r8Support = false;
if (GR_IS_GR_GL(standard)) {
r8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
} else if (GR_IS_GR_GL_ES(standard)) {
r8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
} else if (GR_IS_GR_WEBGL(standard)) {
r8Support = ctxInfo.version() >= GR_GL_VER(2, 0);
}
if (formatWorkarounds.fDisallowR8ForPowerVRSGX54x) {
r8Support = false;
}
if (r8Support) {
info.fFlags |= FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
}
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_R8;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_R8 : GR_GL_RED;
}
if (r8Support) {
info.fColorTypeInfoCount = 3;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: R8, Surface: kR_8
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kR_8;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kR_8, GrGLFormat::kR8);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: R8, Surface: kR_8, Data: kR_8
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kR_8;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_RED;
ioFormat.fExternalReadFormat = GR_GL_RED;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: R8, Surface: kR_8, Data: kR_8xxx
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kR_8xxx;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
// Format: R8, Surface: kAlpha_8
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kAlpha_8;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
this->setColorTypeFormat(GrColorType::kAlpha_8, GrGLFormat::kR8);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: R8, Surface: kAlpha_8, Data: kAlpha_8
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kAlpha_8;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_RED;
ioFormat.fExternalReadFormat = GR_GL_RED;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: R8, Surface: kAlpha_8, Data: kAlpha_8xxx
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kAlpha_8xxx;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
// Format: R8, Surface: kGray_8
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kGray_8;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
ctInfo.fReadSwizzle = skgpu::Swizzle("rrr1");
this->setColorTypeFormat(GrColorType::kGray_8, GrGLFormat::kR8);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: R8, Surface: kGray_8, Data: kGray_8
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kGray_8;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_RED;
ioFormat.fExternalReadFormat = GR_GL_RED;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: R8, Surface: kGray_8, Data: kGray_8xxx
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kGray_8xxx;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: ALPHA8
{
bool alpha8IsValidForGL = GR_IS_GR_GL(standard) &&
(!fIsCoreProfile || version <= GR_GL_VER(3, 0));
bool alpha8IsValidForGLES = GR_IS_GR_GL_ES(standard);
bool alpha8IsValidForWebGL = GR_IS_GR_WEBGL(standard);
FormatInfo& info = this->getFormatInfo(GrGLFormat::kALPHA8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
// GL_EXT_texture_storage adds GL_ALPHA8 for texture storage. However, ES3 has glTexStorage
// but does not have GL_ALPHA8 (and requires a sized internal format for glTexStorage).
// WebGL never has GL_ALPHA8.
bool alpha8SizedEnumSupported =
alpha8IsValidForGL ||
(alpha8IsValidForGLES && ctxInfo.hasExtension("GL_EXT_texture_storage"));
bool alpha8TexStorageSupported = alpha8SizedEnumSupported && texStorageSupported;
bool alpha8IsRenderable = false;
if (alpha8IsValidForGL) {
// Core profile removes ALPHA8 support.
// OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
alpha8IsRenderable = ctxInfo.version() >= GR_GL_VER(3, 0) ||
ctxInfo.hasExtension("GL_ARB_framebuffer_object");
}
info.fInternalFormatForRenderbuffer = GR_GL_ALPHA8;
info.fDefaultExternalFormat = GR_GL_ALPHA;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kAlpha_8;
if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
}
if (alpha8IsRenderable && alpha8IsValidForGL) {
// We will use ALPHA8 to create MSAA renderbuffers.
SkASSERT(alpha8SizedEnumSupported);
info.fFlags |= msaaRenderFlags;
}
if (alpha8TexStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA8;
} else {
// Even if GL_ALPHA8 is added to ES by GL_EXT_texture_storage it doesn't become legal
// for glTexImage2D.
if (!GR_IS_GR_GL_ES(standard) && texImageSupportsSizedInternalFormat &&
alpha8SizedEnumSupported) {
info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA8;
} else {
info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA;
}
}
if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: ALPHA8, Surface: kAlpha_8
{
if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kAlpha_8;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag |
ColorTypeInfo::kRenderable_Flag;
int idx = static_cast<int>(GrColorType::kAlpha_8);
if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
this->setColorTypeFormat(GrColorType::kAlpha_8, GrGLFormat::kALPHA8);
}
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: ALPHA8, Surface: kAlpha_8, Data: kAlpha_8
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kAlpha_8;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_ALPHA;
ioFormat.fExternalReadFormat = GR_GL_ALPHA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: ALPHA8, Surface: kAlpha_8, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
}
// Do we support the lumincance and luminance_alpha formats
bool lum8Supported = false;
bool lum8SizedFormatSupported = false;
if (GR_IS_GR_GL(standard) && !fIsCoreProfile) {
lum8Supported = true;
lum8SizedFormatSupported = true;
} else if (GR_IS_GR_GL_ES(standard)) {
lum8Supported = true;
// Even on ES3 this extension is required to define LUMINANCE8. GL_LUMINANCE8 is not a
// valid internal format for TexImage2D so we need to be using texture storage to use
// it. Even though we check the extension for texture storage here, we also check to see
// if texStorageSupported may have been disabled for a workaround.
lum8SizedFormatSupported =
texStorageSupported && ctxInfo.hasExtension("GL_EXT_texture_storage");
} else if (GR_IS_GR_WEBGL(standard)) {
lum8Supported = true;
}
// Format: LUMINANCE8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE8;
info.fDefaultExternalFormat = GR_GL_LUMINANCE;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kGray_8;
if (lum8Supported) {
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
}
if (texStorageSupported && lum8SizedFormatSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8;
} else if (texImageSupportsSizedInternalFormat && lum8SizedFormatSupported) {
info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8;
} else {
info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE;
}
// We are not enabling attaching to an FBO for LUMINANCE8 mostly because of confusion in the
// spec. For GLES it does not seem to ever support LUMINANCE8 being color-renderable. For GL
// versions less than 3.0 it is provided by GL_ARB_framebuffer_object. However, the original
// version of that extension did not add LUMINANCE8, but was added in a later revsion. So
// even the presence of that extension does not guarantee support. GL 3.0 and higher (core
// or compatibility) do not list LUMINANCE8 as color-renderable (which is strange since the
// GL_ARB_framebuffer_object extension was meant to bring 3.0 functionality to lower
// versions).
if (lum8Supported) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: LUMINANCE8, Surface: kGray_8
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kGray_8;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
int idx = static_cast<int>(GrColorType::kGray_8);
if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
this->setColorTypeFormat(GrColorType::kGray_8, GrGLFormat::kLUMINANCE8);
}
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: LUMINANCE8, Surface: kGray_8, Data: kGray_8
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kGray_8;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE;
ioFormat.fExternalReadFormat = 0;
}
// Format: LUMINANCE8, Surface: kGray_8, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: LUMINANCE8_ALPHA8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE8_ALPHA8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE8_ALPHA8;
info.fDefaultExternalFormat = GR_GL_LUMINANCE_ALPHA;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kGrayAlpha_88;
if (lum8Supported) {
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
}
if (texStorageSupported && lum8SizedFormatSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8_ALPHA8;
} else if (texImageSupportsSizedInternalFormat && lum8SizedFormatSupported) {
info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8_ALPHA8;
} else {
info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE_ALPHA;
}
// See note in LUMINANCE8 section about not attaching to framebuffers.
if (lum8Supported) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: LUMINANCE8_ALPHA8, Surface: kGrayAlpha_88
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kGrayAlpha_88;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
int idx = static_cast<int>(GrColorType::kGrayAlpha_88);
if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
this->setColorTypeFormat(GrColorType::kGrayAlpha_88,
GrGLFormat::kLUMINANCE8_ALPHA8);
}
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: LUMINANCE8, Surface: kGrayAlpha_88, Data: kGrayAlpha_88
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kGrayAlpha_88;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE_ALPHA;
ioFormat.fExternalReadFormat = 0;
}
// Format: LUMINANCE8, Surface: kGrayAlpha_88, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: BGRA8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kBGRA8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fDefaultExternalFormat = GR_GL_BGRA;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kBGRA_8888;
GrGLenum bgraTexImageFormat;
// If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
// as a base format. Which base format depends on which extension is used.
if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
// GL_EXT_texture_format_BGRA8888:
// This extension adds GL_BGRA as an unsized internal format. However, it is
// written against ES 2.0 and therefore doesn't define a GL_BGRA8 as ES 2.0 doesn't
// have sized internal formats. See later where we check for tex storage BGRA8
// support.
bgraTexImageFormat = GR_GL_BGRA;
} else {
// GL_APPLE_texture_format_BGRA8888:
// ES 2.0: the extension makes BGRA an external format but not an internal format.
// ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format
// for glTexImage (just for glTexStorage).
bgraTexImageFormat = GR_GL_RGBA;
}
// TexStorage requires using a sized internal format and BGRA8 is only supported if we have
// the GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texture_storage and
// GL_EXT_texture_format_BGRA8888.
bool supportsBGRATexStorage = false;
if (GR_IS_GR_GL_ES(standard)) {
if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
// The GL_EXT_texture_format_BGRA8888 extension adds BGRA color renderbuffer support
// for ES 2.0. The extension adds BGRA to the supported renerable formats in table
// 4.5. In ES 2.0. All the extensions that add multisample support, all reference
// table 4.5 as the formats that are supported. Thus we can use msaaRenderFlags.
// Additionally, the renderable support was added in a later revision of the
// extension. So it is possible for older drivers to support the extension but only
// an early revision of it without renderable support. We have no way of
// distinguishing between the two and assume renderable.
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag;
// Only enable BGRA msaa if we know we're going through Angle. The spec for
// GL_EXT_texture_format_BGRA8888 was updated in 2016 to add support for GL_BGRA_EXT
// as a sized, renderable format. But we may end up running on old drivers written
// against earlier version of the spec. Also the interactions between all these
// extensions are very suibtle and it wouldn't be hard for a driver to mess them up.
// We are confident that Angle does it as we expect. Our non-angle test bots do seem
// to pass and draw correctly so we could consider enabling this more broadly in the
// future.
// In addition, we also need to disable BGRA MSAA on Mesa. When a client attempts
// to wrap a GPU-backed texture into an SkSurface with MSAA, Ganesh will create
// a MSAA renderbuffer to first render to before resolving to the single-sampled
// texture. Mesa claims to support EXT_texture_format_BGRA8888, and according to
// the spec, this should imply support for both BGRA textures and renderbuffers.
// In practice, however, Mesa only supports BGRA textures and will error on
// glRenderbufferStorage* if the internalformat is BGRA.
if (ctxInfo.angleBackend() != GrGLANGLEBackend::kUnknown &&
ctxInfo.angleDriver() != GrGLDriver::kMesa) {
// Angle incorrectly requires GL_BGRA8_EXT for the interalFormat for both ES2
// and ES3 even though this extension does not define that value. The extension
// only defines GL_BGRA_EXT as an internal format.
info.fInternalFormatForRenderbuffer = GR_GL_BGRA8;
info.fFlags |= msaaRenderFlags;
} else {
// It is not clear what the correct format to use on ES3 is. This extension only
// defines GL_BGRA_EXT. That is definitely the correct thing to use on ES2, but
// its unclear whether that is valid in ES3 or if it wants something like
// GL_BGRA8_EXT (which is only defined in the apple extenstion). For now we set
// everything to use BGRA since its the only explicitly defined value. Until we
// enable MSAA for non-angle this is a moot point.
info.fInternalFormatForRenderbuffer = GR_GL_BGRA;
info.fFlags |= nonMSAARenderFlags;
}
// GL_EXT_texture storage has defined interactions with
// GL_EXT_texture_format_BGRA8888. However, ES3 supports glTexStorage but
// without GL_EXT_texture_storage it does not allow the BGRA8 sized internal format.
if (ctxInfo.hasExtension("GL_EXT_texture_storage") &&
!formatWorkarounds.fDisableBGRATextureStorageForIntelWindowsES) {
supportsBGRATexStorage = true;
}
} else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
// This APPLE extension introduces complexity on ES2. It leaves the internal format
// as RGBA, but allows BGRA as the external format. From testing, it appears that
// the driver remembers the external format when the texture is created (with
// TexImage). If you then try to upload data in the other swizzle (with
// TexSubImage), it fails. We could work around this, but it adds even more state
// tracking to code that is already too tricky. Instead, we opt not to support BGRA
// on ES2 with this extension. This also side-steps some ambiguous interactions with
// the texture storage extension.
if (version >= GR_GL_VER(3,0)) {
// The APPLE extension doesn't explicitly make this renderable, but
// internally it appears to use RGBA8, which we'll patch up below.
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
// The GL_APPLE_texture_format_BGRA8888 does not add support for BGRA color
// renderbuffers at all so we use RGBA here.
info.fInternalFormatForRenderbuffer = GR_GL_RGBA8;
supportsBGRATexStorage = true;
}
}
}
if (texStorageSupported && supportsBGRATexStorage) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_BGRA8;
} else {
info.fInternalFormatForTexImageOrStorage = bgraTexImageFormat;
}
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 2;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: BGRA8, Surface: kBGRA_8888
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kBGRA_8888;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kBGRA_8888, GrGLFormat::kBGRA8);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: BGRA8, Surface: kBGRA_8888, Data: kBGRA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kBGRA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
ioFormat.fExternalReadFormat = 0;
ioFormat.fExternalReadFormat =
formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: BGRA8, Surface: kBGRA_8888, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
// Format: BGRA8, Surface: kRGB_888x
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGB_888x;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 1;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: BGRA8, Surface: kRGB_888x, Data: kRGBA_888x
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGB_888x;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: RGB565
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB565);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_RGB565;
info.fDefaultExternalFormat = GR_GL_RGB;
info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
info.fDefaultColorType = GrColorType::kBGR_565;
if (GR_IS_GR_GL(standard)) {
if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
}
} else if (GR_IS_GR_GL_ES(standard)) {
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
} else if (GR_IS_GR_WEBGL(standard)) {
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
}
// 565 is not a sized internal format on desktop GL. So on desktop with
// 565 we always use an unsized internal format to let the system pick
// the best sized format to convert the 565 data to. Since TexStorage
// only allows sized internal formats we disallow it.
//
// TODO: As of 4.2, regular GL supports 565. This logic is due for an
// update.
if (texStorageSupported && GR_IS_GR_GL_ES(standard)) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RGB565;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RGB565 : GR_GL_RGB;
}
if (SkToBool(info.fFlags &FormatInfo::kTexturable_Flag)) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: RGB565, Surface: kBGR_565
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kBGR_565;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kBGR_565, GrGLFormat::kRGB565);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGB565, Surface: kBGR_565, Data: kBGR_565
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kBGR_565;
ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
ioFormat.fExternalTexImageFormat = GR_GL_RGB;
ioFormat.fExternalReadFormat = GR_GL_RGB;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: RGB565, Surface: kBGR_565, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: RGBA16F
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA16F);
info.fFormatType = FormatType::kFloat;
info.fInternalFormatForRenderbuffer = GR_GL_RGBA16F;
info.fDefaultExternalFormat = GR_GL_RGBA;
info.fDefaultExternalType = halfFloatType;
info.fDefaultColorType = GrColorType::kRGBA_F16;
bool rgba16FTextureSupport = false;
bool rgba16FRenderTargetSupport = false;
if (GR_IS_GR_GL(standard)) {
if (version >= GR_GL_VER(3, 0)) {
rgba16FTextureSupport = true;
rgba16FRenderTargetSupport = true;
} else if (ctxInfo.hasExtension("GL_ARB_texture_float")) {
rgba16FTextureSupport = true;
}
} else if (GR_IS_GR_GL_ES(standard)) {
if (version >= GR_GL_VER(3, 0)) {
rgba16FTextureSupport = true;
rgba16FRenderTargetSupport =
version >= GR_GL_VER(3, 2) ||
ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
ctxInfo.hasExtension("GL_EXT_color_buffer_float");
} else if (ctxInfo.hasExtension("GL_OES_texture_half_float") &&
ctxInfo.hasExtension("GL_OES_texture_half_float_linear")) {
rgba16FTextureSupport = true;
rgba16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
}
} else if (GR_IS_GR_WEBGL(standard)) {
if (version >= GR_GL_VER(2, 0)) {
rgba16FTextureSupport = true;
rgba16FRenderTargetSupport =
ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
ctxInfo.hasExtension("EXT_color_buffer_half_float") ||
ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
ctxInfo.hasExtension("EXT_color_buffer_float");
} else if ((ctxInfo.hasExtension("GL_OES_texture_half_float") ||
ctxInfo.hasExtension("OES_texture_half_float")) &&
(ctxInfo.hasExtension("GL_OES_texture_half_float_linear") ||
ctxInfo.hasExtension("OES_texture_half_float_linear"))) {
rgba16FTextureSupport = true;
// We don't check for EXT_color_buffer_float as it's only defined for WebGL 2.
rgba16FRenderTargetSupport =
ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
ctxInfo.hasExtension("EXT_color_buffer_half_float");
}
}
if (rgba16FTextureSupport) {
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (rgba16FRenderTargetSupport) {
info.fFlags |= fpRenderFlags;
}
}
if (texStorageSupported && !formatWorkarounds.fDisableRGBA16FTexStorageForCrBug1008003) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA16F;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RGBA16F : GR_GL_RGBA;
}
if (rgba16FTextureSupport) {
uint32_t flags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
info.fColorTypeInfoCount = 3;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: RGBA16F, Surface: kRGBA_F16
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGBA_F16;
ctInfo.fFlags = flags;
this->setColorTypeFormat(GrColorType::kRGBA_F16, GrGLFormat::kRGBA16F);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGBA16F, Surface: kRGBA_F16, Data: kRGBA_F16
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_F16;
ioFormat.fExternalType = halfFloatType;
ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: RGBA16F, Surface: kRGBA_F16, Data: kRGBA_F32
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_F32;
ioFormat.fExternalType = GR_GL_FLOAT;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
// Format: RGBA16F, Surface: kRGBA_F16_Clamped
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGBA_F16_Clamped;
ctInfo.fFlags = flags;
this->setColorTypeFormat(GrColorType::kRGBA_F16_Clamped, GrGLFormat::kRGBA16F);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGBA16F, Surface: kRGBA_F16_Clamped, Data: kRGBA_F16_Clamped
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_F16_Clamped;
ioFormat.fExternalType = halfFloatType;
ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: RGBA16F, Surface: kRGBA_F16_Clamped, Data: kRGBA_F32
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_F32;
ioFormat.fExternalType = GR_GL_FLOAT;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
// Format: RGBA16F, Surface: kRGB_F16F16F16x
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGB_F16F16F16x;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
ctInfo.fWriteSwizzle = skgpu::Swizzle::RGB1();
this->setColorTypeFormat(GrColorType::kRGB_F16F16F16x, GrGLFormat::kRGBA16F);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGBA16F, Surface: kRGB_F16F16F16x, Data: kRGB_F16F16F16x
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGB_F16F16F16x;
ioFormat.fExternalType = halfFloatType;
ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: RGBA16F, Surface: kRGB_F16F16F16x, Data: kRGBA_F32
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_F32;
ioFormat.fExternalType = GR_GL_FLOAT;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: R16F
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kR16F);
info.fFormatType = FormatType::kFloat;
info.fInternalFormatForRenderbuffer = GR_GL_R16F;
info.fDefaultExternalFormat = GR_GL_RED;
info.fDefaultExternalType = halfFloatType;
info.fDefaultColorType = GrColorType::kR_F16;
bool r16FTextureSupport = false;
bool r16FRenderTargetSupport = false;
if (GR_IS_GR_GL(standard)) {
if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg")) {
r16FTextureSupport = true;
r16FRenderTargetSupport = true;
}
} else if (GR_IS_GR_GL_ES(standard)) {
// It seems possible that a combination of GL_EXT_texture_rg and
// GL_EXT_color_buffer_half_float might add this format to ES 2.0 but it is not entirely
// clear. The latter mentions interaction but that may only be for renderbuffers as
// neither adds the texture format explicitly.
// GL_OES_texture_format_half_float makes no reference to RED formats.
if (version >= GR_GL_VER(3, 0)) {
r16FTextureSupport = true;
r16FRenderTargetSupport = version >= GR_GL_VER(3, 2) ||
ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
}
} else if (GR_IS_GR_WEBGL(standard)) {
if (version >= GR_GL_VER(2, 0)) {
r16FTextureSupport = true;
r16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
ctxInfo.hasExtension("EXT_color_buffer_float");
}
}
if (r16FTextureSupport) {
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (r16FRenderTargetSupport) {
info.fFlags |= fpRenderFlags;
}
}
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_R16F;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_R16F : GR_GL_RED;
}
if (r16FTextureSupport) {
// Format: R16F, Surface: kAlpha_F16
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kAlpha_F16;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
this->setColorTypeFormat(GrColorType::kAlpha_F16, GrGLFormat::kR16F);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: R16F, Surface: kAlpha_F16, Data: kAlpha_F16
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kAlpha_F16;
ioFormat.fExternalType = halfFloatType;
ioFormat.fExternalTexImageFormat = GR_GL_RED;
ioFormat.fExternalReadFormat = GR_GL_RED;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: R16F, Surface: kAlpha_F16, Data: kAlpha_F32xxx
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kAlpha_F32xxx;
ioFormat.fExternalType = GR_GL_FLOAT;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: LUMINANCE16F
{
// NOTE: We disallow lum16f on ES devices if linear filtering modes are not
// supported. This is for simplicity, but a more granular approach is possible.
bool lum16FSupported = false;
bool lum16FSizedFormatSupported = false;
GrGLenum lumHalfFloatType = halfFloatType;
if (GR_IS_GR_GL(standard)) {
if (!fIsCoreProfile && ctxInfo.hasExtension("GL_ARB_texture_float")) {
lum16FSupported = true;
lum16FSizedFormatSupported = true;
}
} else if (GR_IS_GR_GL_ES(standard)) {
if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
ctxInfo.hasExtension("GL_OES_texture_half_float")) {
lum16FSupported = true;
// Even in ES 3.0+ LUMINANCE and GL_HALF_FLOAT are not listed as a valid
// combination. Thus we must use GL_HALF_FLOAT_OES provided by the extension
// GL_OES_texture_half_float. Note: these two types are not defined to be the same
// value.
lumHalfFloatType = GR_GL_HALF_FLOAT_OES;
// Even on ES3 this extension is required to define LUMINANCE16F.
lum16FSizedFormatSupported = ctxInfo.hasExtension("GL_EXT_texture_storage");
}
} // No WebGL support
if (formatWorkarounds.fDisableLuminance16F) {
lum16FSupported = false;
}
FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE16F);
info.fFormatType = FormatType::kFloat;
info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE16F;
info.fDefaultExternalFormat = GR_GL_LUMINANCE;
info.fDefaultExternalType = lumHalfFloatType;
info.fDefaultColorType = GrColorType::kGray_F16;
if (lum16FSupported) {
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (texStorageSupported && lum16FSizedFormatSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE16F;
} else if (texImageSupportsSizedInternalFormat && lum16FSizedFormatSupported) {
info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE16F;
} else {
info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE;
}
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: LUMINANCE16F, Surface: kAlpha_F16
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kAlpha_F16;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
ctInfo.fWriteSwizzle = skgpu::Swizzle("aaa0");
int idx = static_cast<int>(GrColorType::kAlpha_F16);
if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
this->setColorTypeFormat(GrColorType::kAlpha_F16, GrGLFormat::kLUMINANCE16F);
}
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: LUMINANCE16F, Surface: kAlpha_F16, Data: kAlpha_F16
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kAlpha_F16;
ioFormat.fExternalType = lumHalfFloatType;
ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE;
ioFormat.fExternalReadFormat = 0;
}
// Format: LUMINANCE16F, Surface: kAlpha_F16, Data: kRGBA_F32
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_F32;
ioFormat.fExternalType = GR_GL_FLOAT;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: RGBx8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBX8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_RGBX8;
info.fDefaultExternalFormat = GR_GL_RGB;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kRGB_888;
bool supportsSizedRGBX = false;
// The GL_ANGLE_rgbx_internal_format extension only adds the sized GL_RGBX8 type and does
// not have a way to create a texture of that format with texImage using an unsized type. So
// we require that we either have texture storage support or that tex image supports sized
// formats to say that this format is supported.
if (GR_IS_GR_GL_ES(standard) && ctxInfo.hasExtension("GL_ANGLE_rgbx_internal_format") &&
(texStorageSupported || texImageSupportsSizedInternalFormat)) {
supportsSizedRGBX = true;
}
if (supportsSizedRGBX) {
info.fInternalFormatForTexImageOrStorage = GR_GL_RGBX8;
info.fFlags = FormatInfo::kTexturable_Flag |
FormatInfo::kTransfers_Flag |
msaaRenderFlags;
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
}
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: RGBX8, Surface: kRGB_888x
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGB_888x;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kRGB_888x, GrGLFormat::kRGBX8);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGBX8, Surface: kRGB_888x, Data: kRGB_888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGB_888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_RGB;
ioFormat.fExternalReadFormat = 0;
}
// Format: RGBX8, Surface: kRGB_888x, Data: kRGB_888x
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGB_888x;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBX8;
}
}
}
}
// Format: RGB8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_RGB8;
info.fDefaultExternalFormat = GR_GL_RGB;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kRGB_888;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (GR_IS_GR_GL(standard)) {
// Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be
// a supported render buffer format. Since we usually use render buffers for MSAA on
// non-ES GL we don't support MSAA for GL_RGB8. On 4.2+ we could check using
// glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if
// this becomes an issue.
info.fFlags |= nonMSAARenderFlags;
} else if (GR_IS_GR_GL_ES(standard)) {
// 3.0 and the extension support this as a render buffer format.
if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
info.fFlags |= msaaRenderFlags;
}
} else if (GR_IS_GR_WEBGL(standard)) {
// WebGL seems to support RBG8
info.fFlags |= msaaRenderFlags;
}
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RGB8;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RGB8 : GR_GL_RGB;
}
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: RGB8, Surface: kRGB_888x
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGB_888x;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
int idx = static_cast<int>(GrColorType::kRGB_888x);
if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
this->setColorTypeFormat(GrColorType::kRGB_888x, GrGLFormat::kRGB8);
}
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGB8, Surface: kRGB_888x, Data: kRGB_888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGB_888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_RGB;
ioFormat.fExternalReadFormat = 0;
}
// Format: RGB8, Surface: kRGB_888x, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
// Format: RG8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_RG8;
info.fDefaultExternalFormat = GR_GL_RG;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kRG_88;
bool rg8Support = false;
if (GR_IS_GR_GL(standard)) {
rg8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
} else if (GR_IS_GR_GL_ES(standard)) {
rg8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
} else if (GR_IS_GR_WEBGL(standard)) {
rg8Support = version >= GR_GL_VER(2, 0);
}
if (rg8Support) {
info.fFlags |= FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RG8;
}
}
if (!(info.fFlags & FormatInfo::kUseTexStorage_Flag)) {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RG8 : GR_GL_RG;
}
if (rg8Support) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: RG8, Surface: kRG_88
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRG_88;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kRG_88, GrGLFormat::kRG8);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RG8, Surface: kRG_88, Data: kRG_88
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRG_88;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = GR_GL_RG;
ioFormat.fExternalReadFormat = 0;
if (GR_IS_GR_GL(standard) && !formatWorkarounds.fDisallowDirectRG8ReadPixels) {
ioFormat.fExternalReadFormat = GR_GL_RG;
}
}
// Format: RG8, Surface: kRG_88, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: RGB10_A2
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB10_A2);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_RGB10_A2;
info.fDefaultExternalFormat = GR_GL_RGBA;
info.fDefaultExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
info.fDefaultColorType = GrColorType::kRGBA_1010102;
if (GR_IS_GR_GL(standard) ||
(GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3, 0))) {
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
} else if (GR_IS_GR_GL_ES(standard) &&
ctxInfo.hasExtension("GL_EXT_texture_type_2_10_10_10_REV")) {
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
} // No WebGL support
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RGB10_A2;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RGB10_A2 : GR_GL_RGBA;
}
if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
bool supportsBGRAColorType = GR_IS_GR_GL(standard) &&
(version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra"));
info.fColorTypeInfoCount = supportsBGRAColorType ? 3 : 2;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: RGB10_A2, Surface: kRGBA_1010102
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGBA_1010102;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kRGBA_1010102, GrGLFormat::kRGB10_A2);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGB10_A2, Surface: kRGBA_1010102, Data: kRGBA_1010102
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_1010102;
ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: RGB10_A2, Surface: kRGBA_1010102, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
//------------------------------------------------------------------
// Format: RGB10_A2, Surface: kBGRA_1010102
if (supportsBGRAColorType) {
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kBGRA_1010102;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kBGRA_1010102, GrGLFormat::kRGB10_A2);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGB10_A2, Surface: kBGRA_1010102, Data: kBGRA_1010102
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kBGRA_1010102;
ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
ioFormat.fExternalReadFormat =
formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: RGB10_A2, Surface: kBGRA_1010102, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
// Format: RGB10_A2, Surface: kRGB_101010x
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGB_101010x;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
ctInfo.fWriteSwizzle = skgpu::Swizzle::RGB1();
this->setColorTypeFormat(GrColorType::kRGB_101010x, GrGLFormat::kRGB10_A2);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGB10_A2, Surface: kRGB_101010x, Data: kRGB_101010x
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGB_101010x;
ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: RGB10_A2, Surface: kRGB_101010x, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: RGBA4
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA4);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_RGBA4;
info.fDefaultExternalFormat = GR_GL_RGBA;
info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
info.fDefaultColorType = GrColorType::kABGR_4444;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (GR_IS_GR_GL(standard)) {
if (version >= GR_GL_VER(4, 2)) {
info.fFlags |= msaaRenderFlags;
}
} else if (GR_IS_GR_GL_ES(standard)) {
info.fFlags |= msaaRenderFlags;
} else if (GR_IS_GR_WEBGL(standard)) {
info.fFlags |= msaaRenderFlags;
}
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA4;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RGBA4 : GR_GL_RGBA;
}
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: RGBA4, Surface: kABGR_4444
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kABGR_4444;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kABGR_4444, GrGLFormat::kRGBA4);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: RGBA4, Surface: kABGR_4444, Data: kABGR_4444
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kABGR_4444;
ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: RGBA4, Surface: kABGR_4444, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
// Format: SRGB8_ALPHA8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kSRGB8_ALPHA8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_SRGB8_ALPHA8;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kRGBA_8888_SRGB;
// We may modify the default external format below.
info.fDefaultExternalFormat = GR_GL_RGBA;
bool srgb8Alpha8TexStorageSupported = texStorageSupported;
bool srgb8Alpha8TextureSupport = false;
bool srgb8Alpha8RenderTargetSupport = false;
if (GR_IS_GR_GL(standard)) {
if (version >= GR_GL_VER(3, 0)) {
srgb8Alpha8TextureSupport = true;
srgb8Alpha8RenderTargetSupport = true;
} else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
srgb8Alpha8TextureSupport = true;
if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
srgb8Alpha8RenderTargetSupport = true;
}
}
} else if (GR_IS_GR_GL_ES(standard)) {
if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_sRGB")) {
srgb8Alpha8TextureSupport = true;
srgb8Alpha8RenderTargetSupport = true;
}
if (version < GR_GL_VER(3, 0)) {
// ES 2.0 requires that the external format matches the internal format.
info.fDefaultExternalFormat = GR_GL_SRGB_ALPHA;
// There is no defined interaction between GL_EXT_sRGB and GL_EXT_texture_storage.
srgb8Alpha8TexStorageSupported = false;
}
} else if (GR_IS_GR_WEBGL(standard)) {
// sRGB extension should be on most WebGL 1.0 contexts, although sometimes under 2
// names.
if (version >= GR_GL_VER(2, 0) || ctxInfo.hasExtension("GL_EXT_sRGB") ||
ctxInfo.hasExtension("EXT_sRGB")) {
srgb8Alpha8TextureSupport = true;
srgb8Alpha8RenderTargetSupport = true;
}
if (version < GR_GL_VER(2, 0)) {
// WebGL 1.0 requires that the external format matches the internal format.
info.fDefaultExternalFormat = GR_GL_SRGB_ALPHA;
// There is no extension to WebGL 1 that adds glTexStorage.
SkASSERT(!srgb8Alpha8TexStorageSupported);
}
}
if (srgb8Alpha8TextureSupport) {
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (srgb8Alpha8RenderTargetSupport) {
info.fFlags |= formatWorkarounds.fDisableSRGBRenderWithMSAAForMacAMD
? nonMSAARenderFlags
: msaaRenderFlags;
}
}
if (srgb8Alpha8TexStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_SRGB8_ALPHA8;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_SRGB8_ALPHA8 : GR_GL_SRGB_ALPHA;
}
if (srgb8Alpha8TextureSupport) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: SRGB8_ALPHA8, Surface: kRGBA_8888_SRGB
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGBA_8888_SRGB;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kRGBA_8888_SRGB, GrGLFormat::kSRGB8_ALPHA8);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 1;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: SRGB8_ALPHA8, Surface: kRGBA_8888_SRGB, Data: kRGBA_8888_SRGB
{
// GL does not do srgb<->rgb conversions when transferring between cpu and gpu.
// Thus, the external format is GL_RGBA. See below for note about ES2.0 and
// glTex[Sub]Image.
GrGLenum texImageExternalFormat = GR_GL_RGBA;
// OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the
// <format> param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and
// <format> params to match. Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the
// <format> param. On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the
// <format> param to glTexImage.
if (GR_IS_GR_GL_ES(standard) && version == GR_GL_VER(2,0)) {
texImageExternalFormat = GR_GL_SRGB_ALPHA;
}
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888_SRGB;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = texImageExternalFormat;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: COMPRESSED_RGB8_BC1
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGB8_BC1);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
if (ctxInfo.hasExtension("GL_EXT_texture_compression_s3tc")) {
info.fFlags = FormatInfo::kTexturable_Flag;
}
} else if (GR_IS_GR_WEBGL(standard)) {
if (ctxInfo.hasExtension("WEBGL_compressed_texture_s3tc")) {
info.fFlags = FormatInfo::kTexturable_Flag;
}
}
// There are no support GrColorTypes for this format
}
// Format: COMPRESSED_RGBA8_BC1
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGBA8_BC1);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
if (ctxInfo.hasExtension("GL_EXT_texture_compression_s3tc")) {
info.fFlags = FormatInfo::kTexturable_Flag;
}
} else if (GR_IS_GR_WEBGL(standard)) {
if (ctxInfo.hasExtension("WEBGL_compressed_texture_s3tc")) {
info.fFlags = FormatInfo::kTexturable_Flag;
}
}
// There are no support GrColorTypes for this format
}
// Format: COMPRESSED_RGB8_ETC2
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGB8_ETC2);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGB8_ETC2;
if (!formatWorkarounds.fDisallowETC2Compression) {
if (GR_IS_GR_GL(standard)) {
if (version >= GR_GL_VER(4, 3) ||
ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
info.fFlags = FormatInfo::kTexturable_Flag;
}
} else if (GR_IS_GR_GL_ES(standard)) {
if (version >= GR_GL_VER(3, 0) ||
ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture")) {
info.fFlags = FormatInfo::kTexturable_Flag;
}
} else if (GR_IS_GR_WEBGL(standard)) {
if (ctxInfo.hasExtension("WEBGL_compressed_texture_etc")) {
info.fFlags = FormatInfo::kTexturable_Flag;
}
}
}
// There are no support GrColorTypes for this format
}
// Format: COMPRESSED_ETC1_RGB8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_ETC1_RGB8);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_ETC1_RGB8;
if (GR_IS_GR_GL_ES(standard)) {
if (ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture")) {
info.fFlags = FormatInfo::kTexturable_Flag;
}
} else if (GR_IS_GR_WEBGL(standard)) {
if (ctxInfo.hasExtension("WEBGL_compressed_texture_etc1")) {
info.fFlags = FormatInfo::kTexturable_Flag;
}
}
// No GL support
// There are no support GrColorTypes for this format
}
// Format: R16
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kR16);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_R16;
info.fDefaultExternalFormat = GR_GL_RED;
info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
info.fDefaultColorType = GrColorType::kR_16;
bool r16Supported = false;
if (!formatWorkarounds.fDisallowTextureUnorm16) {
if (GR_IS_GR_GL(standard)) {
r16Supported = version >= GR_GL_VER(3, 0) ||
ctxInfo.hasExtension("GL_ARB_texture_rg");
} else if (GR_IS_GR_GL_ES(standard)) {
r16Supported = ctxInfo.hasExtension("GL_EXT_texture_norm16");
} // No WebGL support
}
if (r16Supported) {
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
if (!formatWorkarounds.fDisallowUnorm16Transfers) {
info.fFlags |= FormatInfo::kTransfers_Flag;
}
}
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_R16;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_R16 : GR_GL_RED;
}
if (r16Supported) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: R16, Surface: kAlpha_16
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kAlpha_16;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
this->setColorTypeFormat(GrColorType::kAlpha_16, GrGLFormat::kR16);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: R16, Surface: kAlpha_16, Data: kAlpha_16
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kAlpha_16;
ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
ioFormat.fExternalTexImageFormat = GR_GL_RED;
ioFormat.fExternalReadFormat = GR_GL_RED;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: R16, Surface: kAlpha_16, Data: kAlpha_8xxx
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kAlpha_8xxx;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: RG16
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG16);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RG16 : GR_GL_RG;
info.fInternalFormatForRenderbuffer = GR_GL_RG16;
info.fDefaultExternalFormat = GR_GL_RG;
info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
info.fDefaultColorType = GrColorType::kRG_1616;
bool rg16Supported = false;
if (!formatWorkarounds.fDisallowTextureUnorm16) {
if (GR_IS_GR_GL(standard)) {
rg16Supported = version >= GR_GL_VER(3, 0) ||
ctxInfo.hasExtension("GL_ARB_texture_rg");
} else if (GR_IS_GR_GL_ES(standard)) {
rg16Supported = ctxInfo.hasExtension("GL_EXT_texture_norm16");
} // No WebGL support
}
if (rg16Supported) {
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
if (!formatWorkarounds.fDisallowUnorm16Transfers) {
info.fFlags |= FormatInfo::kTransfers_Flag;
}
}
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RG16;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RG16 : GR_GL_RG;
}
if (rg16Supported) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: GR_GL_RG16, Surface: kRG_1616
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRG_1616;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kRG_1616, GrGLFormat::kRG16);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: GR_GL_RG16, Surface: kRG_1616, Data: kRG_1616
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRG_1616;
ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
ioFormat.fExternalTexImageFormat = GR_GL_RG;
ioFormat.fExternalReadFormat = GR_GL_RG;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: GR_GL_RG16, Surface: kRG_1616, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format: RGBA16
{
bool rgba16Support = false;
if (!formatWorkarounds.fDisallowTextureUnorm16) {
if (GR_IS_GR_GL(standard)) {
rgba16Support = version >= GR_GL_VER(3, 0);
} else if (GR_IS_GR_GL_ES(standard)) {
rgba16Support = ctxInfo.hasExtension("GL_EXT_texture_norm16");
} // No WebGL support
}
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA16);
info.fFormatType = FormatType::kNormalizedFixedPoint;
info.fInternalFormatForRenderbuffer = GR_GL_RGBA16;
info.fDefaultExternalFormat = GR_GL_RGBA;
info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
info.fDefaultColorType = GrColorType::kRGBA_16161616;
if (rgba16Support) {
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
if (!formatWorkarounds.fDisallowUnorm16Transfers) {
info.fFlags |= FormatInfo::kTransfers_Flag;
}
}
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA16;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RGBA16 : GR_GL_RGBA;
}
if (rgba16Support) {
// Format: GR_GL_RGBA16, Surface: kRGBA_16161616
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRGBA_16161616;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kRGBA_16161616, GrGLFormat::kRGBA16);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: GR_GL_RGBA16, Surface: kRGBA_16161616, Data: kRGBA_16161616
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_16161616;
ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: GR_GL_RGBA16, Surface: kRGBA_16161616, Data: kRGBA_8888
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_8888;
ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
// Format:RG16F
{
bool rg16FTextureSupport = false;
bool rg16FRenderTargetSupport = false;
if (GR_IS_GR_GL(standard)) {
if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
rg16FTextureSupport = true;
rg16FRenderTargetSupport = true;
}
} else if (GR_IS_GR_GL_ES(standard)) {
// It seems possible that a combination of GL_EXT_texture_rg and
// GL_EXT_color_buffer_half_float might add this format to ES 2.0 but it is not entirely
// clear. The latter mentions interaction but that may only be for renderbuffers as
// neither adds the texture format explicitly.
// GL_OES_texture_format_half_float makes no reference to RG formats.
if (version >= GR_GL_VER(3, 0)) {
rg16FTextureSupport = true;
rg16FRenderTargetSupport = version >= GR_GL_VER(3, 2) ||
ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
}
} else if (GR_IS_GR_WEBGL(standard)) {
if (version >= GR_GL_VER(2, 0)) {
rg16FTextureSupport = true;
rg16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
ctxInfo.hasExtension("EXT_color_buffer_half_float") ||
ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
ctxInfo.hasExtension("EXT_color_buffer_float");
}
}
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG16F);
info.fFormatType = FormatType::kFloat;
info.fInternalFormatForRenderbuffer = GR_GL_RG16F;
info.fDefaultExternalFormat = GR_GL_RG;
info.fDefaultExternalType = halfFloatType;
info.fDefaultColorType = GrColorType::kRG_F16;
if (rg16FTextureSupport) {
info.fFlags |= FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (rg16FRenderTargetSupport) {
info.fFlags |= fpRenderFlags;
}
}
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RG16F;
} else {
info.fInternalFormatForTexImageOrStorage =
texImageSupportsSizedInternalFormat ? GR_GL_RG16F : GR_GL_RG;
}
if (rg16FTextureSupport) {
info.fColorTypeInfoCount = 1;
info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
int ctIdx = 0;
// Format: GR_GL_RG16F, Surface: kRG_F16
{
auto& ctInfo = info.fColorTypeInfos[ctIdx++];
ctInfo.fColorType = GrColorType::kRG_F16;
ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
this->setColorTypeFormat(GrColorType::kRG_F16, GrGLFormat::kRG16F);
// External IO ColorTypes:
ctInfo.fExternalIOFormatCount = 2;
ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
ctInfo.fExternalIOFormatCount);
int ioIdx = 0;
// Format: GR_GL_RG16F, Surface: kRG_F16, Data: kRG_F16
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRG_F16;
ioFormat.fExternalType = halfFloatType;
ioFormat.fExternalTexImageFormat = GR_GL_RG;
ioFormat.fExternalReadFormat = GR_GL_RG;
// Not guaranteed by ES/WebGL.
ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
}
// Format: GR_GL_RG16F, Surface: kRG_F16, Data: kRGBA_F32
{
auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
ioFormat.fColorType = GrColorType::kRGBA_F32;
ioFormat.fExternalType = GR_GL_FLOAT;
ioFormat.fExternalTexImageFormat = 0;
ioFormat.fExternalReadFormat = GR_GL_RGBA;
}
}
}
}
this->setupSampleCounts(ctxInfo, gli);
#ifdef SK_DEBUG
for (int i = 0; i < kGrGLColorFormatCount; ++i) {
if (GrGLFormat::kUnknown == static_cast<GrGLFormat>(i)) {
continue;
}
const auto& formatInfo = fFormatTable[i];
// Make sure we didn't set fbo attachable with msaa and not fbo attachable.
SkASSERT(!((formatInfo.fFlags & FormatInfo::kFBOColorAttachmentWithMSAA_Flag) &&
!(formatInfo.fFlags & FormatInfo::kFBOColorAttachment_Flag)));
// Make sure we set all the formats' FormatType
SkASSERT(formatInfo.fFormatType != FormatType::kUnknown);
// Make sure if we added a ColorTypeInfo we filled it out
for (int j = 0; j < formatInfo.fColorTypeInfoCount; ++j) {
const auto& ctInfo = formatInfo.fColorTypeInfos[j];
SkASSERT(ctInfo.fColorType != GrColorType::kUnknown);
// Seems silly to add a color type if we don't support any flags on it.
SkASSERT(ctInfo.fFlags);
// Make sure if we added any ExternalIOFormats we filled it out
for (int k = 0; k < ctInfo.fExternalIOFormatCount; ++k) {
const auto& ioInfo = ctInfo.fExternalIOFormats[k];
SkASSERT(ioInfo.fColorType != GrColorType::kUnknown);
}
}
}
#endif
}