gecko-dev/dom/canvas/WebGLFormats.cpp

1128 строки
52 KiB
C++
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLFormats.h"
#include "GLDefs.h"
#include "mozilla/StaticMutex.h"
namespace mozilla {
namespace webgl {
//////////////////////////////////////////////////////////////////////////////////////////
std::map<EffectiveFormat, const CompressedFormatInfo> gCompressedFormatInfoMap;
std::map<EffectiveFormat, const FormatInfo> gFormatInfoMap;
std::map<UnpackTuple, const FormatInfo*> gUnpackTupleMap;
std::map<GLenum, const FormatInfo*> gSizedFormatMap;
static const CompressedFormatInfo*
GetCompressedFormatInfo(EffectiveFormat format)
{
MOZ_ASSERT(!gCompressedFormatInfoMap.empty());
auto itr = gCompressedFormatInfoMap.find(format);
if (itr == gCompressedFormatInfoMap.end())
return nullptr;
return &(itr->second);
}
static const FormatInfo*
GetFormatInfo_NoLock(EffectiveFormat format)
{
MOZ_ASSERT(!gFormatInfoMap.empty());
auto itr = gFormatInfoMap.find(format);
if (itr == gFormatInfoMap.end())
return nullptr;
return &(itr->second);
}
template<typename K, typename V, typename K2, typename V2>
static void
AlwaysInsert(std::map<K,V>& dest, const K2& key, const V2& val)
{
auto res = dest.insert({ key, val });
bool didInsert = res.second;
MOZ_ALWAYS_TRUE(didInsert);
}
//////////////////////////////////////////////////////////////////////////////////////////
static void
AddCompressedFormatInfo(EffectiveFormat format, uint16_t bitsPerBlock, uint8_t blockWidth,
uint8_t blockHeight, bool requirePOT,
SubImageUpdateBehavior subImageUpdateBehavior)
{
MOZ_ASSERT(bitsPerBlock % 8 == 0);
uint16_t bytesPerBlock = bitsPerBlock / 8; // The specs always state these in bits,
// but it's only ever useful to us as
// bytes.
MOZ_ASSERT(bytesPerBlock <= 255);
const CompressedFormatInfo info = { format, uint8_t(bytesPerBlock), blockWidth,
blockHeight, requirePOT, subImageUpdateBehavior };
AlwaysInsert(gCompressedFormatInfoMap, format, info);
}
static void
InitCompressedFormatInfo()
{
// GLES 3.0.4, p147, table 3.19
// GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_ETC2 , 64, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ETC2 , 64, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA8_ETC2_EAC , 128, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC , 128, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_R11_EAC , 64, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RG11_EAC , 128, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_R11_EAC , 64, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RG11_EAC , 128, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 , 64, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 64, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
// AMD_compressed_ATC_texture
AddCompressedFormatInfo(EffectiveFormat::ATC_RGB_AMD , 64, 4, 4, false, SubImageUpdateBehavior::Forbidden);
AddCompressedFormatInfo(EffectiveFormat::ATC_RGBA_EXPLICIT_ALPHA_AMD , 128, 4, 4, false, SubImageUpdateBehavior::Forbidden);
AddCompressedFormatInfo(EffectiveFormat::ATC_RGBA_INTERPOLATED_ALPHA_AMD, 128, 4, 4, false, SubImageUpdateBehavior::Forbidden);
// EXT_texture_compression_s3tc
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_S3TC_DXT1 , 64, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT1, 64, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT3, 128, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT5, 128, 4, 4, false, SubImageUpdateBehavior::BlockAligned);
// IMG_texture_compression_pvrtc
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_PVRTC_4BPPV1 , 256, 8, 8, true, SubImageUpdateBehavior::FullOnly);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_PVRTC_4BPPV1, 256, 8, 8, true, SubImageUpdateBehavior::FullOnly);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_PVRTC_2BPPV1 , 256, 16, 8, true, SubImageUpdateBehavior::FullOnly);
AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_PVRTC_2BPPV1, 256, 16, 8, true, SubImageUpdateBehavior::FullOnly);
// OES_compressed_ETC1_RGB8_texture
AddCompressedFormatInfo(EffectiveFormat::ETC1_RGB8, 64, 4, 4, false, SubImageUpdateBehavior::Forbidden);
}
//////////////////////////////////////////////////////////////////////////////////////////
static void
AddFormatInfo(EffectiveFormat format, const char* name, uint8_t bytesPerPixel,
UnsizedFormat unsizedFormat, ComponentType colorComponentType)
{
bool hasColor = false;
bool hasAlpha = false;
bool hasDepth = false;
bool hasStencil = false;
switch (unsizedFormat) {
case UnsizedFormat::L:
case UnsizedFormat::R:
case UnsizedFormat::RG:
case UnsizedFormat::RGB:
hasColor = true;
break;
case UnsizedFormat::A:
hasAlpha = true;
break;
case UnsizedFormat::LA:
case UnsizedFormat::RGBA:
hasColor = true;
hasAlpha = true;
break;
case UnsizedFormat::D:
hasDepth = true;
break;
case UnsizedFormat::S:
hasStencil = true;
break;
case UnsizedFormat::DS:
hasDepth = true;
hasStencil = true;
break;
default:
MOZ_CRASH("Missing UnsizedFormat case.");
}
const CompressedFormatInfo* compressedFormatInfo = GetCompressedFormatInfo(format);
MOZ_ASSERT(!bytesPerPixel == bool(compressedFormatInfo));
const FormatInfo info = { format, name, unsizedFormat, colorComponentType,
bytesPerPixel, hasColor, hasAlpha, hasDepth, hasStencil,
compressedFormatInfo };
AlwaysInsert(gFormatInfoMap, format, info);
}
static void
InitFormatInfoMap()
{
#ifdef FOO
#error FOO is already defined!
#endif
#define FOO(x) EffectiveFormat::x, #x
// GLES 3.0.4, p130-132, table 3.13
AddFormatInfo(FOO(R8 ), 1, UnsizedFormat::R , ComponentType::NormUInt );
AddFormatInfo(FOO(R8_SNORM ), 1, UnsizedFormat::R , ComponentType::NormInt );
AddFormatInfo(FOO(RG8 ), 2, UnsizedFormat::RG , ComponentType::NormUInt );
AddFormatInfo(FOO(RG8_SNORM ), 2, UnsizedFormat::RG , ComponentType::NormInt );
AddFormatInfo(FOO(RGB8 ), 3, UnsizedFormat::RGB , ComponentType::NormUInt );
AddFormatInfo(FOO(RGB8_SNORM ), 3, UnsizedFormat::RGB , ComponentType::NormInt );
AddFormatInfo(FOO(RGB565 ), 2, UnsizedFormat::RGB , ComponentType::NormUInt );
AddFormatInfo(FOO(RGBA4 ), 2, UnsizedFormat::RGBA, ComponentType::NormUInt );
AddFormatInfo(FOO(RGB5_A1 ), 2, UnsizedFormat::RGBA, ComponentType::NormUInt );
AddFormatInfo(FOO(RGBA8 ), 4, UnsizedFormat::RGBA, ComponentType::NormUInt );
AddFormatInfo(FOO(RGBA8_SNORM ), 4, UnsizedFormat::RGBA, ComponentType::NormInt );
AddFormatInfo(FOO(RGB10_A2 ), 4, UnsizedFormat::RGBA, ComponentType::NormUInt );
AddFormatInfo(FOO(RGB10_A2UI ), 4, UnsizedFormat::RGBA, ComponentType::UInt );
AddFormatInfo(FOO(SRGB8 ), 3, UnsizedFormat::RGB , ComponentType::NormUIntSRGB);
AddFormatInfo(FOO(SRGB8_ALPHA8 ), 4, UnsizedFormat::RGBA, ComponentType::NormUIntSRGB);
AddFormatInfo(FOO(R16F ), 2, UnsizedFormat::R , ComponentType::Float );
AddFormatInfo(FOO(RG16F ), 4, UnsizedFormat::RG , ComponentType::Float );
AddFormatInfo(FOO(RGB16F ), 6, UnsizedFormat::RGB , ComponentType::Float );
AddFormatInfo(FOO(RGBA16F ), 8, UnsizedFormat::RGBA, ComponentType::Float );
AddFormatInfo(FOO(R32F ), 4, UnsizedFormat::R , ComponentType::Float );
AddFormatInfo(FOO(RG32F ), 8, UnsizedFormat::RG , ComponentType::Float );
AddFormatInfo(FOO(RGB32F ), 12, UnsizedFormat::RGB , ComponentType::Float );
AddFormatInfo(FOO(RGBA32F ), 16, UnsizedFormat::RGBA, ComponentType::Float );
AddFormatInfo(FOO(R11F_G11F_B10F), 4, UnsizedFormat::RGB , ComponentType::Float );
AddFormatInfo(FOO(RGB9_E5 ), 4, UnsizedFormat::RGB , ComponentType::SharedExp );
AddFormatInfo(FOO(R8I ), 1, UnsizedFormat::R , ComponentType::Int );
AddFormatInfo(FOO(R8UI ), 1, UnsizedFormat::R , ComponentType::UInt );
AddFormatInfo(FOO(R16I ), 2, UnsizedFormat::R , ComponentType::Int );
AddFormatInfo(FOO(R16UI ), 2, UnsizedFormat::R , ComponentType::UInt );
AddFormatInfo(FOO(R32I ), 4, UnsizedFormat::R , ComponentType::Int );
AddFormatInfo(FOO(R32UI ), 4, UnsizedFormat::R , ComponentType::UInt );
AddFormatInfo(FOO(RG8I ), 2, UnsizedFormat::RG , ComponentType::Int );
AddFormatInfo(FOO(RG8UI ), 2, UnsizedFormat::RG , ComponentType::UInt );
AddFormatInfo(FOO(RG16I ), 4, UnsizedFormat::RG , ComponentType::Int );
AddFormatInfo(FOO(RG16UI ), 4, UnsizedFormat::RG , ComponentType::UInt );
AddFormatInfo(FOO(RG32I ), 8, UnsizedFormat::RG , ComponentType::Int );
AddFormatInfo(FOO(RG32UI ), 8, UnsizedFormat::RG , ComponentType::UInt );
AddFormatInfo(FOO(RGB8I ), 3, UnsizedFormat::RGB , ComponentType::Int );
AddFormatInfo(FOO(RGB8UI ), 3, UnsizedFormat::RGB , ComponentType::UInt );
AddFormatInfo(FOO(RGB16I ), 6, UnsizedFormat::RGB , ComponentType::Int );
AddFormatInfo(FOO(RGB16UI ), 6, UnsizedFormat::RGB , ComponentType::UInt );
AddFormatInfo(FOO(RGB32I ), 12, UnsizedFormat::RGB , ComponentType::Int );
AddFormatInfo(FOO(RGB32UI ), 12, UnsizedFormat::RGB , ComponentType::UInt );
AddFormatInfo(FOO(RGBA8I ), 4, UnsizedFormat::RGBA, ComponentType::Int );
AddFormatInfo(FOO(RGBA8UI ), 4, UnsizedFormat::RGBA, ComponentType::UInt );
AddFormatInfo(FOO(RGBA16I ), 8, UnsizedFormat::RGBA, ComponentType::Int );
AddFormatInfo(FOO(RGBA16UI ), 8, UnsizedFormat::RGBA, ComponentType::UInt );
AddFormatInfo(FOO(RGBA32I ), 16, UnsizedFormat::RGBA, ComponentType::Int );
AddFormatInfo(FOO(RGBA32UI ), 16, UnsizedFormat::RGBA, ComponentType::UInt );
// GLES 3.0.4, p133, table 3.14
AddFormatInfo(FOO(DEPTH_COMPONENT16 ), 2, UnsizedFormat::D , ComponentType::None);
AddFormatInfo(FOO(DEPTH_COMPONENT24 ), 3, UnsizedFormat::D , ComponentType::None);
AddFormatInfo(FOO(DEPTH_COMPONENT32F), 4, UnsizedFormat::D , ComponentType::None);
AddFormatInfo(FOO(DEPTH24_STENCIL8 ), 4, UnsizedFormat::DS, ComponentType::None);
AddFormatInfo(FOO(DEPTH32F_STENCIL8 ), 5, UnsizedFormat::DS, ComponentType::None);
// GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
AddFormatInfo(FOO(STENCIL_INDEX8), 1, UnsizedFormat::S, ComponentType::None);
// GLES 3.0.4, p128, table 3.12.
AddFormatInfo(FOO(Luminance8Alpha8), 2, UnsizedFormat::LA, ComponentType::NormUInt);
AddFormatInfo(FOO(Luminance8 ), 1, UnsizedFormat::L , ComponentType::NormUInt);
AddFormatInfo(FOO(Alpha8 ), 1, UnsizedFormat::A , ComponentType::None );
// GLES 3.0.4, p147, table 3.19
// GLES 3.0.4 p286+ $C.1 "ETC Compressed Texture Image Formats"
AddFormatInfo(FOO(COMPRESSED_RGB8_ETC2 ), 0, UnsizedFormat::RGB , ComponentType::NormUInt );
AddFormatInfo(FOO(COMPRESSED_SRGB8_ETC2 ), 0, UnsizedFormat::RGB , ComponentType::NormUIntSRGB);
AddFormatInfo(FOO(COMPRESSED_RGBA8_ETC2_EAC ), 0, UnsizedFormat::RGBA, ComponentType::NormUInt );
AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC ), 0, UnsizedFormat::RGBA, ComponentType::NormUIntSRGB);
AddFormatInfo(FOO(COMPRESSED_R11_EAC ), 0, UnsizedFormat::R , ComponentType::NormUInt );
AddFormatInfo(FOO(COMPRESSED_RG11_EAC ), 0, UnsizedFormat::RG , ComponentType::NormUInt );
AddFormatInfo(FOO(COMPRESSED_SIGNED_R11_EAC ), 0, UnsizedFormat::R , ComponentType::NormInt );
AddFormatInfo(FOO(COMPRESSED_SIGNED_RG11_EAC ), 0, UnsizedFormat::RG , ComponentType::NormInt );
AddFormatInfo(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 ), 0, UnsizedFormat::RGBA, ComponentType::NormUInt );
AddFormatInfo(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2), 0, UnsizedFormat::RGBA, ComponentType::NormUIntSRGB);
// AMD_compressed_ATC_texture
AddFormatInfo(FOO(ATC_RGB_AMD ), 0, UnsizedFormat::RGB , ComponentType::NormUInt);
AddFormatInfo(FOO(ATC_RGBA_EXPLICIT_ALPHA_AMD ), 0, UnsizedFormat::RGBA, ComponentType::NormUInt);
AddFormatInfo(FOO(ATC_RGBA_INTERPOLATED_ALPHA_AMD), 0, UnsizedFormat::RGBA, ComponentType::NormUInt);
// EXT_texture_compression_s3tc
AddFormatInfo(FOO(COMPRESSED_RGB_S3TC_DXT1 ), 0, UnsizedFormat::RGB , ComponentType::NormUInt);
AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT1), 0, UnsizedFormat::RGBA, ComponentType::NormUInt);
AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT3), 0, UnsizedFormat::RGBA, ComponentType::NormUInt);
AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT5), 0, UnsizedFormat::RGBA, ComponentType::NormUInt);
// IMG_texture_compression_pvrtc
AddFormatInfo(FOO(COMPRESSED_RGB_PVRTC_4BPPV1 ), 0, UnsizedFormat::RGB , ComponentType::NormUInt);
AddFormatInfo(FOO(COMPRESSED_RGBA_PVRTC_4BPPV1), 0, UnsizedFormat::RGBA, ComponentType::NormUInt);
AddFormatInfo(FOO(COMPRESSED_RGB_PVRTC_2BPPV1 ), 0, UnsizedFormat::RGB , ComponentType::NormUInt);
AddFormatInfo(FOO(COMPRESSED_RGBA_PVRTC_2BPPV1), 0, UnsizedFormat::RGBA, ComponentType::NormUInt);
// OES_compressed_ETC1_RGB8_texture
AddFormatInfo(FOO(ETC1_RGB8), 0, UnsizedFormat::RGB, ComponentType::NormUInt);
// OES_texture_float
AddFormatInfo(FOO(Luminance32FAlpha32F), 2, UnsizedFormat::LA, ComponentType::Float);
AddFormatInfo(FOO(Luminance32F ), 1, UnsizedFormat::L , ComponentType::Float);
AddFormatInfo(FOO(Alpha32F ), 1, UnsizedFormat::A , ComponentType::Float);
// OES_texture_half_float
AddFormatInfo(FOO(Luminance16FAlpha16F), 2, UnsizedFormat::LA, ComponentType::Float);
AddFormatInfo(FOO(Luminance16F ), 1, UnsizedFormat::L , ComponentType::Float);
AddFormatInfo(FOO(Alpha16F ), 1, UnsizedFormat::A , ComponentType::Float);
#undef FOO
}
//////////////////////////////////////////////////////////////////////////////////////////
static void
AddUnpackTuple(GLenum unpackFormat, GLenum unpackType, EffectiveFormat effectiveFormat)
{
const UnpackTuple unpack = { unpackFormat, unpackType };
const FormatInfo* info = GetFormatInfo_NoLock(effectiveFormat);
MOZ_ASSERT(info);
AlwaysInsert(gUnpackTupleMap, unpack, info);
}
static void
InitUnpackTupleMap()
{
AddUnpackTuple(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGBA8 );
AddUnpackTuple(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4, EffectiveFormat::RGBA4 );
AddUnpackTuple(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1, EffectiveFormat::RGB5_A1);
AddUnpackTuple(LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGB8 );
AddUnpackTuple(LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_SHORT_5_6_5 , EffectiveFormat::RGB565 );
AddUnpackTuple(LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8Alpha8);
AddUnpackTuple(LOCAL_GL_LUMINANCE , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8 );
AddUnpackTuple(LOCAL_GL_ALPHA , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Alpha8 );
AddUnpackTuple(LOCAL_GL_RGB , LOCAL_GL_FLOAT, EffectiveFormat::RGB32F );
AddUnpackTuple(LOCAL_GL_RGBA , LOCAL_GL_FLOAT, EffectiveFormat::RGBA32F);
AddUnpackTuple(LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_FLOAT, EffectiveFormat::Luminance32FAlpha32F);
AddUnpackTuple(LOCAL_GL_LUMINANCE , LOCAL_GL_FLOAT, EffectiveFormat::Luminance32F);
AddUnpackTuple(LOCAL_GL_ALPHA , LOCAL_GL_FLOAT, EffectiveFormat::Alpha32F);
AddUnpackTuple(LOCAL_GL_RGB , LOCAL_GL_HALF_FLOAT, EffectiveFormat::RGB16F );
AddUnpackTuple(LOCAL_GL_RGBA , LOCAL_GL_HALF_FLOAT, EffectiveFormat::RGBA16F);
AddUnpackTuple(LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_HALF_FLOAT, EffectiveFormat::Luminance16FAlpha16F);
AddUnpackTuple(LOCAL_GL_LUMINANCE , LOCAL_GL_HALF_FLOAT, EffectiveFormat::Luminance16F);
AddUnpackTuple(LOCAL_GL_ALPHA , LOCAL_GL_HALF_FLOAT, EffectiveFormat::Alpha16F);
// Everyone's favorite problem-child:
AddUnpackTuple(LOCAL_GL_RGB , LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::RGB16F );
AddUnpackTuple(LOCAL_GL_RGBA , LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::RGBA16F);
AddUnpackTuple(LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::Luminance16FAlpha16F);
AddUnpackTuple(LOCAL_GL_LUMINANCE , LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::Luminance16F);
AddUnpackTuple(LOCAL_GL_ALPHA , LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::Alpha16F);
}
//////////////////////////////////////////////////////////////////////////////////////////
static void
AddSizedFormat(GLenum sizedFormat, EffectiveFormat effectiveFormat)
{
const FormatInfo* info = GetFormatInfo_NoLock(effectiveFormat);
MOZ_ASSERT(info);
AlwaysInsert(gSizedFormatMap, sizedFormat, info);
}
static void
InitSizedFormatMap()
{
// GLES 3.0.4, p128-129 "Required Texture Formats"
// "Texture and renderbuffer color formats"
#ifdef FOO
#error FOO is already defined!
#endif
#define FOO(x) AddSizedFormat(LOCAL_GL_ ## x, EffectiveFormat::x)
FOO(RGBA32I);
FOO(RGBA32UI);
FOO(RGBA16I);
FOO(RGBA16UI);
FOO(RGBA8);
FOO(RGBA8I);
FOO(RGBA8UI);
FOO(SRGB8_ALPHA8);
FOO(RGB10_A2);
FOO(RGB10_A2UI);
FOO(RGBA4);
FOO(RGB5_A1);
FOO(RGB8);
FOO(RGB565);
FOO(RG32I);
FOO(RG32UI);
FOO(RG16I);
FOO(RG16UI);
FOO(RG8);
FOO(RG8I);
FOO(RG8UI);
FOO(R32I);
FOO(R32UI);
FOO(R16I);
FOO(R16UI);
FOO(R8);
FOO(R8I);
FOO(R8UI);
// "Texture-only color formats"
FOO(RGBA32F);
FOO(RGBA16F);
FOO(RGBA8_SNORM);
FOO(RGB32F);
FOO(RGB32I);
FOO(RGB32UI);
FOO(RGB16F);
FOO(RGB16I);
FOO(RGB16UI);
FOO(RGB8_SNORM);
FOO(RGB8I);
FOO(RGB8UI);
FOO(SRGB8);
FOO(R11F_G11F_B10F);
FOO(RGB9_E5);
FOO(RG32F);
FOO(RG16F);
FOO(RG8_SNORM);
FOO(R32F);
FOO(R16F);
FOO(R8_SNORM);
// "Depth formats"
FOO(DEPTH_COMPONENT32F);
FOO(DEPTH_COMPONENT24);
FOO(DEPTH_COMPONENT16);
// "Combined depth+stencil formats"
FOO(DEPTH32F_STENCIL8);
FOO(DEPTH24_STENCIL8);
// GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
FOO(STENCIL_INDEX8);
#undef FOO
}
//////////////////////////////////////////////////////////////////////////////////////////
bool gAreFormatTablesInitialized = false;
static void
EnsureInitFormatTables()
{
if (MOZ_LIKELY(gAreFormatTablesInitialized))
return;
gAreFormatTablesInitialized = true;
InitCompressedFormatInfo();
InitFormatInfoMap();
InitUnpackTupleMap();
InitSizedFormatMap();
}
//////////////////////////////////////////////////////////////////////////////////////////
// Public funcs
StaticMutex gFormatMapMutex;
const FormatInfo*
GetFormatInfo(EffectiveFormat format)
{
StaticMutexAutoLock lock(gFormatMapMutex);
EnsureInitFormatTables();
return GetFormatInfo_NoLock(format);
}
const FormatInfo*
GetInfoByUnpackTuple(GLenum unpackFormat, GLenum unpackType)
{
StaticMutexAutoLock lock(gFormatMapMutex);
EnsureInitFormatTables();
const UnpackTuple unpack = { unpackFormat, unpackType };
MOZ_ASSERT(!gUnpackTupleMap.empty());
auto itr = gUnpackTupleMap.find(unpack);
if (itr == gUnpackTupleMap.end())
return nullptr;
return itr->second;
}
const FormatInfo*
GetInfoBySizedFormat(GLenum sizedFormat)
{
StaticMutexAutoLock lock(gFormatMapMutex);
EnsureInitFormatTables();
MOZ_ASSERT(!gSizedFormatMap.empty());
auto itr = gSizedFormatMap.find(sizedFormat);
if (itr == gSizedFormatMap.end())
return nullptr;
return itr->second;
}
//////////////////////////////////////////////////////////////////////////////////////////
bool
FormatUsageInfo::CanUnpackWith(GLenum unpackFormat, GLenum unpackType) const
{
const UnpackTuple key = { unpackFormat, unpackType };
auto itr = validUnpacks.find(key);
return itr != validUnpacks.end();
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// FormatUsageAuthority
UniquePtr<FormatUsageAuthority>
FormatUsageAuthority::CreateForWebGL1()
{
UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
////////////////////////////////////////////////////////////////////////////
// GLES 2.0.25, p117, Table 4.5
// RGBA8 is made renderable in WebGL 1.0, "Framebuffer Object Attachments"
// render filter
// RB able Tex able
ret->AddFormat(EffectiveFormat::RGBA8 , false, true , true, true);
ret->AddFormat(EffectiveFormat::RGBA4 , true , true , true, true);
ret->AddFormat(EffectiveFormat::RGB5_A1, true , true , true, true);
ret->AddFormat(EffectiveFormat::RGB8 , false, false, true, true);
ret->AddFormat(EffectiveFormat::RGB565 , true , true , true, true);
ret->AddFormat(EffectiveFormat::Luminance8Alpha8, false, false, true, true);
ret->AddFormat(EffectiveFormat::Luminance8 , false, false, true, true);
ret->AddFormat(EffectiveFormat::Alpha8 , false, false, true, true);
ret->AddFormat(EffectiveFormat::DEPTH_COMPONENT16, true, true, false, false);
ret->AddFormat(EffectiveFormat::STENCIL_INDEX8 , true, true, false, false);
// Added in WebGL 1.0 spec:
ret->AddFormat(EffectiveFormat::DEPTH24_STENCIL8, true, true, false, false);
////////////////////////////////////////////////////////////////////////////
// GLES 2.0.25, p63, Table 3.4
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGBA8 );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4, EffectiveFormat::RGBA4 );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1, EffectiveFormat::RGB5_A1);
ret->AddUnpackOption(LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGB8 );
ret->AddUnpackOption(LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_SHORT_5_6_5 , EffectiveFormat::RGB565 );
ret->AddUnpackOption(LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8Alpha8);
ret->AddUnpackOption(LOCAL_GL_LUMINANCE , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8 );
ret->AddUnpackOption(LOCAL_GL_ALPHA , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Alpha8 );
return Move(ret);
}
static void
AddES3TexFormat(FormatUsageAuthority* that, EffectiveFormat format, bool isRenderable,
bool isFilterable)
{
bool asRenderbuffer = isRenderable;
bool asTexture = true;
that->AddFormat(format, asRenderbuffer, isRenderable, asTexture, isFilterable);
}
UniquePtr<FormatUsageAuthority>
FormatUsageAuthority::CreateForWebGL2()
{
UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
FormatUsageAuthority* const ptr = ret.get();
////////////////////////////////////////////////////////////////////////////
// For renderable, see GLES 3.0.4, p212 "Framebuffer Completeness"
// For filterable, see GLES 3.0.4, p161 "...a texture is complete unless..."
// GLES 3.0.4, p128-129 "Required Texture Formats"
// GLES 3.0.4, p130-132, table 3.13
// render filter
// able able
AddES3TexFormat(ptr, EffectiveFormat::R8 , true , true );
AddES3TexFormat(ptr, EffectiveFormat::R8_SNORM , false, true );
AddES3TexFormat(ptr, EffectiveFormat::RG8 , true , true );
AddES3TexFormat(ptr, EffectiveFormat::RG8_SNORM , false, true );
AddES3TexFormat(ptr, EffectiveFormat::RGB8 , true , true );
AddES3TexFormat(ptr, EffectiveFormat::RGB8_SNORM , false, true );
AddES3TexFormat(ptr, EffectiveFormat::RGB565 , true , true );
AddES3TexFormat(ptr, EffectiveFormat::RGBA4 , true , true );
AddES3TexFormat(ptr, EffectiveFormat::RGB5_A1 , true , true );
AddES3TexFormat(ptr, EffectiveFormat::RGBA8 , true , true );
AddES3TexFormat(ptr, EffectiveFormat::RGBA8_SNORM, false, true );
AddES3TexFormat(ptr, EffectiveFormat::RGB10_A2 , true , true );
AddES3TexFormat(ptr, EffectiveFormat::RGB10_A2UI , true , false);
AddES3TexFormat(ptr, EffectiveFormat::SRGB8 , false, true);
AddES3TexFormat(ptr, EffectiveFormat::SRGB8_ALPHA8, true , true);
AddES3TexFormat(ptr, EffectiveFormat::R16F , false, true);
AddES3TexFormat(ptr, EffectiveFormat::RG16F , false, true);
AddES3TexFormat(ptr, EffectiveFormat::RGB16F , false, true);
AddES3TexFormat(ptr, EffectiveFormat::RGBA16F, false, true);
AddES3TexFormat(ptr, EffectiveFormat::R32F , false, false);
AddES3TexFormat(ptr, EffectiveFormat::RG32F , false, false);
AddES3TexFormat(ptr, EffectiveFormat::RGB32F , false, false);
AddES3TexFormat(ptr, EffectiveFormat::RGBA32F, false, false);
AddES3TexFormat(ptr, EffectiveFormat::R11F_G11F_B10F, false, true);
AddES3TexFormat(ptr, EffectiveFormat::RGB9_E5 , false, true);
AddES3TexFormat(ptr, EffectiveFormat::R8I , true, false);
AddES3TexFormat(ptr, EffectiveFormat::R8UI , true, false);
AddES3TexFormat(ptr, EffectiveFormat::R16I , true, false);
AddES3TexFormat(ptr, EffectiveFormat::R16UI, true, false);
AddES3TexFormat(ptr, EffectiveFormat::R32I , true, false);
AddES3TexFormat(ptr, EffectiveFormat::R32UI, true, false);
AddES3TexFormat(ptr, EffectiveFormat::RG8I , true, false);
AddES3TexFormat(ptr, EffectiveFormat::RG8UI , true, false);
AddES3TexFormat(ptr, EffectiveFormat::RG16I , true, false);
AddES3TexFormat(ptr, EffectiveFormat::RG16UI, true, false);
AddES3TexFormat(ptr, EffectiveFormat::RG32I , true, false);
AddES3TexFormat(ptr, EffectiveFormat::RG32UI, true, false);
AddES3TexFormat(ptr, EffectiveFormat::RGB8I , false, false);
AddES3TexFormat(ptr, EffectiveFormat::RGB8UI , false, false);
AddES3TexFormat(ptr, EffectiveFormat::RGB16I , false, false);
AddES3TexFormat(ptr, EffectiveFormat::RGB16UI, false, false);
AddES3TexFormat(ptr, EffectiveFormat::RGB32I , false, false);
AddES3TexFormat(ptr, EffectiveFormat::RGB32UI, false, false);
AddES3TexFormat(ptr, EffectiveFormat::RGBA8I , true, false);
AddES3TexFormat(ptr, EffectiveFormat::RGBA8UI , true, false);
AddES3TexFormat(ptr, EffectiveFormat::RGBA16I , true, false);
AddES3TexFormat(ptr, EffectiveFormat::RGBA16UI, true, false);
AddES3TexFormat(ptr, EffectiveFormat::RGBA32I , true, false);
AddES3TexFormat(ptr, EffectiveFormat::RGBA32UI, true, false);
// GLES 3.0.4, p133, table 3.14
// GLES 3.0.4, p161 "...a texture is complete unless..."
AddES3TexFormat(ptr, EffectiveFormat::DEPTH_COMPONENT16 , true, false);
AddES3TexFormat(ptr, EffectiveFormat::DEPTH_COMPONENT24 , true, false);
AddES3TexFormat(ptr, EffectiveFormat::DEPTH_COMPONENT32F, true, false);
AddES3TexFormat(ptr, EffectiveFormat::DEPTH24_STENCIL8 , true, false);
AddES3TexFormat(ptr, EffectiveFormat::DEPTH32F_STENCIL8 , true, false);
// GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
AddES3TexFormat(ptr, EffectiveFormat::STENCIL_INDEX8, true, false);
// GLES 3.0.4, p128, table 3.12.
// Unsized RGBA/RGB formats are renderable, other unsized are not.
AddES3TexFormat(ptr, EffectiveFormat::Luminance8Alpha8, false, true);
AddES3TexFormat(ptr, EffectiveFormat::Luminance8 , false, true);
AddES3TexFormat(ptr, EffectiveFormat::Alpha8 , false, true);
// GLES 3.0.4, p147, table 3.19
// GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
// (jgilbert) I can't find where these are established as filterable.
AddES3TexFormat(ptr, EffectiveFormat::COMPRESSED_RGB8_ETC2 , false, true);
AddES3TexFormat(ptr, EffectiveFormat::COMPRESSED_SRGB8_ETC2 , false, true);
AddES3TexFormat(ptr, EffectiveFormat::COMPRESSED_RGBA8_ETC2_EAC , false, true);
AddES3TexFormat(ptr, EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC , false, true);
AddES3TexFormat(ptr, EffectiveFormat::COMPRESSED_R11_EAC , false, true);
AddES3TexFormat(ptr, EffectiveFormat::COMPRESSED_RG11_EAC , false, true);
AddES3TexFormat(ptr, EffectiveFormat::COMPRESSED_SIGNED_R11_EAC , false, true);
AddES3TexFormat(ptr, EffectiveFormat::COMPRESSED_SIGNED_RG11_EAC , false, true);
AddES3TexFormat(ptr, EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 , false, true);
AddES3TexFormat(ptr, EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, false, true);
////////////////////////////////////////////////////////////////////////////
// GLES 3.0.4 p111-113
// RGBA
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGBA8 );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGB5_A1 );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGBA4 );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::SRGB8_ALPHA8);
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_BYTE , EffectiveFormat::RGBA8_SNORM );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 , EffectiveFormat::RGBA4 );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 , EffectiveFormat::RGB5_A1 );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV, EffectiveFormat::RGB10_A2 );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV, EffectiveFormat::RGB5_A1 );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT , EffectiveFormat::RGBA16F );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_FLOAT , EffectiveFormat::RGBA32F );
ret->AddUnpackOption(LOCAL_GL_RGBA, LOCAL_GL_FLOAT , EffectiveFormat::RGBA16F );
// RGBA_INTEGER
ret->AddUnpackOption(LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGBA8UI );
ret->AddUnpackOption(LOCAL_GL_RGBA_INTEGER, LOCAL_GL_BYTE , EffectiveFormat::RGBA8I );
ret->AddUnpackOption(LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_SHORT , EffectiveFormat::RGBA16UI );
ret->AddUnpackOption(LOCAL_GL_RGBA_INTEGER, LOCAL_GL_SHORT , EffectiveFormat::RGBA16I );
ret->AddUnpackOption(LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_INT , EffectiveFormat::RGBA32UI );
ret->AddUnpackOption(LOCAL_GL_RGBA_INTEGER, LOCAL_GL_INT , EffectiveFormat::RGBA32I );
ret->AddUnpackOption(LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV, EffectiveFormat::RGB10_A2UI);
// RGB
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGB8 );
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGB565 );
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::SRGB8 );
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_BYTE , EffectiveFormat::RGB8_SNORM );
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_SHORT_5_6_5 , EffectiveFormat::RGB565 );
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV, EffectiveFormat::R11F_G11F_B10F);
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV , EffectiveFormat::RGB9_E5 );
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT , EffectiveFormat::RGB16F );
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT , EffectiveFormat::R11F_G11F_B10F);
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT , EffectiveFormat::RGB9_E5 );
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_FLOAT , EffectiveFormat::RGB32F );
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_FLOAT , EffectiveFormat::RGB16F );
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_FLOAT , EffectiveFormat::R11F_G11F_B10F);
ret->AddUnpackOption(LOCAL_GL_RGB, LOCAL_GL_FLOAT , EffectiveFormat::RGB9_E5 );
// RGB_INTEGER
ret->AddUnpackOption(LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGB8UI );
ret->AddUnpackOption(LOCAL_GL_RGB_INTEGER, LOCAL_GL_BYTE , EffectiveFormat::RGB8I );
ret->AddUnpackOption(LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_SHORT, EffectiveFormat::RGB16UI);
ret->AddUnpackOption(LOCAL_GL_RGB_INTEGER, LOCAL_GL_SHORT , EffectiveFormat::RGB16I );
ret->AddUnpackOption(LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_INT , EffectiveFormat::RGB32UI);
ret->AddUnpackOption(LOCAL_GL_RGB_INTEGER, LOCAL_GL_INT , EffectiveFormat::RGB32I );
// RG
ret->AddUnpackOption(LOCAL_GL_RG, LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::RG8 );
ret->AddUnpackOption(LOCAL_GL_RG, LOCAL_GL_BYTE , EffectiveFormat::RG8_SNORM);
ret->AddUnpackOption(LOCAL_GL_RG, LOCAL_GL_HALF_FLOAT , EffectiveFormat::RG16F );
ret->AddUnpackOption(LOCAL_GL_RG, LOCAL_GL_FLOAT , EffectiveFormat::RG32F );
ret->AddUnpackOption(LOCAL_GL_RG, LOCAL_GL_FLOAT , EffectiveFormat::RG16F );
// RG_INTEGER
ret->AddUnpackOption(LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RG8UI );
ret->AddUnpackOption(LOCAL_GL_RG_INTEGER, LOCAL_GL_BYTE , EffectiveFormat::RG8I );
ret->AddUnpackOption(LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_SHORT, EffectiveFormat::RG16UI);
ret->AddUnpackOption(LOCAL_GL_RG_INTEGER, LOCAL_GL_SHORT , EffectiveFormat::RG16I );
ret->AddUnpackOption(LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_INT , EffectiveFormat::RG32UI);
ret->AddUnpackOption(LOCAL_GL_RG_INTEGER, LOCAL_GL_INT , EffectiveFormat::RG32I );
// RED
ret->AddUnpackOption(LOCAL_GL_RED, LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::R8 );
ret->AddUnpackOption(LOCAL_GL_RED, LOCAL_GL_BYTE , EffectiveFormat::R8_SNORM);
ret->AddUnpackOption(LOCAL_GL_RED, LOCAL_GL_HALF_FLOAT , EffectiveFormat::R16F );
ret->AddUnpackOption(LOCAL_GL_RED, LOCAL_GL_FLOAT , EffectiveFormat::R32F );
ret->AddUnpackOption(LOCAL_GL_RED, LOCAL_GL_FLOAT , EffectiveFormat::R16F );
// RED_INTEGER
ret->AddUnpackOption(LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::R8UI );
ret->AddUnpackOption(LOCAL_GL_RED_INTEGER, LOCAL_GL_BYTE , EffectiveFormat::R8I );
ret->AddUnpackOption(LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_SHORT, EffectiveFormat::R16UI);
ret->AddUnpackOption(LOCAL_GL_RED_INTEGER, LOCAL_GL_SHORT , EffectiveFormat::R16I );
ret->AddUnpackOption(LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_INT , EffectiveFormat::R32UI);
ret->AddUnpackOption(LOCAL_GL_RED_INTEGER, LOCAL_GL_INT , EffectiveFormat::R32I );
// DEPTH_COMPONENT
ret->AddUnpackOption(LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_SHORT, EffectiveFormat::DEPTH_COMPONENT16 );
ret->AddUnpackOption(LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_INT , EffectiveFormat::DEPTH_COMPONENT24 );
ret->AddUnpackOption(LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_INT , EffectiveFormat::DEPTH_COMPONENT16 );
ret->AddUnpackOption(LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_FLOAT , EffectiveFormat::DEPTH_COMPONENT32F);
// DEPTH_STENCIL
ret->AddUnpackOption(LOCAL_GL_DEPTH_STENCIL, LOCAL_GL_UNSIGNED_INT_24_8 , EffectiveFormat::DEPTH24_STENCIL8 );
ret->AddUnpackOption(LOCAL_GL_DEPTH_STENCIL, LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV, EffectiveFormat::DEPTH32F_STENCIL8);
// Unsized formats
ret->AddUnpackOption(LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8Alpha8);
ret->AddUnpackOption(LOCAL_GL_LUMINANCE , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8 );
ret->AddUnpackOption(LOCAL_GL_ALPHA , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Alpha8 );
return Move(ret);
}
//////////////////////////////////////////////////////////////////////////////////////////
FormatUsageInfo*
FormatUsageAuthority::GetUsage(EffectiveFormat format)
{
auto itr = mInfoMap.find(format);
if (itr == mInfoMap.end())
return nullptr;
return &(itr->second);
}
void
FormatUsageAuthority::AddFormat(EffectiveFormat format, bool asRenderbuffer,
bool isRenderable, bool asTexture, bool isFilterable)
{
MOZ_ASSERT_IF(asRenderbuffer, isRenderable);
MOZ_ASSERT_IF(isFilterable, asTexture);
const FormatInfo* formatInfo = GetFormatInfo(format);
MOZ_RELEASE_ASSERT(formatInfo);
FormatUsageInfo usage = { formatInfo, asRenderbuffer, isRenderable, asTexture,
isFilterable, std::set<UnpackTuple>() };
AlwaysInsert(mInfoMap, format, usage);
}
void
FormatUsageAuthority::AddUnpackOption(GLenum unpackFormat, GLenum unpackType,
EffectiveFormat effectiveFormat)
{
const UnpackTuple unpack = { unpackFormat, unpackType };
FormatUsageInfo* usage = GetUsage(effectiveFormat);
MOZ_RELEASE_ASSERT(usage);
if (!usage)
return;
MOZ_RELEASE_ASSERT(usage->asTexture);
auto res = usage->validUnpacks.insert(unpack);
bool didInsert = res.second;
MOZ_ALWAYS_TRUE(didInsert);
}
////////////////////////////////////////////////////////////////////////////////
struct ComponentSizes
{
GLubyte redSize;
GLubyte greenSize;
GLubyte blueSize;
GLubyte alphaSize;
GLubyte depthSize;
GLubyte stencilSize;
};
static ComponentSizes kComponentSizes[] = {
// GLES 3.0.4, p128-129, "Required Texture Formats"
// "Texture and renderbuffer color formats"
{ 32, 32, 32, 32, 0, 0 }, // RGBA32I,
{ 32, 32, 32, 32, 0, 0 }, // RGBA32UI,
{ 16, 16, 16, 16, 0, 0 }, // RGBA16I,
{ 16, 16, 16, 16, 0, 0 }, // RGBA16UI,
{ 8, 8, 8, 8, 0, 0 }, // RGBA8,
{ 8, 8, 8, 8, 0, 0 }, // RGBA8I,
{ 8, 8, 8, 8, 0, 0 }, // RGBA8UI,
{ 8, 8, 8, 8, 0, 0 }, // SRGB8_ALPHA8,
{ 10, 10, 10, 2, 0, 0 }, // RGB10_A2,
{ 10, 10, 10, 2, 0, 0 }, // RGB10_A2UI,
{ 4, 4, 4, 4, 0, 0 }, // RGBA4,
{ 5, 5, 5, 1, 0, 0 }, // RGB5_A1,
{ 8, 8, 8, 0, 0, 0 }, // RGB8,
{ 8, 8, 8, 0, 0, 0 }, // RGB565,
{ 32, 32, 0, 0, 0, 0 }, // RG32I,
{ 32, 32, 0, 0, 0, 0 }, // RG32UI,
{ 16, 16, 0, 0, 0, 0 }, // RG16I,
{ 16, 16, 0, 0, 0, 0 }, // RG16UI,
{ 8, 8, 0, 0, 0, 0 }, // RG8,
{ 8, 8, 0, 0, 0, 0 }, // RG8I,
{ 8, 8, 0, 0, 0, 0 }, // RG8UI,
{ 32, 0, 0, 0, 0, 0 }, // R32I,
{ 32, 0, 0, 0, 0, 0 }, // R32UI,
{ 16, 0, 0, 0, 0, 0 }, // R16I,
{ 16, 0, 0, 0, 0, 0 }, // R16UI,
{ 8, 0, 0, 0, 0, 0 }, // R8,
{ 8, 0, 0, 0, 0, 0 }, // R8I,
{ 8, 0, 0, 0, 0, 0 }, // R8UI,
// "Texture-only color formats"
{ 32, 32, 32, 32, 0, 0 }, // RGBA32F,
{ 16, 16, 16, 16, 0, 0 }, // RGBA16F,
{ 8, 8, 8, 8, 0, 0 }, // RGBA8_SNORM,
{ 32, 32, 32, 0, 0, 0 }, // RGB32F,
{ 32, 32, 32, 0, 0, 0 }, // RGB32I,
{ 32, 32, 32, 0, 0, 0 }, // RGB32UI,
{ 16, 16, 16, 0, 0, 0 }, // RGB16F,
{ 16, 16, 16, 0, 0, 0 }, // RGB16I,
{ 16, 16, 16, 0, 0, 0 }, // RGB16UI,
{ 8, 8, 8, 0, 0, 0 }, // RGB8_SNORM,
{ 8, 8, 8, 0, 0, 0 }, // RGB8I,
{ 8, 8, 8, 0, 0, 0 }, // RGB8UI,
{ 8, 8, 8, 0, 0, 0 }, // SRGB8,
{ 11, 11, 11, 0, 0, 0 }, // R11F_G11F_B10F,
{ 9, 9, 9, 0, 0, 0 }, // RGB9_E5,
{ 32, 32, 0, 0, 0, 0 }, // RG32F,
{ 16, 16, 0, 0, 0, 0 }, // RG16F,
{ 8, 8, 0, 0, 0, 0 }, // RG8_SNORM,
{ 32, 0, 0, 0, 0, 0 }, // R32F,
{ 16, 0, 0, 0, 0, 0 }, // R16F,
{ 8, 0, 0, 0, 0, 0 }, // R8_SNORM,
// "Depth formats"
{ 0, 0, 0, 0, 32, 0 }, // DEPTH_COMPONENT32F,
{ 0, 0, 0, 0, 24, 0 }, // DEPTH_COMPONENT24,
{ 0, 0, 0, 0, 16, 0 }, // DEPTH_COMPONENT16,
// "Combined depth+stencil formats"
{ 0, 0, 0, 0, 32, 8 }, // DEPTH32F_STENCIL0,
{ 0, 0, 0, 0, 24, 8 }, // DEPTH24_STENCIL8,
// GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
{ 0, 0, 0, 0, 0, 8 }, // STENCIL_INDEX8,
// GLES 3.0.4, p128, table 3.12.
{ 8, 8, 8, 8, 0, 0 }, // Luminance8Alpha8,
{ 8, 8, 8, 0, 0, 0 }, // Luminance8,
{ 0, 0, 0, 8, 0, 0 }, // Alpha8,
// GLES 3.0.4, p147, table 3.19
// GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_R11_EAC,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_SIGNED_R11_EAC,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RG11_EAC,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_SIGNED_RG11_EAC,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGB8_ETC2,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_SRGB8_ETC2,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA8_ETC2_EAC,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
// AMD_compressed_ATC_texture
{ 8, 8, 8, 0, 0, 0 }, // ATC_RGB_AMD,
{ 8, 8, 8, 8, 0, 0 }, // ATC_RGBA_EXPLICIT_ALPHA_AMD,
{ 8, 8, 8, 8, 0, 0 }, // ATC_RGBA_INTERPOLATED_ALPHA_AMD,
// EXT_texture_compression_s3tc
{ 8, 8, 8, 0, 0, 0 }, // COMPRESSED_RGB_S3TC_DXT1,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA_S3TC_DXT1,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA_S3TC_DXT3,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA_S3TC_DXT5,
// IMG_texture_compression_pvrtc
{ 8, 8, 8, 0, 0, 0 }, // COMPRESSED_RGB_PVRTC_4BPPV1,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA_PVRTC_4BPPV1,
{ 8, 8, 8, 0, 0, 0 }, // COMPRESSED_RGB_PVRTC_2BPPV1,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA_PVRTC_2BPPV1,
// OES_compressed_ETC1_RGB8_texture
{ 8, 8, 8, 0, 0, 0 }, // ETC1_RGB8,
// OES_texture_float
{ 32, 32, 32, 32, 0, 0 }, // Luminance32FAlpha32F,
{ 32, 32, 32, 0, 0, 0 }, // Luminance32F,
{ 0, 0, 0, 32, 0, 0 }, // Alpha32F,
// OES_texture_half_float
{ 16, 16, 16, 16, 0, 0 }, // Luminance16FAlpha16F,
{ 16, 16, 16, 0, 0, 0 }, // Luminance16F,
{ 0, 0, 0, 16, 0, 0 }, // Alpha16F,
{ 0, } // MAX
};
GLint
GetComponentSize(EffectiveFormat format, GLenum component)
{
ComponentSizes compSize = kComponentSizes[(int) format];
switch (component) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
case LOCAL_GL_RENDERBUFFER_RED_SIZE:
case LOCAL_GL_RED_BITS:
return compSize.redSize;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
case LOCAL_GL_RENDERBUFFER_GREEN_SIZE:
case LOCAL_GL_GREEN_BITS:
return compSize.greenSize;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
case LOCAL_GL_RENDERBUFFER_BLUE_SIZE:
case LOCAL_GL_BLUE_BITS:
return compSize.blueSize;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
case LOCAL_GL_RENDERBUFFER_ALPHA_SIZE:
case LOCAL_GL_ALPHA_BITS:
return compSize.alphaSize;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
case LOCAL_GL_RENDERBUFFER_DEPTH_SIZE:
case LOCAL_GL_DEPTH_BITS:
return compSize.depthSize;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
case LOCAL_GL_RENDERBUFFER_STENCIL_SIZE:
case LOCAL_GL_STENCIL_BITS:
return compSize.stencilSize;
}
return 0;
}
static GLenum kComponentTypes[] = {
// GLES 3.0.4, p128-129, "Required Texture Formats"
// "Texture and renderbuffer color formats"
LOCAL_GL_INT, // RGBA32I,
LOCAL_GL_UNSIGNED_INT, // RGBA32UI,
LOCAL_GL_INT, // RGBA16I,
LOCAL_GL_UNSIGNED_INT, // RGBA16UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGBA8,
LOCAL_GL_INT, // RGBA8I,
LOCAL_GL_UNSIGNED_INT, // RGBA8UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // SRGB8_ALPHA8,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGB10_A2,
LOCAL_GL_UNSIGNED_INT, // RGB10_A2UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGBA4,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGB5_A1,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGB8,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGB565,
LOCAL_GL_INT, // RG32I,
LOCAL_GL_UNSIGNED_INT, // RG32UI,
LOCAL_GL_INT, // RG16I,
LOCAL_GL_UNSIGNED_INT, // RG16UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // RG8,
LOCAL_GL_INT, // RG8I,
LOCAL_GL_UNSIGNED_INT, // RG8UI,
LOCAL_GL_INT, // R32I,
LOCAL_GL_UNSIGNED_INT, // R32UI,
LOCAL_GL_INT, // R16I,
LOCAL_GL_UNSIGNED_INT, // R16UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // R8,
LOCAL_GL_INT, // R8I,
LOCAL_GL_UNSIGNED_INT, // R8UI,
// "Texture-only color formats"
LOCAL_GL_FLOAT, // RGBA32F,
LOCAL_GL_FLOAT, // RGBA16F,
LOCAL_GL_SIGNED_NORMALIZED, // RGBA8_SNORM,
LOCAL_GL_FLOAT, // RGB32F,
LOCAL_GL_INT, // RGB32I,
LOCAL_GL_UNSIGNED_INT, // RGB32UI,
LOCAL_GL_FLOAT, // RGB16F,
LOCAL_GL_INT, // RGB16I,
LOCAL_GL_UNSIGNED_INT, // RGB16UI,
LOCAL_GL_SIGNED_NORMALIZED, // RGB8_SNORM,
LOCAL_GL_INT, // RGB8I,
LOCAL_GL_UNSIGNED_INT, // RGB8UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // SRGB8,
LOCAL_GL_FLOAT, // R11F_G11F_B10F,
LOCAL_GL_FLOAT, // RGB9_E5,
LOCAL_GL_FLOAT, // RG32F,
LOCAL_GL_FLOAT, // RG16F,
LOCAL_GL_SIGNED_NORMALIZED, // RG8_SNORM,
LOCAL_GL_FLOAT, // R32F,
LOCAL_GL_FLOAT, // R16F,
LOCAL_GL_SIGNED_NORMALIZED, // R8_SNORM,
// "Depth formats"
LOCAL_GL_FLOAT, // DEPTH_COMPONENT32F,
LOCAL_GL_UNSIGNED_NORMALIZED, // DEPTH_COMPONENT24,
LOCAL_GL_UNSIGNED_NORMALIZED, // DEPTH_COMPONENT16,
// "Combined depth+stencil formats"
LOCAL_GL_FLOAT, // DEPTH32F_STENCIL8,
LOCAL_GL_UNSIGNED_NORMALIZED, // DEPTH24_STENCIL8,
// GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
LOCAL_GL_UNSIGNED_NORMALIZED, // STENCIL_INDEX8,
// GLES 3.0.4, p128, table 3.12.
LOCAL_GL_UNSIGNED_NORMALIZED, // Luminance8Alpha8,
LOCAL_GL_UNSIGNED_NORMALIZED, // Luminance8,
LOCAL_GL_UNSIGNED_NORMALIZED, // Alpha8,
// GLES 3.0.4, p147, table 3.19
// GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_R11_EAC,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_SIGNED_R11_EAC,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RG11_EAC,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_SIGNED_RG11_EAC,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGB8_ETC2,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_SRGB8_ETC2,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA8_ETC2_EAC,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
// AMD_compressed_ATC_texture
LOCAL_GL_UNSIGNED_NORMALIZED, // ATC_RGB_AMD,
LOCAL_GL_UNSIGNED_NORMALIZED, // ATC_RGBA_EXPLICIT_ALPHA_AMD,
LOCAL_GL_UNSIGNED_NORMALIZED, // ATC_RGBA_INTERPOLATED_ALPHA_AMD,
// EXT_texture_compression_s3tc
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGB_S3TC_DXT1,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA_S3TC_DXT1,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA_S3TC_DXT3,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA_S3TC_DXT5,
// IMG_texture_compression_pvrtc
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGB_PVRTC_4BPPV1,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA_PVRTC_4BPPV1,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGB_PVRTC_2BPPV1,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA_PVRTC_2BPPV1,
// OES_compressed_ETC1_RGB8_texture
LOCAL_GL_UNSIGNED_NORMALIZED, // ETC1_RGB8,
// OES_texture_float
LOCAL_GL_FLOAT, // Luminance32FAlpha32F,
LOCAL_GL_FLOAT, // Luminance32F,
LOCAL_GL_FLOAT, // Alpha32F,
// OES_texture_half_float
LOCAL_GL_FLOAT, // Luminance16FAlpha16F,
LOCAL_GL_FLOAT, // Luminance16F,
LOCAL_GL_FLOAT, // Alpha16F,
LOCAL_GL_NONE // MAX
};
GLenum
GetComponentType(EffectiveFormat format)
{
return kComponentTypes[(int) format];
}
GLenum
GetColorEncoding(EffectiveFormat format)
{
const bool isSRGB = (GetFormatInfo(format)->colorComponentType ==
ComponentType::NormUIntSRGB);
return (isSRGB) ? LOCAL_GL_SRGB : LOCAL_GL_LINEAR;
}
} // namespace webgl
} // namespace mozilla