Optimize Fragment Shader Type Match Validation

Improves ValidateFragmentShaderColorBufferTypeMatch by storing input and
output types into a bitmask for quick comparison when validation is
needed. This shows a 2% improvement to glDrawElements for the aquarium
workload.

BUG=angleproject:2203
Change-Id: Iade2ecf28383164e370b48442f01fba6c0962fba
Reviewed-on: https://chromium-review.googlesource.com/775019
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index ae564b7..a0617c2 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -397,18 +397,12 @@
     const Program *program         = context->getGLState().getProgram();
     const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
 
-    const auto &programOutputTypes = program->getOutputVariableTypes();
-    for (size_t drawBufferIdx = 0; drawBufferIdx < programOutputTypes.size(); drawBufferIdx++)
+    if (!DrawBufferTypeMask::ProgramOutputsMatchFramebuffer(
+            program->getDrawBufferTypeMask(), framebuffer->getDrawBufferTypeMask(),
+            program->getActiveOutputVariables(), framebuffer->getDrawBufferMask()))
     {
-        GLenum outputType = programOutputTypes[drawBufferIdx];
-        GLenum inputType  = framebuffer->getDrawbufferWriteType(drawBufferIdx);
-        if (outputType != GL_NONE && inputType != GL_NONE && inputType != outputType)
-        {
-            context->handleError(InvalidOperation() << "Fragment shader output type does not "
-                                                       "match the bound framebuffer attachment "
-                                                       "type.");
-            return false;
-        }
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), DrawBufferTypeMismatch);
+        return false;
     }
 
     return true;