Commit 0d665139 by Markus Tavenrath Committed by Commit Bot

Don't generate TypeInfo objects as static objects within GetTypeInfo function

Generating static objects within a function results in multithread safe code. This code generates the static objects upon the first execution of the line which declares the object. This results in high runtime cost for synchronization and a bigger code size. Instead introduce a new function uint32_t GetPackedTypeInfo(GLenum type) which returns a packed representation for the Type class. This representation is usually returned in a register on the assembly level. As a result we save constant storage for the TypeInfo object and one indirection when reading any value from this object. The Type constructor accepts the packed representation and unpacks it an inline function. For fields which are not used the compiler also applies dead code elimination which reduces the cost furthermore. As a result of this change the cost of GetTypeInfo is reduced by a factor of 4-5. Bug: angleproject:2974 Change-Id: I8ed0bf2f09d087fa4cffa04f82e3b7f8c183fe30 Reviewed-on: https://chromium-review.googlesource.com/c/1340221Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 573f76b3
...@@ -123,6 +123,7 @@ NVIDIA Corporation ...@@ -123,6 +123,7 @@ NVIDIA Corporation
Sami Väisänen Sami Väisänen
Martin Radev Martin Radev
Joonatan Saarhelo Joonatan Saarhelo
Markus Tavenrath
Opera Software ASA Opera Software ASA
Daniel Bratell Daniel Bratell
......
...@@ -39,16 +39,25 @@ bool CheckedMathResult(const CheckedNumeric<GLuint> &value, GLuint *resultOut) ...@@ -39,16 +39,25 @@ bool CheckedMathResult(const CheckedNumeric<GLuint> &value, GLuint *resultOut)
return true; return true;
} }
} }
} // anonymous namespace
FormatType::FormatType() : format(GL_NONE), type(GL_NONE) constexpr GLuint Log2(GLuint bytes)
{ {
return bytes == 1 ? 0 : (1 + Log2(bytes / 2));
} }
FormatType::FormatType(GLenum format_, GLenum type_) : format(format_), type(type_) constexpr uint32_t PackTypeInfo(GLuint bytes, bool specialized)
{ {
// static_assert within constexpr requires c++17
// static_assert(isPow2(bytes));
return bytes | (Log2(bytes) << 8) | (specialized << 16);
} }
} // anonymous namespace
FormatType::FormatType() : format(GL_NONE), type(GL_NONE) {}
FormatType::FormatType(GLenum format_, GLenum type_) : format(format_), type(type_) {}
bool FormatType::operator<(const FormatType &other) const bool FormatType::operator<(const FormatType &other) const
{ {
if (format != other.format) if (format != other.format)
...@@ -56,25 +65,6 @@ bool FormatType::operator<(const FormatType &other) const ...@@ -56,25 +65,6 @@ bool FormatType::operator<(const FormatType &other) const
return type < other.type; return type < other.type;
} }
Type::Type() : bytes(0), bytesShift(0), specialInterpretation(false)
{
}
static Type GenTypeInfo(GLuint bytes, bool specialInterpretation)
{
Type info;
info.bytes = bytes;
GLuint i = 0;
while ((1u << i) < bytes)
{
++i;
}
info.bytesShift = i;
ASSERT((1u << info.bytesShift) == bytes);
info.specialInterpretation = specialInterpretation;
return info;
}
bool operator<(const Type &a, const Type &b) bool operator<(const Type &a, const Type &b)
{ {
return memcmp(&a, &b, sizeof(Type)) < 0; return memcmp(&a, &b, sizeof(Type)) < 0;
...@@ -494,13 +484,9 @@ bool InternalFormat::isRequiredRenderbufferFormat(const Version &version) const ...@@ -494,13 +484,9 @@ bool InternalFormat::isRequiredRenderbufferFormat(const Version &version) const
} }
} }
Format::Format(GLenum internalFormat) : Format(GetSizedInternalFormatInfo(internalFormat)) Format::Format(GLenum internalFormat) : Format(GetSizedInternalFormatInfo(internalFormat)) {}
{
}
Format::Format(const InternalFormat &internalFormat) : info(&internalFormat) Format::Format(const InternalFormat &internalFormat) : info(&internalFormat) {}
{
}
Format::Format(GLenum internalFormat, GLenum type) Format::Format(GLenum internalFormat, GLenum type)
: info(&GetInternalFormatInfo(internalFormat, type)) : info(&GetInternalFormatInfo(internalFormat, type))
...@@ -1043,30 +1029,30 @@ static FormatSet BuildAllSizedInternalFormatSet() ...@@ -1043,30 +1029,30 @@ static FormatSet BuildAllSizedInternalFormatSet()
return result; return result;
} }
const Type &GetTypeInfo(GLenum type) uint32_t GetPackedTypeInfo(GLenum type)
{ {
switch (type) switch (type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
case GL_BYTE: case GL_BYTE:
{ {
static const Type info = GenTypeInfo(1, false); static constexpr uint32_t kPacked = PackTypeInfo(1, false);
return info; return kPacked;
} }
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT:
case GL_SHORT: case GL_SHORT:
case GL_HALF_FLOAT: case GL_HALF_FLOAT:
case GL_HALF_FLOAT_OES: case GL_HALF_FLOAT_OES:
{ {
static const Type info = GenTypeInfo(2, false); static constexpr uint32_t kPacked = PackTypeInfo(2, false);
return info; return kPacked;
} }
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
case GL_INT: case GL_INT:
case GL_FLOAT: case GL_FLOAT:
{ {
static const Type info = GenTypeInfo(4, false); static constexpr uint32_t kPacked = PackTypeInfo(4, false);
return info; return kPacked;
} }
case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4:
...@@ -1074,8 +1060,8 @@ const Type &GetTypeInfo(GLenum type) ...@@ -1074,8 +1060,8 @@ const Type &GetTypeInfo(GLenum type)
case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
{ {
static const Type info = GenTypeInfo(2, true); static constexpr uint32_t kPacked = PackTypeInfo(2, true);
return info; return kPacked;
} }
case GL_UNSIGNED_INT_2_10_10_10_REV: case GL_UNSIGNED_INT_2_10_10_10_REV:
case GL_UNSIGNED_INT_24_8: case GL_UNSIGNED_INT_24_8:
...@@ -1083,18 +1069,17 @@ const Type &GetTypeInfo(GLenum type) ...@@ -1083,18 +1069,17 @@ const Type &GetTypeInfo(GLenum type)
case GL_UNSIGNED_INT_5_9_9_9_REV: case GL_UNSIGNED_INT_5_9_9_9_REV:
{ {
ASSERT(GL_UNSIGNED_INT_24_8_OES == GL_UNSIGNED_INT_24_8); ASSERT(GL_UNSIGNED_INT_24_8_OES == GL_UNSIGNED_INT_24_8);
static const Type info = GenTypeInfo(4, true); static constexpr uint32_t kPacked = PackTypeInfo(4, true);
return info; return kPacked;
} }
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
{ {
static const Type info = GenTypeInfo(8, true); static constexpr uint32_t kPacked = PackTypeInfo(8, true);
return info; return kPacked;
} }
default: default:
{ {
static const Type defaultInfo; return 0;
return defaultInfo;
} }
} }
} }
...@@ -2253,4 +2238,4 @@ VertexFormat::VertexFormat(GLenum typeIn, ...@@ -2253,4 +2238,4 @@ VertexFormat::VertexFormat(GLenum typeIn,
ASSERT(!(type == GL_FLOAT || type == GL_HALF_FLOAT || type == GL_FIXED) || ASSERT(!(type == GL_FLOAT || type == GL_HALF_FLOAT || type == GL_FIXED) ||
normalized == GL_FALSE); normalized == GL_FALSE);
} }
} } // namespace gl
...@@ -38,14 +38,27 @@ struct FormatType final ...@@ -38,14 +38,27 @@ struct FormatType final
struct Type struct Type
{ {
Type(); Type() : bytes(0), bytesShift(0), specialInterpretation(0) {}
Type(uint32_t packedTypeInfo)
: bytes(packedTypeInfo & 0xff),
bytesShift((packedTypeInfo >> 8) & 0xff),
specialInterpretation((packedTypeInfo >> 16) & 1)
{
}
GLuint bytes; GLuint bytes;
GLuint bytesShift; // Bit shift by this value to effectively divide/multiply by "bytes" in a GLuint bytesShift; // Bit shift by this value to effectively divide/multiply by "bytes" in a
// more optimal way // more optimal way
bool specialInterpretation; bool specialInterpretation;
}; };
const Type &GetTypeInfo(GLenum type);
uint32_t GetPackedTypeInfo(GLenum type);
ANGLE_INLINE const Type GetTypeInfo(GLenum type)
{
return Type(GetPackedTypeInfo(type));
}
// Information about an OpenGL internal format. Can be keyed on the internalFormat and type // Information about an OpenGL internal format. Can be keyed on the internalFormat and type
// members. // members.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment