b=590244; update ANGLE to r385; r=vlad; a=b
authorVladimir Vukicevic <vladimir@pobox.com>
Wed, 01 Sep 2010 15:04:51 -0400
changeset 51844 09872e2e2130f663f5d5e90500e3b4dfc679548a
parent 51843 2796c7e86c52d0404aaf754ccebd17db8cbd247f
child 51845 d460a2e5f0e84bcc77050d463aa73e13db981c35
push id15447
push uservladimir@mozilla.com
push dateWed, 01 Sep 2010 19:05:59 +0000
treeherdermozilla-central@09872e2e2130 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvlad, b
bugs590244
milestone2.0b6pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
b=590244; update ANGLE to r385; r=vlad; a=b
gfx/angle/CONTRIBUTORS
gfx/angle/LICENSE.preprocessor
gfx/angle/README.mozilla
gfx/angle/generated/glslang.cpp
gfx/angle/generated/glslang_tab.cpp
gfx/angle/src/build_angle.gyp
gfx/angle/src/compiler/BaseTypes.h
gfx/angle/src/compiler/Intermediate.cpp
gfx/angle/src/compiler/OutputGLSL.cpp
gfx/angle/src/compiler/ParseHelper.cpp
gfx/angle/src/compiler/PoolAlloc.h
gfx/angle/src/compiler/glslang.l
gfx/angle/src/compiler/glslang.y
gfx/angle/src/compiler/parseConst.cpp
gfx/angle/src/compiler/preprocessor/atom.c
gfx/angle/src/compiler/preprocessor/atom.h
gfx/angle/src/compiler/preprocessor/compile.h
gfx/angle/src/compiler/preprocessor/cpp.c
gfx/angle/src/compiler/preprocessor/cpp.h
gfx/angle/src/compiler/preprocessor/cppstruct.c
gfx/angle/src/compiler/preprocessor/memory.c
gfx/angle/src/compiler/preprocessor/memory.h
gfx/angle/src/compiler/preprocessor/parser.h
gfx/angle/src/compiler/preprocessor/preprocess.h
gfx/angle/src/compiler/preprocessor/scanner.c
gfx/angle/src/compiler/preprocessor/scanner.h
gfx/angle/src/compiler/preprocessor/slglobals.h
gfx/angle/src/compiler/preprocessor/symbols.c
gfx/angle/src/compiler/preprocessor/symbols.h
gfx/angle/src/compiler/preprocessor/tokens.c
gfx/angle/src/compiler/preprocessor/tokens.h
gfx/angle/src/libEGL/Display.cpp
gfx/angle/src/libEGL/Display.h
gfx/angle/src/libEGL/libEGL.vcproj
gfx/angle/src/libGLESv2/Blit.cpp
gfx/angle/src/libGLESv2/Context.cpp
gfx/angle/src/libGLESv2/Texture.cpp
gfx/angle/src/libGLESv2/Texture.h
gfx/angle/src/libGLESv2/libGLESv2.cpp
gfx/angle/src/libGLESv2/utilities.cpp
gfx/angle/src/libGLESv2/utilities.h
--- a/gfx/angle/CONTRIBUTORS
+++ b/gfx/angle/CONTRIBUTORS
@@ -12,11 +12,13 @@ TransGaming Inc.
  Andrew Lewycky
  Gavriel State
  Shannon Woods
 
 Google Inc.
  Henry Bridge
  Vangelis Kokkevis
  Alok Priyadarshi
+ Alastair Patrick
 
 Aitor Moreno <aitormoreno at gmail.com>
 Jim Hauxwell <james at dattrax.co.uk>
+Vladimir Vukicevic <vladimir at mozilla.com>
new file mode 100644
--- /dev/null
+++ b/gfx/angle/LICENSE.preprocessor
@@ -0,0 +1,45 @@
+Files in src/compiler/preprocessor are provided under the following license:
+
+****************************************************************************
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+****************************************************************************
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -1,18 +1,16 @@
 This is the ANGLE project, from http://code.google.com/p/angleproject/.
 
-Current revision: r367
+Current revision: r385
 
 Local patches:
     angle-nspr.patch - use NSPR for TLS
 
     angle-shared.patch - add declspec dllexport/dllimport support on win32
 
-    angle-sunstudio.patch - Fix compilation with Sun Studio on Solaris
-
     fix-compile.patch - Remove some trailing commas
 
 To regenerate the flex/yacc generated files:
 
 flex --noline --nounistd --outfile=generated/glslang.cpp src/compiler/glslang.l
 bison --no-lines --defines=generated/glslang_tab.h --skeleton=yacc.c --output=generated/glslang_tab.cpp src/compiler/glslang.y
 
--- a/gfx/angle/generated/glslang.cpp
+++ b/gfx/angle/generated/glslang.cpp
@@ -1,10 +1,10 @@
 
-#line 3 "glslang.cpp"
+#line 3 "generated/glslang.cpp"
 
 #define  YY_INT_ALIGNED short int
 
 /* A lexical scanner generated by flex */
 
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
@@ -2676,26 +2676,26 @@ int PaParseStrings(char* argv[], int str
     cpp->PaArgv     = argv;
     cpp->PaArgc     = argc;
     cpp->PaStrLen   = strLen;
     cpp->pastFirstStatement = 0;
     yylineno   = 1;
    
     if (*cpp->PaStrLen >= 0) {    
         int ret = yyparse((void*)(&parseContextLocal));
-        if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
+        if (ret || cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
              return 1;
         else
              return 0;
     }
     else
         return 0;
 }
 
-void yyerror(char *s) 
+void yyerror(const char *s) 
 {
     if (((TParseContext *)cpp->pC)->AfterEOF) {
         if (cpp->tokensBeforeEOF == 1) {
             GlobalParseContext->error(yylineno, "syntax error", "pre-mature EOF", s, "");
             GlobalParseContext->recover();
         }
     } else {
         GlobalParseContext->error(yylineno, "syntax error", yytext, s, "");
--- a/gfx/angle/generated/glslang_tab.cpp
+++ b/gfx/angle/generated/glslang_tab.cpp
@@ -92,17 +92,17 @@ Jutta Degener, 1995
 /*
 TODO(alokp): YYPARSE_PARAM_DECL is only here to support old bison.exe in
 compiler/tools. Remove it when we can exclusively use the newer version.
 */
 #define YYPARSE_PARAM_DECL void*
 #define parseContext ((TParseContext*)(parseContextLocal))
 #define YYLEX_PARAM parseContextLocal
 #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
-extern void yyerror(char*);
+extern void yyerror(const char*);
 
 #define FRAG_VERT_ONLY(S, L) {                                                  \
     if (parseContext->language != EShLangFragment &&                             \
         parseContext->language != EShLangVertex) {                               \
         parseContext->error(L, " supported in vertex/fragment shaders only ", S, "", "");   \
         parseContext->recover();                                                            \
     }                                                                           \
 }
--- a/gfx/angle/src/build_angle.gyp
+++ b/gfx/angle/src/build_angle.gyp
@@ -226,17 +226,20 @@
             'libEGL/libEGL.def',
             'libEGL/main.cpp',
             'libEGL/main.h',
             'libEGL/Surface.cpp',
             'libEGL/Surface.h',
           ],
           'msvs_settings': {
             'VCLinkerTool': {
-              'AdditionalDependencies': ['d3d9.lib'],
+              'AdditionalLibraryDirectories': ['$(DXSDK_DIR)/lib/x86'],
+              'AdditionalDependencies': [
+                'dxguid.lib',
+              ],
             }
           },
         },
       ],
     }],
   ],
 }
 
