Commit a07a2360 authored by oetuaho@nvidia.com's avatar oetuaho@nvidia.com

Micro-optimization in HandleVertexAttribPointer

vertexAttribPointer is a fairly common GL call, so substituting integer
division with bitwise and which has far less latency on common CPU
architectures is a worthwhile optimization.

IsPOT function is added for asserts that make sure this does not break.
Redundant comparison against zero is dropped from IsNPOT. In C++,
unsigned integers are specified to work with mod 2^n arithmetic.

TEST=gpu_unittests
BUG=400135

Review URL: https://codereview.chromium.org/439253002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287512 0039d316-1c4b-4281-b951-d872f2087c98
parent 308a1779
...@@ -156,8 +156,14 @@ class GLES2_UTILS_EXPORT GLES2Util { ...@@ -156,8 +156,14 @@ class GLES2_UTILS_EXPORT GLES2Util {
static uint32_t GetChannelsNeededForAttachmentType( static uint32_t GetChannelsNeededForAttachmentType(
int type, uint32_t max_color_attachments); int type, uint32_t max_color_attachments);
// Return true if value is neither a power of two nor zero.
static bool IsNPOT(uint32_t value) { static bool IsNPOT(uint32_t value) {
return value > 0 && (value & (value - 1)) != 0; return (value & (value - 1)) != 0;
}
// Return true if value is a power of two or zero.
static bool IsPOT(uint32_t value) {
return (value & (value - 1)) == 0;
} }
static std::string GetStringEnum(uint32_t value); static std::string GetStringEnum(uint32_t value);
......
...@@ -7205,13 +7205,15 @@ error::Error GLES2DecoderImpl::HandleVertexAttribPointer( ...@@ -7205,13 +7205,15 @@ error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
} }
GLsizei component_size = GLsizei component_size =
GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type); GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
if (offset % component_size > 0) { // component_size must be a power of two to use & as optimized modulo.
DCHECK(GLES2Util::IsPOT(component_size));
if (offset & (component_size - 1)) {
LOCAL_SET_GL_ERROR( LOCAL_SET_GL_ERROR(
GL_INVALID_OPERATION, GL_INVALID_OPERATION,
"glVertexAttribPointer", "offset not valid for type"); "glVertexAttribPointer", "offset not valid for type");
return error::kNoError; return error::kNoError;
} }
if (stride % component_size > 0) { if (stride & (component_size - 1)) {
LOCAL_SET_GL_ERROR( LOCAL_SET_GL_ERROR(
GL_INVALID_OPERATION, GL_INVALID_OPERATION,
"glVertexAttribPointer", "stride not valid for type"); "glVertexAttribPointer", "stride not valid for type");
...@@ -7984,8 +7986,7 @@ bool IsValidDXTSize(GLint level, GLsizei size) { ...@@ -7984,8 +7986,7 @@ bool IsValidDXTSize(GLint level, GLsizei size) {
} }
bool IsValidPVRTCSize(GLint level, GLsizei size) { bool IsValidPVRTCSize(GLint level, GLsizei size) {
// Ensure that the size is a power of two return GLES2Util::IsPOT(size);
return (size & (size - 1)) == 0;
} }
} // anonymous namespace. } // anonymous namespace.
......
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