--- a/dom/canvas/WebGLFormats.cpp
+++ b/dom/canvas/WebGLFormats.cpp
@@ -34,38 +34,38 @@ FindOrNull(const std::map<K,V*>& dest, c
return nullptr;
return itr->second;
}
// Returns a pointer to the in-place value for `key`.
template<typename K, typename V, typename K2>
static inline V*
-FindPtrOrNull(const std::map<K,V>& dest, const K2& key)
+FindPtrOrNull(std::map<K,V>& dest, const K2& key)
{
auto itr = dest.find(key);
if (itr == dest.end())
return nullptr;
return &(itr->second);
}
//////////////////////////////////////////////////////////////////////////////////////////
std::map<EffectiveFormat, const CompressedFormatInfo> gCompressedFormatInfoMap;
-std::map<EffectiveFormat, const FormatInfo> gFormatInfoMap;
+std::map<EffectiveFormat, FormatInfo> gFormatInfoMap;
static inline const CompressedFormatInfo*
GetCompressedFormatInfo(EffectiveFormat format)
{
MOZ_ASSERT(!gCompressedFormatInfoMap.empty());
return FindPtrOrNull(gCompressedFormatInfoMap, format);
}
-static inline const FormatInfo*
+static inline FormatInfo*
GetFormatInfo_NoLock(EffectiveFormat format)
{
MOZ_ASSERT(!gFormatInfoMap.empty());
return FindPtrOrNull(gFormatInfoMap, format);
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -303,16 +303,95 @@ InitFormatInfo()
AddFormatInfo(FOO(Alpha32F ), 4, 0,0,0,32, 0,0, UnsizedFormat::A , false, ComponentType::Float);
// OES_texture_half_float
AddFormatInfo(FOO(Luminance16FAlpha16F), 4, 16,0,0,16, 0,0, UnsizedFormat::LA, false, ComponentType::Float);
AddFormatInfo(FOO(Luminance16F ), 2, 16,0,0, 0, 0,0, UnsizedFormat::L , false, ComponentType::Float);
AddFormatInfo(FOO(Alpha16F ), 2, 0,0,0,16, 0,0, UnsizedFormat::A , false, ComponentType::Float);
#undef FOO
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ const auto fnSetCopyDecay = [](EffectiveFormat src, EffectiveFormat asR,
+ EffectiveFormat asRG, EffectiveFormat asRGB,
+ EffectiveFormat asRGBA, EffectiveFormat asL,
+ EffectiveFormat asA, EffectiveFormat asLA)
+ {
+ auto& map = GetFormatInfo_NoLock(src)->copyDecayFormats;
+
+ const auto fnSet = [&map](UnsizedFormat uf, EffectiveFormat ef) {
+ if (ef == EffectiveFormat::MAX)
+ return;
+
+ const auto* format = GetFormatInfo_NoLock(ef);
+ MOZ_ASSERT(format->unsizedFormat == uf);
+ AlwaysInsert(map, uf, format);
+ };
+
+ fnSet(UnsizedFormat::R , asR);
+ fnSet(UnsizedFormat::RG , asRG);
+ fnSet(UnsizedFormat::RGB , asRGB);
+ fnSet(UnsizedFormat::RGBA, asRGBA);
+ fnSet(UnsizedFormat::L , asL);
+ fnSet(UnsizedFormat::A , asA);
+ fnSet(UnsizedFormat::LA , asLA);
+ };
+
+#define SET_COPY_DECAY(src,asR,asRG,asRGB,asRGBA,asL,asA,asLA) \
+ fnSetCopyDecay(EffectiveFormat::src, EffectiveFormat::asR, EffectiveFormat::asRG, \
+ EffectiveFormat::asRGB, EffectiveFormat::asRGBA, EffectiveFormat::asL, \
+ EffectiveFormat::asA, EffectiveFormat::asLA);
+
+ //////
+
+#define SET_BY_SUFFIX(X) \
+ SET_COPY_DECAY( R##X, R##X, MAX, MAX, MAX, Luminance##X, MAX, MAX) \
+ SET_COPY_DECAY( RG##X, R##X, RG##X, MAX, MAX, Luminance##X, MAX, MAX) \
+ SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, Luminance##X, Alpha##X, Luminance##X##Alpha##X)
+
+ SET_BY_SUFFIX(8)
+ SET_BY_SUFFIX(16F)
+ SET_BY_SUFFIX(32F)
+
+#undef SET_BY_SUFFIX
+
+ //////
+
+#define SET_BY_SUFFIX(X) \
+ SET_COPY_DECAY( R##X, R##X, MAX, MAX, MAX, MAX, MAX, MAX) \
+ SET_COPY_DECAY( RG##X, R##X, RG##X, MAX, MAX, MAX, MAX, MAX) \
+ SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, MAX, MAX, MAX)
+
+ SET_BY_SUFFIX(8I)
+ SET_BY_SUFFIX(8UI)
+
+ SET_BY_SUFFIX(16I)
+ SET_BY_SUFFIX(16UI)
+
+ SET_BY_SUFFIX(32I)
+ SET_BY_SUFFIX(32UI)
+
+#undef SET_BY_SUFFIX
+
+ //////
+
+ SET_COPY_DECAY( RGB8, R8, RG8, RGB8, MAX, Luminance8, MAX, MAX)
+ SET_COPY_DECAY( RGB565, R8, RG8, RGB565, MAX, Luminance8, MAX, MAX)
+ SET_COPY_DECAY( RGBA4, R8, RG8, RGB565, RGBA4, Luminance8, Alpha8, Luminance8Alpha8)
+ SET_COPY_DECAY( RGB5_A1, R8, RG8, RGB565, RGB5_A1, Luminance8, Alpha8, Luminance8Alpha8)
+ SET_COPY_DECAY( RGB10_A2, R8, RG8, RGB8, RGB10_A2, Luminance8, Alpha8, MAX)
+
+ SET_COPY_DECAY(RGB10_A2UI, R8UI, RG8UI, RGB8UI, RGB10_A2UI, MAX, MAX, MAX)
+
+ SET_COPY_DECAY(SRGB8_ALPHA8, MAX, MAX, MAX, SRGB8_ALPHA8, MAX, Alpha8, MAX)
+
+ SET_COPY_DECAY(R11F_G11F_B10F, R16F, RG16F, R11F_G11F_B10F, MAX, Luminance16F, MAX, MAX)
+
+#undef SET_COPY_DECAY
}
//////////////////////////////////////////////////////////////////////////////////////////
bool gAreFormatTablesInitialized = false;
static void
EnsureInitFormatTables(const StaticMutexAutoLock&) // Prove that you locked it!
@@ -337,16 +416,22 @@ GetFormat(EffectiveFormat format)
StaticMutexAutoLock lock(gFormatMapMutex);
EnsureInitFormatTables(lock);
return GetFormatInfo_NoLock(format);
}
//////////////////////////////////////////////////////////////////////////////////////////
+const FormatInfo*
+FormatInfo::GetCopyDecayFormat(UnsizedFormat uf) const
+{
+ return FindOrNull(this->copyDecayFormats, uf);
+}
+
uint8_t
BytesPerPixel(const PackingInfo& packing)
{
uint8_t bytesPerChannel;
switch (packing.type) {
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
@@ -539,33 +624,52 @@ AddUnsizedFormats(FormatUsageAuthority*
AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1, EffectiveFormat::RGB5_A1);
AddSimpleUnsized(fua, LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGB8 );
AddSimpleUnsized(fua, LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_SHORT_5_6_5 , EffectiveFormat::RGB565 );
// L, A, LA
return AddLegacyFormats_LA8(fua, gl);
}
+void
+FormatUsageInfo::SetRenderable()
+{
+ this->isRenderable = true;
+
+#ifdef DEBUG
+ const auto format = this->format;
+ if (format->isColorFormat) {
+ const auto& map = format->copyDecayFormats;
+ const auto itr = map.find(format->unsizedFormat);
+ MOZ_ASSERT(itr != map.end());
+ MOZ_ASSERT(itr->second == format);
+ }
+#endif
+}
+
UniquePtr<FormatUsageAuthority>
FormatUsageAuthority::CreateForWebGL1(gl::GLContext* gl)
{
UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
const auto ptr = ret.get();
////////////////////////////////////////////////////////////////////////////
// Usages
const auto fnSet = [ptr](EffectiveFormat effFormat, bool isRenderable,
bool isFilterable)
{
MOZ_ASSERT(!ptr->GetUsage(effFormat));
auto usage = ptr->EditUsage(effFormat);
- usage->isRenderable = isRenderable;
usage->isFilterable = isFilterable;
+
+ if (isRenderable) {
+ usage->SetRenderable();
+ }
};
// GLES 2.0.25, p117, Table 4.5
// RGBA8 is made renderable in WebGL 1.0, "Framebuffer Object Attachments"
// render filter
// able able
fnSet(EffectiveFormat::RGBA8 , true, true);
fnSet(EffectiveFormat::RGBA4 , true, true);
@@ -725,19 +829,22 @@ FormatUsageAuthority::CreateForWebGL2(gl
// For renderable, see GLES 3.0.4, p212 "Framebuffer Completeness"
// For filterable, see GLES 3.0.4, p161 "...a texture is complete unless..."
const auto fnAllowES3TexFormat = [ptr](GLenum sizedFormat, EffectiveFormat effFormat,
bool isRenderable, bool isFilterable)
{
auto usage = ptr->EditUsage(effFormat);
- usage->isRenderable = isRenderable;
usage->isFilterable = isFilterable;
+ if (isRenderable) {
+ usage->SetRenderable();
+ }
+
ptr->AllowSizedTexFormat(sizedFormat, usage);
if (isRenderable) {
ptr->AllowRBFormat(sizedFormat, usage);
}
};
#define FOO(x) LOCAL_GL_ ## x, EffectiveFormat::x
@@ -836,17 +943,17 @@ FormatUsageAuthority::CreateForWebGL2(gl
#endif
#undef FOO
// GLES 3.0.4, p206, "Required Renderbuffer Formats":
// "Implementations are also required to support STENCIL_INDEX8. Requesting this
// internal format for a renderbuffer will allocate at least 8 stencil bit planes."
auto usage = ptr->EditUsage(EffectiveFormat::STENCIL_INDEX8);
- usage->isRenderable = true;
+ usage->SetRenderable();
ptr->AllowRBFormat(LOCAL_GL_STENCIL_INDEX8, usage);
////////////////
// Legacy formats
if (!AddUnsizedFormats(ptr, gl))
return nullptr;
@@ -856,16 +963,18 @@ FormatUsageAuthority::CreateForWebGL2(gl
if (gfxPrefs::WebGL2CompatMode()) {
AddSimpleUnsized(ptr, LOCAL_GL_RGBA, LOCAL_GL_FLOAT, EffectiveFormat::RGBA32F);
AddSimpleUnsized(ptr, LOCAL_GL_RGB , LOCAL_GL_FLOAT, EffectiveFormat::RGB32F );
AddSimpleUnsized(ptr, LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::RGBA16F);
AddSimpleUnsized(ptr, LOCAL_GL_RGB , LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::RGB16F );
}
+ ////////////////////////////////////
+
return Move(ret);
}
//////////////////////////////////////////////////////////////////////////////////////////
void
FormatUsageAuthority::AddTexUnpack(FormatUsageInfo* usage, const PackingInfo& pi,
const DriverUnpackInfo& dui)
@@ -904,17 +1013,17 @@ FormatUsageAuthority::AreUnpackEnumsVali
////////////////////
void
FormatUsageAuthority::AllowRBFormat(GLenum sizedFormat, const FormatUsageInfo* usage)
{
MOZ_ASSERT(!usage->format->compression);
MOZ_ASSERT(usage->format->sizedFormat);
- MOZ_ASSERT(usage->isRenderable);
+ MOZ_ASSERT(usage->IsRenderable());
AlwaysInsert(mRBFormatMap, sizedFormat, usage);
}
void
FormatUsageAuthority::AllowSizedTexFormat(GLenum sizedFormat,
const FormatUsageInfo* usage)
{