--- a/gfx/angle/src/compiler/BaseTypes.h
+++ b/gfx/angle/src/compiler/BaseTypes.h
@@ -18,17 +18,17 @@ enum TPrecision
 {
     // These need to be kept sorted
     EbpUndefined,
     EbpLow,
     EbpMedium,
     EbpHigh,
 };
 
-__inline const char* getPrecisionString(TPrecision p)
+inline const char* getPrecisionString(TPrecision p)
 {
     switch(p)
     {
     case EbpHigh:		return "highp";		break;
     case EbpMedium:		return "mediump";	break;
     case EbpLow:		return "lowp";		break;
     default:			return "mediump";   break;   // Safest fallback
     }
@@ -46,17 +46,17 @@ enum TBasicType
     EbtGuardSamplerBegin,  // non type:  see implementation of IsSampler()
     EbtSampler2D,
     EbtSamplerCube,
     EbtGuardSamplerEnd,    // non type:  see implementation of IsSampler()
     EbtStruct,
     EbtAddress,            // should be deprecated??
 };
 
-__inline bool IsSampler(TBasicType type)
+inline bool IsSampler(TBasicType type)
 {
     return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
 }
 
 //
 // Qualifiers and built-ins.  These are mainly used to see what can be read
 // or written, and by the machine dependent translator to know which registers
 // to allocate variables in.  Since built-ins tend to go to different registers
@@ -99,17 +99,17 @@ enum TQualifier
 
     // end of list
     EvqLast,
 };
 
 //
 // This is just for debug print out, carried along with the definitions above.
 //
-__inline const char* getQualifierString(TQualifier q)
+inline const char* getQualifierString(TQualifier q)
 {
     switch(q)
     {
     case EvqTemporary:      return "Temporary";      break;
     case EvqGlobal:         return "Global";         break;
     case EvqConst:          return "const";          break;
     case EvqConstReadOnly:  return "const";          break;
     case EvqAttribute:      return "attribute";      break;
--- a/gfx/angle/src/compiler/Intermediate.cpp
+++ b/gfx/angle/src/compiler/Intermediate.cpp
@@ -5,26 +5,28 @@
 //
 
 //
 // Build the intermediate representation.
 //
 
 #include <float.h>
 #include <limits.h>
+#include <algorithm>
 
 #include "compiler/localintermediate.h"
 #include "compiler/QualifierAlive.h"
 #include "compiler/RemoveTree.h"
 
 bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray);
 
-TPrecision GetHighestPrecision( TPrecision left, TPrecision right ){
+static TPrecision GetHigherPrecision( TPrecision left, TPrecision right ){
     return left > right ? left : right;
 }
+
 ////////////////////////////////////////////////////////////////////////////
 //
 // First set of functions are to help build the intermediate representation.
 // These functions are not member functions of the nodes.
 // They are called from parser productions.
 //
 /////////////////////////////////////////////////////////////////////////////
 
@@ -106,22 +108,16 @@ TIntermTyped* TIntermediate::addBinaryMa
     node->setLeft(left);
     node->setRight(right);
     if (! node->promote(infoSink))
         return 0;
 
     TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
     TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
 
-    if (leftTempConstant)
-        leftTempConstant = left->getAsConstantUnion();
-
-    if (rightTempConstant)
-        rightTempConstant = right->getAsConstantUnion();
-
     //
     // See if we can fold constants.
     //
 
     TIntermTyped* typedReturnNode = 0;
     if ( leftTempConstant && rightTempConstant) {
         typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
 
@@ -759,44 +755,48 @@ bool TIntermUnary::promote(TInfoSink&)
 //
 // Establishes the type of the resultant operation, as well as
 // makes the operator the correct one for the operands.
 //
 // Returns false if operator can't work on operands.
 //
 bool TIntermBinary::promote(TInfoSink& infoSink)
 {
-    int size = left->getNominalSize();
-    if (right->getNominalSize() > size)
-        size = right->getNominalSize();
-
-    TBasicType type = left->getBasicType();
-
-    //
-    // Arrays have to be exact matches.
-    //
-    if ((left->isArray() || right->isArray()) && (left->getType() != right->getType()))
+    // GLSL ES 2.0 does not support implicit type casting.
+    // So the basic type should always match.
+    if (left->getBasicType() != right->getBasicType())
         return false;
 
     //
     // Base assumption:  just make the type the same as the left
     // operand.  Then only deviations from this need be coded.
     //
     setType(left->getType());
 
-    TPrecision highestPrecision = GetHighestPrecision(left->getPrecision(), right->getPrecision());
-    getTypePointer()->changePrecision(highestPrecision);
+    // The result gets promoted to the highest precision.
+    TPrecision higherPrecision = GetHigherPrecision(left->getPrecision(), right->getPrecision());
+    getTypePointer()->changePrecision(higherPrecision);
+
+    // Binary operations results in temporary variables unless both
+    // operands are const.
+    if (left->getQualifier() != EvqConst || right->getQualifier() != EvqConst) {
+        getTypePointer()->changeQualifier(EvqTemporary);
+    }
 
     //
     // Array operations.
     //
-    if (left->isArray()) {
+    if (left->isArray() || right->isArray()) {
+        //
+        // Arrays types have to be exact matches.
+        //
+        if (left->getType() != right->getType())
+            return false;
 
         switch (op) {
-
             //
             // Promote to conditional
             //
             case EOpEqual:
             case EOpNotEqual:
                 setType(TType(EbtBool, EbpUndefined));
                 break;
 
@@ -807,27 +807,26 @@ bool TIntermBinary::promote(TInfoSink& i
             case EOpInitialize:
                 getTypePointer()->setArraySize(left->getType().getArraySize());
                 getTypePointer()->setArrayInformationType(left->getType().getArrayInformationType());
                 break;
 
             default:
                 return false;
         }
-
         return true;
     }
 
+    int size = std::max(left->getNominalSize(), right->getNominalSize());
+
     //
-    // All scalars.  Code after this test assumes this case is removed!
+    // All scalars. Code after this test assumes this case is removed!
     //
     if (size == 1) {
-
         switch (op) {
-
             //
             // Promote to conditional
             //
             case EOpEqual:
             case EOpNotEqual:
             case EOpLessThan:
             case EOpGreaterThan:
             case EOpLessThanEqual:
@@ -835,67 +834,70 @@ bool TIntermBinary::promote(TInfoSink& i
                 setType(TType(EbtBool, EbpUndefined));
                 break;
 
             //
             // And and Or operate on conditionals
             //
             case EOpLogicalAnd:
             case EOpLogicalOr:
+                // Both operands must be of type bool.
                 if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool)
                     return false;
                 setType(TType(EbtBool, EbpUndefined));
                 break;
 
-            //
-            // Everything else should have matching types
-            //
             default:
-                if (left->getBasicType() != right->getBasicType() ||
-                    left->isMatrix()     != right->isMatrix())
-                    return false;
+                break;
         }
-
         return true;
     }
 
-    //
+    // If we reach here, at least one of the operands is vector or matrix.
+    // The other operand could be a scalar, vector, or matrix.
     // Are the sizes compatible?
     //
-    if ( left->getNominalSize() != size &&  left->getNominalSize() != 1 ||
-        right->getNominalSize() != size && right->getNominalSize() != 1)
-        return false;
+    if (left->getNominalSize() != right->getNominalSize()) {
+        // If the nominal size of operands do not match:
+        // One of them must be scalar.
+        if (left->getNominalSize() != 1 && right->getNominalSize() != 1)
+            return false;
+        // Operator cannot be of type pure assignment.
+        if (op == EOpAssign || op == EOpInitialize)
+            return false;
+    }
 
     //
     // Can these two operands be combined?
     //
+    TBasicType basicType = left->getBasicType();
     switch (op) {
         case EOpMul:
             if (!left->isMatrix() && right->isMatrix()) {
                 if (left->isVector())
                     op = EOpVectorTimesMatrix;
                 else {
                     op = EOpMatrixTimesScalar;
-                    setType(TType(type, highestPrecision, EvqTemporary, size, true));
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, true));
                 }
             } else if (left->isMatrix() && !right->isMatrix()) {
                 if (right->isVector()) {
                     op = EOpMatrixTimesVector;
-                    setType(TType(type, highestPrecision, EvqTemporary, size, false));
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
                 } else {
                     op = EOpMatrixTimesScalar;
                 }
             } else if (left->isMatrix() && right->isMatrix()) {
                 op = EOpMatrixTimesMatrix;
             } else if (!left->isMatrix() && !right->isMatrix()) {
                 if (left->isVector() && right->isVector()) {
                     // leave as component product
                 } else if (left->isVector() || right->isVector()) {
                     op = EOpVectorTimesScalar;
-                    setType(TType(type, highestPrecision, EvqTemporary, size, false));
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
                 }
             } else {
                 infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
                 return false;
             }
             break;
         case EOpMulAssign:
             if (!left->isMatrix() && right->isMatrix()) {
@@ -914,75 +916,54 @@ bool TIntermBinary::promote(TInfoSink& i
                 op = EOpMatrixTimesMatrixAssign;
             } else if (!left->isMatrix() && !right->isMatrix()) {
                 if (left->isVector() && right->isVector()) {
                     // leave as component product
                 } else if (left->isVector() || right->isVector()) {
                     if (! left->isVector())
                         return false;
                     op = EOpVectorTimesScalarAssign;
-                    setType(TType(type, highestPrecision, EvqTemporary, size, false));
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
                 }
             } else {
                 infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
                 return false;
             }
             break;
+
         case EOpAssign:
         case EOpInitialize:
-            if (left->getNominalSize() != right->getNominalSize())
-                return false;
-            // fall through
         case EOpAdd:
         case EOpSub:
         case EOpDiv:
         case EOpAddAssign:
         case EOpSubAssign:
         case EOpDivAssign:
             if (left->isMatrix() && right->isVector() ||
-                left->isVector() && right->isMatrix() ||
-                left->getBasicType() != right->getBasicType())
+                left->isVector() && right->isMatrix())
                 return false;
-            setType(TType(type, highestPrecision, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
+            setType(TType(basicType, higherPrecision, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
             break;
 
         case EOpEqual:
         case EOpNotEqual:
         case EOpLessThan:
         case EOpGreaterThan:
         case EOpLessThanEqual:
         case EOpGreaterThanEqual:
             if (left->isMatrix() && right->isVector() ||
-                left->isVector() && right->isMatrix() ||
-                left->getBasicType() != right->getBasicType())
+                left->isVector() && right->isMatrix())
                 return false;
             setType(TType(EbtBool, EbpUndefined));
             break;
 
         default:
             return false;
     }
-
-    //
-    // One more check for assignment.  The Resulting type has to match the left operand.
-    //
-    switch (op) {
-        case EOpAssign:
-        case EOpInitialize:
-        case EOpAddAssign:
-        case EOpSubAssign:
-        case EOpMulAssign:
-        case EOpDivAssign:
-            if (getType() != left->getType())
-                return false;
-            break;
-        default:
-            break;
-    }
-
+    
     return true;
 }
 
 bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
 {
     TTypeList* fields = leftNodeType.getStruct();
 
     size_t structSize = fields->size();
--- a/gfx/angle/src/compiler/OutputGLSL.cpp
+++ b/gfx/angle/src/compiler/OutputGLSL.cpp
@@ -299,18 +299,16 @@ bool TOutputGLSL::visitBinary(Visit visi
         default: UNREACHABLE(); break;
     }
 
     return visitChildren;
 }
 
 bool TOutputGLSL::visitUnary(Visit visit, TIntermUnary* node)
 {
-    TInfoSinkBase& out = objSink();
-
     switch (node->getOp())
     {
         case EOpNegative: writeTriplet(visit, "(-", NULL, ")"); break;
         case EOpVectorLogicalNot: writeTriplet(visit, "not(", NULL, ")"); break;
         case EOpLogicalNot: writeTriplet(visit, "(!", NULL, ")"); break;
 
         case EOpPostIncrement: writeTriplet(visit, "(", NULL, "++)"); break;
         case EOpPostDecrement: writeTriplet(visit, "(", NULL, "--)"); break;
@@ -645,18 +643,16 @@ bool TOutputGLSL::visitLoop(Visit visit,
 
     // No need to visit children. They have been already processed in
     // this function.
     return false;
 }
 
 bool TOutputGLSL::visitBranch(Visit visit, TIntermBranch* node)
 {
-    TInfoSinkBase &out = objSink();
-
     switch (node->getFlowOp())
     {
         case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break;
         case EOpBreak: writeTriplet(visit, "break", NULL, NULL); break;
         case EOpContinue: writeTriplet(visit, "continue", NULL, NULL); break;
         case EOpReturn: writeTriplet(visit, "return ", NULL, NULL); break;
         default: UNREACHABLE(); break;
     }
--- a/gfx/angle/src/compiler/ParseHelper.cpp
+++ b/gfx/angle/src/compiler/ParseHelper.cpp
@@ -908,31 +908,34 @@ bool TParseContext::extensionErrorCheck(
 
 //
 // Look up a function name in the symbol table, and make sure it is a function.
 //
 // Return the function symbol if found, otherwise 0.
 //
 const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
 {
-    const TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn);
+    // First find by unmangled name to check whether the function name has been
+    // hidden by a variable name or struct typename.
+    const TSymbol* symbol = symbolTable.find(call->getName(), builtIn);
+    if (symbol == 0) {
+        symbol = symbolTable.find(call->getMangledName(), builtIn);
+    }
 
-    if (symbol == 0) {        
+    if (symbol == 0) {
         error(line, "no matching overloaded function found", call->getName().c_str(), "");
         return 0;
     }
 
-    if (! symbol->isFunction()) {
+    if (!symbol->isFunction()) {
         error(line, "function name expected", call->getName().c_str(), "");
         return 0;
     }
-    
-    const TFunction* function = static_cast<const TFunction*>(symbol);
-    
-    return function;
+
+    return static_cast<const TFunction*>(symbol);
 }
 
 //
 // Initializers show up in several places in the grammar.  Have one set of
 // code to handle them here.
 //
 bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, 
                                        TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
--- a/gfx/angle/src/compiler/PoolAlloc.h
+++ b/gfx/angle/src/compiler/PoolAlloc.h
@@ -152,21 +152,22 @@ public:
     // by calling pop(), and to not have to solve memory leak problems.
     //
 
 protected:
     friend struct tHeader;
     
     struct tHeader {
         tHeader(tHeader* nextPage, size_t pageCount) :
+            nextPage(nextPage),
+            pageCount(pageCount)
 #ifdef GUARD_BLOCKS
-            lastAllocation(0),
+          , lastAllocation(0)
 #endif
-            nextPage(nextPage),
-            pageCount(pageCount) { }
+            { }
 
         ~tHeader() {
 #ifdef GUARD_BLOCKS
             if (lastAllocation)
                 lastAllocation->checkAllocList();
 #endif
         }
 
--- a/gfx/angle/src/compiler/glslang.l
+++ b/gfx/angle/src/compiler/glslang.l
@@ -304,26 +304,26 @@ int PaParseStrings(char* argv[], int str
     cpp->PaArgv     = argv;
     cpp->PaArgc     = argc;
     cpp->PaStrLen   = strLen;
     cpp->pastFirstStatement = 0;
     yylineno   = 1;
    
     if (*cpp->PaStrLen >= 0) {    
         int ret = yyparse((void*)(&parseContextLocal));
-        if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
+        if (ret || cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
              return 1;
         else
              return 0;
     }
     else
         return 0;
 }
 
-void yyerror(char *s) 
+void yyerror(const char *s) 
 {
     if (((TParseContext *)cpp->pC)->AfterEOF) {
         if (cpp->tokensBeforeEOF == 1) {
             GlobalParseContext->error(yylineno, "syntax error", "pre-mature EOF", s, "");
             GlobalParseContext->recover();
         }
     } else {
         GlobalParseContext->error(yylineno, "syntax error", yytext, s, "");
--- a/gfx/angle/src/compiler/glslang.y
+++ b/gfx/angle/src/compiler/glslang.y
@@ -33,17 +33,17 @@ Jutta Degener, 1995
 /*
 TODO(alokp): YYPARSE_PARAM_DECL is only here to support old bison.exe in
 compiler/tools. Remove it when we can exclusively use the newer version.
 */
 #define YYPARSE_PARAM_DECL void*
 #define parseContext ((TParseContext*)(parseContextLocal))
 #define YYLEX_PARAM parseContextLocal
 #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
-extern void yyerror(char*);
+extern void yyerror(const char*);
 
 #define FRAG_VERT_ONLY(S, L) {                                                  \
     if (parseContext->language != EShLangFragment &&                             \
         parseContext->language != EShLangVertex) {                               \
         parseContext->error(L, " supported in vertex/fragment shaders only ", S, "", "");   \
         parseContext->recover();                                                            \
     }                                                                           \
 }
--- a/gfx/angle/src/compiler/parseConst.cpp
+++ b/gfx/angle/src/compiler/parseConst.cpp
@@ -7,33 +7,41 @@
 #include "compiler/ParseHelper.h"
 
 //
 // Use this class to carry along data from node to node in 
 // the traversal
 //
 class TConstTraverser : public TIntermTraverser {
 public:
-    TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t) : unionArray(cUnion), type(t),
-        constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), symbolTable(symTable), error(false), isMatrix(false), matrixSize(0)
-	{
-		index = 0;
-	}
+    TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t)
+        : error(false),
+          index(0),
+          unionArray(cUnion),
+          type(t),
+          constructorType(constructType),
+          singleConstantParam(singleConstParam),
+          infoSink(sink),
+          symbolTable(symTable),
+          size(0),
+          isMatrix(false),
+          matrixSize(0) {
+    }
 
-	bool error;
+    bool error;
 
 protected:
-	void visitSymbol(TIntermSymbol*);
-	void visitConstantUnion(TIntermConstantUnion*);
-	bool visitBinary(Visit visit, TIntermBinary*);
-	bool visitUnary(Visit visit, TIntermUnary*);
-	bool visitSelection(Visit visit, TIntermSelection*);
-	bool visitAggregate(Visit visit, TIntermAggregate*);
-	bool visitLoop(Visit visit, TIntermLoop*);
-	bool visitBranch(Visit visit, TIntermBranch*);
+    void visitSymbol(TIntermSymbol*);
+    void visitConstantUnion(TIntermConstantUnion*);
+    bool visitBinary(Visit visit, TIntermBinary*);
+    bool visitUnary(Visit visit, TIntermUnary*);
+    bool visitSelection(Visit visit, TIntermSelection*);
+    bool visitAggregate(Visit visit, TIntermAggregate*);
+    bool visitLoop(Visit visit, TIntermLoop*);
+    bool visitBranch(Visit visit, TIntermBranch*);
 
     int index;
     ConstantUnion *unionArray;
     TType type;
     TOperator constructorType;
     bool singleConstantParam;
     TInfoSink& infoSink;
     TSymbolTable& symbolTable;
--- a/gfx/angle/src/compiler/preprocessor/atom.c
+++ b/gfx/angle/src/compiler/preprocessor/atom.c
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
@@ -619,17 +614,17 @@ static int AddAtomFixed(AtomTable *atabl
 
 /*
  * InitAtomTable() - Initialize the atom table.
  *
  */
 
 int InitAtomTable(AtomTable *atable, int htsize)
 {
-    int ii;
+    unsigned int ii;
 
     htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
     if (!InitStringTable(&atable->stable))
         return 0;
     if (!InitHashTable(&atable->htable, htsize))
         return 0;
 
     atable->nextFree = 0;
--- a/gfx/angle/src/compiler/preprocessor/atom.h
+++ b/gfx/angle/src/compiler/preprocessor/atom.h
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/compile.h
+++ b/gfx/angle/src/compiler/preprocessor/compile.h
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/cpp.c
+++ b/gfx/angle/src/compiler/preprocessor/cpp.c
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/cpp.h
+++ b/gfx/angle/src/compiler/preprocessor/cpp.h
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/cppstruct.c
+++ b/gfx/angle/src/compiler/preprocessor/cppstruct.c
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/memory.c
+++ b/gfx/angle/src/compiler/preprocessor/memory.c
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/memory.h
+++ b/gfx/angle/src/compiler/preprocessor/memory.h
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/parser.h
+++ b/gfx/angle/src/compiler/preprocessor/parser.h
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/preprocess.h
+++ b/gfx/angle/src/compiler/preprocessor/preprocess.h
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/scanner.c
+++ b/gfx/angle/src/compiler/preprocessor/scanner.c
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/scanner.h
+++ b/gfx/angle/src/compiler/preprocessor/scanner.h
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/slglobals.h
+++ b/gfx/angle/src/compiler/preprocessor/slglobals.h
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/symbols.c
+++ b/gfx/angle/src/compiler/preprocessor/symbols.c
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
@@ -152,17 +147,17 @@ Scope *PopScope(void)
  * NewSymbol() - Allocate a new symbol node;
  *
  */
 
 Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind)
 {
     Symbol *lSymb;
     char *pch;
-    int ii;
+    unsigned int ii;
 
     lSymb = (Symbol *) mem_Alloc(fScope->pool, sizeof(Symbol));
     lSymb->left = NULL;
     lSymb->right = NULL;
     lSymb->next = NULL;
     lSymb->name = name;
     lSymb->loc = *loc;
     lSymb->kind = kind;
--- a/gfx/angle/src/compiler/preprocessor/symbols.h
+++ b/gfx/angle/src/compiler/preprocessor/symbols.h
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/compiler/preprocessor/tokens.c
+++ b/gfx/angle/src/compiler/preprocessor/tokens.c
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
@@ -205,17 +200,17 @@ void DeleteTokenStream(TokenStream *pTok
 /*
  * RecordToken() - Add a token to the end of a list for later playback or printout.
  *
  */
 
 void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
 {
     const char *s;
-    unsigned char *str=NULL;
+    char *str=NULL;
 
     if (token > 256)
         lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80));
     else
         lAddByte(pTok, (unsigned char)(token & 0x7f));
     switch (token) {
     case CPP_IDENTIFIER:
     case CPP_TYPEIDENTIFIER:
--- a/gfx/angle/src/compiler/preprocessor/tokens.h
+++ b/gfx/angle/src/compiler/preprocessor/tokens.h
@@ -1,13 +1,8 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
 /****************************************************************************\
 Copyright (c) 2002, NVIDIA Corporation.
 
 NVIDIA Corporation("NVIDIA") supplies this software to you in
 consideration of your agreement to the following terms, and your use,
 installation, modification or redistribution of this NVIDIA software
 constitutes acceptance of these terms.  If you do not agree with these
 terms, please do not use, install, modify or redistribute this NVIDIA
--- a/gfx/angle/src/libEGL/Display.cpp
+++ b/gfx/angle/src/libEGL/Display.cpp
@@ -18,17 +18,20 @@
 #include "libEGL/main.h"
 
 #define REF_RAST 0   // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
 
 namespace egl
 {
 Display::Display(HDC deviceContext) : mDc(deviceContext)
 {
+    mD3d9Module = NULL;
+    
     mD3d9 = NULL;
+    mD3d9ex = NULL;
     mDevice = NULL;
     mDeviceWindow = NULL;
 
     mAdapter = D3DADAPTER_DEFAULT;
 
     #if REF_RAST == 1 || defined(FORCE_REF_RAST)
         mDeviceType = D3DDEVTYPE_REF;
     #else
@@ -47,17 +50,48 @@ Display::~Display()
 
 bool Display::initialize()
 {
     if (isInitialized())
     {
         return true;
     }
 
-    mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
+    mD3d9Module = LoadLibrary(TEXT("d3d9.dll"));
+    if (mD3d9Module == NULL)
+    {
+        terminate();
+        return false;
+    }
+
+    typedef IDirect3D9* (WINAPI *Direct3DCreate9Func)(UINT);
+    Direct3DCreate9Func Direct3DCreate9Ptr = reinterpret_cast<Direct3DCreate9Func>(GetProcAddress(mD3d9Module, "Direct3DCreate9"));
+
+    if (Direct3DCreate9Ptr == NULL)
+    {
+        terminate();
+        return false;
+    }
+
+    typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
+    Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
+
+    // Use Direct3D9Ex if available. Among other things, this version is less
+    // inclined to report a lost context, for example when the user switches
+    // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
+    if (Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
+    {
+        ASSERT(mD3d9ex);
+        mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
+        ASSERT(mD3d9);
+    }
+    else
+    {
+        mD3d9 = Direct3DCreate9Ptr(D3D_SDK_VERSION);
+    }
 
     if (mD3d9)
     {
         if (mDc != NULL)
         {
         //  UNIMPLEMENTED();   // FIXME: Determine which adapter index the device context corresponds to
         }
 
@@ -65,96 +99,94 @@ bool Display::initialize()
 
         if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
         {
             return error(EGL_BAD_ALLOC, false);
         }
 
         if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
         {
-            mD3d9->Release();
-            mD3d9 = NULL;
+            terminate();
+            return error(EGL_NOT_INITIALIZED, false);
         }
-        else
+
+        mMinSwapInterval = 4;
+        mMaxSwapInterval = 0;
+
+        if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) {mMinSwapInterval = std::min(mMinSwapInterval, 0); mMaxSwapInterval = std::max(mMaxSwapInterval, 0);}
+        if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE)       {mMinSwapInterval = std::min(mMinSwapInterval, 1); mMaxSwapInterval = std::max(mMaxSwapInterval, 1);}
+        if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)       {mMinSwapInterval = std::min(mMinSwapInterval, 2); mMaxSwapInterval = std::max(mMaxSwapInterval, 2);}
+        if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE)     {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);}
+        if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR)      {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);}
+
+        const D3DFORMAT renderTargetFormats[] =
         {
-            mMinSwapInterval = 4;
-            mMaxSwapInterval = 0;
+            D3DFMT_A1R5G5B5,
+        //  D3DFMT_A2R10G10B10,   // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
+            D3DFMT_A8R8G8B8,
+            D3DFMT_R5G6B5,
+            D3DFMT_X1R5G5B5,
+            D3DFMT_X8R8G8B8
+        };
 
-            if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) {mMinSwapInterval = std::min(mMinSwapInterval, 0); mMaxSwapInterval = std::max(mMaxSwapInterval, 0);}
-            if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE)       {mMinSwapInterval = std::min(mMinSwapInterval, 1); mMaxSwapInterval = std::max(mMaxSwapInterval, 1);}
-            if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)       {mMinSwapInterval = std::min(mMinSwapInterval, 2); mMaxSwapInterval = std::max(mMaxSwapInterval, 2);}
-            if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE)     {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);}
-            if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR)      {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);}
+        const D3DFORMAT depthStencilFormats[] =
+        {
+        //  D3DFMT_D16_LOCKABLE,
+            D3DFMT_D32,
+        //  D3DFMT_D15S1,
+            D3DFMT_D24S8,
+            D3DFMT_D24X8,
+        //  D3DFMT_D24X4S4,
+            D3DFMT_D16,
+        //  D3DFMT_D32F_LOCKABLE,
+        //  D3DFMT_D24FS8
+        };
 
-            const D3DFORMAT renderTargetFormats[] =
-            {
-                D3DFMT_A1R5G5B5,
-            //  D3DFMT_A2R10G10B10,   // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
-                D3DFMT_A8R8G8B8,
-                D3DFMT_R5G6B5,
-                D3DFMT_X1R5G5B5,
-                D3DFMT_X8R8G8B8
-            };
+        D3DDISPLAYMODE currentDisplayMode;
+        mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+        ConfigSet configSet;
 
-            const D3DFORMAT depthStencilFormats[] =
+        for (int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(D3DFORMAT); formatIndex++)
+        {
+            D3DFORMAT renderTargetFormat = renderTargetFormats[formatIndex];
+
+            HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
+
+            if (SUCCEEDED(result))
             {
-            //  D3DFMT_D16_LOCKABLE,
-                D3DFMT_D32,
-            //  D3DFMT_D15S1,
-                D3DFMT_D24S8,
-                D3DFMT_D24X8,
-            //  D3DFMT_D24X4S4,
-                D3DFMT_D16,
-            //  D3DFMT_D32F_LOCKABLE,
-            //  D3DFMT_D24FS8
-            };
-
-            D3DDISPLAYMODE currentDisplayMode;
-            mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+                for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++)
+                {
+                    D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex];
+                    HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
 
-            ConfigSet configSet;
-
-            for (int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(D3DFORMAT); formatIndex++)
-            {
-                D3DFORMAT renderTargetFormat = renderTargetFormats[formatIndex];
-
-                HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
-
-                if (SUCCEEDED(result))
-                {
-                    for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++)
+                    if (SUCCEEDED(result))
                     {
-                        D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex];
-                        HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
+                        HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
 
                         if (SUCCEEDED(result))
                         {
-                            HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
+                            // FIXME: Enumerate multi-sampling
 
-                            if (SUCCEEDED(result))
-                            {
-                                // FIXME: Enumerate multi-sampling
-
-                                configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0);
-                            }
+                            configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0);
                         }
                     }
                 }
             }
+        }
 
-            // Give the sorted configs a unique ID and store them internally
-            EGLint index = 1;
-            for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
-            {
-                Config configuration = *config;
-                configuration.mConfigID = index;
-                index++;
+        // Give the sorted configs a unique ID and store them internally
+        EGLint index = 1;
+        for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
+        {
+            Config configuration = *config;
+            configuration.mConfigID = index;
+            index++;
 
-                mConfigSet.mSet.insert(configuration);
-            }
+            mConfigSet.mSet.insert(configuration);
         }
 
         if (!createDevice())
         {
             terminate();
 
             return false;
         }
@@ -194,16 +226,28 @@ void Display::terminate()
         mD3d9 = NULL;
     }
 
     if (mDeviceWindow)
     {
         DestroyWindow(mDeviceWindow);
         mDeviceWindow = NULL;
     }
+    
+    if (mD3d9ex)
+    {
+        mD3d9ex->Release();
+        mD3d9ex = NULL;
+    }
+
+    if (mD3d9Module)
+    {
+        FreeLibrary(mD3d9Module);
+        mD3d9Module = NULL;
+    }
 }
 
 void Display::startScene()
 {
     if (!mSceneStarted)
     {
         long result = mDevice->BeginScene();
         ASSERT(SUCCEEDED(result));
--- a/gfx/angle/src/libEGL/Display.h
+++ b/gfx/angle/src/libEGL/Display.h
@@ -60,19 +60,22 @@ class Display
 
     virtual IDirect3DDevice9 *getDevice();
     virtual D3DCAPS9 getDeviceCaps();
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Display);
     const HDC mDc;
 
+    HMODULE mD3d9Module;
+    
     UINT mAdapter;
     D3DDEVTYPE mDeviceType;
-    IDirect3D9 *mD3d9;
+    IDirect3D9 *mD3d9;  // Always valid after successful initialization.
+    IDirect3D9Ex *mD3d9ex;  // Might be null if D3D9Ex is not supported.
     IDirect3DDevice9 *mDevice;
     D3DCAPS9 mDeviceCaps;
     HWND mDeviceWindow;
 
     bool mSceneStarted;
     GLint mSwapInterval;
     EGLint mMaxSwapInterval;
     EGLint mMinSwapInterval;
--- a/gfx/angle/src/libEGL/libEGL.vcproj
+++ b/gfx/angle/src/libEGL/libEGL.vcproj
@@ -57,17 +57,17 @@
 			<Tool
 				Name="VCResourceCompilerTool"
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="d3d9.lib"
+				AdditionalDependencies="dxguid.lib"
 				LinkIncremental="2"
 				ModuleDefinitionFile="libEGL.def"
 				GenerateDebugInformation="true"
 				SubSystem="2"
 				RandomizedBaseAddress="1"
 				DataExecutionPrevention="0"
 				TargetMachine="1"
 			/>
@@ -135,17 +135,17 @@
 			<Tool
 				Name="VCResourceCompilerTool"
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="d3d9.lib"
+				AdditionalDependencies="dxguid.lib"
 				LinkIncremental="1"
 				ModuleDefinitionFile="libEGL.def"
 				GenerateDebugInformation="true"
 				SubSystem="2"
 				OptimizeReferences="2"
 				EnableCOMDATFolding="2"
 				RandomizedBaseAddress="1"
 				DataExecutionPrevention="0"
--- a/gfx/angle/src/libGLESv2/Blit.cpp
+++ b/gfx/angle/src/libGLESv2/Blit.cpp
@@ -320,16 +320,17 @@ bool Blit::formatConvert(IDirect3DSurfac
 bool Blit::setFormatConvertShaders(GLenum destFormat)
 {
     bool okay = setVertexShader(SHADER_VS_STANDARD);
 
     switch (destFormat)
     {
       default: UNREACHABLE();
       case GL_RGBA:
+      case GL_BGRA_EXT:
       case GL_RGB:
       case GL_ALPHA:
         okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK);
         break;
 
       case GL_LUMINANCE:
       case GL_LUMINANCE_ALPHA:
         okay = okay && setPixelShader(SHADER_PS_LUMINANCE);
@@ -346,16 +347,17 @@ bool Blit::setFormatConvertShaders(GLenu
     // The meaning of this constant depends on the shader that was selected.
     // See the shader assembly code above for details.
     float psConst0[4] = { 0, 0, 0, 0 };
 
     switch (destFormat)
     {
       default: UNREACHABLE();
       case GL_RGBA:
+      case GL_BGRA_EXT:
         psConst0[X] = 1;
         psConst0[Z] = 1;
         break;
 
       case GL_RGB:
         psConst0[X] = 1;
         psConst0[W] = 1;
         break;
--- a/gfx/angle/src/libGLESv2/Context.cpp
+++ b/gfx/angle/src/libGLESv2/Context.cpp
@@ -1404,16 +1404,17 @@ bool Context::applyRenderTarget(bool ign
     IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
     IDirect3DSurface9 *depthStencil = NULL;
 
     unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial();
     if (renderTargetSerial != mAppliedRenderTargetSerial)
     {
         device->SetRenderTarget(0, renderTarget);
         mAppliedRenderTargetSerial = renderTargetSerial;
+        mScissorStateDirty = true; // Scissor area must be clamped to render target's size-- this is different for different render targets.
     }
 
     unsigned int depthbufferSerial = 0;
     unsigned int stencilbufferSerial = 0;
     if (framebufferObject->getDepthbufferType() != GL_NONE)
     {
         depthStencil = framebufferObject->getDepthbuffer()->getDepthStencil();
         depthbufferSerial = framebufferObject->getDepthbuffer()->getSerial();
@@ -1465,25 +1466,26 @@ bool Context::applyRenderTarget(bool ign
     if (mScissorStateDirty)
     {
         if (mState.scissorTest)
         {
             RECT rect = {mState.scissorX,
                          mState.scissorY,
                          mState.scissorX + mState.scissorWidth,
                          mState.scissorY + mState.scissorHeight};
-
+            rect.right = std::min(static_cast<UINT>(rect.right), desc.Width);
+            rect.bottom = std::min(static_cast<UINT>(rect.bottom), desc.Height);
             device->SetScissorRect(&rect);
             device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
         }
         else
         {
             device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
         }
-        
+
         mScissorStateDirty = false;
     }
 
     if (mState.currentProgram)
     {
         Program *programObject = getCurrentProgram();
 
         GLint halfPixelSize = programObject->getDxHalfPixelSizeLocation();
@@ -1938,16 +1940,29 @@ void Context::readPixels(GLint x, GLint 
     unsigned char *source = (unsigned char*)lock.pBits;
     unsigned char *dest = (unsigned char*)pixels;
     unsigned short *dest16 = (unsigned short*)pixels;
 
     GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
 
     for (int j = 0; j < rect.bottom - rect.top; j++)
     {
+        if (desc.Format == D3DFMT_A8R8G8B8 &&
+            format == GL_BGRA_EXT &&
+            type == GL_UNSIGNED_BYTE)
+        {
+            // Fast path for EXT_read_format_bgra, given
+            // an RGBA source buffer.  Note that buffers with no
+            // alpha go through the slow path below.
+            memcpy(dest + j * outputPitch,
+                   source + j * lock.Pitch,
+                   (rect.right - rect.left) * 4);
+            continue;
+        }
+
         for (int i = 0; i < rect.right - rect.left; i++)
         {
             float r;
             float g;
             float b;
             float a;
 
             switch (desc.Format)
@@ -2026,16 +2041,56 @@ void Context::readPixels(GLint x, GLint 
                     dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
                     dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
                     dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
                     dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
                     break;
                   default: UNREACHABLE();
                 }
                 break;
+              case GL_BGRA_EXT:
+                switch (type)
+                {
+                  case GL_UNSIGNED_BYTE:
+                    dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
+                    dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+                    dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
+                    dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
+                    break;
+                  case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+                    // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+                    // this type is packed as follows:
+                    //   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+                    //  --------------------------------------------------------------------------------
+                    // |       4th         |        3rd         |        2nd        |   1st component   |
+                    //  --------------------------------------------------------------------------------
+                    // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+                    dest16[i + j * outputPitch / sizeof(unsigned short)] =
+                        ((unsigned short)(15 * a + 0.5f) << 12)|
+                        ((unsigned short)(15 * r + 0.5f) << 8) |
+                        ((unsigned short)(15 * g + 0.5f) << 4) |
+                        ((unsigned short)(15 * b + 0.5f) << 0);
+                    break;
+                  case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+                    // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+                    // this type is packed as follows:
+                    //   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+                    //  --------------------------------------------------------------------------------
+                    // | 4th |          3rd           |           2nd          |      1st component     |
+                    //  --------------------------------------------------------------------------------
+                    // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+                    dest16[i + j * outputPitch / sizeof(unsigned short)] =
+                        ((unsigned short)(     a + 0.5f) << 15) |
+                        ((unsigned short)(31 * r + 0.5f) << 10) |
+                        ((unsigned short)(31 * g + 0.5f) << 5) |
+                        ((unsigned short)(31 * b + 0.5f) << 0);
+                    break;
+                  default: UNREACHABLE();
+                }
+                break;
               case GL_RGB:   // IMPLEMENTATION_COLOR_READ_FORMAT
                 switch (type)
                 {
                   case GL_UNSIGNED_SHORT_5_6_5:   // IMPLEMENTATION_COLOR_READ_TYPE
                     dest16[i + j * outputPitch / sizeof(unsigned short)] = 
                         ((unsigned short)(31 * b + 0.5f) << 0) |
                         ((unsigned short)(63 * g + 0.5f) << 5) |
                         ((unsigned short)(31 * r + 0.5f) << 11);
@@ -2723,16 +2778,18 @@ void Context::setVertexAttrib(GLuint ind
     mState.vertexAttribute[index].mCurrentValue[3] = values[3];
 
     mVertexDataManager->dirtyCurrentValues();
 }
 
 void Context::initExtensionString()
 {
     mExtensionString += "GL_OES_packed_depth_stencil ";
+    mExtensionString += "GL_EXT_texture_format_BGRA8888 ";
+    mExtensionString += "GL_EXT_read_format_bgra ";
 
     if (mBufferBackEnd->supportIntIndices())
     {
         mExtensionString += "GL_OES_element_index_uint ";
     }
 
     std::string::size_type end = mExtensionString.find_last_not_of(' ');
     if (end != std::string::npos)
--- a/gfx/angle/src/libGLESv2/Texture.cpp
+++ b/gfx/angle/src/libGLESv2/Texture.cpp
@@ -34,16 +34,19 @@ Texture::Image::~Image()
 
 Texture::Texture(GLuint id) : RefCountObject(id)
 {
     mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
     mMagFilter = GL_LINEAR;
     mWrapS = GL_REPEAT;
     mWrapT = GL_REPEAT;
 
+    mWidth = 0;
+    mHeight = 0;
+
     mDirtyMetaData = true;
     mDirty = true;
     mIsRenderable = false;
     mBaseTexture = NULL;
 }
 
 Texture::~Texture()
 {
@@ -190,16 +193,22 @@ void Texture::loadImageData(GLint xoffse
     GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
 
     for (int y = 0; y < height; y++)
     {
         const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
         const unsigned short *source16 = reinterpret_cast<const unsigned short*>(source);
         unsigned char *dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
 
+        // fast path for EXT_texture_format_BGRA8888
+        if (format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) {
+            memcpy(dest, source, width*4);
+            continue;
+        }
+
         for (int x = 0; x < width; x++)
         {
             unsigned char r;
             unsigned char g;
             unsigned char b;
             unsigned char a;
 
             switch (format)
@@ -332,32 +341,37 @@ void Texture::setImage(GLsizei width, GL
         }
 
         img->dirty = true;
     }
 
     mDirtyMetaData = true;
 }
 
-void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
+bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
 {
-    if (width + xoffset > img->width || height + yoffset > img->height) return error(GL_INVALID_VALUE);
+    if (width + xoffset > img->width || height + yoffset > img->height)
+    {
+        error(GL_INVALID_VALUE);
+        return false;
+    }
 
     D3DLOCKED_RECT locked;
     HRESULT result = img->surface->LockRect(&locked, NULL, 0);
 
     ASSERT(SUCCEEDED(result));
 
     if (SUCCEEDED(result))
     {
         loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits);
         img->surface->UnlockRect();
     }
 
     img->dirty = true;
+    return true;
 }
 
 IDirect3DBaseTexture9 *Texture::getTexture()
 {
     if (!isComplete())
     {
         return NULL;
     }
@@ -555,27 +569,33 @@ void Texture2D::commitRect(GLint level, 
 
             img->dirty = false;
         }
     }
 }
 
 void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
 {
-    Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[level]);
-    commitRect(level, xoffset, yoffset, width, height);
+    if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[level]))
+    {
+        commitRect(level, xoffset, yoffset, width, height);
+    }
 }
 
 void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
 {
     if (redefineTexture(level, internalFormat, width, height))
     {
         convertToRenderTarget();
         pushTexture(mTexture, true);
     }
+    else
+    {
+        needRenderTarget();
+    }
 
     if (width != 0 && height != 0 && level < levelCount())
     {
         RECT sourceRect;
         sourceRect.left = x;
         sourceRect.right = x + width;
         sourceRect.top = y;
         sourceRect.bottom = y + height;
@@ -991,18 +1011,20 @@ void TextureCubeMap::commitRect(GLenum f
 
             img->dirty = false;
         }
     }
 }
 
 void TextureCubeMap::subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
 {
-    Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(face)][level]);
-    commitRect(face, level, xoffset, yoffset, width, height);
+    if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(face)][level]))
+    {
+        commitRect(face, level, xoffset, yoffset, width, height);
+    }
 }
 
 // Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
 bool TextureCubeMap::isComplete() const
 {
     int size = mImageArray[0][0].width;
 
     if (size <= 0)
@@ -1284,16 +1306,20 @@ void TextureCubeMap::copyImage(GLenum fa
 {
     unsigned int faceindex = faceIndex(face);
 
     if (redefineTexture(level, internalFormat, width))
     {
         convertToRenderTarget();
         pushTexture(mTexture, true);
     }
+    else
+    {
+        needRenderTarget();
+    }
 
     ASSERT(width == height);
 
     if (width > 0 && level < levelCount())
     {
         RECT sourceRect;
         sourceRect.left = x;
         sourceRect.right = x + width;
@@ -1353,17 +1379,17 @@ void TextureCubeMap::copySubImage(GLenum
 
     if (redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width))
     {
         convertToRenderTarget();
         pushTexture(mTexture, true);
     }
     else
     {
-        getRenderTarget(face);
+        needRenderTarget();
     }
 
     if (level < levelCount())
     {
         RECT sourceRect;
         sourceRect.left = x;
         sourceRect.right = x + width;
         sourceRect.top = y;
--- a/gfx/angle/src/libGLESv2/Texture.h
+++ b/gfx/angle/src/libGLESv2/Texture.h
@@ -101,23 +101,18 @@ class Texture : public RefCountObject
         bool dirty;
 
         IDirect3DSurface9 *surface;
     };
 
     static D3DFORMAT selectFormat(GLenum format);
     int imagePitch(const Image& img) const;
 
-    GLenum mMinFilter;
-    GLenum mMagFilter;
-    GLenum mWrapS;
-    GLenum mWrapT;
-
     void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
-    void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
+    bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
 
     void needRenderTarget();
 
     GLint creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const;
     GLint creationLevels(GLsizei size, GLint maxlevel) const;
 
     // The pointer returned is weak and it is assumed the derived class will keep a strong pointer until the next createTexture() call.
     virtual IDirect3DBaseTexture9 *createTexture() = 0;
@@ -127,32 +122,36 @@ class Texture : public RefCountObject
 
     virtual bool dirtyImageData() const = 0;
 
     void dropTexture();
     void pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable);
 
     Blit *getBlitter();
 
+    int levelCount() const;
+
     unsigned int mWidth;
     unsigned int mHeight;
-
-    int levelCount() const;
+    GLenum mMinFilter;
+    GLenum mMagFilter;
+    GLenum mWrapS;
+    GLenum mWrapT;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture);
 
+    void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
+                       GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
+
     IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
+
+    bool mDirty;
     bool mDirtyMetaData;
     bool mIsRenderable;
-
-    bool mDirty;
-
-    void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
-                       GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
 };
 
 class Texture2D : public Texture
 {
   public:
     explicit Texture2D(GLuint id);
 
     ~Texture2D();
@@ -171,30 +170,28 @@ class Texture2D : public Texture
     virtual Renderbuffer *getColorbuffer(GLenum target);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture2D);
 
     virtual IDirect3DBaseTexture9 *createTexture();
     virtual void updateTexture();
     virtual IDirect3DBaseTexture9 *convertToRenderTarget();
+    virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
 
     virtual bool dirtyImageData() const;
 
+    bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
     void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
 
     Image mImageArray[MAX_TEXTURE_LEVELS];
 
     IDirect3DTexture9 *mTexture;
 
     Renderbuffer *mColorbufferProxy;
-
-    bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
-
-    virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
 };
 
 class TextureCubeMap : public Texture
 {
   public:
     explicit TextureCubeMap(GLuint id);
 
     ~TextureCubeMap();
@@ -219,16 +216,17 @@ class TextureCubeMap : public Texture
     virtual Renderbuffer *getColorbuffer(GLenum target);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
 
     virtual IDirect3DBaseTexture9 *createTexture();
     virtual void updateTexture();
     virtual IDirect3DBaseTexture9 *convertToRenderTarget();
+    virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
 
     virtual bool dirtyImageData() const;
 
     // faceIdentifier is 0-5 or one of the GL_TEXTURE_CUBE_MAP_* enumerants.
     // Returns NULL if the call underlying Direct3D call fails.
     IDirect3DSurface9 *getCubeMapSurface(unsigned int faceIdentifier, unsigned int level);
 
     static unsigned int faceIndex(GLenum face);
@@ -239,14 +237,12 @@ class TextureCubeMap : public Texture
     void commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
     bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width);
 
     Image mImageArray[6][MAX_TEXTURE_LEVELS];
 
     IDirect3DCubeTexture9 *mTexture;
 
     Renderbuffer *mFaceProxies[6];
-
-    virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
 };
 }
 
 #endif   // LIBGLESV2_TEXTURE_H_
--- a/gfx/angle/src/libGLESv2/libGLESv2.cpp
+++ b/gfx/angle/src/libGLESv2/libGLESv2.cpp
@@ -3486,16 +3486,27 @@ void __stdcall glReadPixels(GLint x, GLi
             switch (type)
             {
               case GL_UNSIGNED_BYTE:
                 break;
               default:
                 return error(GL_INVALID_OPERATION);
             }
             break;
+          case GL_BGRA_EXT:
+            switch (type)
+            {
+              case GL_UNSIGNED_BYTE:
+              case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+              case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+                break;
+              default:
+                return error(GL_INVALID_OPERATION);
+            }
+            break;
           case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
             switch (type)
             {
               case gl::IMPLEMENTATION_COLOR_READ_TYPE:
                 break;
               default:
                 return error(GL_INVALID_OPERATION);
             }
@@ -3968,16 +3979,25 @@ void __stdcall glTexImage2D(GLenum targe
               case GL_UNSIGNED_BYTE:
               case GL_UNSIGNED_SHORT_4_4_4_4:
               case GL_UNSIGNED_SHORT_5_5_5_1:
                 break;
               default:
                 return error(GL_INVALID_ENUM);
             }
             break;
+          case GL_BGRA_EXT:
+            switch (type)
+            {
+              case GL_UNSIGNED_BYTE:
+                break;
+              default:
+                return error(GL_INVALID_ENUM);
+            }
+            break;
           default:
             return error(GL_INVALID_VALUE);
         }
 
         if (border != 0)
         {
             return error(GL_INVALID_VALUE);
         }
--- a/gfx/angle/src/libGLESv2/utilities.cpp
+++ b/gfx/angle/src/libGLESv2/utilities.cpp
@@ -191,16 +191,17 @@ int ComputePixelSize(GLenum format, GLen
       case GL_UNSIGNED_BYTE:
         switch (format)
         {
           case GL_ALPHA:           return sizeof(unsigned char);
           case GL_LUMINANCE:       return sizeof(unsigned char);
           case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
           case GL_RGB:             return sizeof(unsigned char) * 3;
           case GL_RGBA:            return sizeof(unsigned char) * 4;
+          case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
           default: UNREACHABLE();
         }
         break;
       case GL_UNSIGNED_SHORT_4_4_4_4:
       case GL_UNSIGNED_SHORT_5_5_5_1:
       case GL_UNSIGNED_SHORT_5_6_5:
         return sizeof(unsigned short);
       default: UNREACHABLE();
@@ -223,16 +224,17 @@ bool IsTextureTarget(GLenum target)
 bool CheckTextureFormatType(GLenum format, GLenum type)
 {
     switch (type)
     {
       case GL_UNSIGNED_BYTE:
         switch (format)
         {
           case GL_RGBA:
+          case GL_BGRA_EXT:
           case GL_RGB:
           case GL_ALPHA:
           case GL_LUMINANCE:
           case GL_LUMINANCE_ALPHA:
             return true;
 
           default:
             return false;
--- a/gfx/angle/src/libGLESv2/utilities.h
+++ b/gfx/angle/src/libGLESv2/utilities.h
@@ -6,16 +6,17 @@
 
 // utilities.h: Conversion functions and other utility routines.
 
 #ifndef LIBGLESV2_UTILITIES_H
 #define LIBGLESV2_UTILITIES_H
 
 #define GL_APICALL
 #include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 #include <d3d9.h>
 
 namespace gl
 {
 
 struct Color;
 
 int UniformComponentCount(GLenum type);