b=583375; update ANGLE to r367; r=vlad
authorVladimir Vukicevic <vladimir@pobox.com>
Fri, 30 Jul 2010 15:22:11 -0700
changeset 48434 582be9aca672167c31380f8f6fc23b9e1f8d6994
parent 48433 ad20c4b23510b1c375b9406bbe0ba29c81b72eb1
child 48435 d02490c3c2181b3b32cfebac629813fd98d8f0d7
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersvlad
bugs583375
milestone2.0b3pre
b=583375; update ANGLE to r367; r=vlad
content/canvas/src/WebGLContextGL.cpp
gfx/angle/README.mozilla
gfx/angle/angle-shared.patch
gfx/angle/include/GLSLANG/ShaderLang.h
gfx/angle/src/build_angle.gyp
gfx/angle/src/compiler/CodeGenGLSL.cpp
gfx/angle/src/compiler/CodeGenHLSL.cpp
gfx/angle/src/compiler/Common.h
gfx/angle/src/compiler/Initialize.cpp
gfx/angle/src/compiler/Initialize.h
gfx/angle/src/compiler/InitializeDll.cpp
gfx/angle/src/compiler/InitializeDll.h
gfx/angle/src/compiler/InitializeParseContext.h
gfx/angle/src/compiler/Link.cpp
gfx/angle/src/compiler/OutputGLSL.cpp
gfx/angle/src/compiler/OutputHLSL.cpp
gfx/angle/src/compiler/ParseHelper.cpp
gfx/angle/src/compiler/ParseHelper.h
gfx/angle/src/compiler/ShHandle.h
gfx/angle/src/compiler/ShaderLang.cpp
gfx/angle/src/compiler/SymbolTable.h
gfx/angle/src/compiler/TranslatorGLSL.cpp
gfx/angle/src/compiler/TranslatorGLSL.h
gfx/angle/src/compiler/TranslatorHLSL.cpp
gfx/angle/src/compiler/TranslatorHLSL.h
gfx/angle/src/compiler/glslang.y
gfx/angle/src/compiler/translator_common.vcproj
gfx/angle/src/libEGL/Display.cpp
gfx/angle/src/libEGL/Display.h
gfx/angle/src/libEGL/Surface.cpp
gfx/angle/src/libEGL/Surface.h
gfx/angle/src/libEGL/libEGL.cpp
gfx/angle/src/libGLESv2/Blit.cpp
gfx/angle/src/libGLESv2/Buffer.cpp
gfx/angle/src/libGLESv2/Buffer.h
gfx/angle/src/libGLESv2/Context.cpp
gfx/angle/src/libGLESv2/Context.h
gfx/angle/src/libGLESv2/Framebuffer.cpp
gfx/angle/src/libGLESv2/Framebuffer.h
gfx/angle/src/libGLESv2/Program.cpp
gfx/angle/src/libGLESv2/Program.h
gfx/angle/src/libGLESv2/RefCountObject.cpp
gfx/angle/src/libGLESv2/RefCountObject.h
gfx/angle/src/libGLESv2/Renderbuffer.cpp
gfx/angle/src/libGLESv2/Renderbuffer.h
gfx/angle/src/libGLESv2/ResourceManager.cpp
gfx/angle/src/libGLESv2/ResourceManager.h
gfx/angle/src/libGLESv2/Shader.cpp
gfx/angle/src/libGLESv2/Shader.h
gfx/angle/src/libGLESv2/Texture.cpp
gfx/angle/src/libGLESv2/Texture.h
gfx/angle/src/libGLESv2/geometry/VertexDataManager.cpp
gfx/angle/src/libGLESv2/geometry/backend.h
gfx/angle/src/libGLESv2/geometry/dx9.cpp
gfx/angle/src/libGLESv2/geometry/dx9.h
gfx/angle/src/libGLESv2/libGLESv2.cpp
gfx/angle/src/libGLESv2/libGLESv2.vcproj
gfx/angle/src/libGLESv2/main.h
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -2906,22 +2906,22 @@ WebGLContext::CompileShader(nsIWebGLShad
         resources.maxVertexUniformVectors = mGLMaxVertexUniformVectors;
         resources.maxVaryingVectors = mGLMaxVaryingVectors;
         resources.maxVertexTextureImageUnits = mGLMaxVertexTextureImageUnits;
         resources.maxCombinedTextureImageUnits = mGLMaxTextureUnits;
         resources.maxTextureImageUnits = mGLMaxTextureImageUnits;
         resources.maxFragmentUniformVectors = mGLMaxFragmentUniformVectors;
         resources.maxDrawBuffers = 1;
 
-        compiler = ShConstructCompiler(lang, debugFlags);
+        compiler = ShConstructCompiler(lang, EShSpecWebGL, &resources);
 
         nsDependentCString src(shader->Source());
         const char *s = src.get();
 
-        if (!ShCompile(compiler, &s, 1, EShOptNone, &resources, debugFlags)) {
+        if (!ShCompile(compiler, &s, 1, EShOptSimple, debugFlags)) {
             shader->SetTranslationFailure(nsDependentCString(ShGetInfoLog(compiler)));
             ShDestruct(compiler);
             return NS_OK;
         }
 
         s = ShGetObjectCode(compiler);
         gl->fShaderSource(shadername, 1, &s, NULL);
         shader->SetTranslationSuccess();
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -1,11 +1,11 @@
 This is the ANGLE project, from http://code.google.com/p/angleproject/.
 
-Current revision: r343
+Current revision: r367
 
 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
 
--- a/gfx/angle/angle-shared.patch
+++ b/gfx/angle/angle-shared.patch
@@ -1,183 +1,80 @@
 # HG changeset patch
+# User Vladimir Vukicevic <vladimir@pobox.com>
+# Date 1280525409 25200
+# Node ID d683bc8242ec4b6e19196fc6f6d090a6da2fa07d
+# Parent  3693726d10c60b8b2637407709d595151c191a64
+[mq]: angle-shared.patch
 
 diff --git a/gfx/angle/include/GLSLANG/ShaderLang.h b/gfx/angle/include/GLSLANG/ShaderLang.h
 --- a/gfx/angle/include/GLSLANG/ShaderLang.h
 +++ b/gfx/angle/include/GLSLANG/ShaderLang.h
-@@ -1,42 +1,54 @@
- //
- // 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.
- //
+@@ -6,8 +6,24 @@
  #ifndef _COMPILER_INTERFACE_INCLUDED_
  #define _COMPILER_INTERFACE_INCLUDED_
  
 +#include "nscore.h"
 +
  #include "ResourceLimits.h"
  
- #ifdef _WIN32
--#define C_DECL __cdecl
++#ifdef WIN32
 +# if !defined(MOZ_ENABLE_LIBXUL) && !defined(MOZ_STATIC_BUILD)
 +#  ifdef ANGLE_BUILD
 +#   define ANGLE_API NS_EXPORT
 +#  else
 +#   define ANGLE_API NS_IMPORT
 +#  endif
 +# else
 +#  define ANGLE_API  /*nothing*/
 +# endif
-+# define C_DECL __cdecl
- #else
--#define __fastcall
--#define C_DECL
++#else
 +# define ANGLE_API NS_EXTERNAL_VIS
-+# define __fastcall
-+# define C_DECL
- #endif
- 
++#endif
++
  //
  // This is the platform independent interface between an OGL driver
- // and the shading language compiler/linker.
- //
- 
- #ifdef __cplusplus
- 	extern "C" {
- #endif
- //
+ // and the shading language compiler.
+@@ -20,11 +36,11 @@ extern "C" {
  // Driver must call this first, once, before doing any other
- // compiler/linker operations.
+ // compiler operations.
  //
 -int ShInitialize();
 +ANGLE_API int ShInitialize();
  //
  // Driver should call this at shutdown.
  //
--int __fastcall ShFinalize();
+-int ShFinalize();
 +ANGLE_API int ShFinalize();
  //
  // Types of languages the compiler can consume.
  //
- typedef enum {
- 	EShLangVertex,
- 	EShLangFragment,
- 	EShLangCount
- } EShLanguage;
-@@ -83,88 +95,88 @@ typedef struct {
- // If handle creation fails, 0 will be returned.
+@@ -70,8 +86,8 @@ typedef void* ShHandle;
  //
- typedef void* ShHandle;
- 
+ // Driver calls these to create and destroy compiler objects.
  //
- // Driver calls these to create and destroy compiler/linker
- // objects.
- //
--ShHandle ShConstructCompiler(const EShLanguage, int debugOptions);  // one per shader
--ShHandle ShConstructLinker(const EShExecutable, int debugOptions);  // one per shader pair
--ShHandle ShConstructUniformMap();                 // one per uniform namespace (currently entire program object)
+-ShHandle ShConstructCompiler(EShLanguage, EShSpec, const TBuiltInResource*);
 -void ShDestruct(ShHandle);
-+ANGLE_API ShHandle ShConstructCompiler(const EShLanguage, int debugOptions);  // one per shader
-+ANGLE_API ShHandle ShConstructLinker(const EShExecutable, int debugOptions);  // one per shader pair
-+ANGLE_API ShHandle ShConstructUniformMap();                 // one per uniform namespace (currently entire program object)
++ANGLE_API ShHandle ShConstructCompiler(EShLanguage, EShSpec, const TBuiltInResource*);
 +ANGLE_API void ShDestruct(ShHandle);
  
  //
  // The return value of ShCompile is boolean, indicating
- // success or failure.
- //
+@@ -80,7 +96,7 @@ void ShDestruct(ShHandle);
  // The info-log should be written by ShCompile into 
  // ShHandle, so it can answer future queries.
  //
 -int ShCompile(
 +ANGLE_API int ShCompile(
- 	const ShHandle,
- 	const char* const shaderStrings[],
- 	const int numStrings,
- 	const EShOptimizationLevel,
- 	const TBuiltInResource *resources,
- 	int debugOptions
- 	);
- 
- 
- //
- // Similar to ShCompile, but accepts an opaque handle to an
- // intermediate language structure.
- //
--int ShCompileIntermediate(
-+ANGLE_API int ShCompileIntermediate(
- 	ShHandle compiler,
- 	ShHandle intermediate,
- 	const EShOptimizationLevel,
- 	int debuggable           // boolean
- 	);
- 
--int ShLink(
-+ANGLE_API int ShLink(
- 	const ShHandle,               // linker object
- 	const ShHandle h[],           // compiler objects to link together
- 	const int numHandles,
- 	ShHandle uniformMap,          // updated with new uniforms
- 	short int** uniformsAccessed,  // returned with indexes of uniforms accessed
- 	int* numUniformsAccessed); 	
- 
--int ShLinkExt(
-+ANGLE_API int ShLinkExt(
- 	const ShHandle,               // linker object
- 	const ShHandle h[],           // compiler objects to link together
- 	const int numHandles);
- 
- //
- // ShSetEncrpytionMethod is a place-holder for specifying
- // how source code is encrypted.
- //
--void ShSetEncryptionMethod(ShHandle);
-+ANGLE_API void ShSetEncryptionMethod(ShHandle);
- 
- //
+     const ShHandle,
+     const char* const shaderStrings[],
+     const int numStrings,
+@@ -92,8 +108,8 @@ int ShCompile(
  // All the following return 0 if the information is not
  // available in the object passed down, or the object is bad.
  //
 -const char* ShGetInfoLog(const ShHandle);
 -const char* ShGetObjectCode(const ShHandle);
--const void* ShGetExecutable(const ShHandle);
--int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*);   // to detect user aliasing
--int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*);     // to force any physical mappings
--int ShGetPhysicalAttributeBindings(const ShHandle, const ShBindingTable**); // for all attributes
 +ANGLE_API const char* ShGetInfoLog(const ShHandle);
 +ANGLE_API const char* ShGetObjectCode(const ShHandle);
-+ANGLE_API const void* ShGetExecutable(const ShHandle);
-+ANGLE_API int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*);   // to detect user aliasing
-+ANGLE_API int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*);     // to force any physical mappings
-+ANGLE_API int ShGetPhysicalAttributeBindings(const ShHandle, const ShBindingTable**); // for all attributes
- //
- // Tell the linker to never assign a vertex attribute to this list of physical attributes
- //
--int ShExcludeAttributes(const ShHandle, int *attributes, int count);
-+ANGLE_API int ShExcludeAttributes(const ShHandle, int *attributes, int count);
  
- //
- // Returns the location ID of the named uniform.
- // Returns -1 if error.
- //
--int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
-+ANGLE_API int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
- 
- enum TDebugOptions {
- 	EDebugOpNone               = 0x000,
- 	EDebugOpIntermediate       = 0x001,
- 	EDebugOpAssembly           = 0x002,
- 	EDebugOpObjectCode         = 0x004,
- 	EDebugOpLinkMaps           = 0x008
- };
-diff --git a/gfx/angle/src/compiler/ShaderLang.cpp b/gfx/angle/src/compiler/ShaderLang.cpp
---- a/gfx/angle/src/compiler/ShaderLang.cpp
-+++ b/gfx/angle/src/compiler/ShaderLang.cpp
-@@ -130,7 +130,7 @@ void ShDestruct(ShHandle handle)
- //
- // Cleanup symbol tables
- //
--int __fastcall ShFinalize()
-+int ShFinalize()
- {  
-   if (PerProcessGPA) {
-     PerProcessGPA->popAll();
+ #ifdef __cplusplus
+ }
--- a/gfx/angle/include/GLSLANG/ShaderLang.h
+++ b/gfx/angle/include/GLSLANG/ShaderLang.h
@@ -5,183 +5,114 @@
 //
 #ifndef _COMPILER_INTERFACE_INCLUDED_
 #define _COMPILER_INTERFACE_INCLUDED_
 
 #include "nscore.h"
 
 #include "ResourceLimits.h"
 
-#ifdef _WIN32
+#ifdef WIN32
 # if !defined(MOZ_ENABLE_LIBXUL) && !defined(MOZ_STATIC_BUILD)
 #  ifdef ANGLE_BUILD
 #   define ANGLE_API NS_EXPORT
 #  else
 #   define ANGLE_API NS_IMPORT
 #  endif
 # else
 #  define ANGLE_API  /*nothing*/
 # endif
-# define C_DECL __cdecl
 #else
 # define ANGLE_API NS_EXTERNAL_VIS
-# define __fastcall
-# define C_DECL
 #endif
 
 //
 // This is the platform independent interface between an OGL driver
-// and the shading language compiler/linker.
+// and the shading language compiler.
 //
 
 #ifdef __cplusplus
-	extern "C" {
+extern "C" {
 #endif
 //
 // Driver must call this first, once, before doing any other
-// compiler/linker operations.
+// compiler operations.
 //
 ANGLE_API int ShInitialize();
 //
 // Driver should call this at shutdown.
 //
 ANGLE_API int ShFinalize();
 //
 // Types of languages the compiler can consume.
 //
 typedef enum {
-	EShLangVertex,
-	EShLangFragment,
-	EShLangCount
+    EShLangVertex,
+    EShLangFragment,
+    EShLangCount,
 } EShLanguage;
 
 //
-// Types of output the linker will create.
+// The language specification compiler conforms to.
+// It currently supports OpenGL ES and WebGL specifications.
 //
 typedef enum {
-	EShExVertexFragment,
-	EShExFragment
-} EShExecutable;
+    EShSpecGLES2,
+    EShSpecWebGL,
+} EShSpec;
 
 //
 // Optimization level for the compiler.
 //
 typedef enum {
-	EShOptNoGeneration,
-	EShOptNone,
-	EShOptSimple,       // Optimizations that can be done quickly
-	EShOptFull          // Optimizations that will take more time
+    EShOptNoGeneration,
+    EShOptNone,
+    EShOptSimple,       // Optimizations that can be done quickly
+    EShOptFull,         // Optimizations that will take more time
 } EShOptimizationLevel;
 
-//
-// Build a table for bindings.  This can be used for locating
-// attributes, uniforms, globals, etc., as needed.
-//
-typedef struct {
-	const char* name;
-	int binding;
-} ShBinding;
-
-typedef struct {
-	int numBindings;
-	ShBinding* bindings;  // array of bindings
-} ShBindingTable;
+enum TDebugOptions {
+    EDebugOpNone               = 0x000,
+    EDebugOpIntermediate       = 0x001,  // Writes intermediate tree into info-log.
+};
 
 //
 // ShHandle held by but opaque to the driver.  It is allocated,
-// managed, and de-allocated by the compiler/linker. It's contents 
-// are defined by and used by the compiler and linker.  For example,
-// symbol table information and object code passed from the compiler 
-// to the linker can be stored where ShHandle points.
+// managed, and de-allocated by the compiler. It's contents 
+// are defined by and used by the compiler.
 //
 // If handle creation fails, 0 will be returned.
 //
 typedef void* ShHandle;
 
 //
-// Driver calls these to create and destroy compiler/linker
-// objects.
+// Driver calls these to create and destroy compiler objects.
 //
-ANGLE_API ShHandle ShConstructCompiler(const EShLanguage, int debugOptions);  // one per shader
-ANGLE_API ShHandle ShConstructLinker(const EShExecutable, int debugOptions);  // one per shader pair
-ANGLE_API ShHandle ShConstructUniformMap();                 // one per uniform namespace (currently entire program object)
+ANGLE_API ShHandle ShConstructCompiler(EShLanguage, EShSpec, const TBuiltInResource*);
 ANGLE_API void ShDestruct(ShHandle);
 
 //
 // The return value of ShCompile is boolean, indicating
 // success or failure.
 //
 // The info-log should be written by ShCompile into 
 // ShHandle, so it can answer future queries.
 //
 ANGLE_API int ShCompile(
-	const ShHandle,
-	const char* const shaderStrings[],
-	const int numStrings,
-	const EShOptimizationLevel,
-	const TBuiltInResource *resources,
-	int debugOptions
-	);
-
-
-//
-// Similar to ShCompile, but accepts an opaque handle to an
-// intermediate language structure.
-//
-ANGLE_API int ShCompileIntermediate(
-	ShHandle compiler,
-	ShHandle intermediate,
-	const EShOptimizationLevel,
-	int debuggable           // boolean
-	);
-
-ANGLE_API int ShLink(
-	const ShHandle,               // linker object
-	const ShHandle h[],           // compiler objects to link together
-	const int numHandles,
-	ShHandle uniformMap,          // updated with new uniforms
-	short int** uniformsAccessed,  // returned with indexes of uniforms accessed
-	int* numUniformsAccessed); 	
-
-ANGLE_API int ShLinkExt(
-	const ShHandle,               // linker object
-	const ShHandle h[],           // compiler objects to link together
-	const int numHandles);
-
-//
-// ShSetEncrpytionMethod is a place-holder for specifying
-// how source code is encrypted.
-//
-ANGLE_API void ShSetEncryptionMethod(ShHandle);
+    const ShHandle,
+    const char* const shaderStrings[],
+    const int numStrings,
+    const EShOptimizationLevel,
+    int debugOptions
+    );
 
 //
 // All the following return 0 if the information is not
 // available in the object passed down, or the object is bad.
 //
 ANGLE_API const char* ShGetInfoLog(const ShHandle);
 ANGLE_API const char* ShGetObjectCode(const ShHandle);
-ANGLE_API const void* ShGetExecutable(const ShHandle);
-ANGLE_API int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*);   // to detect user aliasing
-ANGLE_API int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*);     // to force any physical mappings
-ANGLE_API int ShGetPhysicalAttributeBindings(const ShHandle, const ShBindingTable**); // for all attributes
-//
-// Tell the linker to never assign a vertex attribute to this list of physical attributes
-//
-ANGLE_API int ShExcludeAttributes(const ShHandle, int *attributes, int count);
 
-//
-// Returns the location ID of the named uniform.
-// Returns -1 if error.
-//
-ANGLE_API int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
-
-enum TDebugOptions {
-	EDebugOpNone               = 0x000,
-	EDebugOpIntermediate       = 0x001,
-	EDebugOpAssembly           = 0x002,
-	EDebugOpObjectCode         = 0x004,
-	EDebugOpLinkMaps           = 0x008
-};
 #ifdef __cplusplus
-	}
+}
 #endif
 
 #endif // _COMPILER_INTERFACE_INCLUDED_
--- a/gfx/angle/src/build_angle.gyp
+++ b/gfx/angle/src/build_angle.gyp
@@ -29,17 +29,16 @@
         'compiler/InitializeDll.cpp',
         'compiler/InitializeDll.h',
         'compiler/InitializeGlobals.h',
         'compiler/InitializeParseContext.h',
         'compiler/Intermediate.cpp',
         'compiler/intermediate.h',
         'compiler/intermOut.cpp',
         'compiler/IntermTraverse.cpp',
-        'compiler/Link.cpp',
         'compiler/localintermediate.h',
         'compiler/MMap.h',
         'compiler/osinclude.h',
         'compiler/parseConst.cpp',
         'compiler/ParseHelper.cpp',
         'compiler/ParseHelper.h',
         'compiler/PoolAlloc.cpp',
         'compiler/PoolAlloc.h',
@@ -182,18 +181,22 @@
             'libGLESv2/Framebuffer.h',
             'libGLESv2/libGLESv2.cpp',
             'libGLESv2/libGLESv2.def',
             'libGLESv2/main.cpp',
             'libGLESv2/main.h',
             'libGLESv2/mathutil.h',
             'libGLESv2/Program.cpp',
             'libGLESv2/Program.h',
+            'libGLESv2/RefCountObject.cpp',
+            'libGLESv2/RefCountObject.h',
             'libGLESv2/Renderbuffer.cpp',
             'libGLESv2/Renderbuffer.h',
+            'libGLESv2/ResourceManager.cpp',
+            'libGLESv2/ResourceManager.h',
             'libGLESv2/Shader.cpp',
             'libGLESv2/Shader.h',
             'libGLESv2/Texture.cpp',
             'libGLESv2/Texture.h',
             'libGLESv2/utilities.cpp',
             'libGLESv2/utilities.h',
           ],
           'msvs_settings': {
--- a/gfx/angle/src/compiler/CodeGenGLSL.cpp
+++ b/gfx/angle/src/compiler/CodeGenGLSL.cpp
@@ -6,19 +6,19 @@
 
 #include "compiler/TranslatorGLSL.h"
 
 //
 // This function must be provided to create the actual
 // compile object used by higher level code.  It returns
 // a subclass of TCompiler.
 //
-TCompiler* ConstructCompiler(EShLanguage language, int debugOptions)
+TCompiler* ConstructCompiler(EShLanguage language, EShSpec spec)
 {
-    return new TranslatorGLSL(language, debugOptions);
+    return new TranslatorGLSL(language, spec);
 }
 
 //
 // Delete the compiler made by ConstructCompiler
 //
 void DeleteCompiler(TCompiler* compiler)
 {
     delete compiler;
--- a/gfx/angle/src/compiler/CodeGenHLSL.cpp
+++ b/gfx/angle/src/compiler/CodeGenHLSL.cpp
@@ -6,19 +6,19 @@
 
 #include "compiler/TranslatorHLSL.h"
 
 //
 // This function must be provided to create the actual
 // compile object used by higher level code.  It returns
 // a subclass of TCompiler.
 //
-TCompiler* ConstructCompiler(EShLanguage language, int debugOptions)
+TCompiler* ConstructCompiler(EShLanguage language, EShSpec spec)
 {
-    return new TranslatorHLSL(language, debugOptions);
+    return new TranslatorHLSL(language, spec);
 }
 
 //
 // Delete the compiler made by ConstructCompiler
 //
 void DeleteCompiler(TCompiler* compiler)
 {
     delete compiler;
--- a/gfx/angle/src/compiler/Common.h
+++ b/gfx/angle/src/compiler/Common.h
@@ -40,17 +40,17 @@ typedef std::basic_ostringstream<char, s
 inline TString* NewPoolTString(const char* s)
 {
 	void* memory = GlobalPoolAllocator.allocate(sizeof(TString));
 	return new(memory) TString(s);
 }
 
 //
 // Persistent string memory.  Should only be used for strings that survive
-// across compiles/links.
+// across compiles.
 //
 #define TPersistString std::string
 #define TPersistStringStream std::ostringstream
 
 //
 // Pool allocator versions of vectors, lists, and maps
 //
 template <class T> class TVector : public std::vector<T, pool_allocator<T> > {
--- a/gfx/angle/src/compiler/Initialize.cpp
+++ b/gfx/angle/src/compiler/Initialize.cpp
@@ -9,519 +9,531 @@
 // cannot be expressed in the files, and establish mappings between 
 // built-in functions and operators.
 //
 
 #include "compiler/Initialize.h"
 
 #include "compiler/intermediate.h"
 
-void TBuiltIns::initialize()
+//============================================================================
+//
+// Prototypes for built-in functions seen by both vertex and fragment shaders.
+//
+//============================================================================
+static TString BuiltInFunctionsCommon()
 {
+    TString s;
+
     //
-    // Initialize all the built-in strings for parsing.
+    // Angle and Trigonometric Functions.
     //
-    TString BuiltInFunctions;
-    TString BuiltInFunctionsVertex;
-    TString BuiltInFunctionsFragment;
-    TString StandardUniforms;
-    TString VertexDefaultPrecision;
-    TString FragmentDefaultPrecision;
+    s.append(TString("float radians(float degrees);"));
+    s.append(TString("vec2  radians(vec2  degrees);"));
+    s.append(TString("vec3  radians(vec3  degrees);"));
+    s.append(TString("vec4  radians(vec4  degrees);"));
 
-    {
-        //============================================================================
-        //
-        // Prototypes for built-in functions seen by both vertex and fragment shaders.
-        //
-        //============================================================================
+    s.append(TString("float degrees(float radians);"));
+    s.append(TString("vec2  degrees(vec2  radians);"));
+    s.append(TString("vec3  degrees(vec3  radians);"));
+    s.append(TString("vec4  degrees(vec4  radians);"));
 
-        TString& s = BuiltInFunctions;
+    s.append(TString("float sin(float angle);"));
+    s.append(TString("vec2  sin(vec2  angle);"));
+    s.append(TString("vec3  sin(vec3  angle);"));
+    s.append(TString("vec4  sin(vec4  angle);"));
 
-        //
-        // Angle and Trigonometric Functions.
-        //
-        s.append(TString("float radians(float degrees);"));
-        s.append(TString("vec2  radians(vec2  degrees);"));
-        s.append(TString("vec3  radians(vec3  degrees);"));
-        s.append(TString("vec4  radians(vec4  degrees);"));
+    s.append(TString("float cos(float angle);"));
+    s.append(TString("vec2  cos(vec2  angle);"));
+    s.append(TString("vec3  cos(vec3  angle);"));
+    s.append(TString("vec4  cos(vec4  angle);"));
 
-        s.append(TString("float degrees(float radians);"));
-        s.append(TString("vec2  degrees(vec2  radians);"));
-        s.append(TString("vec3  degrees(vec3  radians);"));
-        s.append(TString("vec4  degrees(vec4  radians);"));
+    s.append(TString("float tan(float angle);"));
+    s.append(TString("vec2  tan(vec2  angle);"));
+    s.append(TString("vec3  tan(vec3  angle);"));
+    s.append(TString("vec4  tan(vec4  angle);"));
+
+    s.append(TString("float asin(float x);"));
+    s.append(TString("vec2  asin(vec2  x);"));
+    s.append(TString("vec3  asin(vec3  x);"));
+    s.append(TString("vec4  asin(vec4  x);"));
 
-        s.append(TString("float sin(float angle);"));
-        s.append(TString("vec2  sin(vec2  angle);"));
-        s.append(TString("vec3  sin(vec3  angle);"));
-        s.append(TString("vec4  sin(vec4  angle);"));
+    s.append(TString("float acos(float x);"));
+    s.append(TString("vec2  acos(vec2  x);"));
+    s.append(TString("vec3  acos(vec3  x);"));
+    s.append(TString("vec4  acos(vec4  x);"));
 
-        s.append(TString("float cos(float angle);"));
-        s.append(TString("vec2  cos(vec2  angle);"));
-        s.append(TString("vec3  cos(vec3  angle);"));
-        s.append(TString("vec4  cos(vec4  angle);"));
+    s.append(TString("float atan(float y, float x);"));
+    s.append(TString("vec2  atan(vec2  y, vec2  x);"));
+    s.append(TString("vec3  atan(vec3  y, vec3  x);"));
+    s.append(TString("vec4  atan(vec4  y, vec4  x);"));
 
-        s.append(TString("float tan(float angle);"));
-        s.append(TString("vec2  tan(vec2  angle);"));
-        s.append(TString("vec3  tan(vec3  angle);"));
-        s.append(TString("vec4  tan(vec4  angle);"));
+    s.append(TString("float atan(float y_over_x);"));
+    s.append(TString("vec2  atan(vec2  y_over_x);"));
+    s.append(TString("vec3  atan(vec3  y_over_x);"));
+    s.append(TString("vec4  atan(vec4  y_over_x);"));
 
-        s.append(TString("float asin(float x);"));
-        s.append(TString("vec2  asin(vec2  x);"));
-        s.append(TString("vec3  asin(vec3  x);"));
-        s.append(TString("vec4  asin(vec4  x);"));
+    //
+    // Exponential Functions.
+    //
+    s.append(TString("float pow(float x, float y);"));
+    s.append(TString("vec2  pow(vec2  x, vec2  y);"));
+    s.append(TString("vec3  pow(vec3  x, vec3  y);"));
+    s.append(TString("vec4  pow(vec4  x, vec4  y);"));
 
-        s.append(TString("float acos(float x);"));
-        s.append(TString("vec2  acos(vec2  x);"));
-        s.append(TString("vec3  acos(vec3  x);"));
-        s.append(TString("vec4  acos(vec4  x);"));
+    s.append(TString("float exp(float x);"));
+    s.append(TString("vec2  exp(vec2  x);"));
+    s.append(TString("vec3  exp(vec3  x);"));
+    s.append(TString("vec4  exp(vec4  x);"));
 
-        s.append(TString("float atan(float y, float x);"));
-        s.append(TString("vec2  atan(vec2  y, vec2  x);"));
-        s.append(TString("vec3  atan(vec3  y, vec3  x);"));
-        s.append(TString("vec4  atan(vec4  y, vec4  x);"));
+    s.append(TString("float log(float x);"));
+    s.append(TString("vec2  log(vec2  x);"));
+    s.append(TString("vec3  log(vec3  x);"));
+    s.append(TString("vec4  log(vec4  x);"));
 
-        s.append(TString("float atan(float y_over_x);"));
-        s.append(TString("vec2  atan(vec2  y_over_x);"));
-        s.append(TString("vec3  atan(vec3  y_over_x);"));
-        s.append(TString("vec4  atan(vec4  y_over_x);"));
+    s.append(TString("float exp2(float x);"));
+    s.append(TString("vec2  exp2(vec2  x);"));
+    s.append(TString("vec3  exp2(vec3  x);"));
+    s.append(TString("vec4  exp2(vec4  x);"));
 
-        //
-        // Exponential Functions.
-        //
-        s.append(TString("float pow(float x, float y);"));
-        s.append(TString("vec2  pow(vec2  x, vec2  y);"));
-        s.append(TString("vec3  pow(vec3  x, vec3  y);"));
-        s.append(TString("vec4  pow(vec4  x, vec4  y);"));
+    s.append(TString("float log2(float x);"));
+    s.append(TString("vec2  log2(vec2  x);"));
+    s.append(TString("vec3  log2(vec3  x);"));
+    s.append(TString("vec4  log2(vec4  x);"));
 
-        s.append(TString("float exp(float x);"));
-        s.append(TString("vec2  exp(vec2  x);"));
-        s.append(TString("vec3  exp(vec3  x);"));
-        s.append(TString("vec4  exp(vec4  x);"));
+    s.append(TString("float sqrt(float x);"));
+    s.append(TString("vec2  sqrt(vec2  x);"));
+    s.append(TString("vec3  sqrt(vec3  x);"));
+    s.append(TString("vec4  sqrt(vec4  x);"));
 
-        s.append(TString("float log(float x);"));
-        s.append(TString("vec2  log(vec2  x);"));
-        s.append(TString("vec3  log(vec3  x);"));
-        s.append(TString("vec4  log(vec4  x);"));
-
-        s.append(TString("float exp2(float x);"));
-        s.append(TString("vec2  exp2(vec2  x);"));
-        s.append(TString("vec3  exp2(vec3  x);"));
-        s.append(TString("vec4  exp2(vec4  x);"));
+    s.append(TString("float inversesqrt(float x);"));
+    s.append(TString("vec2  inversesqrt(vec2  x);"));
+    s.append(TString("vec3  inversesqrt(vec3  x);"));
+    s.append(TString("vec4  inversesqrt(vec4  x);"));
 
-        s.append(TString("float log2(float x);"));
-        s.append(TString("vec2  log2(vec2  x);"));
-        s.append(TString("vec3  log2(vec3  x);"));
-        s.append(TString("vec4  log2(vec4  x);"));
+    //
+    // Common Functions.
+    //
+    s.append(TString("float abs(float x);"));
+    s.append(TString("vec2  abs(vec2  x);"));
+    s.append(TString("vec3  abs(vec3  x);"));
+    s.append(TString("vec4  abs(vec4  x);"));
 
-        s.append(TString("float sqrt(float x);"));
-        s.append(TString("vec2  sqrt(vec2  x);"));
-        s.append(TString("vec3  sqrt(vec3  x);"));
-        s.append(TString("vec4  sqrt(vec4  x);"));
+    s.append(TString("float sign(float x);"));
+    s.append(TString("vec2  sign(vec2  x);"));
+    s.append(TString("vec3  sign(vec3  x);"));
+    s.append(TString("vec4  sign(vec4  x);"));
 
-        s.append(TString("float inversesqrt(float x);"));
-        s.append(TString("vec2  inversesqrt(vec2  x);"));
-        s.append(TString("vec3  inversesqrt(vec3  x);"));
-        s.append(TString("vec4  inversesqrt(vec4  x);"));
+    s.append(TString("float floor(float x);"));
+    s.append(TString("vec2  floor(vec2  x);"));
+    s.append(TString("vec3  floor(vec3  x);"));
+    s.append(TString("vec4  floor(vec4  x);"));
+
+    s.append(TString("float ceil(float x);"));
+    s.append(TString("vec2  ceil(vec2  x);"));
+    s.append(TString("vec3  ceil(vec3  x);"));
+    s.append(TString("vec4  ceil(vec4  x);"));
 
-        //
-        // Common Functions.
-        //
-        s.append(TString("float abs(float x);"));
-        s.append(TString("vec2  abs(vec2  x);"));
-        s.append(TString("vec3  abs(vec3  x);"));
-        s.append(TString("vec4  abs(vec4  x);"));
+    s.append(TString("float fract(float x);"));
+    s.append(TString("vec2  fract(vec2  x);"));
+    s.append(TString("vec3  fract(vec3  x);"));
+    s.append(TString("vec4  fract(vec4  x);"));
+
+    s.append(TString("float mod(float x, float y);"));
+    s.append(TString("vec2  mod(vec2  x, float y);"));
+    s.append(TString("vec3  mod(vec3  x, float y);"));
+    s.append(TString("vec4  mod(vec4  x, float y);"));
+    s.append(TString("vec2  mod(vec2  x, vec2  y);"));
+    s.append(TString("vec3  mod(vec3  x, vec3  y);"));
+    s.append(TString("vec4  mod(vec4  x, vec4  y);"));
 
-        s.append(TString("float sign(float x);"));
-        s.append(TString("vec2  sign(vec2  x);"));
-        s.append(TString("vec3  sign(vec3  x);"));
-        s.append(TString("vec4  sign(vec4  x);"));
+    s.append(TString("float min(float x, float y);"));
+    s.append(TString("vec2  min(vec2  x, float y);"));
+    s.append(TString("vec3  min(vec3  x, float y);"));
+    s.append(TString("vec4  min(vec4  x, float y);"));
+    s.append(TString("vec2  min(vec2  x, vec2  y);"));
+    s.append(TString("vec3  min(vec3  x, vec3  y);"));
+    s.append(TString("vec4  min(vec4  x, vec4  y);"));
 
-        s.append(TString("float floor(float x);"));
-        s.append(TString("vec2  floor(vec2  x);"));
-        s.append(TString("vec3  floor(vec3  x);"));
-        s.append(TString("vec4  floor(vec4  x);"));
-
-        s.append(TString("float ceil(float x);"));
-        s.append(TString("vec2  ceil(vec2  x);"));
-        s.append(TString("vec3  ceil(vec3  x);"));
-        s.append(TString("vec4  ceil(vec4  x);"));
+    s.append(TString("float max(float x, float y);"));
+    s.append(TString("vec2  max(vec2  x, float y);"));
+    s.append(TString("vec3  max(vec3  x, float y);"));
+    s.append(TString("vec4  max(vec4  x, float y);"));
+    s.append(TString("vec2  max(vec2  x, vec2  y);"));
+    s.append(TString("vec3  max(vec3  x, vec3  y);"));
+    s.append(TString("vec4  max(vec4  x, vec4  y);"));
 
-        s.append(TString("float fract(float x);"));
-        s.append(TString("vec2  fract(vec2  x);"));
-        s.append(TString("vec3  fract(vec3  x);"));
-        s.append(TString("vec4  fract(vec4  x);"));
+    s.append(TString("float clamp(float x, float minVal, float maxVal);"));
+    s.append(TString("vec2  clamp(vec2  x, float minVal, float maxVal);"));
+    s.append(TString("vec3  clamp(vec3  x, float minVal, float maxVal);"));
+    s.append(TString("vec4  clamp(vec4  x, float minVal, float maxVal);"));
+    s.append(TString("vec2  clamp(vec2  x, vec2  minVal, vec2  maxVal);"));
+    s.append(TString("vec3  clamp(vec3  x, vec3  minVal, vec3  maxVal);"));
+    s.append(TString("vec4  clamp(vec4  x, vec4  minVal, vec4  maxVal);"));
 
-        s.append(TString("float mod(float x, float y);"));
-        s.append(TString("vec2  mod(vec2  x, float y);"));
-        s.append(TString("vec3  mod(vec3  x, float y);"));
-        s.append(TString("vec4  mod(vec4  x, float y);"));
-        s.append(TString("vec2  mod(vec2  x, vec2  y);"));
-        s.append(TString("vec3  mod(vec3  x, vec3  y);"));
-        s.append(TString("vec4  mod(vec4  x, vec4  y);"));
+    s.append(TString("float mix(float x, float y, float a);"));
+    s.append(TString("vec2  mix(vec2  x, vec2  y, float a);"));
+    s.append(TString("vec3  mix(vec3  x, vec3  y, float a);"));
+    s.append(TString("vec4  mix(vec4  x, vec4  y, float a);"));
+    s.append(TString("vec2  mix(vec2  x, vec2  y, vec2  a);"));
+    s.append(TString("vec3  mix(vec3  x, vec3  y, vec3  a);"));
+    s.append(TString("vec4  mix(vec4  x, vec4  y, vec4  a);"));
 
-        s.append(TString("float min(float x, float y);"));
-        s.append(TString("vec2  min(vec2  x, float y);"));
-        s.append(TString("vec3  min(vec3  x, float y);"));
-        s.append(TString("vec4  min(vec4  x, float y);"));
-        s.append(TString("vec2  min(vec2  x, vec2  y);"));
-        s.append(TString("vec3  min(vec3  x, vec3  y);"));
-        s.append(TString("vec4  min(vec4  x, vec4  y);"));
+    s.append(TString("float step(float edge, float x);"));
+    s.append(TString("vec2  step(vec2  edge, vec2  x);"));
+    s.append(TString("vec3  step(vec3  edge, vec3  x);"));
+    s.append(TString("vec4  step(vec4  edge, vec4  x);"));
+    s.append(TString("vec2  step(float edge, vec2  x);"));
+    s.append(TString("vec3  step(float edge, vec3  x);"));
+    s.append(TString("vec4  step(float edge, vec4  x);"));
 
-        s.append(TString("float max(float x, float y);"));
-        s.append(TString("vec2  max(vec2  x, float y);"));
-        s.append(TString("vec3  max(vec3  x, float y);"));
-        s.append(TString("vec4  max(vec4  x, float y);"));
-        s.append(TString("vec2  max(vec2  x, vec2  y);"));
-        s.append(TString("vec3  max(vec3  x, vec3  y);"));
-        s.append(TString("vec4  max(vec4  x, vec4  y);"));
+    s.append(TString("float smoothstep(float edge0, float edge1, float x);"));
+    s.append(TString("vec2  smoothstep(vec2  edge0, vec2  edge1, vec2  x);"));
+    s.append(TString("vec3  smoothstep(vec3  edge0, vec3  edge1, vec3  x);"));
+    s.append(TString("vec4  smoothstep(vec4  edge0, vec4  edge1, vec4  x);"));
+    s.append(TString("vec2  smoothstep(float edge0, float edge1, vec2  x);"));
+    s.append(TString("vec3  smoothstep(float edge0, float edge1, vec3  x);"));
+    s.append(TString("vec4  smoothstep(float edge0, float edge1, vec4  x);"));
 
-        s.append(TString("float clamp(float x, float minVal, float maxVal);"));
-        s.append(TString("vec2  clamp(vec2  x, float minVal, float maxVal);"));
-        s.append(TString("vec3  clamp(vec3  x, float minVal, float maxVal);"));
-        s.append(TString("vec4  clamp(vec4  x, float minVal, float maxVal);"));
-        s.append(TString("vec2  clamp(vec2  x, vec2  minVal, vec2  maxVal);"));
-        s.append(TString("vec3  clamp(vec3  x, vec3  minVal, vec3  maxVal);"));
-        s.append(TString("vec4  clamp(vec4  x, vec4  minVal, vec4  maxVal);"));
+    //
+    // Geometric Functions.
+    //
+    s.append(TString("float length(float x);"));
+    s.append(TString("float length(vec2  x);"));
+    s.append(TString("float length(vec3  x);"));
+    s.append(TString("float length(vec4  x);"));
+
+    s.append(TString("float distance(float p0, float p1);"));
+    s.append(TString("float distance(vec2  p0, vec2  p1);"));
+    s.append(TString("float distance(vec3  p0, vec3  p1);"));
+    s.append(TString("float distance(vec4  p0, vec4  p1);"));
 
-        s.append(TString("float mix(float x, float y, float a);"));
-        s.append(TString("vec2  mix(vec2  x, vec2  y, float a);"));
-        s.append(TString("vec3  mix(vec3  x, vec3  y, float a);"));
-        s.append(TString("vec4  mix(vec4  x, vec4  y, float a);"));
-        s.append(TString("vec2  mix(vec2  x, vec2  y, vec2  a);"));
-        s.append(TString("vec3  mix(vec3  x, vec3  y, vec3  a);"));
-        s.append(TString("vec4  mix(vec4  x, vec4  y, vec4  a);"));
+    s.append(TString("float dot(float x, float y);"));
+    s.append(TString("float dot(vec2  x, vec2  y);"));
+    s.append(TString("float dot(vec3  x, vec3  y);"));
+    s.append(TString("float dot(vec4  x, vec4  y);"));
 
-        s.append(TString("float step(float edge, float x);"));
-        s.append(TString("vec2  step(vec2  edge, vec2  x);"));
-        s.append(TString("vec3  step(vec3  edge, vec3  x);"));
-        s.append(TString("vec4  step(vec4  edge, vec4  x);"));
-        s.append(TString("vec2  step(float edge, vec2  x);"));
-        s.append(TString("vec3  step(float edge, vec3  x);"));
-        s.append(TString("vec4  step(float edge, vec4  x);"));
+    s.append(TString("vec3 cross(vec3 x, vec3 y);"));
+    s.append(TString("float normalize(float x);"));
+    s.append(TString("vec2  normalize(vec2  x);"));
+    s.append(TString("vec3  normalize(vec3  x);"));
+    s.append(TString("vec4  normalize(vec4  x);"));
+
+    s.append(TString("float faceforward(float N, float I, float Nref);"));
+    s.append(TString("vec2  faceforward(vec2  N, vec2  I, vec2  Nref);"));
+    s.append(TString("vec3  faceforward(vec3  N, vec3  I, vec3  Nref);"));
+    s.append(TString("vec4  faceforward(vec4  N, vec4  I, vec4  Nref);"));
 
-        s.append(TString("float smoothstep(float edge0, float edge1, float x);"));
-        s.append(TString("vec2  smoothstep(vec2  edge0, vec2  edge1, vec2  x);"));
-        s.append(TString("vec3  smoothstep(vec3  edge0, vec3  edge1, vec3  x);"));
-        s.append(TString("vec4  smoothstep(vec4  edge0, vec4  edge1, vec4  x);"));
-        s.append(TString("vec2  smoothstep(float edge0, float edge1, vec2  x);"));
-        s.append(TString("vec3  smoothstep(float edge0, float edge1, vec3  x);"));
-        s.append(TString("vec4  smoothstep(float edge0, float edge1, vec4  x);"));
+    s.append(TString("float reflect(float I, float N);"));
+    s.append(TString("vec2  reflect(vec2  I, vec2  N);"));
+    s.append(TString("vec3  reflect(vec3  I, vec3  N);"));
+    s.append(TString("vec4  reflect(vec4  I, vec4  N);"));
 
-        //
-        // Geometric Functions.
-        //
-        s.append(TString("float length(float x);"));
-        s.append(TString("float length(vec2  x);"));
-        s.append(TString("float length(vec3  x);"));
-        s.append(TString("float length(vec4  x);"));
+    s.append(TString("float refract(float I, float N, float eta);"));
+    s.append(TString("vec2  refract(vec2  I, vec2  N, float eta);"));
+    s.append(TString("vec3  refract(vec3  I, vec3  N, float eta);"));
+    s.append(TString("vec4  refract(vec4  I, vec4  N, float eta);"));
+
+    //
+    // Matrix Functions.
+    //
+    s.append(TString("mat2 matrixCompMult(mat2 x, mat2 y);"));
+    s.append(TString("mat3 matrixCompMult(mat3 x, mat3 y);"));
+    s.append(TString("mat4 matrixCompMult(mat4 x, mat4 y);"));
 
-        s.append(TString("float distance(float p0, float p1);"));
-        s.append(TString("float distance(vec2  p0, vec2  p1);"));
-        s.append(TString("float distance(vec3  p0, vec3  p1);"));
-        s.append(TString("float distance(vec4  p0, vec4  p1);"));
-
-        s.append(TString("float dot(float x, float y);"));
-        s.append(TString("float dot(vec2  x, vec2  y);"));
-        s.append(TString("float dot(vec3  x, vec3  y);"));
-        s.append(TString("float dot(vec4  x, vec4  y);"));
+    //
+    // Vector relational functions.
+    //
+    s.append(TString("bvec2 lessThan(vec2 x, vec2 y);"));
+    s.append(TString("bvec3 lessThan(vec3 x, vec3 y);"));
+    s.append(TString("bvec4 lessThan(vec4 x, vec4 y);"));
 
-        s.append(TString("vec3 cross(vec3 x, vec3 y);"));
-        s.append(TString("float normalize(float x);"));
-        s.append(TString("vec2  normalize(vec2  x);"));
-        s.append(TString("vec3  normalize(vec3  x);"));
-        s.append(TString("vec4  normalize(vec4  x);"));
+    s.append(TString("bvec2 lessThan(ivec2 x, ivec2 y);"));
+    s.append(TString("bvec3 lessThan(ivec3 x, ivec3 y);"));
+    s.append(TString("bvec4 lessThan(ivec4 x, ivec4 y);"));
 
-        s.append(TString("float faceforward(float N, float I, float Nref);"));
-        s.append(TString("vec2  faceforward(vec2  N, vec2  I, vec2  Nref);"));
-        s.append(TString("vec3  faceforward(vec3  N, vec3  I, vec3  Nref);"));
-        s.append(TString("vec4  faceforward(vec4  N, vec4  I, vec4  Nref);"));
+    s.append(TString("bvec2 lessThanEqual(vec2 x, vec2 y);"));
+    s.append(TString("bvec3 lessThanEqual(vec3 x, vec3 y);"));
+    s.append(TString("bvec4 lessThanEqual(vec4 x, vec4 y);"));
+
+    s.append(TString("bvec2 lessThanEqual(ivec2 x, ivec2 y);"));
+    s.append(TString("bvec3 lessThanEqual(ivec3 x, ivec3 y);"));
+    s.append(TString("bvec4 lessThanEqual(ivec4 x, ivec4 y);"));
 
-        s.append(TString("float reflect(float I, float N);"));
-        s.append(TString("vec2  reflect(vec2  I, vec2  N);"));
-        s.append(TString("vec3  reflect(vec3  I, vec3  N);"));
-        s.append(TString("vec4  reflect(vec4  I, vec4  N);"));
+    s.append(TString("bvec2 greaterThan(vec2 x, vec2 y);"));
+    s.append(TString("bvec3 greaterThan(vec3 x, vec3 y);"));
+    s.append(TString("bvec4 greaterThan(vec4 x, vec4 y);"));
 
-        s.append(TString("float refract(float I, float N, float eta);"));
-        s.append(TString("vec2  refract(vec2  I, vec2  N, float eta);"));
-        s.append(TString("vec3  refract(vec3  I, vec3  N, float eta);"));
-        s.append(TString("vec4  refract(vec4  I, vec4  N, float eta);"));
+    s.append(TString("bvec2 greaterThan(ivec2 x, ivec2 y);"));
+    s.append(TString("bvec3 greaterThan(ivec3 x, ivec3 y);"));
+    s.append(TString("bvec4 greaterThan(ivec4 x, ivec4 y);"));
+
+    s.append(TString("bvec2 greaterThanEqual(vec2 x, vec2 y);"));
+    s.append(TString("bvec3 greaterThanEqual(vec3 x, vec3 y);"));
+    s.append(TString("bvec4 greaterThanEqual(vec4 x, vec4 y);"));
 
-        //
-        // Matrix Functions.
-        //
-        s.append(TString("mat2 matrixCompMult(mat2 x, mat2 y);"));
-        s.append(TString("mat3 matrixCompMult(mat3 x, mat3 y);"));
-        s.append(TString("mat4 matrixCompMult(mat4 x, mat4 y);"));
+    s.append(TString("bvec2 greaterThanEqual(ivec2 x, ivec2 y);"));
+    s.append(TString("bvec3 greaterThanEqual(ivec3 x, ivec3 y);"));
+    s.append(TString("bvec4 greaterThanEqual(ivec4 x, ivec4 y);"));
+
+    s.append(TString("bvec2 equal(vec2 x, vec2 y);"));
+    s.append(TString("bvec3 equal(vec3 x, vec3 y);"));
+    s.append(TString("bvec4 equal(vec4 x, vec4 y);"));
 
-        //
-        // Vector relational functions.
-        //
-        s.append(TString("bvec2 lessThan(vec2 x, vec2 y);"));
-        s.append(TString("bvec3 lessThan(vec3 x, vec3 y);"));
-        s.append(TString("bvec4 lessThan(vec4 x, vec4 y);"));
+    s.append(TString("bvec2 equal(ivec2 x, ivec2 y);"));
+    s.append(TString("bvec3 equal(ivec3 x, ivec3 y);"));
+    s.append(TString("bvec4 equal(ivec4 x, ivec4 y);"));
+
+    s.append(TString("bvec2 equal(bvec2 x, bvec2 y);"));
+    s.append(TString("bvec3 equal(bvec3 x, bvec3 y);"));
+    s.append(TString("bvec4 equal(bvec4 x, bvec4 y);"));
 
-        s.append(TString("bvec2 lessThan(ivec2 x, ivec2 y);"));
-        s.append(TString("bvec3 lessThan(ivec3 x, ivec3 y);"));
-        s.append(TString("bvec4 lessThan(ivec4 x, ivec4 y);"));
+    s.append(TString("bvec2 notEqual(vec2 x, vec2 y);"));
+    s.append(TString("bvec3 notEqual(vec3 x, vec3 y);"));
+    s.append(TString("bvec4 notEqual(vec4 x, vec4 y);"));
+
+    s.append(TString("bvec2 notEqual(ivec2 x, ivec2 y);"));
+    s.append(TString("bvec3 notEqual(ivec3 x, ivec3 y);"));
+    s.append(TString("bvec4 notEqual(ivec4 x, ivec4 y);"));
 
-        s.append(TString("bvec2 lessThanEqual(vec2 x, vec2 y);"));
-        s.append(TString("bvec3 lessThanEqual(vec3 x, vec3 y);"));
-        s.append(TString("bvec4 lessThanEqual(vec4 x, vec4 y);"));
+    s.append(TString("bvec2 notEqual(bvec2 x, bvec2 y);"));
+    s.append(TString("bvec3 notEqual(bvec3 x, bvec3 y);"));
+    s.append(TString("bvec4 notEqual(bvec4 x, bvec4 y);"));
 
-        s.append(TString("bvec2 lessThanEqual(ivec2 x, ivec2 y);"));
-        s.append(TString("bvec3 lessThanEqual(ivec3 x, ivec3 y);"));
-        s.append(TString("bvec4 lessThanEqual(ivec4 x, ivec4 y);"));
+    s.append(TString("bool any(bvec2 x);"));
+    s.append(TString("bool any(bvec3 x);"));
+    s.append(TString("bool any(bvec4 x);"));
 
-        s.append(TString("bvec2 greaterThan(vec2 x, vec2 y);"));
-        s.append(TString("bvec3 greaterThan(vec3 x, vec3 y);"));
-        s.append(TString("bvec4 greaterThan(vec4 x, vec4 y);"));
+    s.append(TString("bool all(bvec2 x);"));
+    s.append(TString("bool all(bvec3 x);"));
+    s.append(TString("bool all(bvec4 x);"));
 
-        s.append(TString("bvec2 greaterThan(ivec2 x, ivec2 y);"));
-        s.append(TString("bvec3 greaterThan(ivec3 x, ivec3 y);"));
-        s.append(TString("bvec4 greaterThan(ivec4 x, ivec4 y);"));
+    s.append(TString("bvec2 not(bvec2 x);"));
+    s.append(TString("bvec3 not(bvec3 x);"));
+    s.append(TString("bvec4 not(bvec4 x);"));
 
-        s.append(TString("bvec2 greaterThanEqual(vec2 x, vec2 y);"));
-        s.append(TString("bvec3 greaterThanEqual(vec3 x, vec3 y);"));
-        s.append(TString("bvec4 greaterThanEqual(vec4 x, vec4 y);"));
+    //
+    // Texture Functions.
+    //
+    s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
+    s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
+    s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
 
-        s.append(TString("bvec2 greaterThanEqual(ivec2 x, ivec2 y);"));
-        s.append(TString("bvec3 greaterThanEqual(ivec3 x, ivec3 y);"));
-        s.append(TString("bvec4 greaterThanEqual(ivec4 x, ivec4 y);"));
+    s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
 
-        s.append(TString("bvec2 equal(vec2 x, vec2 y);"));
-        s.append(TString("bvec3 equal(vec3 x, vec3 y);"));
-        s.append(TString("bvec4 equal(vec4 x, vec4 y);"));
+    //
+    // Noise functions.
+    //
+    //s.append(TString("float noise1(float x);"));
+    //s.append(TString("float noise1(vec2  x);"));
+    //s.append(TString("float noise1(vec3  x);"));
+    //s.append(TString("float noise1(vec4  x);"));
 
-        s.append(TString("bvec2 equal(ivec2 x, ivec2 y);"));
-        s.append(TString("bvec3 equal(ivec3 x, ivec3 y);"));
-        s.append(TString("bvec4 equal(ivec4 x, ivec4 y);"));
-
-        s.append(TString("bvec2 equal(bvec2 x, bvec2 y);"));
-        s.append(TString("bvec3 equal(bvec3 x, bvec3 y);"));
-        s.append(TString("bvec4 equal(bvec4 x, bvec4 y);"));
+    //s.append(TString("vec2 noise2(float x);"));
+    //s.append(TString("vec2 noise2(vec2  x);"));
+    //s.append(TString("vec2 noise2(vec3  x);"));
+    //s.append(TString("vec2 noise2(vec4  x);"));
 
-        s.append(TString("bvec2 notEqual(vec2 x, vec2 y);"));
-        s.append(TString("bvec3 notEqual(vec3 x, vec3 y);"));
-        s.append(TString("bvec4 notEqual(vec4 x, vec4 y);"));
-
-        s.append(TString("bvec2 notEqual(ivec2 x, ivec2 y);"));
-        s.append(TString("bvec3 notEqual(ivec3 x, ivec3 y);"));
-        s.append(TString("bvec4 notEqual(ivec4 x, ivec4 y);"));
+    //s.append(TString("vec3 noise3(float x);"));
+    //s.append(TString("vec3 noise3(vec2  x);"));
+    //s.append(TString("vec3 noise3(vec3  x);"));
+    //s.append(TString("vec3 noise3(vec4  x);"));
 
-        s.append(TString("bvec2 notEqual(bvec2 x, bvec2 y);"));
-        s.append(TString("bvec3 notEqual(bvec3 x, bvec3 y);"));
-        s.append(TString("bvec4 notEqual(bvec4 x, bvec4 y);"));
+    //s.append(TString("vec4 noise4(float x);"));
+    //s.append(TString("vec4 noise4(vec2  x);"));
+    //s.append(TString("vec4 noise4(vec3  x);"));
+    //s.append(TString("vec4 noise4(vec4  x);"));
 
-        s.append(TString("bool any(bvec2 x);"));
-        s.append(TString("bool any(bvec3 x);"));
-        s.append(TString("bool any(bvec4 x);"));
+    s.append(TString("\n"));
+    return s;
+}
 
-        s.append(TString("bool all(bvec2 x);"));
-        s.append(TString("bool all(bvec3 x);"));
-        s.append(TString("bool all(bvec4 x);"));
+//============================================================================
+//
+// Prototypes for built-in functions seen by vertex shaders only.
+//
+//============================================================================
+static TString BuiltInFunctionsVertex()
+{
+    TString s;
 
-        s.append(TString("bvec2 not(bvec2 x);"));
-        s.append(TString("bvec3 not(bvec3 x);"));
-        s.append(TString("bvec4 not(bvec4 x);"));
-
-        //
-        // Texture Functions.
-        //
-        s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
-        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
-        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
+    //
+    // Geometric Functions.
+    //
+    //s.append(TString("vec4 ftransform();"));
 
-        s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
+    //
+    // Texture Functions.
+    //
+    s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
+    s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
+    s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
+    s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
 
-        //
-        // Noise functions.
-        //
-    //	s.append(TString("float noise1(float x);"));
-    //	s.append(TString("float noise1(vec2  x);"));
-    //	s.append(TString("float noise1(vec3  x);"));
-    //	s.append(TString("float noise1(vec4  x);"));
+    s.append(TString("\n"));
+    return s;
+}
 
-    //	s.append(TString("vec2 noise2(float x);"));
-    //	s.append(TString("vec2 noise2(vec2  x);"));
-    //	s.append(TString("vec2 noise2(vec3  x);"));
-    //	s.append(TString("vec2 noise2(vec4  x);"));
+//============================================================================
+//
+// Prototypes for built-in functions seen by fragment shaders only.
+//
+//============================================================================
+static TString BuiltInFunctionsFragment()
+{
+    TString s;
 
-    //	s.append(TString("vec3 noise3(float x);"));
-    //	s.append(TString("vec3 noise3(vec2  x);"));
-    //	s.append(TString("vec3 noise3(vec3  x);"));
-    //	s.append(TString("vec3 noise3(vec4  x);"));
+    //
+    // Texture Functions.
+    //
+    s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
+    s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
+    s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
+    s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
 
-    //	s.append(TString("vec4 noise4(float x);"));
-    //	s.append(TString("vec4 noise4(vec2  x);"));
-    //	s.append(TString("vec4 noise4(vec3  x);"));
-    //	s.append(TString("vec4 noise4(vec4  x);"));
+    //s.append(TString("float dFdx(float p);"));
+    //s.append(TString("vec2  dFdx(vec2  p);"));
+    //s.append(TString("vec3  dFdx(vec3  p);"));
+    //s.append(TString("vec4  dFdx(vec4  p);"));
 
-        s.append(TString("\n"));
-    }
-    {
-        //============================================================================
-        //
-        // Prototypes for built-in functions seen by vertex shaders only.
-        //
-        //============================================================================
+    //s.append(TString("float dFdy(float p);"));
+    //s.append(TString("vec2  dFdy(vec2  p);"));
+    //s.append(TString("vec3  dFdy(vec3  p);"));
+    //s.append(TString("vec4  dFdy(vec4  p);"));
 
-        TString& s = BuiltInFunctionsVertex;
+    s.append(TString("float fwidth(float p);"));
+    s.append(TString("vec2  fwidth(vec2  p);"));
+    s.append(TString("vec3  fwidth(vec3  p);"));
+    s.append(TString("vec4  fwidth(vec4  p);"));
 
-        //
-        // Geometric Functions.
-        //
-        s.append(TString("vec4 ftransform();"));
+    s.append(TString("\n"));
+    return s;
+}
 
-        //
-        // Texture Functions.
-        //
-        s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
-        s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
-        s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
-
-        s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
+//============================================================================
+//
+// Standard uniforms.
+//
+//============================================================================
+static TString StandardUniforms()
+{
+    TString s;
 
-        s.append(TString("\n"));
-    }
-    {
-        //============================================================================
-        //
-        // Prototypes for built-in functions seen by fragment shaders only.
-        //
-        //============================================================================
+    //
+    // Depth range in window coordinates
+    //
+    s.append(TString("struct gl_DepthRangeParameters {"));
+    s.append(TString("    highp float near;"));        // n
+    s.append(TString("    highp float far;"));         // f
+    s.append(TString("    highp float diff;"));        // f - n
+    s.append(TString("};"));
+    s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
 
-        TString& s = BuiltInFunctionsFragment;
+    s.append(TString("\n"));
+    return s;
+}
 
-        //
-        // Texture Functions.
-        //
-        s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
-        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
-        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
-
-        s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
+//============================================================================
+//
+// Default precision for vertex shaders.
+//
+//============================================================================
+static TString DefaultPrecisionVertex()
+{
+    TString s;
 
-    //	s.append(TString("float dFdx(float p);"));
-    //	s.append(TString("vec2  dFdx(vec2  p);"));
-    //	s.append(TString("vec3  dFdx(vec3  p);"));
-    //	s.append(TString("vec4  dFdx(vec4  p);"));
+    s.append(TString("precision highp int;"));
+    s.append(TString("precision highp float;"));
+
+    s.append(TString("\n"));
+    return s;
+}
 
-    //	s.append(TString("float dFdy(float p);"));
-    //	s.append(TString("vec2  dFdy(vec2  p);"));
-    //	s.append(TString("vec3  dFdy(vec3  p);"));
-    //	s.append(TString("vec4  dFdy(vec4  p);"));
+//============================================================================
+//
+// Default precision for fragment shaders.
+//
+//============================================================================
+static TString DefaultPrecisionFragment()
+{
+    TString s;
 
-        s.append(TString("float fwidth(float p);"));
-        s.append(TString("vec2  fwidth(vec2  p);"));
-        s.append(TString("vec3  fwidth(vec3  p);"));
-        s.append(TString("vec4  fwidth(vec4  p);"));
+    s.append(TString("precision mediump int;"));
+    // No default precision for float in fragment shaders
+
+    s.append(TString("\n"));
+    return s;
+}
 
-        s.append(TString("\n"));
-    }
-    {
-        //============================================================================
-        //
-        // Standard Uniforms
-        //
-        //============================================================================
-
-        TString& s = StandardUniforms;
+//============================================================================
+//
+// Implementation dependent built-in constants.
+//
+//============================================================================
+static TString BuiltInConstants(const TBuiltInResource &resources)
+{
+    TStringStream s;
 
-        //
-        // Depth range in window coordinates
-        //
-        s.append(TString("struct gl_DepthRangeParameters {"));
-        s.append(TString("    highp float near;"));        // n
-        s.append(TString("    highp float far;"));         // f
-        s.append(TString("    highp float diff;"));        // f - n
-        s.append(TString("};"));
-        s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
+    s << "const int gl_MaxVertexAttribs = " << resources.maxVertexAttribs << ";";
+    s << "const int gl_MaxVertexUniformVectors = " << resources.maxVertexUniformVectors << ";";
 
-        s.append(TString("\n"));
-    }
-    {
-        //============================================================================
-        //
-        // Default precision for vertex shaders.
-        //
-        //============================================================================
+    s << "const int gl_MaxVaryingVectors = " << resources.maxVaryingVectors << ";";
+    s << "const int gl_MaxVertexTextureImageUnits = " << resources.maxVertexTextureImageUnits << ";";
+    s << "const int gl_MaxCombinedTextureImageUnits = " << resources.maxCombinedTextureImageUnits << ";";
+    s << "const int gl_MaxTextureImageUnits = " << resources.maxTextureImageUnits << ";";
+    s << "const int gl_MaxFragmentUniformVectors = " << resources.maxFragmentUniformVectors << ";";
+    s << "const int gl_MaxDrawBuffers = " << resources.maxDrawBuffers << ";";
+
+    return s.str();
+}
 
-        TString& s = VertexDefaultPrecision;
+void TBuiltIns::initialize(EShLanguage language, EShSpec spec, const TBuiltInResource& resources)
+{
+    switch (language) {
+    case EShLangFragment:
+        builtInStrings.push_back(DefaultPrecisionFragment());
+        builtInStrings.push_back(BuiltInFunctionsCommon());
+        builtInStrings.push_back(BuiltInFunctionsFragment());
+        builtInStrings.push_back(StandardUniforms());
+        break;
 
-        s.append(TString("precision highp int;"));
-        s.append(TString("precision highp float;"));
-        s.append(TString("\n"));
-    }
-    {
-        //============================================================================
-        //
-        // Default precision for fragment shaders.
-        //
-        //============================================================================
-        
-        TString& s = FragmentDefaultPrecision;
-        
-        s.append(TString("precision mediump int;"));
-        // No default precision for float in fragment shaders
-        s.append(TString("\n"));
+    case EShLangVertex:
+        builtInStrings.push_back(DefaultPrecisionVertex());
+        builtInStrings.push_back(BuiltInFunctionsCommon());
+        builtInStrings.push_back(BuiltInFunctionsVertex());
+        builtInStrings.push_back(StandardUniforms());
+        break;
+
+    default: assert(false && "Language not supported");
     }
 
-    builtInStrings[EShLangFragment].push_back(FragmentDefaultPrecision);
-    builtInStrings[EShLangFragment].push_back(BuiltInFunctions.c_str());
-    builtInStrings[EShLangFragment].push_back(BuiltInFunctionsFragment);
-    builtInStrings[EShLangFragment].push_back(StandardUniforms);
-    
-    builtInStrings[EShLangVertex].push_back(VertexDefaultPrecision);
-    builtInStrings[EShLangVertex].push_back(BuiltInFunctions);
-    builtInStrings[EShLangVertex].push_back(BuiltInFunctionsVertex);
-    builtInStrings[EShLangVertex].push_back(StandardUniforms);
+    builtInStrings.push_back(BuiltInConstants(resources));
 }
 
-void TBuiltIns::initialize(const TBuiltInResource &resources)
-{
-    TStringStream builtIns;
-
-    // Implementation dependent constants
-    builtIns << "const int gl_MaxVertexAttribs = " << resources.maxVertexAttribs << ";";
-    builtIns << "const int gl_MaxVertexUniformVectors = " << resources.maxVertexUniformVectors << ";";
-
-    builtIns << "const int gl_MaxVaryingVectors = " << resources.maxVaryingVectors << ";";
-    builtIns << "const int gl_MaxVertexTextureImageUnits = " << resources.maxVertexTextureImageUnits << ";";
-    builtIns << "const int gl_MaxCombinedTextureImageUnits = " << resources.maxCombinedTextureImageUnits << ";";
-    builtIns << "const int gl_MaxTextureImageUnits = " << resources.maxTextureImageUnits << ";";
-    builtIns << "const int gl_MaxFragmentUniformVectors = " << resources.maxFragmentUniformVectors << ";";
-    builtIns << "const int gl_MaxDrawBuffers = " << resources.maxDrawBuffers << ";";
-
-    builtInStrings[EShLangFragment].push_back(builtIns.str());
-    builtInStrings[EShLangVertex].push_back(builtIns.str());
-}
-
-void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable)
+void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource& resources, TSymbolTable& symbolTable)
 {
     //
     // First, insert some special built-in variables that are not in 
     // the built-in header files.
     //
     switch(language) {
-
-    case EShLangFragment: {
-            symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"),                   TType(EbtFloat, EbpMedium, EvqFragCoord,   4)));
-            symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"),                 TType(EbtBool,  EbpUndefined, EvqFrontFacing, 1)));
-            symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"),                   TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
-            symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData,    4)));
-            symbolTable.insert(*new TVariable(NewPoolTString("gl_PointCoord"),                  TType(EbtFloat, EbpMedium, EvqPointCoord,  2)));
-
-        }
+    case EShLangFragment:
+        symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"),                   TType(EbtFloat, EbpMedium, EvqFragCoord,   4)));
+        symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"),                 TType(EbtBool,  EbpUndefined, EvqFrontFacing, 1)));
+        symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"),                   TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
+        symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData,    4)));
+        symbolTable.insert(*new TVariable(NewPoolTString("gl_PointCoord"),                  TType(EbtFloat, EbpMedium, EvqPointCoord,  2)));
         break;
 
     case EShLangVertex:
         symbolTable.insert(*new TVariable(NewPoolTString("gl_Position"),    TType(EbtFloat, EbpHigh, EvqPosition,    4)));
         symbolTable.insert(*new TVariable(NewPoolTString("gl_PointSize"),   TType(EbtFloat, EbpMedium, EvqPointSize,   1)));
         break;
-    default: break;
+
+    default: assert(false && "Language not supported");
     }
 
     //
     // Next, identify which built-ins from the already loaded headers have
     // a mapping to an operator.  Those that are not identified as such are
     // expected to be resolved through a library of functions, versus as
     // operations.
     //
@@ -573,47 +585,33 @@ void IdentifyBuiltIns(EShLanguage langua
     symbolTable.relateToOperator("normalize",    EOpNormalize);
     symbolTable.relateToOperator("faceforward",  EOpFaceForward);
     symbolTable.relateToOperator("reflect",      EOpReflect);
     symbolTable.relateToOperator("refract",      EOpRefract);
     
     symbolTable.relateToOperator("any",          EOpAny);
     symbolTable.relateToOperator("all",          EOpAll);
 
-    switch(language)
-    {
+    // Map language-specific operators.
+    switch(language) {
     case EShLangVertex:
         break;
     case EShLangFragment:
-    //	symbolTable.relateToOperator("dFdx",         EOpDPdx);     // OES_standard_derivatives extension
-    //	symbolTable.relateToOperator("dFdy",         EOpDPdy);     // OES_standard_derivatives extension
-    //	symbolTable.relateToOperator("fwidth",       EOpFwidth);   // OES_standard_derivatives extension
+        //symbolTable.relateToOperator("dFdx",   EOpDPdx);    // OES_standard_derivatives extension
+        //symbolTable.relateToOperator("dFdy",   EOpDPdy);    // OES_standard_derivatives extension
+        //symbolTable.relateToOperator("fwidth", EOpFwidth);  // OES_standard_derivatives extension
         break;
-    default: assert(false && "Language not supported");
+    default: break;
     }
-}
 
-void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources)
-{
-    //
-    // First, insert some special built-in variables that are not in 
-    // the built-in header files.
-    //
+    // Finally add resource-specific variables.
     switch(language) {
-
     case EShLangFragment: {
             // Set up gl_FragData.  The array size.
             TType fragData(EbtFloat, EbpMedium, EvqFragColor,   4, false, true);
             fragData.setArraySize(resources.maxDrawBuffers);
             symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"),    fragData));
         }
         break;
-
     default: break;
     }
 }
 
-const char* GetPreprocessorBuiltinString()
-{
-    static const char *PreprocessorBuiltinString = "";
-
-    return PreprocessorBuiltinString;
-}
--- a/gfx/angle/src/compiler/Initialize.h
+++ b/gfx/angle/src/compiler/Initialize.h
@@ -12,25 +12,24 @@
 #include "compiler/Common.h"
 #include "compiler/ShHandle.h"
 #include "compiler/SymbolTable.h"
 
 typedef TVector<TString> TBuiltInStrings;
 
 class TBuiltIns {
 public:
-	POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-	void initialize();
-	void initialize(const TBuiltInResource& resources);
-	TBuiltInStrings* getBuiltInStrings() { return builtInStrings; }
+    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+
+    void initialize(EShLanguage language, EShSpec spec, const TBuiltInResource& resources);
+    const TBuiltInStrings& getBuiltInStrings() { return builtInStrings; }
+
 protected:
-	TBuiltInStrings builtInStrings[EShLangCount];
+    TBuiltInStrings builtInStrings;
 };
 
-void IdentifyBuiltIns(EShLanguage, TSymbolTable&);
-void IdentifyBuiltIns(EShLanguage, TSymbolTable&, const TBuiltInResource &resources);
-bool GenerateBuiltInSymbolTable(const TBuiltInResource* resources, TInfoSink&, TSymbolTable*, EShLanguage language = EShLangCount);
-bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, const TBuiltInResource *resources, TSymbolTable*);
-const char* GetPreprocessorBuiltinString();
+void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
+                      TSymbolTable& symbolTable);
+
 extern "C" int InitPreprocessor(void);
 extern "C" int FinalizePreprocessor(void);
 
 #endif // _INITIALIZE_INCLUDED_
--- a/gfx/angle/src/compiler/InitializeDll.cpp
+++ b/gfx/angle/src/compiler/InitializeDll.cpp
@@ -1,120 +1,115 @@
 //
 // 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.
 //
 
 #include "compiler/InitializeDll.h"
 
-#include "GLSLANG/ShaderLang.h"
-
 #include "compiler/InitializeGlobals.h"
 #include "compiler/InitializeParseContext.h"
+#include "compiler/osinclude.h"
 
 OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
 
 bool InitProcess()
 {
     if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
-		//
-		// Function is re-entrant.
-		//
+        //
+        // Function is re-entrant.
+        //
         return true;
-	}
+    }
 
     ThreadInitializeIndex = OS_AllocTLSIndex();
 
     if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
         assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
         return false;
-	}
+    }
 
 
     if (!InitializePoolIndex()) {
         assert(0 && "InitProcess(): Failed to initalize global pool");
         return false;
-	}
+    }
 
     if (!InitializeParseContextIndex()) {
         assert(0 && "InitProcess(): Failed to initalize parse context");
         return false;
-	}
-
-	InitThread();
-    return true;
-}
-
-
-bool InitThread()
-{
-	//
-    // This function is re-entrant
-	//
-    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
-		assert(0 && "InitThread(): Process hasn't been initalised.");
-        return false;
-	}
-
-    if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
-        return true;
-
-	InitializeGlobalPools();
-
-	if (!InitializeGlobalParseContext())
-        return false;
+    }
 
-    if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
-		assert(0 && "InitThread(): Unable to set init flag.");
-        return false;
-	}
-
-    return true;
-}
-
-
-bool DetachThread()
-{
-    bool success = true;
-
-    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
-        return true;
-
-	//
-	// Function is re-entrant and this thread may not have been initalised.
-	//
-    if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
-        if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
-			assert(0 && "DetachThread(): Unable to clear init flag.");
-            success = false;
-		}
-
-		FreeGlobalPools();
-
-		if (!FreeParseContext())
-            success = false;
-	}
-
-    return success;
+    return InitThread();
 }
 
 bool DetachProcess()
 {
     bool success = true;
 
     if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
         return true;
 
-    ShFinalize();
-
     success = DetachThread();
 
-	FreePoolIndex();
+    if (!FreeParseContextIndex())
+        success = false;
 
-	if (!FreeParseContextIndex())
-        success = false;
+    FreePoolIndex();
 
     OS_FreeTLSIndex(ThreadInitializeIndex);
     ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
 
     return success;
 }
+
+bool InitThread()
+{
+    //
+    // This function is re-entrant
+    //
+    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 && "InitThread(): Process hasn't been initalised.");
+        return false;
+    }
+
+    if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
+        return true;
+
+    InitializeGlobalPools();
+
+    if (!InitializeGlobalParseContext())
+        return false;
+
+    if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
+        assert(0 && "InitThread(): Unable to set init flag.");
+        return false;
+    }
+
+    return true;
+}
+
+bool DetachThread()
+{
+    bool success = true;
+
+    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
+        return true;
+
+    //
+    // Function is re-entrant and this thread may not have been initalised.
+    //
+    if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
+        if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
+            assert(0 && "DetachThread(): Unable to clear init flag.");
+            success = false;
+        }
+
+        if (!FreeParseContext())
+            success = false;
+
+        FreeGlobalPools();
+    }
+
+    return success;
+}
+
--- a/gfx/angle/src/compiler/InitializeDll.h
+++ b/gfx/angle/src/compiler/InitializeDll.h
@@ -1,19 +1,16 @@
 //
 // 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.
 //
 #ifndef __INITIALIZEDLL_H
 #define __INITIALIZEDLL_H
 
-
-#include "compiler/osinclude.h"
+bool InitProcess();
+bool DetachProcess();
 
-
-bool InitProcess();
 bool InitThread();
 bool DetachThread();
-bool DetachProcess();
 
 #endif // __INITIALIZEDLL_H
 
--- a/gfx/angle/src/compiler/InitializeParseContext.h
+++ b/gfx/angle/src/compiler/InitializeParseContext.h
@@ -1,17 +1,16 @@
 //
 // 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.
 //
 
 #ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
 #define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
-#include "compiler/osinclude.h"
 
 bool InitializeParseContextIndex();
+bool FreeParseContextIndex();
+
 bool InitializeGlobalParseContext();
 bool FreeParseContext();
-bool FreeParseContextIndex();
-
 
 #endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
--- a/gfx/angle/src/compiler/Link.cpp
+++ b/gfx/angle/src/compiler/Link.cpp
@@ -1,62 +0,0 @@
-//
-// 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.
-//
-
-//
-// The top level algorithms for linking multiple
-// shaders together.
-//
-#include "compiler/Common.h"
-#include "compiler/ShHandle.h"
-
-//
-// Actual link object, derived from the shader handle base classes.
-//
-class TGenericLinker : public TLinker {
-public:
-    TGenericLinker(EShExecutable e, int dOptions) : TLinker(e), debugOptions(dOptions) { }
-    bool link(TCompilerList&, TUniformMap*) { return true; }
-    void getAttributeBindings(ShBindingTable const **t) const { }
-    int debugOptions;
-};
-
-//
-// The internal view of a uniform/float object exchanged with the driver.
-//
-class TUniformLinkedMap : public TUniformMap {
-public:
-    TUniformLinkedMap() { }
-    virtual int getLocation(const char* name) { return 0; }
-};
-
-TShHandleBase* ConstructLinker(EShExecutable executable, int debugOptions)
-{
-    return new TGenericLinker(executable, debugOptions);
-}
-
-void DeleteLinker(TShHandleBase* linker)
-{
-    delete linker;
-}
-
-TUniformMap* ConstructUniformMap()
-{
-    return new TUniformLinkedMap();
-}
-
-void DeleteUniformMap(TUniformMap* map)
-{
-    delete map;
-}
-
-TShHandleBase* ConstructBindings()
-{
-    return 0;
-}
-
-void DeleteBindingList(TShHandleBase* bindingList)
-{
-    delete bindingList;
-}
--- a/gfx/angle/src/compiler/OutputGLSL.cpp
+++ b/gfx/angle/src/compiler/OutputGLSL.cpp
@@ -386,23 +386,27 @@ bool TOutputGLSL::visitUnary(Visit visit
 }
 
 bool TOutputGLSL::visitSelection(Visit visit, TIntermSelection* node)
 {
     TInfoSinkBase& out = objSink();
 
     if (node->usesTernaryOperator())
     {
-        out << "(";
+        // Notice two brackets at the beginning and end. The outer ones
+        // encapsulate the whole ternary expression. This preserves the
+        // order of precedence when ternary expressions are used in a
+        // compound expression, i.e., c = 2 * (a < b ? 1 : 2).
+        out << "((";
         node->getCondition()->traverse(this);
         out << ") ? (";
         node->getTrueBlock()->traverse(this);
         out << ") : (";
         node->getFalseBlock()->traverse(this);
-        out << ")";
+        out << "))";
     }
     else
     {
         out << "if (";
         node->getCondition()->traverse(this);
         out << ")\n";
 
         incrementDepth();
--- a/gfx/angle/src/compiler/OutputHLSL.cpp
+++ b/gfx/angle/src/compiler/OutputHLSL.cpp
@@ -5,16 +5,17 @@
 //
 
 #include "compiler/OutputHLSL.h"
 
 #include "compiler/debug.h"
 #include "compiler/InfoSink.h"
 #include "compiler/UnfoldSelect.h"
 
+#include <stdio.h>
 #include <algorithm>
 
 namespace sh
 {
 // Integer to TString conversion
 TString str(int i)
 {
     char buffer[20];
@@ -175,17 +176,17 @@ void OutputHLSL::header()
         {
             out << "static bool gl_FrontFacing = false;\n";
         }
 
         out << "\n";
 
         if (mUsesFragCoord)
         {
-            out << "uniform float4 dx_Window;\n"
+            out << "uniform float4 dx_Viewport;\n"
                    "uniform float2 dx_Depth;\n";
         }
 
         if (mUsesFrontFacing)
         {
             out << "uniform bool dx_PointsOrLines;\n"
                    "uniform bool dx_FrontCCW;\n";
         }
--- a/gfx/angle/src/compiler/ParseHelper.cpp
+++ b/gfx/angle/src/compiler/ParseHelper.cpp
@@ -171,18 +171,18 @@ bool TParseContext::parseMatrixFields(co
 void TParseContext::recover()
 {
     recoveredFromError = true;
 }
 
 //
 // Used by flex/bison to output all syntax and parsing errors.
 //
-void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken, 
-                                 const char *szExtraInfoFormat, ...)
+void TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken, 
+                          const char *szExtraInfoFormat, ...)
 {
     char szExtraInfo[400];
     va_list marker;
 
     va_start(marker, szExtraInfoFormat);
 
     vsnprintf(szExtraInfo, sizeof(szExtraInfo), szExtraInfoFormat, marker);
 
@@ -397,26 +397,39 @@ bool TParseContext::globalErrorCheck(int
 
     return true;
 }
 
 //
 // For now, keep it simple:  if it starts "gl_", it's reserved, independent
 // of scope.  Except, if the symbol table is at the built-in push-level,
 // which is when we are parsing built-ins.
+// Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a
+// webgl shader.
 //
 // Returns true if there was an error.
 //
 bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
 {
+    static const char* reservedErrMsg = "reserved built-in name";
     if (!symbolTable.atBuiltInLevel()) {
         if (identifier.substr(0, 3) == TString("gl_")) {
-            error(line, "reserved built-in name", "gl_", "");
+            error(line, reservedErrMsg, "gl_", "");
             return true;
         }
+        if (spec == EShSpecWebGL) {
+            if (identifier.substr(0, 6) == TString("webgl_")) {
+                error(line, reservedErrMsg, "webgl_", "");
+                return true;
+            }
+            if (identifier.substr(0, 7) == TString("_webgl_")) {
+                error(line, reservedErrMsg, "_webgl_", "");
+                return true;
+            }
+        }
         if (identifier.find("__") != TString::npos) {
             //error(line, "Two consecutive underscores are reserved for future use.", identifier.c_str(), "", "");
             //return true;
             infoSink.info.message(EPrefixWarning, "Two consecutive underscores are reserved for future use.", line);
             return false;
         }
     }
 
@@ -1392,16 +1405,30 @@ bool InitializeParseContextIndex()
     if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
         assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
         return false;
     }
 
     return true;
 }
 
+bool FreeParseContextIndex()
+{
+    OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
+
+    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 && "FreeParseContextIndex(): Parse Context index not initalised");
+        return false;
+    }
+
+    GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+
+    return OS_FreeTLSIndex(tlsiIndex);
+}
+
 bool InitializeGlobalParseContext()
 {
     if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
         assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalised");
         return false;
     }
 
     TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
@@ -1417,46 +1444,33 @@ bool InitializeGlobalParseContext()
     }
 
     lpThreadData->lpGlobalParseContext = 0;
     OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
 
     return true;
 }
 
-TParseContextPointer& GetGlobalParseContext()
-{
-    //
-    // Minimal error checking for speed
-    //
-
-    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-
-    return lpParseContext->lpGlobalParseContext;
-}
-
 bool FreeParseContext()
 {
     if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
         assert(0 && "FreeParseContext(): Parse Context index not initalised");
         return false;
     }
 
     TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
     if (lpParseContext)
         delete lpParseContext;
 
     return true;
 }
 
-bool FreeParseContextIndex()
+TParseContextPointer& GetGlobalParseContext()
 {
-    OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
+    //
+    // Minimal error checking for speed
+    //
 
-    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "FreeParseContextIndex(): Parse Context index not initalised");
-        return false;
-    }
+    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
 
-    GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+    return lpParseContext->lpGlobalParseContext;
+}
 
-    return OS_FreeTLSIndex(tlsiIndex);
-}
--- a/gfx/angle/src/compiler/ParseHelper.h
+++ b/gfx/angle/src/compiler/ParseHelper.h
@@ -31,37 +31,38 @@ struct TPragma {
     TPragmaTable pragmaTable;
 };
 
 //
 // The following are extra variables needed during parsing, grouped together so
 // they can be passed to the parser without needing a global.
 //
 struct TParseContext {
-    TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is) :
-            intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0),
+    TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage l, EShSpec s, TInfoSink& is) :
+            intermediate(interm), symbolTable(symt), infoSink(is), language(l), spec(s), treeRoot(0),
             recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
             inTypeParen(false), contextPragma(true, false) {  }
     TIntermediate& intermediate; // to hold and build a parse tree
     TSymbolTable& symbolTable;   // symbol table that goes with the language currently being parsed
     TInfoSink& infoSink;
     EShLanguage language;        // vertex or fragment language (future: pack or unpack)
+    EShSpec spec;                // The language specification compiler conforms to - GLES2 or WebGL.
     TIntermNode* treeRoot;       // root of parse tree being created
     bool recoveredFromError;     // true if a parse error has occurred, but we continue to parse
     int numErrors;
     bool lexAfterType;           // true if we've recognized a type, so can only be looking for an identifier
     int loopNestingLevel;        // 0 if outside all loops
     bool inTypeParen;            // true if in parentheses, looking only for an identifier
     const TType* currentFunctionType;  // the return type of the function that's currently being parsed
     bool functionReturnsValue;   // true if a non-void function has a return
     TMap<TString, TBehavior> extensionBehavior;
     void initializeExtensionBehavior();
 
-    void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
-                      const char *szExtraInfoFormat, ...);
+    void error(TSourceLoc, const char *szReason, const char *szToken,
+               const char *szExtraInfoFormat, ...);
     bool reservedErrorCheck(int line, const TString& identifier);
     void recover();
 
     bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
     bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
     void assignError(int line, const char* op, TString left, TString right);
     void unaryOpError(int line, const char* op, TString operand);
     void binaryOpError(int line, const char* op, TString left, TString right);
--- a/gfx/angle/src/compiler/ShHandle.h
+++ b/gfx/angle/src/compiler/ShHandle.h
@@ -12,127 +12,65 @@
 // sent as ShHandle to the driver.
 //
 // This should not be included by driver code.
 //
 
 #include "GLSLANG/ShaderLang.h"
 
 #include "compiler/InfoSink.h"
+#include "compiler/SymbolTable.h"
 
 class TCompiler;
-class TLinker;
-class TUniformMap;
-
+class TIntermNode;
 
 //
 // The base class used to back handles returned to the driver.
 //
 class TShHandleBase {
 public:
     TShHandleBase() { }
     virtual ~TShHandleBase() { }
     virtual TCompiler* getAsCompiler() { return 0; }
-    virtual TLinker* getAsLinker() { return 0; }
-    virtual TUniformMap* getAsUniformMap() { return 0; }
 };
 
 //
-// The base class for the machine dependent linker to derive from
-// for managing where uniforms live.
-//
-class TUniformMap : public TShHandleBase {
-public:
-    TUniformMap() { }
-    virtual ~TUniformMap() { }
-    virtual TUniformMap* getAsUniformMap() { return this; }
-    virtual int getLocation(const char* name) = 0;    
-    virtual TInfoSink& getInfoSink() { return infoSink; }
-    TInfoSink infoSink;
-};
-class TIntermNode;
-
-//
 // The base class for the machine dependent compiler to derive from
 // for managing object code from the compile.
 //
 class TCompiler : public TShHandleBase {
 public:
-    TCompiler(EShLanguage l) : language(l), haveValidObjectCode(false) { }
+    TCompiler(EShLanguage l, EShSpec s) : language(l), spec(s) { }
     virtual ~TCompiler() { }
-    EShLanguage getLanguage() { return language; }
-    virtual TInfoSink& getInfoSink() { return infoSink; }
+
+    EShLanguage getLanguage() const { return language; }
+    EShSpec getSpec() const { return spec; }
+    TSymbolTable& getSymbolTable() { return symbolTable; }
+    TInfoSink& getInfoSink() { return infoSink; }
 
     virtual bool compile(TIntermNode* root) = 0;
 
     virtual TCompiler* getAsCompiler() { return this; }
-    virtual bool linkable() { return haveValidObjectCode; }
 
-    TInfoSink infoSink;
 protected:
     EShLanguage language;
-    bool haveValidObjectCode;
-};
-
-//
-// Link operations are base on a list of compile results...
-//
-typedef TVector<TCompiler*> TCompilerList;
-typedef TVector<TShHandleBase*> THandleList;
-
-//
-// The base class for the machine dependent linker to derive from
-// to manage the resulting executable.
-//
+    EShSpec spec;
 
-class TLinker : public TShHandleBase {
-public:
-    TLinker(EShExecutable e) : 
-        executable(e), 
-        haveReturnableObjectCode(false),
-        appAttributeBindings(0),
-        fixedAttributeBindings(0),
-        excludedAttributes(0),
-        excludedCount(0),
-        uniformBindings(0) { }
-    virtual TLinker* getAsLinker() { return this; }
-    virtual ~TLinker() { }
-    virtual bool link(TCompilerList&, TUniformMap*) = 0;
-    virtual bool link(THandleList&) { return false; }
-    virtual void setAppAttributeBindings(const ShBindingTable* t)   { appAttributeBindings = t; }
-    virtual void setFixedAttributeBindings(const ShBindingTable* t) { fixedAttributeBindings = t; }
-    virtual void getAttributeBindings(ShBindingTable const **t) const = 0;
-    virtual void setExcludedAttributes(const int* attributes, int count) { excludedAttributes = attributes; excludedCount = count; }
-    virtual ShBindingTable* getUniformBindings() const  { return uniformBindings; }
-    virtual const void* getObjectCode() const { return 0; } // a real compiler would be returning object code here
-    virtual TInfoSink& getInfoSink() { return infoSink; }
+    // Built-in symbol table for the given language, spec, and resources.
+    // It is preserved from compile-to-compile.
+    TSymbolTable symbolTable;
+    // Output sink.
     TInfoSink infoSink;
-protected:
-    EShExecutable executable;
-    bool haveReturnableObjectCode;  // true when objectCode is acceptable to send to driver
-
-    const ShBindingTable* appAttributeBindings;
-    const ShBindingTable* fixedAttributeBindings;
-    const int* excludedAttributes;
-    int excludedCount;
-    ShBindingTable* uniformBindings;                // created by the linker    
 };
 
 //
 // This is the interface between the machine independent code
 // and the machine dependent code.
 //
 // The machine dependent code should derive from the classes
 // above. Then Construct*() and Delete*() will create and 
 // destroy the machine dependent objects, which contain the
 // above machine independent information.
 //
-TCompiler* ConstructCompiler(EShLanguage, int);
-
-TShHandleBase* ConstructLinker(EShExecutable, int);
-void DeleteLinker(TShHandleBase*);
-
-TUniformMap* ConstructUniformMap();
+TCompiler* ConstructCompiler(EShLanguage, EShSpec);
 void DeleteCompiler(TCompiler*);
 
-void DeleteUniformMap(TUniformMap*);
-
 #endif // _SHHANDLE_INCLUDED_
--- a/gfx/angle/src/compiler/ShaderLang.cpp
+++ b/gfx/angle/src/compiler/ShaderLang.cpp
@@ -1,299 +1,214 @@
 //
 // 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.
 //
 
 //
-// Implement the top-level of interface to the compiler/linker,
+// Implement the top-level of interface to the compiler,
 // as defined in ShaderLang.h
 //
 
 #include "GLSLANG/ShaderLang.h"
 
 #include "compiler/Initialize.h"
 #include "compiler/InitializeDll.h"
 #include "compiler/ParseHelper.h"
 #include "compiler/ShHandle.h"
 #include "compiler/SymbolTable.h"
 
-//
-// A symbol table for each language.  Each has a different
-// set of built-ins, and we want to preserve that from
-// compile to compile.
-//
-TSymbolTable* SymbolTables[EShLangCount];
+static bool InitializeSymbolTable(
+        const TBuiltInStrings& builtInStrings,
+        EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
+        TInfoSink& infoSink, TSymbolTable& symbolTable)
+{
+    TIntermediate intermediate(infoSink);
+    TParseContext parseContext(symbolTable, intermediate, language, spec, infoSink);
+
+    GlobalParseContext = &parseContext;
+
+    setInitialState();
+
+    assert(symbolTable.isEmpty());       
+    //
+    // Parse the built-ins.  This should only happen once per
+    // language symbol table.
+    //
+    // Push the symbol table to give it an initial scope.  This
+    // push should not have a corresponding pop, so that built-ins
+    // are preserved, and the test for an empty table fails.
+    //
+    symbolTable.push();
+    
+    //Initialize the Preprocessor
+    if (InitPreprocessor())
+    {
+        infoSink.info.message(EPrefixInternalError,  "Unable to intialize the Preprocessor");
+        return false;
+    }
 
+    for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
+    {
+        const char* builtInShaders[1];
+        int builtInLengths[1];
 
-TPoolAllocator* PerProcessGPA = 0;
+        builtInShaders[0] = (*i).c_str();
+        builtInLengths[0] = (int) (*i).size();
+
+        if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0)
+        {
+            infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
+            return false;
+        }
+    }
+
+    IdentifyBuiltIns(language, spec, resources, symbolTable);
+
+    FinalizePreprocessor();
+
+    return true;
+}
+
+static bool GenerateBuiltInSymbolTable(
+        EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
+        TInfoSink& infoSink, TSymbolTable& symbolTable)
+{
+    TBuiltIns builtIns;
+
+    builtIns.initialize(language, spec, resources);
+    return InitializeSymbolTable(builtIns.getBuiltInStrings(), language, spec, resources, infoSink, symbolTable);
+}
+
 //
 // This is the platform independent interface between an OGL driver
-// and the shading language compiler/linker.
+// and the shading language compiler.
 //
 
 //
 // Driver must call this first, once, before doing any other
-// compiler/linker operations.
+// compiler operations.
 //
 int ShInitialize()
 {
-    TInfoSink infoSink;
-    bool ret = true;
-
     if (!InitProcess())
         return 0;
 
-    // This method should be called once per process. If its called by multiple threads, then 
-    // we need to have thread synchronization code around the initialization of per process
-    // global pool allocator
-    if (!PerProcessGPA) { 
-        TPoolAllocator *builtInPoolAllocator = new TPoolAllocator(true);
-        builtInPoolAllocator->push();
-        TPoolAllocator* gPoolAllocator = &GlobalPoolAllocator;
-        SetGlobalPoolAllocatorPtr(builtInPoolAllocator);
-
-        TSymbolTable symTables[EShLangCount];
-        GenerateBuiltInSymbolTable(0, infoSink, symTables);
-
-        PerProcessGPA = new TPoolAllocator(true);
-        PerProcessGPA->push();
-        SetGlobalPoolAllocatorPtr(PerProcessGPA);
-
-        SymbolTables[EShLangVertex] = new TSymbolTable;
-        SymbolTables[EShLangVertex]->copyTable(symTables[EShLangVertex]);
-        SymbolTables[EShLangFragment] = new TSymbolTable;
-        SymbolTables[EShLangFragment]->copyTable(symTables[EShLangFragment]);
-
-        SetGlobalPoolAllocatorPtr(gPoolAllocator);
-
-        symTables[EShLangVertex].pop();
-        symTables[EShLangFragment].pop();
-
-        builtInPoolAllocator->popAll();
-        delete builtInPoolAllocator;        
-
-    }
-
-    return ret ? 1 : 0;
+    return 1;
 }
 
 //
-// Driver calls these to create and destroy compiler/linker
-// objects.
+// Driver calls these to create and destroy compiler objects.
 //
 
-ShHandle ShConstructCompiler(const EShLanguage language, int debugOptions)
+ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec, const TBuiltInResource* resources)
 {
     if (!InitThread())
         return 0;
 
-    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, debugOptions));
-    
-    return reinterpret_cast<void*>(base);
-}
-
-ShHandle ShConstructLinker(const EShExecutable executable, int debugOptions)
-{
-    if (!InitThread())
+    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, spec));
+    TCompiler* compiler = base->getAsCompiler();
+    if (compiler == 0)
         return 0;
 
-    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructLinker(executable, debugOptions));
-
-    return reinterpret_cast<void*>(base);
-}
-
-ShHandle ShConstructUniformMap()
-{
-    if (!InitThread())
+    // Generate built-in symbol table.
+    if (!GenerateBuiltInSymbolTable(language, spec, *resources, compiler->getInfoSink(), compiler->getSymbolTable())) {
+        ShDestruct(base);
         return 0;
-
-    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructUniformMap());
+    }
 
     return reinterpret_cast<void*>(base);
 }
 
 void ShDestruct(ShHandle handle)
 {
     if (handle == 0)
         return;
 
     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
 
     if (base->getAsCompiler())
         DeleteCompiler(base->getAsCompiler());
-    else if (base->getAsLinker())
-        DeleteLinker(base->getAsLinker());
-    else if (base->getAsUniformMap())
-        DeleteUniformMap(base->getAsUniformMap());
 }
 
 //
 // Cleanup symbol tables
 //
 int ShFinalize()
-{  
-  if (PerProcessGPA) {
-    PerProcessGPA->popAll();
-    delete PerProcessGPA;
-    PerProcessGPA = 0;
-  }
-  for (int i = 0; i < EShLangCount; ++i) {
-    delete SymbolTables[i];
-    SymbolTables[i] = 0;
-  }
-  return 1;
-}
-
-bool GenerateBuiltInSymbolTable(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable* symbolTables, EShLanguage language)
 {
-    TBuiltIns builtIns;
-    
-	if (resources) {
-		builtIns.initialize(*resources);
-		InitializeSymbolTable(builtIns.getBuiltInStrings(), language, infoSink, resources, symbolTables);
-	} else {
-		builtIns.initialize();
-		InitializeSymbolTable(builtIns.getBuiltInStrings(), EShLangVertex, infoSink, resources, symbolTables);
-		InitializeSymbolTable(builtIns.getBuiltInStrings(), EShLangFragment, infoSink, resources, symbolTables);
-	}
-
-    return true;
-}
-
-bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, const TBuiltInResource* resources, TSymbolTable* symbolTables)
-{
-    TIntermediate intermediate(infoSink);	
-    TSymbolTable* symbolTable;
-	
-	if (resources)
-		symbolTable = symbolTables;
-	else
-		symbolTable = &symbolTables[language];
-
-    TParseContext parseContext(*symbolTable, intermediate, language, infoSink);
-
-    GlobalParseContext = &parseContext;
-    
-    setInitialState();
+    if (!DetachProcess())
+        return 0;
 
-    assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
-       
-    //
-    // Parse the built-ins.  This should only happen once per
-    // language symbol table.
-    //
-    // Push the symbol table to give it an initial scope.  This
-    // push should not have a corresponding pop, so that built-ins
-    // are preserved, and the test for an empty table fails.
-    //
-
-    symbolTable->push();
-    
-    //Initialize the Preprocessor
-    int ret = InitPreprocessor();
-    if (ret) {
-        infoSink.info.message(EPrefixInternalError,  "Unable to intialize the Preprocessor");
-        return false;
-    }
-    
-    for (TBuiltInStrings::iterator i  = BuiltInStrings[parseContext.language].begin();
-                                    i != BuiltInStrings[parseContext.language].end();
-                                    ++i) {
-        const char* builtInShaders[1];
-        int builtInLengths[1];
-
-        builtInShaders[0] = (*i).c_str();
-        builtInLengths[0] = (int) (*i).size();
-
-        if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0) {
-            infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
-            return false;
-        }
-    }
-
-	if (resources) {
-		IdentifyBuiltIns(parseContext.language, *symbolTable, *resources);
-	} else {									   
-		IdentifyBuiltIns(parseContext.language, *symbolTable);
-	}
-
-    FinalizePreprocessor();
-
-    return true;
+    return 1;
 }
 
 //
 // Do an actual compile on the given strings.  The result is left 
 // in the given compile object.
 //
 // Return:  The return value of ShCompile is really boolean, indicating
 // success or failure.
 //
 int ShCompile(
     const ShHandle handle,
     const char* const shaderStrings[],
     const int numStrings,
     const EShOptimizationLevel optLevel,
-    const TBuiltInResource* resources,
     int debugOptions
     )
 {
     if (!InitThread())
         return 0;
 
     if (handle == 0)
         return 0;
 
     TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
     TCompiler* compiler = base->getAsCompiler();
     if (compiler == 0)
         return 0;
     
     GlobalPoolAllocator.push();
-    TInfoSink& infoSink = compiler->infoSink;
+    TInfoSink& infoSink = compiler->getInfoSink();
     infoSink.info.erase();
     infoSink.debug.erase();
     infoSink.obj.erase();
 
     if (numStrings == 0)
         return 1;
 
     TIntermediate intermediate(infoSink);
-    TSymbolTable symbolTable(*SymbolTables[compiler->getLanguage()]);
-    
-    GenerateBuiltInSymbolTable(resources, infoSink, &symbolTable, compiler->getLanguage());
+    TSymbolTable& symbolTable = compiler->getSymbolTable();
 
-    TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), infoSink);
+    TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->getSpec(), infoSink);
     parseContext.initializeExtensionBehavior();
-
     GlobalParseContext = &parseContext;
-    
+ 
     setInitialState();
 
-    InitPreprocessor();    
+    InitPreprocessor();
     //
     // Parse the application's shaders.  All the following symbol table
     // work will be throw-away, so push a new allocation scope that can
     // be thrown away, then push a scope for the current shader's globals.
     //
     bool success = true;
-    
+
     symbolTable.push();
     if (!symbolTable.atGlobalLevel())
         parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
 
     int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext);
     if (ret)
         success = false;
 
     if (success && parseContext.treeRoot) {
         if (optLevel == EShOptNoGeneration)
-            parseContext.infoSink.info.message(EPrefixNone, "No errors.  No code generation or linking was requested.");
+            parseContext.infoSink.info.message(EPrefixNone, "No errors.  No code generation was requested.");
         else {
             success = intermediate.postProcess(parseContext.treeRoot, parseContext.language);
 
             if (success) {
 
                 if (debugOptions & EDebugOpIntermediate)
                     intermediate.outputTree(parseContext.treeRoot);
 
@@ -319,151 +234,51 @@ int ShCompile(
     }
 
     intermediate.remove(parseContext.treeRoot);
 
     //
     // Ensure symbol table is returned to the built-in level,
     // throwing away all but the built-ins.
     //
-    while (! symbolTable.atSharedBuiltInLevel())
+    while (!symbolTable.atBuiltInLevel())
         symbolTable.pop();
 
     FinalizePreprocessor();
     //
     // Throw away all the temporary memory used by the compilation process.
     //
     GlobalPoolAllocator.pop();
 
     return success ? 1 : 0;
 }
 
 //
-// Do an actual link on the given compile objects.
-//
-// Return:  The return value of is really boolean, indicating
-// success or failure.
-//
-int ShLink(
-    const ShHandle linkHandle,
-    const ShHandle compHandles[],
-    const int numHandles,
-    ShHandle uniformMapHandle,
-    short int** uniformsAccessed,
-    int* numUniformsAccessed)
-
-{
-    if (!InitThread())
-        return 0;
-
-    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(linkHandle);
-    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
-    if (linker == 0)
-        return 0;
-
-    int returnValue;
-    GlobalPoolAllocator.push();
-    returnValue = ShLinkExt(linkHandle, compHandles, numHandles);
-    GlobalPoolAllocator.pop();
-
-    if (returnValue)
-        return 1;
-
-    return 0;
-}
-//
-// This link method will be eventually used once the ICD supports the new linker interface
-//
-int ShLinkExt(
-    const ShHandle linkHandle,
-    const ShHandle compHandles[],
-    const int numHandles)
-{
-    if (linkHandle == 0 || numHandles == 0)
-        return 0;
-
-    THandleList cObjects;
-
-    {// support MSVC++6.0
-        for (int i = 0; i < numHandles; ++i) {
-            if (compHandles[i] == 0)
-                return 0;
-            TShHandleBase* base = reinterpret_cast<TShHandleBase*>(compHandles[i]);
-            if (base->getAsLinker()) {
-                cObjects.push_back(base->getAsLinker());
-            }
-            if (base->getAsCompiler())
-                cObjects.push_back(base->getAsCompiler());
-    
-    
-            if (cObjects[i] == 0)
-                return 0;
-        }
-    }
-
-    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(linkHandle);
-    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
-
-    if (linker == 0)
-        return 0;
-
-    linker->infoSink.info.erase();
-    linker->infoSink.obj.erase();
-
-    {// support MSVC++6.0
-        for (int i = 0; i < numHandles; ++i) {
-            if (cObjects[i]->getAsCompiler()) {
-                if (! cObjects[i]->getAsCompiler()->linkable()) {
-                    linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code.");                
-                    return 0;
-                }
-            }
-        }
-    }
-
-    bool ret = linker->link(cObjects);
-
-    return ret ? 1 : 0;
-}
-
-//
-// ShSetEncrpytionMethod is a place-holder for specifying
-// how source code is encrypted.
-//
-void ShSetEncryptionMethod(ShHandle handle)
-{
-    if (handle == 0)
-        return;
-}
-
-//
-// Return any compiler/linker/uniformmap log of messages for the application.
+// Return any compiler log of messages for the application.
 //
 const char* ShGetInfoLog(const ShHandle handle)
 {
     if (!InitThread())
         return 0;
 
     if (handle == 0)
         return 0;
 
     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-    TInfoSink* infoSink;
+    TInfoSink* infoSink = 0;
 
     if (base->getAsCompiler())
         infoSink = &(base->getAsCompiler()->getInfoSink());
-    else if (base->getAsLinker())
-        infoSink = &(base->getAsLinker()->getInfoSink());
 
     infoSink->info << infoSink->debug.c_str();
     return infoSink->info.c_str();
 }
 
 //
-// Return any unlinked object code.
+// Return any object code.
 //
 const char* ShGetObjectCode(const ShHandle handle)
 {
     if (!InitThread())
         return 0;
 
     if (handle == 0)
         return 0;
@@ -471,121 +286,8 @@ const char* ShGetObjectCode(const ShHand
     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
     TInfoSink* infoSink;
 
     if (base->getAsCompiler())
         infoSink = &(base->getAsCompiler()->getInfoSink());
 
     return infoSink->obj.c_str();
 }
-
-//
-// Return the resulting binary code from the link process.  Structure
-// is machine dependent.
-//
-const void* ShGetExecutable(const ShHandle handle)
-{
-    if (!InitThread())
-        return 0;
-
-    if (handle == 0)
-        return 0;
-
-    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
-    
-    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
-    if (linker == 0)
-        return 0;
-
-    return linker->getObjectCode();
-}
-
-//
-// Let the linker know where the application said it's attributes are bound.
-// The linker does not use these values, they are remapped by the ICD or
-// hardware.  It just needs them to know what's aliased.
-//
-// Return:  The return value of is really boolean, indicating
-// success or failure.
-//
-int ShSetVirtualAttributeBindings(const ShHandle handle, const ShBindingTable* table)
-{    
-    if (!InitThread())
-        return 0;
-
-    if (handle == 0)
-        return 0;
-
-    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
-    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
-
-    if (linker == 0)
-        return 0;
-   
-    linker->setAppAttributeBindings(table);
-
-    return 1;
-}
-
-//
-// Let the linker know where the predefined attributes have to live.
-//
-int ShSetFixedAttributeBindings(const ShHandle handle, const ShBindingTable* table)
-{
-    if (!InitThread())
-        return 0;
-
-    if (handle == 0)
-        return 0;
-
-    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
-    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
-
-    if (linker == 0)
-        return 0;
-
-    linker->setFixedAttributeBindings(table);
-    return 1;
-}
-
-//
-// Some attribute locations are off-limits to the linker...
-//
-int ShExcludeAttributes(const ShHandle handle, int *attributes, int count)
-{
-    if (!InitThread())
-        return 0;
-
-    if (handle == 0)
-        return 0;
-
-    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
-    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
-    if (linker == 0)
-        return 0;
-
-    linker->setExcludedAttributes(attributes, count);
-
-    return 1;
-}
-
-//
-// Return the index for OpenGL to use for knowing where a uniform lives.
-//
-// Return:  The return value of is really boolean, indicating
-// success or failure.
-//
-int ShGetUniformLocation(const ShHandle handle, const char* name)
-{
-    if (!InitThread())
-        return 0;
-
-    if (handle == 0)
-        return -1;
-
-    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
-    TUniformMap* uniformMap= base->getAsUniformMap();
-    if (uniformMap == 0)
-        return -1;
-
-    return uniformMap->getLocation(name);
-}
-
--- a/gfx/angle/src/compiler/SymbolTable.h
+++ b/gfx/angle/src/compiler/SymbolTable.h
@@ -26,19 +26,19 @@
 //   in the symbol table.  The parser can substitute constants at parse
 //   time, including doing constant folding and constant propagation.
 //
 // * No temporaries:  Temporaries made from operations (+, --, .xy, etc.)
 //   are tracked in the intermediate representation, not the symbol table.
 //
 
 #include <assert.h>
-#include "compiler/Common.h"
+
+#include "compiler/InfoSink.h"
 #include "compiler/intermediate.h"
-#include "compiler/InfoSink.h"
 
 //
 // Symbol base class.  (Can build functions or variables out of these...)
 //
 class TSymbol {    
 public:
     POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
     TSymbol(const TString *n) :  name(n) { }
@@ -234,41 +234,33 @@ public:
     {
         //
         // The symbol table cannot be used until push() is called, but
         // the lack of an initial call to push() can be used to detect
         // that the symbol table has not been preloaded with built-ins.
         //
     }
 
-    TSymbolTable(TSymbolTable& symTable)
-    {
-        table.push_back(symTable.table[0]);
-        precisionStack.push_back( symTable.precisionStack[0] );
-        uniqueId = symTable.uniqueId;
-    }
-
     ~TSymbolTable()
     {
         // level 0 is always built In symbols, so we never pop that out
         while (table.size() > 1)
             pop();
     }
 
     //
     // When the symbol table is initialized with the built-ins, there should
     // 'push' calls, so that built-ins are at level 0 and the shader
     // globals are at level 1.
     //
     bool isEmpty() { return table.size() == 0; }
-    bool atBuiltInLevel() { return atSharedBuiltInLevel() || atDynamicBuiltInLevel(); }
-    bool atSharedBuiltInLevel() { return table.size() == 1; }	
-    bool atGlobalLevel() { return table.size() <= 3; }
+    bool atBuiltInLevel() { return table.size() == 1; }
+    bool atGlobalLevel() { return table.size() <= 2; }
     void push()
-    { 
+    {
         table.push_back(new TSymbolTableLevel);
         precisionStack.push_back( PrecisionStackLevel() );
     }
 
     void pop()
     { 
         delete table[currentLevel()]; 
         table.pop_back(); 
@@ -292,17 +284,17 @@ public:
         level++;
         if (builtIn)
             *builtIn = level == 0;
         if (sameScope)
             *sameScope = level == currentLevel();
         return symbol;
     }
 
-    TSymbolTableLevel* getGlobalLevel() { assert(table.size() >= 3); return table[2]; }
+    TSymbolTableLevel* getGlobalLevel() { assert(table.size() >= 2); return table[1]; }
     void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); }
     int getMaxSymbolId() { return uniqueId; }
     void dump(TInfoSink &infoSink) const;
     void copyTable(const TSymbolTable& copyOf);
 
     void setDefaultPrecision( TBasicType type, TPrecision prec ){
         if( type != EbtFloat && type != EbtInt ) return; // Only set default precision for int/float
         int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
@@ -324,17 +316,16 @@ public:
             }
             level--;
         }
         return prec;
     }
 
 protected:    
     int currentLevel() const { return static_cast<int>(table.size()) - 1; }
-    bool atDynamicBuiltInLevel() { return table.size() == 2; }
 
     std::vector<TSymbolTableLevel*> table;
     typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
     std::vector< PrecisionStackLevel > precisionStack;
     int uniqueId;     // for unique identification in code generation
 };
 
 #endif // _SYMBOL_TABLE_INCLUDED_
--- a/gfx/angle/src/compiler/TranslatorGLSL.cpp
+++ b/gfx/angle/src/compiler/TranslatorGLSL.cpp
@@ -3,19 +3,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #include "compiler/TranslatorGLSL.h"
 
 #include "compiler/OutputGLSL.h"
 
-TranslatorGLSL::TranslatorGLSL(EShLanguage l, int dOptions)
-        : TCompiler(l),
-          debugOptions(dOptions) {
+TranslatorGLSL::TranslatorGLSL(EShLanguage lang, EShSpec spec)
+    : TCompiler(lang, spec) {
 }
 
 bool TranslatorGLSL::compile(TIntermNode* root) {
     TOutputGLSL outputGLSL(infoSink.obj);
     root->traverse(&outputGLSL);
 
     return true;
 }
--- a/gfx/angle/src/compiler/TranslatorGLSL.h
+++ b/gfx/angle/src/compiler/TranslatorGLSL.h
@@ -6,14 +6,13 @@
 
 #ifndef COMPILER_TRANSLATORGLSL_H_
 #define COMPILER_TRANSLATORGLSL_H_
 
 #include "compiler/ShHandle.h"
 
 class TranslatorGLSL : public TCompiler {
 public:
-    TranslatorGLSL(EShLanguage l, int dOptions);
+    TranslatorGLSL(EShLanguage lang, EShSpec spec);
     virtual bool compile(TIntermNode* root);
-    int debugOptions;
 };
 
 #endif  // COMPILER_TRANSLATORGLSL_H_
--- a/gfx/angle/src/compiler/TranslatorHLSL.cpp
+++ b/gfx/angle/src/compiler/TranslatorHLSL.cpp
@@ -3,18 +3,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #include "compiler/TranslatorHLSL.h"
 
 #include "compiler/OutputHLSL.h"
 
-TranslatorHLSL::TranslatorHLSL(EShLanguage language, int debugOptions)
-    : TCompiler(language), debugOptions(debugOptions)
+TranslatorHLSL::TranslatorHLSL(EShLanguage lang, EShSpec spec)
+    : TCompiler(lang, spec)
 {
 }
 
 bool TranslatorHLSL::compile(TIntermNode *root)
 {
     TParseContext& parseContext = *GetGlobalParseContext();
     sh::OutputHLSL outputHLSL(parseContext);
 
--- a/gfx/angle/src/compiler/TranslatorHLSL.h
+++ b/gfx/angle/src/compiler/TranslatorHLSL.h
@@ -6,14 +6,13 @@
 
 #ifndef COMPILER_TRANSLATORHLSL_H_
 #define COMPILER_TRANSLATORHLSL_H_
 
 #include "compiler/ShHandle.h"
 
 class TranslatorHLSL : public TCompiler {
 public:
-    TranslatorHLSL(EShLanguage l, int dOptions);
+    TranslatorHLSL(EShLanguage lang, EShSpec spec);
     virtual bool compile(TIntermNode* root);
-    int debugOptions;
 };
 
 #endif  // COMPILER_TRANSLATORHLSL_H_
--- a/gfx/angle/src/compiler/glslang.y
+++ b/gfx/angle/src/compiler/glslang.y
@@ -1744,16 +1744,19 @@ type_specifier_nonarray
         TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtStruct, qual, $1.line);
         $$.userDef = &structure;
     }
     ;
 
 struct_specifier
     : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
+        if (parseContext->reservedErrorCheck($2.line, *$2.string))
+            parseContext->recover();
+
         TType* structure = new TType($4, *$2.string);
         TVariable* userTypeDef = new TVariable($2.string, *structure, true);
         if (! parseContext->symbolTable.insert(*userTypeDef)) {
             parseContext->error($2.line, "redefinition", $2.string->c_str(), "struct");
             parseContext->recover();
         }
         $$.setBasic(EbtStruct, EvqTemporary, $1.line);
         $$.userDef = structure;
@@ -1816,21 +1819,27 @@ struct_declarator_list
     }
     | struct_declarator_list COMMA struct_declarator {
         $$->push_back($3);
     }
     ;
 
 struct_declarator
     : IDENTIFIER {
+        if (parseContext->reservedErrorCheck($1.line, *$1.string))
+            parseContext->recover();
+
         $$.type = new TType(EbtVoid, EbpUndefined);
         $$.line = $1.line;
         $$.type->setFieldName(*$1.string);
     }
     | IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        if (parseContext->reservedErrorCheck($1.line, *$1.string))
+            parseContext->recover();
+
         $$.type = new TType(EbtVoid, EbpUndefined);
         $$.line = $1.line;
         $$.type->setFieldName(*$1.string);
 
         int size;
         if (parseContext->arraySizeErrorCheck($2.line, $3, size))
             parseContext->recover();
         $$.type->setArraySize(size);
--- a/gfx/angle/src/compiler/translator_common.vcproj
+++ b/gfx/angle/src/compiler/translator_common.vcproj
@@ -159,53 +159,53 @@
 				RelativePath=".\glslang.l"
 				>
 				<FileConfiguration
 					Name="Debug|Win32"
 					>
 					<Tool
 						Name="VCCustomBuildTool"
 						Description="Executing flex on $(InputPath)"
-						CommandLine="@echo on&#x0D;&#x0A;if EXIST &quot;$(InputDir)Gen_glslang.cpp&quot; del &quot;$(InputDir)Gen_glslang.cpp&quot;&#x0D;&#x0A;&quot;$(InputDir)tools\flex.exe&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;rename &quot;$(InputDir)lex.yy.c&quot; Gen_$(InputName).cpp&#x0D;&#x0A;@echo off"
+						CommandLine="@echo on&#x0D;&#x0A;if EXIST &quot;$(InputDir)Gen_glslang.cpp&quot; del &quot;$(InputDir)Gen_glslang.cpp&quot;&#x0D;&#x0A;&quot;$(InputDir)tools\flex.exe&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;rename &quot;$(InputDir)lex.yy.c&quot; Gen_$(InputName).cpp&#x0D;&#x0A;@echo off&#x0D;&#x0A;"
 						AdditionalDependencies="glslang_tab.h"
 						Outputs="$(InputDir)Gen_glslang.cpp"
 					/>
 				</FileConfiguration>
 				<FileConfiguration
 					Name="Release|Win32"
 					>
 					<Tool
 						Name="VCCustomBuildTool"
 						Description="Executing flex on $(InputPath)"
-						CommandLine="@echo on&#x0D;&#x0A;if EXIST &quot;$(InputDir)Gen_glslang.cpp&quot; del &quot;$(InputDir)Gen_glslang.cpp&quot;&#x0D;&#x0A;&quot;$(InputDir)tools\flex.exe&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;rename &quot;$(InputDir)lex.yy.c&quot; Gen_$(InputName).cpp&#x0D;&#x0A;@echo off"
+						CommandLine="@echo on&#x0D;&#x0A;if EXIST &quot;$(InputDir)Gen_glslang.cpp&quot; del &quot;$(InputDir)Gen_glslang.cpp&quot;&#x0D;&#x0A;&quot;$(InputDir)tools\flex.exe&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;rename &quot;$(InputDir)lex.yy.c&quot; Gen_$(InputName).cpp&#x0D;&#x0A;@echo off&#x0D;&#x0A;"
 						AdditionalDependencies="glslang_tab.h"
 						Outputs="$(InputDir)Gen_glslang.cpp"
 					/>
 				</FileConfiguration>
 			</File>
 			<File
 				RelativePath=".\glslang.y"
 				>
 				<FileConfiguration
 					Name="Debug|Win32"
 					>
 					<Tool
 						Name="VCCustomBuildTool"
 						Description="Executing Bison on $(InputPath)"
-						CommandLine="@echo on&#x0D;&#x0A;SET BISON_SIMPLE=tools\bison.simple&#x0D;&#x0A;SET BISON_HAIRY=tools\bison.simple&#x0D;&#x0A;if EXIST &quot;$(InputDir)Gen_$(InputName)_tab.cpp&quot; del &quot;$(InputDir)Gen_$(InputName)_tab.cpp&quot;&#x0D;&#x0A;tools\bison.exe -d -t -v $(InputName).y&#x0D;&#x0A;rename &quot;$(InputDir)$(InputName)_tab.c&quot; Gen_$(InputName)_tab.cpp&#x0D;&#x0A;@echo off"
+						CommandLine="@echo on&#x0D;&#x0A;SET BISON_SIMPLE=tools\bison.simple&#x0D;&#x0A;SET BISON_HAIRY=tools\bison.simple&#x0D;&#x0A;if EXIST &quot;$(InputDir)Gen_$(InputName)_tab.cpp&quot; del &quot;$(InputDir)Gen_$(InputName)_tab.cpp&quot;&#x0D;&#x0A;tools\bison.exe -d -t -v $(InputName).y&#x0D;&#x0A;rename &quot;$(InputDir)$(InputName)_tab.c&quot; Gen_$(InputName)_tab.cpp&#x0D;&#x0A;@echo off&#x0D;&#x0A;"
 						Outputs="$(InputDir)Gen_$(InputName)_tab.cpp"
 					/>
 				</FileConfiguration>
 				<FileConfiguration
 					Name="Release|Win32"
 					>
 					<Tool
 						Name="VCCustomBuildTool"
 						Description="Executing Bison on $(InputPath)"
-						CommandLine="@echo on&#x0D;&#x0A;SET BISON_SIMPLE=tools\bison.simple&#x0D;&#x0A;SET BISON_HAIRY=tools\bison.simple&#x0D;&#x0A;if EXIST &quot;$(InputDir)Gen_$(InputName)_tab.cpp&quot; del &quot;$(InputDir)Gen_$(InputName)_tab.cpp&quot;&#x0D;&#x0A;tools\bison.exe -d -t -v $(InputName).y&#x0D;&#x0A;rename &quot;$(InputDir)$(InputName)_tab.c&quot; Gen_$(InputName)_tab.cpp&#x0D;&#x0A;@echo off"
+						CommandLine="@echo on&#x0D;&#x0A;SET BISON_SIMPLE=tools\bison.simple&#x0D;&#x0A;SET BISON_HAIRY=tools\bison.simple&#x0D;&#x0A;if EXIST &quot;$(InputDir)Gen_$(InputName)_tab.cpp&quot; del &quot;$(InputDir)Gen_$(InputName)_tab.cpp&quot;&#x0D;&#x0A;tools\bison.exe -d -t -v $(InputName).y&#x0D;&#x0A;rename &quot;$(InputDir)$(InputName)_tab.c&quot; Gen_$(InputName)_tab.cpp&#x0D;&#x0A;@echo off&#x0D;&#x0A;"
 						Outputs="$(InputDir)Gen_$(InputName)_tab.cpp"
 					/>
 				</FileConfiguration>
 			</File>
 			<File
 				RelativePath=".\InfoSink.cpp"
 				>
 			</File>
@@ -225,20 +225,16 @@
 				RelativePath=".\intermOut.cpp"
 				>
 			</File>
 			<File
 				RelativePath=".\IntermTraverse.cpp"
 				>
 			</File>
 			<File
-				RelativePath=".\Link.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\ossource_win.cpp"
 				>
 			</File>
 			<File
 				RelativePath=".\parseConst.cpp"
 				>
 			</File>
 			<File
--- a/gfx/angle/src/libEGL/Display.cpp
+++ b/gfx/angle/src/libEGL/Display.cpp
@@ -20,16 +20,17 @@
 #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)
 {
     mD3d9 = NULL;
     mDevice = NULL;
+    mDeviceWindow = NULL;
 
     mAdapter = D3DADAPTER_DEFAULT;
 
     #if REF_RAST == 1 || defined(FORCE_REF_RAST)
         mDeviceType = D3DDEVTYPE_REF;
     #else
         mDeviceType = D3DDEVTYPE_HAL;
     #endif
@@ -145,16 +146,23 @@ bool Display::initialize()
             {
                 Config configuration = *config;
                 configuration.mConfigID = index;
                 index++;
 
                 mConfigSet.mSet.insert(configuration);
             }
         }
+
+        if (!createDevice())
+        {
+            terminate();
+
+            return false;
+        }
     }
 
     if (!isInitialized())
     {
         terminate();
 
         return false;
     }
@@ -180,16 +188,22 @@ void Display::terminate()
         mDevice = NULL;
     }
 
     if (mD3d9)
     {
         mD3d9->Release();
         mD3d9 = NULL;
     }
+
+    if (mDeviceWindow)
+    {
+        DestroyWindow(mDeviceWindow);
+        mDeviceWindow = NULL;
+    }
 }
 
 void Display::startScene()
 {
     if (!mSceneStarted)
     {
         long result = mDevice->BeginScene();
         ASSERT(SUCCEEDED(result));
@@ -249,142 +263,84 @@ bool Display::getConfigAttrib(EGLConfig 
       case EGL_CONFORMANT:                *value = configuration->mConformant;             break;
       default:
         return false;
     }
 
     return true;
 }
 
+bool Display::createDevice()
+{
+    static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
+    static const TCHAR className[] = TEXT("STATIC");
+
+    mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
+
+    D3DPRESENT_PARAMETERS presentParameters = {0};
+
+    // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
+    presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
+    presentParameters.BackBufferCount = 1;
+    presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
+    presentParameters.BackBufferWidth = 1;
+    presentParameters.BackBufferHeight = 1;
+    presentParameters.EnableAutoDepthStencil = FALSE;
+    presentParameters.Flags = 0;
+    presentParameters.hDeviceWindow = mDeviceWindow;
+    presentParameters.MultiSampleQuality = 0;
+    presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
+    presentParameters.PresentationInterval = convertInterval(mMinSwapInterval);
+    presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+    presentParameters.Windowed = TRUE;
+
+    DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
+
+    HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
+
+    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+    {
+        return error(EGL_BAD_ALLOC, false);
+    }
+
+    if (FAILED(result))
+    {
+        result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
+
+        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+        {
+            return error(EGL_BAD_ALLOC, false);
+        }
+    }
+
+    ASSERT(SUCCEEDED(result));
+
+    // Permanent non-default states
+    mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
+
+    mSceneStarted = false;
+
+    return true;
+}
+
 Surface *Display::createWindowSurface(HWND window, EGLConfig config)
 {
     const Config *configuration = mConfigSet.get(config);
 
-    D3DPRESENT_PARAMETERS presentParameters = {0};
-
-    presentParameters.AutoDepthStencilFormat = configuration->mDepthStencilFormat;
-    presentParameters.BackBufferCount = 1;
-    presentParameters.BackBufferFormat = configuration->mRenderTargetFormat;
-    presentParameters.BackBufferWidth = 0;
-    presentParameters.BackBufferHeight = 0;
-    presentParameters.EnableAutoDepthStencil = configuration->mDepthSize ? TRUE : FALSE;
-    presentParameters.Flags = 0;
-    presentParameters.hDeviceWindow = window;
-    presentParameters.MultiSampleQuality = 0;                  // FIXME: Unimplemented
-    presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;   // FIXME: Unimplemented
-    presentParameters.PresentationInterval = convertInterval(mMinSwapInterval);
-    presentParameters.SwapEffect = D3DSWAPEFFECT_COPY;
-    presentParameters.Windowed = TRUE;   // FIXME
-
-    IDirect3DSwapChain9 *swapChain = NULL;
-    IDirect3DSurface9 *depthStencilSurface = NULL;
-
-    if (!mDevice)
-    {
-        DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
-
-        HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, window, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
-
-        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
-        {
-            return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
-        }
-
-        if (FAILED(result))
-        {
-            result = mD3d9->CreateDevice(mAdapter, mDeviceType, window, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
-
-            if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
-            {
-                return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
-            }
-        }
-
-        ASSERT(SUCCEEDED(result));
-
-        if (mDevice)
-        {
-            mSceneStarted = false;
-            mDevice->GetSwapChain(0, &swapChain);
-            mDevice->GetDepthStencilSurface(&depthStencilSurface);
-        }
-    }
-    else
-    {
-        if (!mSurfaceSet.empty())
-        {
-            // if the device already exists, and there are other surfaces/windows currently in use, we need to create
-            // a separate swap chain for the new draw surface.
-            HRESULT result = mDevice->CreateAdditionalSwapChain(&presentParameters, &swapChain);
-
-            if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
-            {
-                ERR("Could not create additional swap chains. Out of memory.");
-                return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
-            }
-
-            ASSERT(SUCCEEDED(result));
-
-            // CreateAdditionalSwapChain does not automatically generate a depthstencil surface, unlike 
-            // CreateDevice, so we must do so explicitly.
-            result = mDevice->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
-                                                        presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
-                                                        presentParameters.MultiSampleQuality, FALSE, &depthStencilSurface, NULL);
-
-            if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
-            {
-                swapChain->Release();
-                ERR("Could not create depthstencil surface for new swap chain. Out of memory.");
-                return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
-            }
-
-            ASSERT(SUCCEEDED(result));
-        }
-        else
-        {
-            // if the device already exists, but there are no surfaces in use, then all the surfaces/windows
-            // have been destroyed, and we should repurpose the originally created depthstencil surface for
-            // use with the new surface we are creating.
-            HRESULT result = mDevice->Reset(&presentParameters);
-
-            if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
-            {
-                ERR("Could not reset presentation parameters for device. Out of memory.");
-                return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
-            }
-
-            ASSERT(SUCCEEDED(result));
-
-            if (mDevice)
-            {
-                mSceneStarted = false;
-                mDevice->GetSwapChain(0, &swapChain);
-                mDevice->GetDepthStencilSurface(&depthStencilSurface);
-            }
-        }
-    }
-
-    Surface *surface = NULL;
-
-    if (swapChain)
-    {
-        surface = new Surface(this, swapChain, depthStencilSurface, configuration);
-        mSurfaceSet.insert(surface);
-
-        swapChain->Release();
-    }
+    Surface *surface = new Surface(this, configuration, window);
+    mSurfaceSet.insert(surface);
 
     return surface;
 }
 
-EGLContext Display::createContext(EGLConfig configHandle)
+EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
 {
     const egl::Config *config = mConfigSet.get(configHandle);
 
-    gl::Context *context = glCreateContext(config);
+    gl::Context *context = glCreateContext(config, shareContext);
     mContextSet.insert(context);
 
     return context;
 }
 
 void Display::destroySurface(egl::Surface *surface)
 {
     delete surface;
--- a/gfx/angle/src/libEGL/Display.h
+++ b/gfx/angle/src/libEGL/Display.h
@@ -38,17 +38,17 @@ class Display
 
     virtual void startScene();
     virtual void endScene();
 
     bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
     bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
 
     egl::Surface *createWindowSurface(HWND window, EGLConfig config);
-    EGLContext createContext(EGLConfig configHandle);
+    EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext);
 
     void destroySurface(egl::Surface *surface);
     void destroyContext(gl::Context *context);
 
     bool isInitialized();
     bool isValidConfig(EGLConfig config);
     bool isValidContext(gl::Context *context);
     bool isValidSurface(egl::Surface *surface);
@@ -65,26 +65,29 @@ class Display
     DISALLOW_COPY_AND_ASSIGN(Display);
     const HDC mDc;
 
     UINT mAdapter;
     D3DDEVTYPE mDeviceType;
     IDirect3D9 *mD3d9;
     IDirect3DDevice9 *mDevice;
     D3DCAPS9 mDeviceCaps;
+    HWND mDeviceWindow;
 
     bool mSceneStarted;
     GLint mSwapInterval;
     EGLint mMaxSwapInterval;
     EGLint mMinSwapInterval;
     DWORD mPresentInterval;
 
     typedef std::set<Surface*> SurfaceSet;
     SurfaceSet mSurfaceSet;
 
     ConfigSet mConfigSet;
 
     typedef std::set<gl::Context*> ContextSet;
     ContextSet mContextSet;
+
+    bool createDevice();
 };
 }
 
 #endif   // INCLUDE_DISPLAY_H_
--- a/gfx/angle/src/libEGL/Surface.cpp
+++ b/gfx/angle/src/libEGL/Surface.cpp
@@ -12,65 +12,32 @@
 
 #include "common/debug.h"
 
 #include "libEGL/main.h"
 #include "libEGL/Display.h"
 
 namespace egl
 {
-Surface::Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9 *depthStencil, const Config *config) 
-    : mDisplay(display), mSwapChain(swapChain), mDepthStencil(depthStencil), mConfig(config)
+Surface::Surface(Display *display, const Config *config, HWND window) 
+    : mDisplay(display), mConfig(config), mWindow(window)
 {
+    mSwapChain = NULL;
+    mDepthStencil = NULL;
     mBackBuffer = NULL;
     mRenderTarget = NULL;
     mFlipTexture = NULL;
     mFlipState = NULL;
     mPreFlipState = NULL;
 
     mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
     mRenderBuffer = EGL_BACK_BUFFER;
     mSwapBehavior = EGL_BUFFER_PRESERVED;
 
-    if (mSwapChain)
-    {
-        mSwapChain->AddRef();
-        mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
-
-        D3DSURFACE_DESC description;
-        mBackBuffer->GetDesc(&description);
-
-        mWidth = description.Width;
-        mHeight = description.Height;
-
-        IDirect3DDevice9 *device = display->getDevice();
-        HRESULT result = device->CreateRenderTarget(mWidth, mHeight, description.Format, description.MultiSampleType, description.MultiSampleQuality, FALSE, &mRenderTarget, NULL);
-
-        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
-        {
-            error(EGL_BAD_ALLOC);
-
-            return;
-        }
-
-        ASSERT(SUCCEEDED(result));
-
-        result = device->CreateTexture(mWidth, mHeight, 1, D3DUSAGE_RENDERTARGET, description.Format, D3DPOOL_DEFAULT, &mFlipTexture, NULL);
-
-        if (FAILED(result))
-        {
-            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
-
-            error(EGL_BAD_ALLOC);
-
-            mRenderTarget->Release();
-
-            return;
-        }
-    }
+    resetSwapChain();
 }
 
 Surface::~Surface()
 {
     if (mSwapChain)
     {
         mSwapChain->Release();
     }
@@ -101,30 +68,126 @@ Surface::~Surface()
     }
 
     if (mPreFlipState)
     {
         mPreFlipState->Release();
     }
 }
 
+void Surface::resetSwapChain()
+{
+    IDirect3DDevice9 *device = mDisplay->getDevice();
+
+    D3DPRESENT_PARAMETERS presentParameters = {0};
+
+    presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
+    presentParameters.BackBufferCount = 1;
+    presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat;
+    presentParameters.EnableAutoDepthStencil = FALSE;
+    presentParameters.Flags = 0;
+    presentParameters.hDeviceWindow = getWindowHandle();
+    presentParameters.MultiSampleQuality = 0;                  // FIXME: Unimplemented
+    presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;   // FIXME: Unimplemented
+    presentParameters.PresentationInterval = Display::convertInterval(mConfig->mMinSwapInterval);
+    presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+    presentParameters.Windowed = TRUE;
+
+    RECT windowRect;
+    GetClientRect(getWindowHandle(), &windowRect);
+    presentParameters.BackBufferWidth = windowRect.right - windowRect.left;
+    presentParameters.BackBufferHeight = windowRect.bottom - windowRect.top;
+
+    IDirect3DSwapChain9 *swapChain = NULL;
+    HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &swapChain);
+
+    if (FAILED(result))
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+        ERR("Could not create additional swap chains: %08lX", result);
+        return error(EGL_BAD_ALLOC);
+    }
+
+    IDirect3DSurface9 *depthStencilSurface = NULL;
+    result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
+                                               presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
+                                               presentParameters.MultiSampleQuality, FALSE, &depthStencilSurface, NULL);
+
+    if (FAILED(result))
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+        swapChain->Release();
+
+        ERR("Could not create depthstencil surface for new swap chain: %08lX", result);
+        return error(EGL_BAD_ALLOC);
+    }
+
+    IDirect3DSurface9 *renderTarget = NULL;
+    result = device->CreateRenderTarget(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, presentParameters.BackBufferFormat,
+                                        presentParameters.MultiSampleType, presentParameters.MultiSampleQuality, FALSE, &renderTarget, NULL);
+
+    if (FAILED(result))
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+        swapChain->Release();
+        depthStencilSurface->Release();
+
+        ERR("Could not create render target surface for new swap chain: %08lX", result);
+        return error(EGL_BAD_ALLOC);
+    }
+
+    ASSERT(SUCCEEDED(result));
+
+    IDirect3DTexture9 *flipTexture = NULL;
+    result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
+                                   presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &flipTexture, NULL);
+
+    if (FAILED(result))
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+        swapChain->Release();
+        depthStencilSurface->Release();
+        renderTarget->Release();
+
+        ERR("Could not create flip texture for new swap chain: %08lX", result);
+        return error(EGL_BAD_ALLOC);
+    }
+
+    IDirect3DSurface9 *backBuffer = NULL;
+    swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
+
+    if (mSwapChain) mSwapChain->Release();
+    if (mDepthStencil) mDepthStencil->Release();
+    if (mBackBuffer) mBackBuffer->Release();
+    if (mRenderTarget) mRenderTarget->Release();
+    if (mFlipTexture) mFlipTexture->Release();
+
+    mWidth = presentParameters.BackBufferWidth;
+    mHeight = presentParameters.BackBufferHeight;
+
+    mSwapChain = swapChain;
+    mDepthStencil = depthStencilSurface;
+    mBackBuffer = backBuffer;
+    mRenderTarget = renderTarget;
+    mFlipTexture = flipTexture;
+
+    // The flip state block recorded mFlipTexture so it is now invalid.
+    releaseRecordedState(device);
+}
+
 HWND Surface::getWindowHandle()
 {
-    if (mSwapChain)
-    {
-        D3DPRESENT_PARAMETERS presentParameters;
-        mSwapChain->GetPresentParameters(&presentParameters);
-
-        return presentParameters.hDeviceWindow;
-    }
-
-    return NULL;
+    return mWindow;
 }
 
-void Surface::writeRecordableFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source)
+void Surface::writeRecordableFlipState(IDirect3DDevice9 *device)
 {
     // Disable all pipeline operations
     device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
     device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
     device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
     device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
     device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
     device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
@@ -133,50 +196,52 @@ void Surface::writeRecordableFlipState(I
     device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
     device->SetPixelShader(NULL);
     device->SetVertexShader(NULL);
 
     // Just sample the texture
     device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
     device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
     device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
-    device->SetTexture(0, source);
+    device->SetTexture(0, NULL); // The actual texture will change after resizing. But the pre-flip state block must save/restore the texture.
     device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
     device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
     device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
+    device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+    device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
     device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
 
     device->SetStreamSourceFreq(0, 1); // DrawPrimitiveUP only cares about stream 0, not the rest.
 }
 
-void Surface::applyFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source)
+void Surface::applyFlipState(IDirect3DDevice9 *device)
 {
     HRESULT hr;
 
     if (mFlipState == NULL)
     {
         // Create two state blocks both recording the states that are changed when swapping.
 
         // mPreFlipState will record the original state each entry.
         hr = device->BeginStateBlock();
         ASSERT(SUCCEEDED(hr));
-        writeRecordableFlipState(device, source);
+        writeRecordableFlipState(device);
         hr = device->EndStateBlock(&mPreFlipState);
         ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
 
         if (SUCCEEDED(hr))
         {
             mPreFlipState->Capture();
         }
 
         // mFlipState will record the state for the swap operation.
         hr = device->BeginStateBlock();
         ASSERT(SUCCEEDED(hr));
 
-        writeRecordableFlipState(device, source);
+        writeRecordableFlipState(device);
 
         hr = device->EndStateBlock(&mFlipState);
         ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
 
         if (FAILED(hr))
         {
             mFlipState = NULL;
             mPreFlipState->Release();
@@ -218,39 +283,93 @@ void Surface::restoreState(IDirect3DDevi
 
     if (mPreFlipDepthStencil)
     {
         mPreFlipDepthStencil->Release();
         mPreFlipDepthStencil = NULL;
     }
 }
 
+// On the next flip, this will cause the state to be recorded from scratch.
+// In particular we need to do this if the flip texture changes.
+void Surface::releaseRecordedState(IDirect3DDevice9 *device)
+{
+    if (mFlipState)
+    {
+        mFlipState->Release();
+        mFlipState = NULL;
+    }
+
+    if (mPreFlipState)
+    {
+        mPreFlipState->Release();
+        mPreFlipState = NULL;
+    }
+}
+
+bool Surface::checkForWindowResize()
+{
+    RECT client;
+    GetClientRect(getWindowHandle(), &client);
+    if (getWidth() != client.right - client.left || getHeight() != client.bottom - client.top)
+    {
+        resetSwapChain();
+
+        if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
+        {
+            glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
 bool Surface::swap()
 {
     if (mSwapChain)
     {
+        IDirect3DTexture9 *flipTexture = mFlipTexture;
+        flipTexture->AddRef();
+
+        IDirect3DSurface9 *renderTarget = mRenderTarget;
+        renderTarget->AddRef();
+
+        EGLint oldWidth = mWidth;
+        EGLint oldHeight = mHeight;
+
+        checkForWindowResize();
+
         IDirect3DDevice9 *device = mDisplay->getDevice();
 
         IDirect3DSurface9 *textureSurface;
-        mFlipTexture->GetSurfaceLevel(0, &textureSurface);
+        flipTexture->GetSurfaceLevel(0, &textureSurface);
 
         mDisplay->endScene();
-        device->StretchRect(mRenderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE);
+        device->StretchRect(renderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE);
+        renderTarget->Release();
 
-        applyFlipState(device, mFlipTexture);
+        applyFlipState(device);
+        device->SetTexture(0, flipTexture);
+
+        float xscale = (float)mWidth / oldWidth;
+        float yscale = (float)mHeight / oldHeight;
 
         // Render the texture upside down into the back buffer
-        float quad[4][6] = {{     0 - 0.5f,       0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f},
-                            {mWidth - 0.5f,       0 - 0.5f, 0.0f, 1.0f, 1.0f, 1.0f},
-                            {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 1.0f, 0.0f},
-                            {     0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f}};   // x, y, z, rhw, u, v
+        // Texcoords are chosen to pin a potentially resized image into the upper-left corner without scaling.
+        float quad[4][6] = {{     0 - 0.5f,       0 - 0.5f, 0.0f, 1.0f, 0.0f,   1.0f       },
+                            {mWidth - 0.5f,       0 - 0.5f, 0.0f, 1.0f, xscale, 1.0f       },
+                            {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, xscale, 1.0f-yscale},
+                            {     0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f,   1.0f-yscale}};   // x, y, z, rhw, u, v
 
         mDisplay->startScene();
         device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
 
+        flipTexture->Release();
         textureSurface->Release();
 
         restoreState(device);
 
         mDisplay->endScene();
         HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, mDisplay->getPresentInterval());
 
         if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
@@ -259,16 +378,17 @@ bool Surface::swap()
         }
 
         if (result == D3DERR_DEVICELOST)
         {
             return error(EGL_CONTEXT_LOST, false);
         }
 
         ASSERT(SUCCEEDED(result));
+
     }
 
     return true;
 }
 
 EGLint Surface::getWidth() const
 {
     return mWidth;
--- a/gfx/angle/src/libEGL/Surface.h
+++ b/gfx/angle/src/libEGL/Surface.h
@@ -20,47 +20,52 @@
 namespace egl
 {
 class Display;
 class Config;
 
 class Surface
 {
   public:
-    Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9* depthStencil, const egl::Config *config);
+    Surface(Display *display, const egl::Config *config, HWND window);
 
     ~Surface();
 
     HWND getWindowHandle();
     bool swap();
 
     virtual EGLint getWidth() const;
     virtual EGLint getHeight() const;
 
     virtual IDirect3DSurface9 *getRenderTarget();
     virtual IDirect3DSurface9 *getDepthStencil();
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Surface);
 
     Display *const mDisplay;
-    IDirect3DSwapChain9 *const mSwapChain;
+    IDirect3DSwapChain9 *mSwapChain;
     IDirect3DSurface9 *mBackBuffer;
     IDirect3DSurface9 *mRenderTarget;
     IDirect3DSurface9 *mDepthStencil;
     IDirect3DTexture9 *mFlipTexture;
 
-    void applyFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source);
+    void resetSwapChain();
+    bool checkForWindowResize();
+
+    void applyFlipState(IDirect3DDevice9 *device);
     void restoreState(IDirect3DDevice9 *device);
-    void writeRecordableFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source);
+    void writeRecordableFlipState(IDirect3DDevice9 *device);
+    void releaseRecordedState(IDirect3DDevice9 *device);
     IDirect3DStateBlock9 *mFlipState;
     IDirect3DStateBlock9 *mPreFlipState;
     IDirect3DSurface9 *mPreFlipBackBuffer;
     IDirect3DSurface9 *mPreFlipDepthStencil;
 
+    const HWND mWindow;            // Window that the surface is created for.
     const egl::Config *mConfig;    // EGL config surface was created with
     EGLint mHeight;                // Height of surface
     EGLint mWidth;                 // Width of surface
 //  EGLint horizontalResolution;   // Horizontal dot pitch
 //  EGLint verticalResolution;     // Vertical dot pitch
 //  EGLBoolean largestPBuffer;     // If true, create largest pbuffer possible
 //  EGLBoolean mipmapTexture;      // True if texture has mipmaps
 //  EGLint mipmapLevel;            // Mipmap level to render to
--- a/gfx/angle/src/libEGL/libEGL.cpp
+++ b/gfx/angle/src/libEGL/libEGL.cpp
@@ -767,17 +767,17 @@ EGLContext __stdcall eglCreateContext(EG
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
         if (!validate(display, config))
         {
             return EGL_NO_CONTEXT;
         }
 
-        EGLContext context = display->createContext(config);
+        EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context));
 
         return success(context);
     }
     catch(std::bad_alloc&)
     {
         return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
     }
 
@@ -819,19 +819,18 @@ EGLBoolean __stdcall eglMakeCurrent(EGLD
     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
           dpy, draw, read, ctx);
 
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
         gl::Context *context = static_cast<gl::Context*>(ctx);
         IDirect3DDevice9 *device = display->getDevice();
-        DWORD passes;
 
-        if (!device || device->ValidateDevice(&passes) == D3DERR_DEVICELOST)
+        if (!device || device->TestCooperativeLevel() != D3D_OK)
         {
             return error(EGL_CONTEXT_LOST, EGL_FALSE);
         }
 
         if (ctx != EGL_NO_CONTEXT && !validate(display, context))
         {
             return EGL_FALSE;
         }
--- a/gfx/angle/src/libGLESv2/Blit.cpp
+++ b/gfx/angle/src/libGLESv2/Blit.cpp
@@ -227,22 +227,22 @@ bool Blit::setShader(ShaderId source, co
         return false;
     }
 
     return true;
 }
 
 bool Blit::setVertexShader(ShaderId shader)
 {
-    return setShader<IDirect3DVertexShader9>(shader, mContext->getVertexShaderProfile(), &IDirect3DDevice9::CreateVertexShader, &IDirect3DDevice9::SetVertexShader);
+    return setShader<IDirect3DVertexShader9>(shader, mContext->supportsShaderModel3() ? "vs_3_0" : "vs_2_0", &IDirect3DDevice9::CreateVertexShader, &IDirect3DDevice9::SetVertexShader);
 }
 
 bool Blit::setPixelShader(ShaderId shader)
 {
-    return setShader<IDirect3DPixelShader9>(shader, mContext->getPixelShaderProfile(), &IDirect3DDevice9::CreatePixelShader, &IDirect3DDevice9::SetPixelShader);
+    return setShader<IDirect3DPixelShader9>(shader, mContext->supportsShaderModel3() ? "ps_3_0" : "ps_2_0", &IDirect3DDevice9::CreatePixelShader, &IDirect3DDevice9::SetPixelShader);
 }
 
 RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const
 {
     D3DSURFACE_DESC desc;
     surface->GetDesc(&desc);
 
     RECT rect;
--- a/gfx/angle/src/libGLESv2/Buffer.cpp
+++ b/gfx/angle/src/libGLESv2/Buffer.cpp
@@ -8,17 +8,17 @@
 // index data. Implements GL buffer objects and related functionality.
 // [OpenGL ES 2.0.24] section 2.9 page 21.
 
 #include "libGLESv2/Buffer.h"
 
 namespace gl
 {
 
-Buffer::Buffer()
+Buffer::Buffer(GLuint id) : RefCountObject(id)
 {
     mContents = NULL;
     mSize = 0;
     mUsage = GL_DYNAMIC_DRAW;
 }
 
 Buffer::~Buffer()
 {
--- a/gfx/angle/src/libGLESv2/Buffer.h
+++ b/gfx/angle/src/libGLESv2/Buffer.h
@@ -13,24 +13,25 @@
 
 #include <cstddef>
 #include <vector>
 
 #define GL_APICALL
 #include <GLES2/gl2.h>
 
 #include "common/angleutils.h"
+#include "libGLESv2/RefCountObject.h"
 
 namespace gl
 {
 
-class Buffer
+class Buffer : public RefCountObject
 {
   public:
-    Buffer();
+    explicit Buffer(GLuint id);
 
     virtual ~Buffer();
 
     void bufferData(const void *data, GLsizeiptr size, GLenum usage);
     void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
 
     void *data() { return mContents; }
     size_t size() const { return mSize; }
--- a/gfx/angle/src/libGLESv2/Context.cpp
+++ b/gfx/angle/src/libGLESv2/Context.cpp
@@ -12,33 +12,34 @@
 #include <algorithm>
 
 #include "libEGL/Display.h"
 
 #include "libGLESv2/main.h"
 #include "libGLESv2/mathutil.h"
 #include "libGLESv2/utilities.h"
 #include "libGLESv2/Blit.h"
+#include "libGLESv2/ResourceManager.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/FrameBuffer.h"
 #include "libGLESv2/Program.h"
 #include "libGLESv2/RenderBuffer.h"
 #include "libGLESv2/Shader.h"
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/geometry/backend.h"
 #include "libGLESv2/geometry/VertexDataManager.h"
 #include "libGLESv2/geometry/IndexDataManager.h"
 #include "libGLESv2/geometry/dx9.h"
 
 #undef near
 #undef far
 
 namespace gl
 {
-Context::Context(const egl::Config *config)
+Context::Context(const egl::Config *config, const gl::Context *shareContext)
     : mConfig(config)
 {
     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
     mState.depthClearValue = 1.0f;
     mState.stencilClearValue = 0;
 
     mState.cullFace = false;
@@ -98,47 +99,48 @@ Context::Context(const egl::Config *conf
     mState.scissorHeight = config->mDisplayMode.Height;
 
     mState.colorMaskRed = true;
     mState.colorMaskGreen = true;
     mState.colorMaskBlue = true;
     mState.colorMaskAlpha = true;
     mState.depthMask = true;
 
+    if (shareContext != NULL)
+    {
+        mResourceManager = shareContext->mResourceManager;
+        mResourceManager->addRef();
+    }
+    else
+    {
+        mResourceManager = new ResourceManager();
+    }
+
     // [OpenGL ES 2.0.24] section 3.7 page 83:
     // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
     // and cube map texture state vectors respectively associated with them.
     // In order that access to these initial textures not be lost, they are treated as texture
     // objects all of whose names are 0.
 
-    mTexture2DZero = new Texture2D(this);
-    mTextureCubeMapZero = new TextureCubeMap(this);
+    mTexture2DZero = new Texture2D(0);
+    mTextureCubeMapZero = new TextureCubeMap(0);
 
     mColorbufferZero = NULL;
-    mDepthbufferZero = NULL;
-    mStencilbufferZero = NULL;
+    mDepthStencilbufferZero = NULL;
 
     mState.activeSampler = 0;
-    mState.arrayBuffer = 0;
-    mState.elementArrayBuffer = 0;
+    bindArrayBuffer(0);
+    bindElementArrayBuffer(0);
     bindTextureCubeMap(0);
     bindTexture2D(0);
     bindFramebuffer(0);
     bindRenderbuffer(0);
 
     for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
     {
-        for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
-        {
-            mState.samplerTexture[type][sampler] = 0;
-        }
-    }
-
-    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
-    {
         mIncompleteTextures[type] = NULL;
     }
 
     mState.currentProgram = 0;
 
     mState.packAlignment = 4;
     mState.unpackAlignment = 4;
 
@@ -156,69 +158,69 @@ Context::Context(const egl::Config *conf
     mHasBeenCurrent = false;
 
     mMaskedClearSavedState = NULL;
     markAllStateDirty();
 }
 
 Context::~Context()
 {
-    mState.currentProgram = 0;
-
-    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
+    if (mState.currentProgram != 0)
     {
-        delete mIncompleteTextures[type];
-    }
-
-    delete mTexture2DZero;
-    delete mTextureCubeMapZero;
-
-    delete mColorbufferZero;
-    delete mDepthbufferZero;
-    delete mStencilbufferZero;
-
-    delete mBufferBackEnd;
-    delete mVertexDataManager;
-    delete mIndexDataManager;
-    delete mBlit;
-
-    while (!mBufferMap.empty())
-    {
-        deleteBuffer(mBufferMap.begin()->first);
-    }
-
-    while (!mProgramMap.empty())
-    {
-        deleteProgram(mProgramMap.begin()->first);
-    }
-
-    while (!mShaderMap.empty())
-    {
-        deleteShader(mShaderMap.begin()->first);
+        Program *programObject = mResourceManager->getProgram(mState.currentProgram);
+        if (programObject)
+        {
+            programObject->release();
+        }
+        mState.currentProgram = 0;
     }
 
     while (!mFramebufferMap.empty())
     {
         deleteFramebuffer(mFramebufferMap.begin()->first);
     }
 
-    while (!mRenderbufferMap.empty())
+    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
     {
-        deleteRenderbuffer(mRenderbufferMap.begin()->first);
+        for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
+        {
+            mState.samplerTexture[type][sampler].set(NULL);
+        }
+    }
+
+    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
+    {
+        delete mIncompleteTextures[type];
     }
 
-    while (!mTextureMap.empty())
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
     {
-        deleteTexture(mTextureMap.begin()->first);
+        mState.vertexAttribute[i].mBoundBuffer.set(NULL);
     }
 
+    mState.arrayBuffer.set(NULL);
+    mState.elementArrayBuffer.set(NULL);
+    mState.texture2D.set(NULL);
+    mState.textureCubeMap.set(NULL);
+    mState.renderbuffer.set(NULL);
+
+    delete mTexture2DZero;
+    delete mTextureCubeMapZero;
+
+    delete mBufferBackEnd;
+    delete mVertexDataManager;
+    delete mIndexDataManager;
+    delete mBlit;
+
     if (mMaskedClearSavedState)
     {
         mMaskedClearSavedState->Release();
     }
+
+    mResourceManager->release();
 }
 
 void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
 {
     IDirect3DDevice9 *device = display->getDevice();
 
     if (!mHasBeenCurrent)
     {
@@ -243,47 +245,30 @@ void Context::makeCurrent(egl::Display *
 
         mHasBeenCurrent = true;
     }
 
     // Wrap the existing Direct3D 9 resources into GL objects and assign them to the '0' names
     IDirect3DSurface9 *defaultRenderTarget = surface->getRenderTarget();
     IDirect3DSurface9 *depthStencil = surface->getDepthStencil();
 
-    Framebuffer *framebufferZero = new Framebuffer();
     Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
-    Depthbuffer *depthbufferZero = new Depthbuffer(depthStencil);
-    Stencilbuffer *stencilbufferZero = new Stencilbuffer(depthStencil);
+    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
+    Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
 
     setFramebufferZero(framebufferZero);
-    setColorbufferZero(colorbufferZero);
-    setDepthbufferZero(depthbufferZero);
-    setStencilbufferZero(stencilbufferZero);
-
-    framebufferZero->setColorbuffer(GL_RENDERBUFFER, 0);
-    framebufferZero->setDepthbuffer(GL_RENDERBUFFER, 0);
-    framebufferZero->setStencilbuffer(GL_RENDERBUFFER, 0);
 
     defaultRenderTarget->Release();
 
     if (depthStencil)
     {
         depthStencil->Release();
     }
     
-    if (mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0))
-    {
-        mPsProfile = "ps_3_0";
-        mVsProfile = "vs_3_0";
-    }
-    else  // egl::Display guarantees support for at least 2.0
-    {
-        mPsProfile = "ps_2_0";
-        mVsProfile = "vs_2_0";
-    }
+    mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
 
     markAllStateDirty();
 }
 
 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
 void Context::markAllStateDirty()
 {
     mAppliedRenderTargetSerial = 0;
@@ -295,16 +280,22 @@ void Context::markAllStateDirty()
     mDepthStateDirty = true;
     mMaskStateDirty = true;
     mBlendStateDirty = true;
     mStencilStateDirty = true;
     mPolygonOffsetStateDirty = true;
     mScissorStateDirty = true;
     mSampleStateDirty = true;
     mDitherStateDirty = true;
+    mFrontFaceDirty = true;
+
+    if (mBufferBackEnd != NULL)
+    {
+        mBufferBackEnd->invalidate();
+    }
 }
 
 void Context::setClearColor(float red, float green, float blue, float alpha)
 {
     mState.colorClearValue.red = red;
     mState.colorClearValue.green = green;
     mState.colorClearValue.blue = blue;
     mState.colorClearValue.alpha = alpha;
@@ -673,38 +664,38 @@ void Context::setActiveSampler(int activ
 
 GLuint Context::getFramebufferHandle() const
 {
     return mState.framebuffer;
 }
 
 GLuint Context::getRenderbufferHandle() const
 {
-    return mState.renderbuffer;
+    return mState.renderbuffer.id();
 }
 
 GLuint Context::getArrayBufferHandle() const
 {
-    return mState.arrayBuffer;
+    return mState.arrayBuffer.id();
 }
 
 void Context::setVertexAttribEnabled(unsigned int attribNum, bool enabled)
 {
     mState.vertexAttribute[attribNum].mEnabled = enabled;
 }
 
 const AttributeState &Context::getVertexAttribState(unsigned int attribNum)
 {
     return mState.vertexAttribute[attribNum];
 }
 
-void Context::setVertexAttribState(unsigned int attribNum, GLuint boundBuffer, GLint size, GLenum type, bool normalized,
+void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
                                    GLsizei stride, const void *pointer)
 {
-    mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
+    mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer);
     mState.vertexAttribute[attribNum].mSize = size;
     mState.vertexAttribute[attribNum].mType = type;
     mState.vertexAttribute[attribNum].mNormalized = normalized;
     mState.vertexAttribute[attribNum].mStride = stride;
     mState.vertexAttribute[attribNum].mPointer = pointer;
 }
 
 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
@@ -733,82 +724,39 @@ void Context::setUnpackAlignment(GLint a
     mState.unpackAlignment = alignment;
 }
 
 GLint Context::getUnpackAlignment() const
 {
     return mState.unpackAlignment;
 }
 
-// Returns an unused buffer name
 GLuint Context::createBuffer()
 {
-    unsigned int handle = 1;
-
-    while (mBufferMap.find(handle) != mBufferMap.end())
-    {
-        handle++;
-    }
-
-    mBufferMap[handle] = NULL;
-
-    return handle;
+    return mResourceManager->createBuffer();
 }
 
-// Returns an unused shader/program name
+GLuint Context::createProgram()
+{
+    return mResourceManager->createProgram();
+}
+
 GLuint Context::createShader(GLenum type)
 {
-    unsigned int handle = 1;
-
-    while (mShaderMap.find(handle) != mShaderMap.end() || mProgramMap.find(handle) != mProgramMap.end())   // Shared name space
-    {
-        handle++;
-    }
-
-    if (type == GL_VERTEX_SHADER)
-    {
-        mShaderMap[handle] = new VertexShader(this, handle);
-    }
-    else if (type == GL_FRAGMENT_SHADER)
-    {
-        mShaderMap[handle] = new FragmentShader(this, handle);
-    }
-    else UNREACHABLE();
-
-    return handle;
+    return mResourceManager->createShader(type);
 }
 
-// Returns an unused program/shader name
-GLuint Context::createProgram()
-{
-    unsigned int handle = 1;
-
-    while (mProgramMap.find(handle) != mProgramMap.end() || mShaderMap.find(handle) != mShaderMap.end())   // Shared name space
-    {
-        handle++;
-    }
-
-    mProgramMap[handle] = new Program();
-
-    return handle;
-}
-
-// Returns an unused texture name
 GLuint Context::createTexture()
 {
-    unsigned int handle = 1;
-
-    while (mTextureMap.find(handle) != mTextureMap.end())
-    {
-        handle++;
-    }
-
-    mTextureMap[handle] = NULL;
-
-    return handle;
+    return mResourceManager->createTexture();
+}
+
+GLuint Context::createRenderbuffer()
+{
+    return mResourceManager->createRenderbuffer();
 }
 
 // Returns an unused framebuffer name
 GLuint Context::createFramebuffer()
 {
     unsigned int handle = 1;
 
     while (mFramebufferMap.find(handle) != mFramebufferMap.end())
@@ -816,428 +764,246 @@ GLuint Context::createFramebuffer()
         handle++;
     }
 
     mFramebufferMap[handle] = NULL;
 
     return handle;
 }
 
-// Returns an unused renderbuffer name
-GLuint Context::createRenderbuffer()
-{
-    unsigned int handle = 1;
-
-    while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
-    {
-        handle++;
-    }
-
-    mRenderbufferMap[handle] = NULL;
-
-    return handle;
-}
-
 void Context::deleteBuffer(GLuint buffer)
 {
-    BufferMap::iterator bufferObject = mBufferMap.find(buffer);
-
-    if (bufferObject != mBufferMap.end())
+    if (mResourceManager->getBuffer(buffer))
     {
         detachBuffer(buffer);
-
-        delete bufferObject->second;
-        mBufferMap.erase(bufferObject);
     }
+    
+    mResourceManager->deleteBuffer(buffer);
 }
 
 void Context::deleteShader(GLuint shader)
 {
-    ShaderMap::iterator shaderObject = mShaderMap.find(shader);
-
-    if (shaderObject != mShaderMap.end())
-    {
-        if (!shaderObject->second->isAttached())
-        {
-            delete shaderObject->second;
-            mShaderMap.erase(shaderObject);
-        }
-        else
-        {
-            shaderObject->second->flagForDeletion();
-        }
-    }
+    mResourceManager->deleteShader(shader);
 }
 
 void Context::deleteProgram(GLuint program)
 {
-    ProgramMap::iterator programObject = mProgramMap.find(program);
-
-    if (programObject != mProgramMap.end())
-    {
-        if (program != mState.currentProgram)
-        {
-            delete programObject->second;
-            mProgramMap.erase(programObject);
-        }
-        else
-        {
-            programObject->second->flagForDeletion();
-        }
-    }
+    mResourceManager->deleteProgram(program);
 }
 
 void Context::deleteTexture(GLuint texture)
 {
-    TextureMap::iterator textureObject = mTextureMap.find(texture);
-
-    if (textureObject != mTextureMap.end())
+    if (mResourceManager->getTexture(texture))
     {
         detachTexture(texture);
-
-        if (texture != 0)
-        {
-            delete textureObject->second;
-        }
-
-        mTextureMap.erase(textureObject);
     }
+
+    mResourceManager->deleteTexture(texture);
+}
+
+void Context::deleteRenderbuffer(GLuint renderbuffer)
+{
+    if (mResourceManager->getRenderbuffer(renderbuffer))
+    {
+        detachRenderbuffer(renderbuffer);
+    }
+    
+    mResourceManager->deleteRenderbuffer(renderbuffer);
 }
 
 void Context::deleteFramebuffer(GLuint framebuffer)
 {
     FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
 
     if (framebufferObject != mFramebufferMap.end())
     {
         detachFramebuffer(framebuffer);
 
         delete framebufferObject->second;
         mFramebufferMap.erase(framebufferObject);
     }
 }
 
-void Context::deleteRenderbuffer(GLuint renderbuffer)
+Buffer *Context::getBuffer(GLuint handle)
+{
+    return mResourceManager->getBuffer(handle);
+}
+
+Shader *Context::getShader(GLuint handle)
+{
+    return mResourceManager->getShader(handle);
+}
+
+Program *Context::getProgram(GLuint handle)
 {
-    RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
-
-    if (renderbufferObject != mRenderbufferMap.end())
-    {
-        detachRenderbuffer(renderbuffer);
-
-        delete renderbufferObject->second;
-        mRenderbufferMap.erase(renderbufferObject);
-    }
+    return mResourceManager->getProgram(handle);
+}
+
+Texture *Context::getTexture(GLuint handle)
+{
+    return mResourceManager->getTexture(handle);
+}
+
+Renderbuffer *Context::getRenderbuffer(GLuint handle)
+{
+    return mResourceManager->getRenderbuffer(handle);
+}
+
+Framebuffer *Context::getFramebuffer()
+{
+    return getFramebuffer(mState.framebuffer);
 }
 
 void Context::bindArrayBuffer(unsigned int buffer)
 {
-    if (buffer != 0 && !getBuffer(buffer))
-    {
-        mBufferMap[buffer] = new Buffer();
-    }
-
-    mState.arrayBuffer = buffer;
+    mResourceManager->checkBufferAllocation(buffer);
+
+    mState.arrayBuffer.set(getBuffer(buffer));
 }
 
 void Context::bindElementArrayBuffer(unsigned int buffer)
 {
-    if (buffer != 0 && !getBuffer(buffer))
-    {
-        mBufferMap[buffer] = new Buffer();
-    }
-
-    mState.elementArrayBuffer = buffer;
+    mResourceManager->checkBufferAllocation(buffer);
+
+    mState.elementArrayBuffer.set(getBuffer(buffer));
 }
 
 void Context::bindTexture2D(GLuint texture)
 {
-    if (!getTexture(texture) && texture != 0)
-    {
-        mTextureMap[texture] = new Texture2D(this);
-    }
-
-    mState.texture2D = texture;
-
-    mState.samplerTexture[SAMPLER_2D][mState.activeSampler] = texture;
+    mResourceManager->checkTextureAllocation(texture, SAMPLER_2D);
+
+    mState.texture2D.set(getTexture(texture));
+
+    mState.samplerTexture[SAMPLER_2D][mState.activeSampler].set(mState.texture2D.get());
 }
 
 void Context::bindTextureCubeMap(GLuint texture)
 {
-    if (!getTexture(texture) && texture != 0)
-    {
-        mTextureMap[texture] = new TextureCubeMap(this);
-    }
-
-    mState.textureCubeMap = texture;
-
-    mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler] = texture;
+    mResourceManager->checkTextureAllocation(texture, SAMPLER_CUBE);
+
+    mState.textureCubeMap.set(getTexture(texture));
+
+    mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].set(mState.textureCubeMap.get());
 }
 
 void Context::bindFramebuffer(GLuint framebuffer)
 {
     if (!getFramebuffer(framebuffer))
     {
         mFramebufferMap[framebuffer] = new Framebuffer();
     }
 
     mState.framebuffer = framebuffer;
 }
 
 void Context::bindRenderbuffer(GLuint renderbuffer)
 {
-    if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
-    {
-        mRenderbufferMap[renderbuffer] = new Renderbuffer();
-    }
-
-    mState.renderbuffer = renderbuffer;
+    mResourceManager->checkRenderbufferAllocation(renderbuffer);
+
+    mState.renderbuffer.set(getRenderbuffer(renderbuffer));
 }
 
 void Context::useProgram(GLuint program)
 {
-    Program *programObject = getCurrentProgram();
-
     GLuint priorProgram = mState.currentProgram;
     mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
 
-    if (programObject && programObject->isFlaggedForDeletion())
+    if (priorProgram != program)
     {
-        deleteProgram(priorProgram);
+        Program *newProgram = mResourceManager->getProgram(program);
+        Program *oldProgram = mResourceManager->getProgram(priorProgram);
+
+        if (newProgram)
+        {
+            newProgram->addRef();
+        }
+        
+        if (oldProgram)
+        {
+            oldProgram->release();
+        }
     }
 }
 
 void Context::setFramebufferZero(Framebuffer *buffer)
 {
     delete mFramebufferMap[0];
     mFramebufferMap[0] = buffer;
 }
 
-void Context::setColorbufferZero(Colorbuffer *buffer)
-{
-    delete mColorbufferZero;
-    mColorbufferZero = buffer;
-}
-
-void Context::setDepthbufferZero(Depthbuffer *buffer)
-{
-    delete mDepthbufferZero;
-    mDepthbufferZero = buffer;
-}
-
-void Context::setStencilbufferZero(Stencilbuffer *buffer)
-{
-    delete mStencilbufferZero;
-    mStencilbufferZero = buffer;
-}
-
-void Context::setRenderbuffer(Renderbuffer *buffer)
-{
-    delete mRenderbufferMap[mState.renderbuffer];
-    mRenderbufferMap[mState.renderbuffer] = buffer;
-}
-
-Buffer *Context::getBuffer(unsigned int handle)
-{
-    BufferMap::iterator buffer = mBufferMap.find(handle);
-
-    if (buffer == mBufferMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return buffer->second;
-    }
-}
-
-Shader *Context::getShader(unsigned int handle)
+void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
 {
-    ShaderMap::iterator shader = mShaderMap.find(handle);
-
-    if (shader == mShaderMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return shader->second;
-    }
-}
-
-Program *Context::getProgram(unsigned int handle)
-{
-    ProgramMap::iterator program = mProgramMap.find(handle);
-
-    if (program == mProgramMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return program->second;
-    }
-}
-
-Texture *Context::getTexture(unsigned int handle)
-{
-    if (handle == 0) return NULL;
-
-    TextureMap::iterator texture = mTextureMap.find(handle);
-
-    if (texture == mTextureMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return texture->second;
-    }
+    Renderbuffer *renderbufferObject = mState.renderbuffer.get();
+    renderbufferObject->setStorage(renderbuffer);
 }
 
 Framebuffer *Context::getFramebuffer(unsigned int handle)
 {
     FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
 
     if (framebuffer == mFramebufferMap.end())
     {
         return NULL;
     }
     else
     {
         return framebuffer->second;
     }
 }
 
-Renderbuffer *Context::getRenderbuffer(unsigned int handle)
-{
-    RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
-
-    if (renderbuffer == mRenderbufferMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return renderbuffer->second;
-    }
-}
-
-Colorbuffer *Context::getColorbuffer(GLuint handle)
-{
-    if (handle != 0)
-    {
-        Renderbuffer *renderbuffer = getRenderbuffer(handle);
-
-        if (renderbuffer && renderbuffer->isColorbuffer())
-        {
-            return static_cast<Colorbuffer*>(renderbuffer);
-        }
-    }
-    else   // Special case: 0 refers to different initial render targets based on the attachment type
-    {
-        return mColorbufferZero;
-    }
-
-    return NULL;
-}
-
-Depthbuffer *Context::getDepthbuffer(GLuint handle)
-{
-    if (handle != 0)
-    {
-        Renderbuffer *renderbuffer = getRenderbuffer(handle);
-
-        if (renderbuffer && renderbuffer->isDepthbuffer())
-        {
-            return static_cast<Depthbuffer*>(renderbuffer);
-        }
-    }
-    else   // Special case: 0 refers to different initial render targets based on the attachment type
-    {
-        return mDepthbufferZero;
-    }
-
-    return NULL;
-}
-
-Stencilbuffer *Context::getStencilbuffer(GLuint handle)
-{
-    if (handle != 0)
-    {
-        Renderbuffer *renderbuffer = getRenderbuffer(handle);
-
-        if (renderbuffer && renderbuffer->isStencilbuffer())
-        {
-            return static_cast<Stencilbuffer*>(renderbuffer);
-        }
-    }
-    else
-    {
-        return mStencilbufferZero;
-    }
-
-    return NULL;
-}
-
 Buffer *Context::getArrayBuffer()
 {
-    return getBuffer(mState.arrayBuffer);
+    return mState.arrayBuffer.get();
 }
 
 Buffer *Context::getElementArrayBuffer()
 {
-    return getBuffer(mState.elementArrayBuffer);
+    return mState.elementArrayBuffer.get();
 }
 
 Program *Context::getCurrentProgram()
 {
-    return getProgram(mState.currentProgram);
+    return mResourceManager->getProgram(mState.currentProgram);
 }
 
 Texture2D *Context::getTexture2D()
 {
-    if (mState.texture2D == 0)   // Special case: 0 refers to different initial textures based on the target
+    if (mState.texture2D.id() == 0)   // Special case: 0 refers to different initial textures based on the target
     {
         return mTexture2DZero;
     }
 
-    return (Texture2D*)getTexture(mState.texture2D);
+    return static_cast<Texture2D*>(mState.texture2D.get());
 }
 
 TextureCubeMap *Context::getTextureCubeMap()
 {
-    if (mState.textureCubeMap == 0)   // Special case: 0 refers to different initial textures based on the target
+    if (mState.textureCubeMap.id() == 0)   // Special case: 0 refers to different initial textures based on the target
     {
         return mTextureCubeMapZero;
     }
 
-    return (TextureCubeMap*)getTexture(mState.textureCubeMap);
+    return static_cast<TextureCubeMap*>(mState.textureCubeMap.get());
 }
 
 Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type)
 {
-    GLuint texid = mState.samplerTexture[type][sampler];
+    GLuint texid = mState.samplerTexture[type][sampler].id();
 
     if (texid == 0)
     {
         switch (type)
         {
           default: UNREACHABLE();
           case SAMPLER_2D: return mTexture2DZero;
           case SAMPLER_CUBE: return mTextureCubeMapZero;
         }
     }
 
-    return getTexture(texid);
-}
-
-Framebuffer *Context::getFramebuffer()
-{
-    return getFramebuffer(mState.framebuffer);
+    return mState.samplerTexture[type][sampler].get();
 }
 
 bool Context::getBooleanv(GLenum pname, GLboolean *params)
 {
     switch (pname)
     {
       case GL_SHADER_COMPILER:          *params = GL_TRUE;                          break;
       case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;      break;
@@ -1278,17 +1044,17 @@ bool Context::getFloatv(GLenum pname, GL
       case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
       case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
       case GL_ALIASED_LINE_WIDTH_RANGE:
         params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
         params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
         break;
       case GL_ALIASED_POINT_SIZE_RANGE:
         params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
-        params[1] = gl::ALIASED_POINT_SIZE_RANGE_MAX;
+        params[1] = supportsShaderModel3() ? gl::ALIASED_POINT_SIZE_RANGE_MAX_SM3 : gl::ALIASED_POINT_SIZE_RANGE_MAX_SM2;
         break;
       case GL_DEPTH_RANGE:
         params[0] = mState.zNear;
         params[1] = mState.zFar;
         break;
       case GL_COLOR_CLEAR_VALUE:
         params[0] = mState.colorClearValue.red;
         params[1] = mState.colorClearValue.green;
@@ -1324,20 +1090,20 @@ bool Context::getIntegerv(GLenum pname, 
       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
       case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = gl::MAX_TEXTURE_IMAGE_UNITS;          break;
       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = gl::MAX_FRAGMENT_UNIFORM_VECTORS;     break;
       case GL_MAX_RENDERBUFFER_SIZE:            *params = gl::MAX_RENDERBUFFER_SIZE;            break;
       case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = 0;                                    break;
       case GL_COMPRESSED_TEXTURE_FORMATS: /* no compressed texture formats are supported */     break;
       case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
-      case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer;                   break;
-      case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer;            break;
+      case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.id();              break;
+      case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.id();       break;
       case GL_FRAMEBUFFER_BINDING:              *params = mState.framebuffer;                   break;
-      case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer;                  break;
+      case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.id();             break;
       case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
       case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
       case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
       case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
       case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
       case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
       case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
       case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
@@ -1410,32 +1176,32 @@ bool Context::getIntegerv(GLenum pname, 
             {
                 *params = 0;
             }
         }
         break;
       case GL_DEPTH_BITS:
         {
             gl::Framebuffer *framebuffer = getFramebuffer();
-            gl::Depthbuffer *depthbuffer = framebuffer->getDepthbuffer();
+            gl::DepthStencilbuffer *depthbuffer = framebuffer->getDepthbuffer();
 
             if (depthbuffer)
             {
                 *params = depthbuffer->getDepthSize();
             }
             else
             {
                 *params = 0;
             }
         }
         break;
       case GL_STENCIL_BITS:
         {
             gl::Framebuffer *framebuffer = getFramebuffer();
-            gl::Stencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+            gl::DepthStencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
 
             if (stencilbuffer)
             {
                 *params = stencilbuffer->getStencilSize();
             }
             else
             {
                 *params = 0;
@@ -1445,28 +1211,28 @@ bool Context::getIntegerv(GLenum pname, 
       case GL_TEXTURE_BINDING_2D:
         {
             if (mState.activeSampler < 0 || mState.activeSampler > gl::MAX_TEXTURE_IMAGE_UNITS - 1)
             {
                 error(GL_INVALID_OPERATION);
                 return false;
             }
 
-            *params = mState.samplerTexture[SAMPLER_2D][mState.activeSampler];
+            *params = mState.samplerTexture[SAMPLER_2D][mState.activeSampler].id();
         }
         break;
       case GL_TEXTURE_BINDING_CUBE_MAP:
         {
             if (mState.activeSampler < 0 || mState.activeSampler > gl::MAX_TEXTURE_IMAGE_UNITS - 1)
             {
                 error(GL_INVALID_OPERATION);
                 return false;
             }
 
-            *params = mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler];
+            *params = mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].id();
         }
         break;
       default:
         return false;
     }
 
     return true;
 }
@@ -1631,30 +1397,44 @@ bool Context::applyRenderTarget(bool ign
     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
     {
         error(GL_INVALID_FRAMEBUFFER_OPERATION);
 
         return false;
     }
 
     IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
-    IDirect3DSurface9 *depthStencil = framebufferObject->getDepthStencil();
+    IDirect3DSurface9 *depthStencil = NULL;
 
     unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial();
     if (renderTargetSerial != mAppliedRenderTargetSerial)
     {
         device->SetRenderTarget(0, renderTarget);
         mAppliedRenderTargetSerial = renderTargetSerial;
     }
 
-    unsigned int depthbufferSerial = framebufferObject->getDepthbufferSerial();
-    if (depthbufferSerial != mAppliedDepthbufferSerial)
+    unsigned int depthbufferSerial = 0;
+    unsigned int stencilbufferSerial = 0;
+    if (framebufferObject->getDepthbufferType() != GL_NONE)
+    {
+        depthStencil = framebufferObject->getDepthbuffer()->getDepthStencil();
+        depthbufferSerial = framebufferObject->getDepthbuffer()->getSerial();
+    }
+    else if (framebufferObject->getStencilbufferType() != GL_NONE)
+    {
+        depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+        stencilbufferSerial = framebufferObject->getStencilbuffer()->getSerial();
+    }
+
+    if (depthbufferSerial != mAppliedDepthbufferSerial ||
+        stencilbufferSerial != mAppliedStencilbufferSerial)
     {
         device->SetDepthStencilSurface(depthStencil);
         mAppliedDepthbufferSerial = depthbufferSerial;
+        mAppliedStencilbufferSerial = stencilbufferSerial;
     }
 
     D3DVIEWPORT9 viewport;
     D3DSURFACE_DESC desc;
     renderTarget->GetDesc(&desc);
 
     if (ignoreViewport)
     {
@@ -1705,17 +1485,17 @@ bool Context::applyRenderTarget(bool ign
     if (mState.currentProgram)
     {
         Program *programObject = getCurrentProgram();
 
         GLint halfPixelSize = programObject->getDxHalfPixelSizeLocation();
         GLfloat xy[2] = {1.0f / viewport.Width, 1.0f / viewport.Height};
         programObject->setUniform2fv(halfPixelSize, 1, (GLfloat*)&xy);
 
-        GLint window = programObject->getDxWindowLocation();
+        GLint window = programObject->getDxViewportLocation();
         GLfloat whxy[4] = {mState.viewportWidth / 2.0f, mState.viewportHeight / 2.0f, 
                           (float)mState.viewportX + mState.viewportWidth / 2.0f, 
                           (float)mState.viewportY + mState.viewportHeight / 2.0f};
         programObject->setUniform4fv(window, 1, (GLfloat*)&whxy);
 
         GLint depth = programObject->getDxDepthLocation();
         GLfloat dz[2] = {(mState.zFar - mState.zNear) / 2.0f, (mState.zNear + mState.zFar) / 2.0f};
         programObject->setUniform2fv(depth, 1, (GLfloat*)&dz);
@@ -1743,33 +1523,35 @@ void Context::applyState(GLenum drawMode
     GLint frontCCW = programObject->getDxFrontCCWLocation();
     GLint ccw = (mState.frontFace == GL_CCW);
     programObject->setUniform1iv(frontCCW, 1, &ccw);
 
     GLint pointsOrLines = programObject->getDxPointsOrLinesLocation();
     GLint alwaysFront = !isTriangleMode(drawMode);
     programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront);
 
+    Framebuffer *framebufferObject = getFramebuffer();
+
     if (mCullStateDirty || mFrontFaceDirty)
     {
         if (mState.cullFace)
         {
             device->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, mState.frontFace));
         }
         else
         {
             device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
         }
 
         mCullStateDirty = false;
     }
 
     if (mDepthStateDirty)
     {
-        if (mState.depthTest)
+        if (mState.depthTest && framebufferObject->getDepthbufferType() != GL_NONE)
         {
             device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
             device->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc));
         }
         else
         {
             device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
         }
@@ -1840,17 +1622,17 @@ void Context::applyState(GLenum drawMode
                 mState.stencilMask != mState.stencilBackMask)
             {
                 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
                 return error(GL_INVALID_OPERATION);
             }
 
             // get the maximum size of the stencil ref
             gl::Framebuffer *framebuffer = getFramebuffer();
-            gl::Stencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+            gl::DepthStencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
             GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
 
             device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
             device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, 
                                    es2dx::ConvertComparison(mState.stencilFunc));
 
             device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
             device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask);
@@ -1892,17 +1674,17 @@ void Context::applyState(GLenum drawMode
 
         mMaskStateDirty = false;
     }
 
     if (mPolygonOffsetStateDirty)
     {
         if (mState.polygonOffsetFill)
         {
-            gl::Depthbuffer *depthbuffer = getFramebuffer()->getDepthbuffer();
+            gl::DepthStencilbuffer *depthbuffer = getFramebuffer()->getDepthbuffer();
             if (depthbuffer)
             {
                 device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor));
                 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
                 device->SetRenderState(D3DRS_DEPTHBIAS, *((DWORD*)&depthBias));
             }
         }
         else
@@ -2000,17 +1782,17 @@ GLenum Context::applyVertexBuffer(const 
     }
 
     return err;
 }
 
 // Applies the indices and element array bindings to the Direct3D 9 device
 GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
 {
-    GLenum err = mIndexDataManager->preRenderValidate(mode, type, count, getBuffer(mState.elementArrayBuffer), indices, indexInfo);
+    GLenum err = mIndexDataManager->preRenderValidate(mode, type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
 
     if (err == GL_NO_ERROR)
     {
         mBufferBackEnd->setupIndicesPreDraw(*indexInfo);
     }
 
     return err;
 }
@@ -2088,16 +1870,22 @@ void Context::applyTextures()
             }
         }   
     }
 }
 
 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
 {
     Framebuffer *framebuffer = getFramebuffer();
+
+    if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+    {
+        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+    }
+
     IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
     IDirect3DDevice9 *device = getDevice();
 
     D3DSURFACE_DESC desc;
     renderTarget->GetDesc(&desc);
 
     IDirect3DSurface9 *systemSurface;
     HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &systemSurface, NULL);
@@ -2111,29 +1899,29 @@ void Context::readPixels(GLint x, GLint 
 
     if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
     {
         UNIMPLEMENTED();   // FIXME: Requires resolve using StretchRect into non-multisampled render target
     }
 
     result = device->GetRenderTargetData(renderTarget, systemSurface);
 
-    if (result == D3DERR_DRIVERINTERNALERROR)
+    if (FAILED(result))
     {
         systemSurface->Release();
 
-        return error(GL_OUT_OF_MEMORY);
-    }
-
-    if (FAILED(result))
-    {
-        UNREACHABLE();
-        systemSurface->Release();
-
-        return;   // No sensible error to generate
+        switch (result)
+        {
+            case D3DERR_DRIVERINTERNALERROR:
+            case D3DERR_DEVICELOST:
+                return error(GL_OUT_OF_MEMORY);
+            default:
+                UNREACHABLE();
+                return;   // No sensible error to generate
+        }
     }
 
     D3DLOCKED_RECT lock;
     RECT rect = {std::max(x, 0),
                  std::max(y, 0),
                  std::min(x + width, (int)desc.Width),
                  std::min(y + height, (int)desc.Height)};
 
@@ -2294,32 +2082,34 @@ void Context::clear(GLbitfield mask)
     {
         mask &= ~GL_DEPTH_BUFFER_BIT;
         if (mState.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
         {
             flags |= D3DCLEAR_ZBUFFER;
         }
     }
 
-    IDirect3DSurface9 *depthStencil = framebufferObject->getDepthStencil();
-
     GLuint stencilUnmasked = 0x0;
 
-    if ((mask & GL_STENCIL_BUFFER_BIT) && depthStencil)
+    if (mask & GL_STENCIL_BUFFER_BIT)
     {
-        D3DSURFACE_DESC desc;
-        depthStencil->GetDesc(&desc);
-
         mask &= ~GL_STENCIL_BUFFER_BIT;
-        unsigned int stencilSize = es2dx::GetStencilSize(desc.Format);
-        stencilUnmasked = (0x1 << stencilSize) - 1;
-
-        if (stencilUnmasked != 0x0)
+        if (framebufferObject->getStencilbufferType() != GL_NONE)
         {
-            flags |= D3DCLEAR_STENCIL;
+            IDirect3DSurface9 *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+            D3DSURFACE_DESC desc;
+            depthStencil->GetDesc(&desc);
+
+            unsigned int stencilSize = es2dx::GetStencilSize(desc.Format);
+            stencilUnmasked = (0x1 << stencilSize) - 1;
+
+            if (stencilUnmasked != 0x0)
+            {
+                flags |= D3DCLEAR_STENCIL;
+            }
         }
     }
 
     if (mask != 0)
     {
         return error(GL_INVALID_VALUE);
     }
 
@@ -2737,64 +2527,59 @@ GLenum Context::getError()
         mInvalidFramebufferOperation = false;
 
         return GL_INVALID_FRAMEBUFFER_OPERATION;
     }
 
     return GL_NO_ERROR;
 }
 
-const char *Context::getPixelShaderProfile()
+bool Context::supportsShaderModel3() const
 {
-    return mPsProfile;
-}
-
-const char *Context::getVertexShaderProfile()
-{
-    return mVsProfile;
+    return mSupportsShaderModel3;
 }
 
 void Context::detachBuffer(GLuint buffer)
 {
     // [OpenGL ES 2.0.24] section 2.9 page 22:
     // If a buffer object is deleted while it is bound, all bindings to that object in the current context
     // (i.e. in the thread that called Delete-Buffers) are reset to zero.
 
-    if (mState.arrayBuffer == buffer)
+    if (mState.arrayBuffer.id() == buffer)
     {
-        mState.arrayBuffer = 0;
+        mState.arrayBuffer.set(NULL);
     }
 
-    if (mState.elementArrayBuffer == buffer)
+    if (mState.elementArrayBuffer.id() == buffer)
     {
-        mState.elementArrayBuffer = 0;
+        mState.elementArrayBuffer.set(NULL);
     }
 
     for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
     {
-        if (mState.vertexAttribute[attribute].mBoundBuffer == buffer)
+        if (mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer)
         {
-            mState.vertexAttribute[attribute].mBoundBuffer = 0;
+            mState.vertexAttribute[attribute].mBoundBuffer.set(NULL);
         }
     }
 }
 
 void Context::detachTexture(GLuint texture)
 {
     // [OpenGL ES 2.0.24] section 3.8 page 84:
     // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
     // rebound to texture object zero
 
     for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
     {
         for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
         {
-            if (mState.samplerTexture[type][sampler] == texture)
+            if (mState.samplerTexture[type][sampler].id() == texture)
             {
-                mState.samplerTexture[type][sampler] = 0;
+                mState.samplerTexture[type][sampler].set(NULL);
             }
         }
     }
 
     // [OpenGL ES 2.0.24] section 4.4 page 112:
     // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
     // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
     // image was attached in the currently bound framebuffer.
@@ -2820,17 +2605,17 @@ void Context::detachFramebuffer(GLuint f
 }
 
 void Context::detachRenderbuffer(GLuint renderbuffer)
 {
     // [OpenGL ES 2.0.24] section 4.4 page 109:
     // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
     // had been executed with the target RENDERBUFFER and name of zero.
 
-    if (mState.renderbuffer == renderbuffer)
+    if (mState.renderbuffer.id() == renderbuffer)
     {
         bindRenderbuffer(0);
     }
 
     // [OpenGL ES 2.0.24] section 4.4 page 111:
     // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
     // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
     // point to which this image was attached in the currently bound framebuffer.
@@ -2854,25 +2639,25 @@ Texture *Context::getIncompleteTexture(S
         switch (type)
         {
           default:
             UNREACHABLE();
             // default falls through to SAMPLER_2D
 
           case SAMPLER_2D:
             {
-                Texture2D *incomplete2d = new Texture2D(this);
+                Texture2D *incomplete2d = new Texture2D(Texture::INCOMPLETE_TEXTURE_ID);
                 incomplete2d->setImage(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
                 t = incomplete2d;
             }
             break;
 
           case SAMPLER_CUBE:
             {
-              TextureCubeMap *incompleteCube = new TextureCubeMap(this);
+              TextureCubeMap *incompleteCube = new TextureCubeMap(Texture::INCOMPLETE_TEXTURE_ID);
 
               incompleteCube->setImagePosX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
               incompleteCube->setImageNegX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
               incompleteCube->setImagePosY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
               incompleteCube->setImageNegY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
               incompleteCube->setImagePosZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
               incompleteCube->setImageNegZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
 
@@ -2910,19 +2695,19 @@ bool Context::isTriangleMode(GLenum draw
 
     return false;
 }
 
 bool Context::hasStencil()
 {
     Framebuffer *framebufferObject = getFramebuffer();
 
-    if (framebufferObject)
+    if (framebufferObject && framebufferObject->getStencilbufferType() != GL_NONE)
     {
-        Stencilbuffer *stencilbufferObject = framebufferObject->getStencilbuffer();
+        DepthStencilbuffer *stencilbufferObject = framebufferObject->getStencilbuffer();
 
         if (stencilbufferObject)
         {
             return stencilbufferObject->getStencilSize() > 0;
         }
     }
 
     return false;
@@ -2937,16 +2722,18 @@ void Context::setVertexAttrib(GLuint ind
     mState.vertexAttribute[index].mCurrentValue[2] = values[2];
     mState.vertexAttribute[index].mCurrentValue[3] = values[3];
 
     mVertexDataManager->dirtyCurrentValues();
 }
 
 void Context::initExtensionString()
 {
+    mExtensionString += "GL_OES_packed_depth_stencil ";
+
     if (mBufferBackEnd->supportIntIndices())
     {
         mExtensionString += "GL_OES_element_index_uint ";
     }
 
     std::string::size_type end = mExtensionString.find_last_not_of(' ');
     if (end != std::string::npos)
     {
@@ -2958,19 +2745,19 @@ const char *Context::getExtensionString(
 {
     return mExtensionString.c_str();
 }
 
 }
 
 extern "C"
 {
-gl::Context *glCreateContext(const egl::Config *config)
+gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext)
 {
-    return new gl::Context(config);
+    return new gl::Context(config, shareContext);
 }
 
 void glDestroyContext(gl::Context *context)
 {
     delete context;
 
     if (context == gl::getContext())
     {
--- a/gfx/angle/src/libGLESv2/Context.h
+++ b/gfx/angle/src/libGLESv2/Context.h
@@ -2,28 +2,30 @@
 // 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.
 //
 
 // Context.h: Defines the gl::Context class, managing all GL state and performing
 // rendering operations. It is the GLES2 specific implementation of EGLContext.
 
-#ifndef INCLUDE_CONTEXT_H_
-#define INCLUDE_CONTEXT_H_
+#ifndef LIBGLESV2_CONTEXT_H_
+#define LIBGLESV2_CONTEXT_H_
 
 #define GL_APICALL
 #include <GLES2/gl2.h>
 #define EGLAPI
 #include <EGL/egl.h>
 #include <d3d9.h>
 
 #include <map>
 
 #include "common/angleutils.h"
+#include "libGLESv2/ResourceManager.h"
+#include "libGLESv2/RefCountObject.h"
 
 namespace egl
 {
 class Display;
 class Surface;
 class Config;
 }
 
@@ -35,19 +37,21 @@ struct TranslatedIndexData;
 class Buffer;
 class Shader;
 class Program;
 class Texture;
 class Texture2D;
 class TextureCubeMap;
 class Framebuffer;
 class Renderbuffer;
+class RenderbufferStorage;
 class Colorbuffer;
 class Depthbuffer;
 class Stencilbuffer;
+class DepthStencilbuffer;
 class VertexDataManager;
 class IndexDataManager;
 class BufferBackEnd;
 class Blit;
 
 enum
 {
     MAX_VERTEX_ATTRIBS = 12,
@@ -62,55 +66,48 @@ enum
 
     IMPLEMENTATION_COLOR_READ_FORMAT = GL_RGB,
     IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_SHORT_5_6_5
 };
 
 const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
 const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;
 const float ALIASED_POINT_SIZE_RANGE_MIN = 1.0f;
-const float ALIASED_POINT_SIZE_RANGE_MAX = 1.0f;
-
-enum SamplerType
-{
-    SAMPLER_2D,
-    SAMPLER_CUBE,
-
-    SAMPLER_TYPE_COUNT
-};
+const float ALIASED_POINT_SIZE_RANGE_MAX_SM2 = 1.0f;
+const float ALIASED_POINT_SIZE_RANGE_MAX_SM3 = 64.0f;
 
 struct Color
 {
     float red;
     float green;
     float blue;
     float alpha;
 };
 
 // Helper structure describing a single vertex attribute
 class AttributeState
 {
   public:
     AttributeState()
-        : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mBoundBuffer(0), mEnabled(false)
+        : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mEnabled(false)
     {
         mCurrentValue[0] = 0;
         mCurrentValue[1] = 0;
         mCurrentValue[2] = 0;
         mCurrentValue[3] = 1;
     }
 
     // From VertexArrayPointer
     GLenum mType;
     GLint mSize;
     bool mNormalized;
     GLsizei mStride; // 0 means natural stride
     const void *mPointer;
 
-    GLuint mBoundBuffer; // Captured when VertexArrayPointer is called.
+    BindingPointer<Buffer> mBoundBuffer; // Captured when VertexArrayPointer is called.
 
     bool mEnabled; // From Enable/DisableVertexAttribArray
 
     float mCurrentValue[4]; // From VertexAttrib4f
 };
 
 // Helper structure to store all raw state
 struct State
@@ -175,35 +172,35 @@ struct State
 
     bool colorMaskRed;
     bool colorMaskGreen;
     bool colorMaskBlue;
     bool colorMaskAlpha;
     bool depthMask;
 
     int activeSampler;   // Active texture unit selector - GL_TEXTURE0
-    GLuint arrayBuffer;
-    GLuint elementArrayBuffer;
-    GLuint texture2D;
-    GLuint textureCubeMap;
+    BindingPointer<Buffer> arrayBuffer;
+    BindingPointer<Buffer> elementArrayBuffer;
+    BindingPointer<Texture> texture2D;
+    BindingPointer<Texture> textureCubeMap;
     GLuint framebuffer;
-    GLuint renderbuffer;
+    BindingPointer<Renderbuffer> renderbuffer;
     GLuint currentProgram;
 
     AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS];
-    GLuint samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
+    BindingPointer<Texture> samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
 
     GLint unpackAlignment;
     GLint packAlignment;
 };
 
 class Context
 {
   public:
-    Context(const egl::Config *config);
+    Context(const egl::Config *config, const gl::Context *shareContext);
 
     ~Context();
 
     void makeCurrent(egl::Display *display, egl::Surface *surface);
 
     void markAllStateDirty();
 
     // State manipulation
@@ -278,67 +275,66 @@ class Context
 
     GLuint getFramebufferHandle() const;
     GLuint getRenderbufferHandle() const;
 
     GLuint getArrayBufferHandle() const;
 
     void setVertexAttribEnabled(unsigned int attribNum, bool enabled);
     const AttributeState &getVertexAttribState(unsigned int attribNum);
-    void setVertexAttribState(unsigned int attribNum, GLuint boundBuffer, GLint size, GLenum type,
+    void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
                               bool normalized, GLsizei stride, const void *pointer);
     const void *getVertexAttribPointer(unsigned int attribNum) const;
 
     const AttributeState *getVertexAttribBlock();
 
     void setUnpackAlignment(GLint alignment);
     GLint getUnpackAlignment() const;
 
     void setPackAlignment(GLint alignment);
     GLint getPackAlignment() const;
 
+    // These create  and destroy methods are merely pass-throughs to 
+    // ResourceManager, which owns these object types
     GLuint createBuffer();
     GLuint createShader(GLenum type);
     GLuint createProgram();
     GLuint createTexture();
-    GLuint createFramebuffer();
     GLuint createRenderbuffer();
 
     void deleteBuffer(GLuint buffer);
     void deleteShader(GLuint shader);
     void deleteProgram(GLuint program);
     void deleteTexture(GLuint texture);
+    void deleteRenderbuffer(GLuint renderbuffer);
+
+    // Framebuffers are owned by the Context, so these methods do not pass through
+    GLuint createFramebuffer();
     void deleteFramebuffer(GLuint framebuffer);
-    void deleteRenderbuffer(GLuint renderbuffer);
 
     void bindArrayBuffer(GLuint buffer);
     void bindElementArrayBuffer(GLuint buffer);
     void bindTexture2D(GLuint texture);
     void bindTextureCubeMap(GLuint texture);
     void bindFramebuffer(GLuint framebuffer);
     void bindRenderbuffer(GLuint renderbuffer);
     void useProgram(GLuint program);
 
     void setFramebufferZero(Framebuffer *framebuffer);
-    void setColorbufferZero(Colorbuffer *renderbuffer);
-    void setDepthbufferZero(Depthbuffer *depthBuffer);
-    void setStencilbufferZero(Stencilbuffer *stencilBuffer);
-    void setRenderbuffer(Renderbuffer *renderbuffer);
+
+    void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
 
     void setVertexAttrib(GLuint index, const GLfloat *values);
 
     Buffer *getBuffer(GLuint handle);
     Shader *getShader(GLuint handle);
     Program *getProgram(GLuint handle);
     Texture *getTexture(GLuint handle);
     Framebuffer *getFramebuffer(GLuint handle);
     Renderbuffer *getRenderbuffer(GLuint handle);
-    Colorbuffer *getColorbuffer(GLuint handle);
-    Depthbuffer *getDepthbuffer(GLuint handle);
-    Stencilbuffer *getStencilbuffer(GLuint handle);
 
     Buffer *getArrayBuffer();
     Buffer *getElementArrayBuffer();
     Program *getCurrentProgram();
     Texture2D *getTexture2D();
     TextureCubeMap *getTextureCubeMap();
     Texture *getSamplerTexture(unsigned int sampler, SamplerType type);
     Framebuffer *getFramebuffer();
@@ -368,19 +364,17 @@ class Context
     void recordInvalidEnum();
     void recordInvalidValue();
     void recordInvalidOperation();
     void recordOutOfMemory();
     void recordInvalidFramebufferOperation();
 
     GLenum getError();
 
-    const char *getPixelShaderProfile();
-    const char *getVertexShaderProfile();
-
+    bool supportsShaderModel3() const;
     const char *getExtensionString() const;
 
     Blit *getBlitter() { return mBlit; }
 
     const D3DCAPS9 &getDeviceCaps() { return mDeviceCaps; }
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Context);
@@ -401,63 +395,47 @@ class Context
     const egl::Config *const mConfig;
 
     State   mState;
 
     Texture2D *mTexture2DZero;
     TextureCubeMap *mTextureCubeMapZero;
 
     Colorbuffer *mColorbufferZero;
-    Depthbuffer *mDepthbufferZero;
-    Stencilbuffer *mStencilbufferZero;
-
-    typedef std::map<GLuint, Buffer*> BufferMap;
-    BufferMap mBufferMap;
-
-    typedef std::map<GLuint, Shader*> ShaderMap;
-    ShaderMap mShaderMap;
-
-    typedef std::map<GLuint, Program*> ProgramMap;
-    ProgramMap mProgramMap;
-
-    typedef std::map<GLuint, Texture*> TextureMap;
-    TextureMap mTextureMap;
+    DepthStencilbuffer *mDepthStencilbufferZero;
 
     typedef std::map<GLuint, Framebuffer*> FramebufferMap;
     FramebufferMap mFramebufferMap;
 
-    typedef std::map<GLuint, Renderbuffer*> RenderbufferMap;
-    RenderbufferMap mRenderbufferMap;
-
     void initExtensionString();
     std::string mExtensionString;
 
     BufferBackEnd *mBufferBackEnd;
     VertexDataManager *mVertexDataManager;
     IndexDataManager *mIndexDataManager;
 
     Blit *mBlit;
-
+    
     Texture *mIncompleteTextures[SAMPLER_TYPE_COUNT];
 
     // Recorded errors
     bool mInvalidEnum;
     bool mInvalidValue;
     bool mInvalidOperation;
     bool mOutOfMemory;
     bool mInvalidFramebufferOperation;
 
     bool mHasBeenCurrent;
 
     unsigned int mAppliedProgram;
     unsigned int mAppliedRenderTargetSerial;
     unsigned int mAppliedDepthbufferSerial;
+    unsigned int mAppliedStencilbufferSerial;
 
-    const char *mPsProfile;
-    const char *mVsProfile;
+    bool mSupportsShaderModel3;
 
     // state caching flags
     bool mClearStateDirty;
     bool mCullStateDirty;
     bool mDepthStateDirty;
     bool mMaskStateDirty;
     bool mPixelPackingStateDirty;
     bool mBlendStateDirty;
@@ -466,22 +444,24 @@ class Context
     bool mScissorStateDirty;
     bool mSampleStateDirty;
     bool mFrontFaceDirty;
     bool mDitherStateDirty;
 
     IDirect3DStateBlock9 *mMaskedClearSavedState;
 
     D3DCAPS9 mDeviceCaps;
+
+    ResourceManager *mResourceManager;
 };
 }
 
 extern "C"
 {
 // Exported functions for use by EGL
-gl::Context *glCreateContext(const egl::Config *config);
+gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext);
 void glDestroyContext(gl::Context *context);
 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
 gl::Context *glGetCurrentContext();
 __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname);
 }
 
 #endif   // INCLUDE_CONTEXT_H_
--- a/gfx/angle/src/libGLESv2/Framebuffer.cpp
+++ b/gfx/angle/src/libGLESv2/Framebuffer.cpp
@@ -11,193 +11,192 @@
 
 #include "libGLESv2/main.h"
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/utilities.h"
 
 namespace gl
 {
+
 Framebuffer::Framebuffer()
 {
     mColorbufferType = GL_NONE;
-    mColorbufferHandle = 0;
-
     mDepthbufferType = GL_NONE;
-    mDepthbufferHandle = 0;
-
     mStencilbufferType = GL_NONE;
-    mStencilbufferHandle = 0;
 }
 
 Framebuffer::~Framebuffer()
 {
+    mColorbufferPointer.set(NULL);
+    mDepthbufferPointer.set(NULL);
+    mStencilbufferPointer.set(NULL);
+}
+
+Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
+{
+    gl::Context *context = gl::getContext();
+    Renderbuffer *buffer = NULL;
+
+    if (type == GL_NONE)
+    {
+        buffer = NULL;
+    }
+    else if (type == GL_RENDERBUFFER)
+    {
+        buffer = context->getRenderbuffer(handle);
+    }
+    else if (IsTextureTarget(type))
+    {
+        buffer = context->getTexture(handle)->getColorbuffer(type);
+    }
+    else
+    {
+        UNREACHABLE();
+    }
+
+    return buffer;
 }
 
 void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
 {
     mColorbufferType = type;
-    mColorbufferHandle = colorbuffer;
+    mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer));
 }
 
 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
 {
     mDepthbufferType = type;
-    mDepthbufferHandle = depthbuffer;
+    mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer));
 }
 
 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
 {
     mStencilbufferType = type;
-    mStencilbufferHandle = stencilbuffer;
+    mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer));
 }
 
 void Framebuffer::detachTexture(GLuint texture)
 {
-    if (mColorbufferHandle == texture && IsTextureTarget(mColorbufferType))
+    if (mColorbufferPointer.id() == texture && IsTextureTarget(mColorbufferType))
     {
         mColorbufferType = GL_NONE;
-        mColorbufferHandle = 0;
+        mColorbufferPointer.set(NULL);
     }
 
-    if (mDepthbufferHandle == texture && IsTextureTarget(mDepthbufferType))
+    if (mDepthbufferPointer.id() == texture && IsTextureTarget(mDepthbufferType))
     {
         mDepthbufferType = GL_NONE;
-        mDepthbufferHandle = 0;
+        mDepthbufferPointer.set(NULL);
     }
 
-    if (mStencilbufferHandle == texture && IsTextureTarget(mStencilbufferType))
+    if (mStencilbufferPointer.id() == texture && IsTextureTarget(mStencilbufferType))
     {
         mStencilbufferType = GL_NONE;
-        mStencilbufferHandle = 0;
+        mStencilbufferPointer.set(NULL);
     }
 }
 
 void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
 {
-    if (mColorbufferHandle == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
+    if (mColorbufferPointer.id() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
     {
         mColorbufferType = GL_NONE;
-        mColorbufferHandle = 0;
+        mColorbufferPointer.set(NULL);
     }
 
-    if (mDepthbufferHandle == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
+    if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
     {
         mDepthbufferType = GL_NONE;
-        mDepthbufferHandle = 0;
+        mDepthbufferPointer.set(NULL);
     }
 
-    if (mStencilbufferHandle == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
+    if (mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
     {
         mStencilbufferType = GL_NONE;
-        mStencilbufferHandle = 0;
+        mStencilbufferPointer.set(NULL);
     }
 }
 
 unsigned int Framebuffer::getRenderTargetSerial()
 {
-    Renderbuffer *colorbuffer = getColorbuffer();
+    Renderbuffer *colorbuffer = mColorbufferPointer.get();
 
     if (colorbuffer)
     {
         return colorbuffer->getSerial();
     }
 
     return 0;
 }
 
 IDirect3DSurface9 *Framebuffer::getRenderTarget()
 {
-    Renderbuffer *colorbuffer = getColorbuffer();
+    Renderbuffer *colorbuffer = mColorbufferPointer.get();
 
     if (colorbuffer)
     {
         return colorbuffer->getRenderTarget();
     }
 
     return NULL;
 }
 
 unsigned int Framebuffer::getDepthbufferSerial()
 {
-    gl::Context *context = gl::getContext();
-    Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+    Renderbuffer *depthbuffer = mDepthbufferPointer.get();
 
     if (depthbuffer)
     {
         return depthbuffer->getSerial();
     }
 
     return 0;
 }
 
-IDirect3DSurface9 *Framebuffer::getDepthStencil()
-{
-    gl::Context *context = gl::getContext();
-    Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
-
-    if (depthbuffer)
-    {
-        return depthbuffer->getDepthStencil();
-    }
-
-    return NULL;
-}
-
 Colorbuffer *Framebuffer::getColorbuffer()
 {
-    gl::Context *context = gl::getContext();
-    Colorbuffer *colorbuffer = NULL;
+    Renderbuffer *rb = mColorbufferPointer.get();
 
-    if (mColorbufferType == GL_NONE)
+    if (rb != NULL && rb->isColorbuffer())
     {
-        UNREACHABLE();
-        colorbuffer = NULL;
-    }
-    else if (mColorbufferType == GL_RENDERBUFFER)
-    {
-        colorbuffer = context->getColorbuffer(mColorbufferHandle);
+        return static_cast<Colorbuffer*>(rb->getStorage());
     }
     else
     {
-        colorbuffer = context->getTexture(mColorbufferHandle)->getColorbuffer(mColorbufferType);
+        return NULL;
     }
-
-    if (colorbuffer && colorbuffer->isColorbuffer())
-    {
-        return colorbuffer;
-    }
-
-    return NULL;
 }
 
-Depthbuffer *Framebuffer::getDepthbuffer()
+DepthStencilbuffer *Framebuffer::getDepthbuffer()
 {
-    gl::Context *context = gl::getContext();
-    Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+    Renderbuffer *rb = mDepthbufferPointer.get();
 
-    if (depthbuffer && depthbuffer->isDepthbuffer())
+    if (rb != NULL && rb->isDepthbuffer())
     {
-        return depthbuffer;
+        return static_cast<DepthStencilbuffer*>(rb->getStorage());
     }
-
-    return NULL;
+    else
+    {
+        return NULL;
+    }
 }
 
-Stencilbuffer *Framebuffer::getStencilbuffer()
+DepthStencilbuffer *Framebuffer::getStencilbuffer()
 {
-    gl::Context *context = gl::getContext();
-    Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
+    Renderbuffer *rb = mStencilbufferPointer.get();
 
-    if (stencilbuffer && stencilbuffer->isStencilbuffer())
+    if (rb != NULL && rb->isStencilbuffer())
     {
-        return stencilbuffer;
+        return static_cast<DepthStencilbuffer*>(rb->getStorage());
     }
-
-    return NULL;
+    else
+    {
+        return NULL;
+    }
 }
 
 GLenum Framebuffer::getColorbufferType()
 {
     return mColorbufferType;
 }
 
 GLenum Framebuffer::getDepthbufferType()
@@ -207,33 +206,31 @@ GLenum Framebuffer::getDepthbufferType()
 
 GLenum Framebuffer::getStencilbufferType()
 {
     return mStencilbufferType;
 }
 
 GLuint Framebuffer::getColorbufferHandle()
 {
-    return mColorbufferHandle;
+    return mColorbufferPointer.id();
 }
 
 GLuint Framebuffer::getDepthbufferHandle()
 {
-    return mDepthbufferHandle;
+    return mDepthbufferPointer.id();
 }
 
 GLuint Framebuffer::getStencilbufferHandle()
 {
-    return mStencilbufferHandle;
+    return mStencilbufferPointer.id();
 }
 
 GLenum Framebuffer::completeness()
 {
-    gl::Context *context = gl::getContext();
-
     int width = 0;
     int height = 0;
 
     if (mColorbufferType != GL_NONE)
     {
         Colorbuffer *colorbuffer = getColorbuffer();
 
         if (!colorbuffer)
@@ -244,20 +241,27 @@ GLenum Framebuffer::completeness()
         if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
         {
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
         width = colorbuffer->getWidth();
         height = colorbuffer->getHeight();
     }
+    else
+    {
+        return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+    }
+
+    DepthStencilbuffer *depthbuffer = NULL;
+    DepthStencilbuffer *stencilbuffer = NULL;
 
     if (mDepthbufferType != GL_NONE)
     {
-        Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+        depthbuffer = getDepthbuffer();
 
         if (!depthbuffer)
         {
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
         if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
         {
@@ -272,17 +276,17 @@ GLenum Framebuffer::completeness()
         else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
         }
     }
 
     if (mStencilbufferType != GL_NONE)
     {
-        Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
+        stencilbuffer = getStencilbuffer();
 
         if (!stencilbuffer)
         {
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
         if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
         {
@@ -295,11 +299,40 @@ GLenum Framebuffer::completeness()
             height = stencilbuffer->getHeight();
         }
         else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
         }
     }
 
+    if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
+    {
+        if (depthbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
+            stencilbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
+            depthbuffer->getSerial() != stencilbuffer->getSerial())
+        {
+            return GL_FRAMEBUFFER_UNSUPPORTED;
+        }
+    }
+
     return GL_FRAMEBUFFER_COMPLETE;
 }
+
+DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil)
+{
+    mColorbufferType = GL_RENDERBUFFER;
+    mDepthbufferType = GL_RENDERBUFFER;
+    mStencilbufferType = GL_RENDERBUFFER;
+
+    mColorbufferPointer.set(new Renderbuffer(0, color));
+
+    Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
+    mDepthbufferPointer.set(depthStencilRenderbuffer);
+    mStencilbufferPointer.set(depthStencilRenderbuffer);
 }
+
+GLenum DefaultFramebuffer::completeness()
+{
+    return GL_FRAMEBUFFER_COMPLETE;
+}
+
+}
--- a/gfx/angle/src/libGLESv2/Framebuffer.h
+++ b/gfx/angle/src/libGLESv2/Framebuffer.h
@@ -10,64 +10,82 @@
 #ifndef LIBGLESV2_FRAMEBUFFER_H_
 #define LIBGLESV2_FRAMEBUFFER_H_
 
 #define GL_APICALL
 #include <GLES2/gl2.h>
 #include <d3d9.h>
 
 #include "common/angleutils.h"
+#include "libGLESv2/RefCountObject.h"
 
 namespace gl
 {
+class Renderbuffer;
 class Colorbuffer;
 class Depthbuffer;
 class Stencilbuffer;
+class DepthStencilbuffer;
 
 class Framebuffer
 {
   public:
     Framebuffer();
 
-    ~Framebuffer();
+    virtual ~Framebuffer();
 
     void setColorbuffer(GLenum type, GLuint colorbuffer);
     void setDepthbuffer(GLenum type, GLuint depthbuffer);
     void setStencilbuffer(GLenum type, GLuint stencilbuffer);
 
     void detachTexture(GLuint texture);
     void detachRenderbuffer(GLuint renderbuffer);
 
     IDirect3DSurface9 *getRenderTarget();
     IDirect3DSurface9 *getDepthStencil();
 
     unsigned int getRenderTargetSerial();
     unsigned int getDepthbufferSerial();
 
     Colorbuffer *getColorbuffer();
-    Depthbuffer *getDepthbuffer();
-    Stencilbuffer *getStencilbuffer();
+    DepthStencilbuffer *getDepthbuffer();
+    DepthStencilbuffer *getStencilbuffer();
 
     GLenum getColorbufferType();
     GLenum getDepthbufferType();
     GLenum getStencilbufferType();
 
     GLuint getColorbufferHandle();
     GLuint getDepthbufferHandle();
     GLuint getStencilbufferHandle();
 
-    GLenum completeness();
+    virtual GLenum completeness();
+
+  protected:
+    GLenum mColorbufferType;
+    BindingPointer<Renderbuffer> mColorbufferPointer;
+
+    GLenum mDepthbufferType;
+    BindingPointer<Renderbuffer> mDepthbufferPointer;
+
+    GLenum mStencilbufferType;
+    BindingPointer<Renderbuffer> mStencilbufferPointer;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Framebuffer);
 
-    GLuint mColorbufferHandle;
-    GLenum mColorbufferType;
+    Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;
+};
 
-    GLuint mDepthbufferHandle;
-    GLenum mDepthbufferType;
+class DefaultFramebuffer : public Framebuffer
+{
+  public:
+    DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil);
 
-    GLuint mStencilbufferHandle;
-    GLenum mStencilbufferType;
+    virtual GLenum completeness();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(DefaultFramebuffer);
 };
+
 }
 
 #endif   // LIBGLESV2_FRAMEBUFFER_H_
--- a/gfx/angle/src/libGLESv2/Program.cpp
+++ b/gfx/angle/src/libGLESv2/Program.cpp
@@ -40,98 +40,100 @@ Uniform::~Uniform()
     delete[] data;
 }
 
 UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) 
     : name(name), element(element), index(index)
 {
 }
 
-Program::Program()
+Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
 {
     mFragmentShader = NULL;
     mVertexShader = NULL;
 
     mPixelExecutable = NULL;
     mVertexExecutable = NULL;
     mConstantTablePS = NULL;
     mConstantTableVS = NULL;
 
     mInfoLog = NULL;
     mValidated = false;
 
     unlink();
 
     mDeleteStatus = false;
 
+    mRefCount = 0;
+
     mSerial = issueSerial();
 }
 
 Program::~Program()
 {
     unlink(true);
 
     if (mVertexShader != NULL)
     {
-        mVertexShader->detach();
+        mVertexShader->release();
     }
 
     if (mFragmentShader != NULL)
     {
-        mFragmentShader->detach();
+        mFragmentShader->release();
     }
 }
 
 bool Program::attachShader(Shader *shader)
 {
     if (shader->getType() == GL_VERTEX_SHADER)
     {
         if (mVertexShader)
         {
             return false;
         }
 
         mVertexShader = (VertexShader*)shader;
-        mVertexShader->attach();
+        mVertexShader->addRef();
     }
     else if (shader->getType() == GL_FRAGMENT_SHADER)
     {
         if (mFragmentShader)
         {
             return false;
         }
 
         mFragmentShader = (FragmentShader*)shader;
-        mFragmentShader->attach();
+        mFragmentShader->addRef();
     }
     else UNREACHABLE();
 
     return true;
 }
 
 bool Program::detachShader(Shader *shader)
 {
     if (shader->getType() == GL_VERTEX_SHADER)
     {
         if (mVertexShader != shader)
         {
             return false;
         }
 
-        mVertexShader->detach();
+        mVertexShader->release();
         mVertexShader = NULL;
     }
     else if (shader->getType() == GL_FRAGMENT_SHADER)
     {
         if (mFragmentShader != shader)
         {
             return false;
         }
 
-        mFragmentShader->detach();
+        mFragmentShader->release();
         mFragmentShader = NULL;
     }
     else UNREACHABLE();
 
     unlink();
 
     return true;
 }
@@ -1190,16 +1192,20 @@ bool Program::linkVaryings()
         if (!matched)
         {
             appendToInfoLog("Fragment varying varying %s does not match any vertex varying", input->name.c_str());
 
             return false;
         }
     }
 
+    Context *context = getContext();
+    bool sm3 = context->supportsShaderModel3();
+    std::string varyingSemantic = (sm3 ? "COLOR" : "TEXCOORD");
+
     mVertexHLSL += "struct VS_INPUT\n"
                    "{\n";
 
     int semanticIndex = 0;
     for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++)
     {
         switch (attribute->type)
         {
@@ -1223,22 +1229,27 @@ bool Program::linkVaryings()
                    "struct VS_OUTPUT\n"
                    "{\n"
                    "    float4 gl_Position : POSITION;\n";
 
     for (int r = 0; r < registers; r++)
     {
         int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
 
-        mVertexHLSL += "    float" + str(registerSize) + " v" + str(r) + " : TEXCOORD" + str(r) + ";\n";
+        mVertexHLSL += "    float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
     }
 
     if (mFragmentShader->mUsesFragCoord)
     {
-        mVertexHLSL += "    float4 gl_FragCoord : TEXCOORD" + str(registers) + ";\n";
+        mVertexHLSL += "    float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+    }
+
+    if (mVertexShader->mUsesPointSize && sm3)
+    {
+        mVertexHLSL += "    float gl_PointSize : PSIZE;\n";
     }
 
     mVertexHLSL += "};\n"
                    "\n"
                    "VS_OUTPUT main(VS_INPUT input)\n"
                    "{\n";
 
     for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++)
@@ -1257,16 +1268,21 @@ bool Program::linkVaryings()
                    "    gl_main();\n"
                    "\n"
                    "    VS_OUTPUT output;\n"
                    "    output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n"
                    "    output.gl_Position.y = -(gl_Position.y - dx_HalfPixelSize.y * gl_Position.w);\n"
                    "    output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
                    "    output.gl_Position.w = gl_Position.w;\n";
 
+    if (mVertexShader->mUsesPointSize && sm3)
+    {
+        mVertexHLSL += "    output.gl_PointSize = clamp(gl_PointSize, 1.0, " + str((int)ALIASED_POINT_SIZE_RANGE_MAX_SM3) + ");\n";
+    }
+
     if (mFragmentShader->mUsesFragCoord)
     {
         mVertexHLSL += "    output.gl_FragCoord = gl_Position;\n";
     }
 
     for (VaryingList::iterator varying = mVertexShader->varyings.begin(); varying != mVertexShader->varyings.end(); varying++)
     {
         if (varying->reg >= 0)
@@ -1340,28 +1356,33 @@ bool Program::linkVaryings()
         if (varying->reg >= 0)
         {
             for (int i = 0; i < varying->size; i++)
             {
                 int rows = VariableRowCount(varying->type);
                 for (int j = 0; j < rows; j++)
                 {
                     std::string n = str(varying->reg + i * rows + j);
-                    mPixelHLSL += "    float4 v" + n + " : TEXCOORD" + n + ";\n";
+                    mPixelHLSL += "    float4 v" + n + " : " + varyingSemantic + n + ";\n";
                 }
             }
         }
         else UNREACHABLE();
     }
 
     if (mFragmentShader->mUsesFragCoord)
     {
-        mPixelHLSL += "    float4 gl_FragCoord : TEXCOORD" + str(registers) + ";\n";
+        mPixelHLSL += "    float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
     }
-        
+
+    if (mFragmentShader->mUsesPointCoord && sm3)
+    {
+        mPixelHLSL += "    float2 gl_PointCoord : TEXCOORD0;\n";
+    }
+
     if (mFragmentShader->mUsesFrontFacing)
     {
         mPixelHLSL += "    float vFace : VFACE;\n";
     }
 
     mPixelHLSL += "};\n"
                   "\n"
                   "struct PS_OUTPUT\n"
@@ -1370,22 +1391,27 @@ bool Program::linkVaryings()
                   "};\n"
                   "\n"
                   "PS_OUTPUT main(PS_INPUT input)\n"
                   "{\n";
 
     if (mFragmentShader->mUsesFragCoord)
     {
         mPixelHLSL += "    float rhw = 1.0 / input.gl_FragCoord.w;\n"
-                      "    gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Window.x + dx_Window.z;\n"
-                      "    gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Window.y + dx_Window.w;\n"
+                      "    gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Viewport.x + dx_Viewport.z;\n"
+                      "    gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Viewport.y + dx_Viewport.w;\n"
                       "    gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
                       "    gl_FragCoord.w = rhw;\n";
     }
 
+    if (mFragmentShader->mUsesPointCoord && sm3)
+    {
+        mPixelHLSL += "    gl_PointCoord = float2(input.gl_PointCoord.x, 1.0 - input.gl_PointCoord.y);\n";
+    }
+
     if (mFragmentShader->mUsesFrontFacing)
     {
         mPixelHLSL += "    gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n";
     }
 
     for (VaryingList::iterator varying = mFragmentShader->varyings.begin(); varying != mFragmentShader->varyings.end(); varying++)
     {
         if (varying->reg >= 0)
@@ -1442,28 +1468,28 @@ void Program::link()
         return;
     }
 
     if (!mVertexShader || !mVertexShader->isCompiled())
     {
         return;
     }
 
-    Context *context = getContext();
-    const char *vertexProfile = context->getVertexShaderProfile();
-    const char *pixelProfile = context->getPixelShaderProfile();
-
     mPixelHLSL = mFragmentShader->getHLSL();
     mVertexHLSL = mVertexShader->getHLSL();
 
     if (!linkVaryings())
     {
         return;
     }
 
+    Context *context = getContext();
+    const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0";
+    const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0";
+
     ID3DXBuffer *vertexBinary = compileToBinary(mVertexHLSL.c_str(), vertexProfile, &mConstantTableVS);
     ID3DXBuffer *pixelBinary = compileToBinary(mPixelHLSL.c_str(), pixelProfile, &mConstantTablePS);
 
     if (vertexBinary && pixelBinary)
     {
         IDirect3DDevice9 *device = getDevice();
         HRESULT vertexResult = device->CreateVertexShader((DWORD*)vertexBinary->GetBufferPointer(), &mVertexExecutable);
         HRESULT pixelResult = device->CreatePixelShader((DWORD*)pixelBinary->GetBufferPointer(), &mPixelExecutable);
@@ -1498,17 +1524,17 @@ void Program::link()
             }
 
             // these uniforms are searched as already-decorated because gl_ and dx_
             // are reserved prefixes, and do not receive additional decoration
             mDepthRangeNearLocation = getUniformLocation("gl_DepthRange.near", true);
             mDepthRangeFarLocation = getUniformLocation("gl_DepthRange.far", true);
             mDepthRangeDiffLocation = getUniformLocation("gl_DepthRange.diff", true);
             mDxDepthLocation = getUniformLocation("dx_Depth", true);
-            mDxWindowLocation = getUniformLocation("dx_Window", true);
+            mDxViewportLocation = getUniformLocation("dx_Viewport", true);
             mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize", true);
             mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW", true);
             mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines", true);
 
             mLinked = true;   // Success
         }
     }
 }
@@ -2350,23 +2376,23 @@ void Program::resetInfoLog()
 
 // Returns the program object to an unlinked state, after detaching a shader, before re-linking, or at destruction
 void Program::unlink(bool destroy)
 {
     if (destroy)   // Object being destructed
     {
         if (mFragmentShader)
         {
-            mFragmentShader->detach();
+            mFragmentShader->release();
             mFragmentShader = NULL;
         }
 
         if (mVertexShader)
         {
-            mVertexShader->detach();
+            mVertexShader->release();
             mVertexShader = NULL;
         }
     }
 
     if (mPixelExecutable)
     {
         mPixelExecutable->Release();
         mPixelExecutable = NULL;
@@ -2407,17 +2433,17 @@ void Program::unlink(bool destroy)
         delete mUniforms.back();
         mUniforms.pop_back();
     }
 
     mDepthRangeDiffLocation = -1;
     mDepthRangeNearLocation = -1;
     mDepthRangeFarLocation = -1;
     mDxDepthLocation = -1;
-    mDxWindowLocation = -1;
+    mDxViewportLocation = -1;
     mDxHalfPixelSizeLocation = -1;
     mDxFrontCCWLocation = -1;
     mDxPointsOrLinesLocation = -1;
 
     mUniformIndex.clear();
 
     mPixelHLSL.clear();
     mVertexHLSL.clear();
@@ -2433,16 +2459,36 @@ bool Program::isLinked()
     return mLinked;
 }
 
 bool Program::isValidated() const 
 {
     return mValidated;
 }
 
+void Program::release()
+{
+    mRefCount--;
+
+    if (mRefCount == 0 && mDeleteStatus)
+    {
+        mResourceManager->deleteProgram(mHandle);
+    }
+}
+
+void Program::addRef()
+{
+    mRefCount++;
+}
+
+unsigned int Program::getRefCount() const
+{
+    return mRefCount;
+}
+
 unsigned int Program::getSerial() const
 {
     return mSerial;
 }
 
 unsigned int Program::issueSerial()
 {
     return mCurrentSerial++;
@@ -2732,19 +2778,19 @@ GLint Program::getDepthRangeFarLocation(
     return mDepthRangeFarLocation;
 }
 
 GLint Program::getDxDepthLocation() const
 {
     return mDxDepthLocation;
 }
 
-GLint Program::getDxWindowLocation() const
+GLint Program::getDxViewportLocation() const
 {
-    return mDxWindowLocation;
+    return mDxViewportLocation;
 }
 
 GLint Program::getDxHalfPixelSizeLocation() const
 {
     return mDxHalfPixelSizeLocation;
 }
 
 GLint Program::getDxFrontCCWLocation() const
--- a/gfx/angle/src/libGLESv2/Program.h
+++ b/gfx/angle/src/libGLESv2/Program.h
@@ -15,16 +15,17 @@
 #include <vector>
 #include <set>
 
 #include "libGLESv2/Shader.h"
 #include "libGLESv2/Context.h"
 
 namespace gl
 {
+class ResourceManager;
 class FragmentShader;
 class VertexShader;
 
 // Helper struct representing a single shader uniform
 struct Uniform
 {
     Uniform(GLenum type, const std::string &name, unsigned int arraySize);
 
@@ -50,17 +51,17 @@ struct UniformLocation
     std::string name;
     unsigned int element;
     unsigned int index;
 };
 
 class Program
 {
   public:
-    Program();
+    Program(ResourceManager *manager, GLuint handle);
 
     ~Program();
 
     bool attachShader(Shader *shader);
     bool detachShader(Shader *shader);
     int getAttachedShadersCount() const;
 
     IDirect3DPixelShader9 *getPixelShader();
@@ -92,17 +93,17 @@ class Program
 
     bool getUniformfv(GLint location, GLfloat *params);
     bool getUniformiv(GLint location, GLint *params);
 
     GLint getDepthRangeDiffLocation() const;
     GLint getDepthRangeNearLocation() const;
     GLint getDepthRangeFarLocation() const;
     GLint getDxDepthLocation() const;
-    GLint getDxWindowLocation() const;
+    GLint getDxViewportLocation() const;
     GLint getDxHalfPixelSizeLocation() const;
     GLint getDxFrontCCWLocation() const;
     GLint getDxPointsOrLinesLocation() const;
 
     void dirtyAllUniforms();
     void applyUniforms();
 
     void link();
@@ -114,16 +115,19 @@ class Program
     void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
     GLint getActiveAttributeCount();
     GLint getActiveAttributeMaxLength();
 
     void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
     GLint getActiveUniformCount();
     GLint getActiveUniformMaxLength();
 
+    void addRef();
+    void release();
+    unsigned int getRefCount() const;
     void flagForDeletion();
     bool isFlaggedForDeletion() const;
 
     void validate();
     bool validateSamplers() const;
     bool isValidated() const;
 
     unsigned int getSerial() const;
@@ -199,25 +203,30 @@ class Program
     UniformArray mUniforms;
     typedef std::vector<UniformLocation> UniformIndex;
     UniformIndex mUniformIndex;
 
     GLint mDepthRangeDiffLocation;
     GLint mDepthRangeNearLocation;
     GLint mDepthRangeFarLocation;
     GLint mDxDepthLocation;
-    GLint mDxWindowLocation;
+    GLint mDxViewportLocation;
     GLint mDxHalfPixelSizeLocation;
     GLint mDxFrontCCWLocation;
     GLint mDxPointsOrLinesLocation;
 
     bool mLinked;
     bool mDeleteStatus;   // Flag to indicate that the program can be deleted when no longer in use
     char *mInfoLog;
     bool mValidated;
 
+    unsigned int mRefCount;
+
     unsigned int mSerial;
 
     static unsigned int mCurrentSerial;
+
+    ResourceManager *mResourceManager;
+    const GLuint mHandle;
 };
 }
 
 #endif   // LIBGLESV2_PROGRAM_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/RefCountObject.cpp
@@ -0,0 +1,51 @@
+//
+// 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.
+//
+
+// RefCountObject.cpp: Defines the gl::RefCountObject base class that provides
+// lifecycle support for GL objects using the traditional BindObject scheme, but
+// that need to be reference counted for correct cross-context deletion.
+// (Concretely, textures, buffers and renderbuffers.)
+
+#include "RefCountObject.h"
+
+namespace gl
+{
+
+RefCountObject::RefCountObject(GLuint id)
+{
+    mId = id;
+    mRefCount = 0;
+}
+
+RefCountObject::~RefCountObject()
+{
+}
+
+void RefCountObject::addRef() const
+{
+    mRefCount++;
+}
+
+void RefCountObject::release() const
+{
+    ASSERT(mRefCount > 0);
+
+    if (--mRefCount == 0)
+    {
+        delete this;
+    }
+}
+
+void RefCountObjectBindingPointer::set(RefCountObject *newObject)
+{
+    // addRef first in case newObject == mObject and this is the last reference to it.
+    if (newObject != NULL) newObject->addRef();
+    if (mObject != NULL) mObject->release();
+
+    mObject = newObject;
+}
+
+}
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/RefCountObject.h
@@ -0,0 +1,70 @@
+//
+// 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.
+//
+
+// RefCountObject.h: Defines the gl::RefCountObject base class that provides
+// lifecycle support for GL objects using the traditional BindObject scheme, but
+// that need to be reference counted for correct cross-context deletion.
+// (Concretely, textures, buffers and renderbuffers.)
+
+#ifndef LIBGLESV2_REFCOUNTOBJECT_H_
+#define LIBGLESV2_REFCOUNTOBJECT_H_
+
+#include <cstddef>
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+
+#include "common/debug.h"
+
+namespace gl
+{
+
+class RefCountObject
+{
+  public:
+    explicit RefCountObject(GLuint id);
+    virtual ~RefCountObject();
+
+    virtual void addRef() const;
+    virtual void release() const;
+
+    GLuint id() const { return mId; }
+    
+  private:
+    GLuint mId;
+
+    mutable std::size_t mRefCount;
+};
+
+class RefCountObjectBindingPointer
+{
+  protected:
+    RefCountObjectBindingPointer() : mObject(NULL) { }
+    ~RefCountObjectBindingPointer() { ASSERT(mObject == NULL); } // Objects have to be released before the resource manager is destroyed, so they must be explicitly cleaned up.
+
+    void set(RefCountObject *newObject);
+    RefCountObject *get() const { return mObject; }
+
+  public:
+    GLuint id() const { return (mObject != NULL) ? mObject->id() : 0; }
+    bool operator ! () const { return (get() == NULL); }
+
+  private:
+    RefCountObject *mObject;
+};
+
+template <class ObjectType>
+class BindingPointer : public RefCountObjectBindingPointer
+{
+  public:
+    void set(ObjectType *newObject) { RefCountObjectBindingPointer::set(newObject); }
+    ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); }
+    ObjectType *operator -> () const { return get(); }
+};
+
+}
+
+#endif   // LIBGLESV2_REFCOUNTOBJECT_H_
--- a/gfx/angle/src/libGLESv2/Renderbuffer.cpp
+++ b/gfx/angle/src/libGLESv2/Renderbuffer.cpp
@@ -10,83 +10,143 @@
 
 #include "libGLESv2/Renderbuffer.h"
 
 #include "libGLESv2/main.h"
 #include "libGLESv2/utilities.h"
 
 namespace gl
 {
-unsigned int Renderbuffer::mCurrentSerial = 1;
+unsigned int RenderbufferStorage::mCurrentSerial = 1;
 
-Renderbuffer::Renderbuffer()
+Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id)
 {
-    mWidth = 0;
-    mHeight = 0;
-    mFormat = GL_RGBA4; // default format, needs to be one of the expected renderbuffer formats
-    mSerial = issueSerial();
+    ASSERT(storage != NULL);
+    mStorage = storage;
 }
 
 Renderbuffer::~Renderbuffer()
 {
+    delete mStorage;
+}
+
+bool Renderbuffer::isColorbuffer() const
+{
+    return mStorage->isColorbuffer();
+}
+
+bool Renderbuffer::isDepthbuffer() const
+{
+    return mStorage->isDepthbuffer();
+}
+
+bool Renderbuffer::isStencilbuffer() const
+{
+    return mStorage->isStencilbuffer();
+}
+
+IDirect3DSurface9 *Renderbuffer::getRenderTarget()
+{
+    return mStorage->getRenderTarget();
+}
+
+IDirect3DSurface9 *Renderbuffer::getDepthStencil()
+{
+    return mStorage->getDepthStencil();
+}
+
+int Renderbuffer::getWidth() const
+{
+    return mStorage->getWidth();
 }
 
-bool Renderbuffer::isColorbuffer()
+int Renderbuffer::getHeight() const
+{
+    return mStorage->getHeight();
+}
+
+GLenum Renderbuffer::getFormat() const
 {
-    return false;
+    return mStorage->getFormat();
+}
+
+unsigned int Renderbuffer::getSerial() const
+{
+    return mStorage->getSerial();
 }
 
-bool Renderbuffer::isDepthbuffer()
+void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
+{
+    ASSERT(newStorage != NULL);
+
+    delete mStorage;
+    mStorage = newStorage;
+}
+
+RenderbufferStorage::RenderbufferStorage()
+{
+    mSerial = issueSerial();
+}
+
+RenderbufferStorage::~RenderbufferStorage()
+{
+}
+
+bool RenderbufferStorage::isColorbuffer() const
 {
     return false;
 }
 
-bool Renderbuffer::isStencilbuffer()
+bool RenderbufferStorage::isDepthbuffer() const
 {
     return false;
 }
 
-IDirect3DSurface9 *Renderbuffer::getRenderTarget()
+bool RenderbufferStorage::isStencilbuffer() const
+{
+    return false;
+}
+
+IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
 {
     return NULL;
 }
 
-IDirect3DSurface9 *Renderbuffer::getDepthStencil()
+IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
 {
     return NULL;
 }
 
-int Renderbuffer::getWidth()
+int RenderbufferStorage::getWidth() const
 {
     return mWidth;
 }
 
-int Renderbuffer::getHeight()
+int RenderbufferStorage::getHeight() const
 {
     return mHeight;
 }
 
-void Renderbuffer::setSize(int width, int height)
+void RenderbufferStorage::setSize(int width, int height)
 {
     mWidth = width;
     mHeight = height;
 }
 
-
-GLenum Renderbuffer::getFormat()
+GLenum RenderbufferStorage::getFormat() const
 {
     return mFormat;
 }
 
-unsigned int Renderbuffer::getSerial() const
+unsigned int RenderbufferStorage::getSerial() const
 {
     return mSerial;
 }
 
-unsigned int Renderbuffer::issueSerial()
+unsigned int RenderbufferStorage::issueSerial()
 {
     return mCurrentSerial++;
 }
 
 Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget)
 {
     if (renderTarget)
     {
@@ -100,28 +160,32 @@ Colorbuffer::Colorbuffer(IDirect3DSurfac
 
 }
 
 Colorbuffer::Colorbuffer(int width, int height, GLenum format)
 {
     IDirect3DDevice9 *device = getDevice();
 
     mRenderTarget = NULL;
-    HRESULT result = device->CreateRenderTarget(width, height, es2dx::ConvertRenderbufferFormat(format), 
-                                                D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
 
-    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+    if (width > 0 && height > 0)
     {
-        error(GL_OUT_OF_MEMORY);
+        HRESULT result = device->CreateRenderTarget(width, height, es2dx::ConvertRenderbufferFormat(format), 
+                                                    D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
 
-        return;
+        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+        {
+            error(GL_OUT_OF_MEMORY);
+
+            return;
+        }
+
+        ASSERT(SUCCEEDED(result));
     }
 
-    ASSERT(SUCCEEDED(result));
-
     if (mRenderTarget)
     {
         setSize(width, height);
         mFormat = format;
     }
     else
     {
         setSize(0, 0);
@@ -132,61 +196,61 @@ Colorbuffer::Colorbuffer(int width, int 
 Colorbuffer::~Colorbuffer()
 {
     if (mRenderTarget)
     {
         mRenderTarget->Release();
     }
 }
 
-bool Colorbuffer::isColorbuffer()
+bool Colorbuffer::isColorbuffer() const
 {
     return true;
 }
 
-GLuint Colorbuffer::getRedSize()
+GLuint Colorbuffer::getRedSize() const
 {
     if (mRenderTarget)
     {
         D3DSURFACE_DESC description;
         mRenderTarget->GetDesc(&description);
 
         return es2dx::GetRedSize(description.Format);
     }
 
     return 0;
 }
 
-GLuint Colorbuffer::getGreenSize()
+GLuint Colorbuffer::getGreenSize() const
 {
     if (mRenderTarget)
     {
         D3DSURFACE_DESC description;
         mRenderTarget->GetDesc(&description);
 
         return es2dx::GetGreenSize(description.Format);
     }
 
     return 0;
 }
 
-GLuint Colorbuffer::getBlueSize()
+GLuint Colorbuffer::getBlueSize() const
 {
     if (mRenderTarget)
     {
         D3DSURFACE_DESC description;
         mRenderTarget->GetDesc(&description);
 
         return es2dx::GetBlueSize(description.Format);
     }
 
     return 0;
 }
 
-GLuint Colorbuffer::getAlphaSize()
+GLuint Colorbuffer::getAlphaSize() const
 {
     if (mRenderTarget)
     {
         D3DSURFACE_DESC description;
         mRenderTarget->GetDesc(&description);
 
         return es2dx::GetAlphaSize(description.Format);
     }
@@ -194,33 +258,31 @@ GLuint Colorbuffer::getAlphaSize()
     return 0;
 }
 
 IDirect3DSurface9 *Colorbuffer::getRenderTarget()
 {
     return mRenderTarget;
 }
 
-Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
+DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
 {
     if (depthStencil)
     {
         depthStencil->AddRef();
 
         D3DSURFACE_DESC description;
         depthStencil->GetDesc(&description);
 
         setSize(description.Width, description.Height);
-        mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
-                                        // will expect one of the valid renderbuffer formats for use in 
-                                        // glRenderbufferStorage
+        mFormat = GL_DEPTH24_STENCIL8_OES; 
     }
 }
 
-Depthbuffer::Depthbuffer(int width, int height)
+DepthStencilbuffer::DepthStencilbuffer(int width, int height)
 {
     IDirect3DDevice9 *device = getDevice();
 
     mDepthStencil = NULL;
     HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
 
     if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
     {
@@ -229,127 +291,138 @@ Depthbuffer::Depthbuffer(int width, int 
         return;
     }
 
     ASSERT(SUCCEEDED(result));
 
     if (mDepthStencil)
     {
         setSize(width, height);
-        mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
-                                        // will expect one of the valid renderbuffer formats for use in 
-                                        // glRenderbufferStorage
+        mFormat = GL_DEPTH24_STENCIL8_OES;  
     }
     else
     {
         setSize(0, 0);
         mFormat = GL_RGBA4; //default format
     }
 }
 
-Depthbuffer::~Depthbuffer()
+DepthStencilbuffer::~DepthStencilbuffer()
 {
     if (mDepthStencil)
     {
         mDepthStencil->Release();
     }
 }
 
-bool Depthbuffer::isDepthbuffer()
+bool DepthStencilbuffer::isDepthbuffer() const
 {
     return true;
 }
 
-GLuint Depthbuffer::getDepthSize()
+bool DepthStencilbuffer::isStencilbuffer() const
+{
+    return true;
+}
+
+GLuint DepthStencilbuffer::getDepthSize() const
 {
     if (mDepthStencil)
     {
         D3DSURFACE_DESC description;
         mDepthStencil->GetDesc(&description);
 
         return es2dx::GetDepthSize(description.Format);
     }
 
     return 0;
 }
 
-IDirect3DSurface9 *Depthbuffer::getDepthStencil()
-{
-    return mDepthStencil;
-}
-
-Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
-{
-    if (depthStencil)
-    {
-        depthStencil->AddRef();
-
-        D3DSURFACE_DESC description;
-        depthStencil->GetDesc(&description);
-
-        setSize(description.Width, description.Height);
-        mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
-                                     // will expect one of the valid renderbuffer formats for use in 
-                                     // glRenderbufferStorage
-    }
-}
-
-Stencilbuffer::Stencilbuffer(int width, int height)
-{
-    IDirect3DDevice9 *device = getDevice();
-
-    mDepthStencil = NULL;
-    HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
-
-    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
-    {
-        error(GL_OUT_OF_MEMORY);
-
-        return;
-    }
-
-    ASSERT(SUCCEEDED(result));
-
-    if (mDepthStencil)
-    {
-        setSize(width, height);
-        mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
-                                     // will expect one of the valid renderbuffer formats for use in 
-                                     // glRenderbufferStorage
-    }
-    else
-    {
-        setSize(0, 0);
-        mFormat = GL_RGBA4; //default format
-    }
-}
-
-Stencilbuffer::~Stencilbuffer()
-{
-    if (mDepthStencil)
-    {
-        mDepthStencil->Release();
-    }
-}
-
-GLuint Stencilbuffer::getStencilSize()
+GLuint DepthStencilbuffer::getStencilSize() const
 {
     if (mDepthStencil)
     {
         D3DSURFACE_DESC description;
         mDepthStencil->GetDesc(&description);
 
         return es2dx::GetStencilSize(description.Format);
     }
 
     return 0;
 }
 
-bool Stencilbuffer::isStencilbuffer()
+IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
+{
+    return mDepthStencil;
+}
+
+Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
+{
+    if (depthStencil)
+    {
+        mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
+                                        // will expect one of the valid renderbuffer formats for use in 
+                                        // glRenderbufferStorage
+    }
+}
+
+Depthbuffer::Depthbuffer(int width, int height) : DepthStencilbuffer(width, height)
+{
+    if (getDepthStencil())
+    {
+        mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
+                                        // will expect one of the valid renderbuffer formats for use in 
+                                        // glRenderbufferStorage
+    }
+}
+
+Depthbuffer::~Depthbuffer()
+{
+}
+
+bool Depthbuffer::isDepthbuffer() const
 {
     return true;
 }
 
-IDirect3DSurface9 *Stencilbuffer::getDepthStencil()
+bool Depthbuffer::isStencilbuffer() const
+{
+    return false;
+}
+
+Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
+{
+    if (depthStencil)
+    {
+        mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
+                                     // will expect one of the valid renderbuffer formats for use in 
+                                     // glRenderbufferStorage
+    }
+    else
+    {
+        mFormat = GL_RGBA4; //default format
+    }
+}
+
+Stencilbuffer::Stencilbuffer(int width, int height) : DepthStencilbuffer(width, height)
 {
-    return mDepthStencil;
+    if (getDepthStencil())
+    {
+        mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
+                                     // will expect one of the valid renderbuffer formats for use in 
+                                     // glRenderbufferStorage
+    }
+}
+
+Stencilbuffer::~Stencilbuffer()
+{
+}
+
+bool Stencilbuffer::isDepthbuffer() const
+{
+    return false;
+}
+
+bool Stencilbuffer::isStencilbuffer() const
+{
+    return true;
 }
 }
--- a/gfx/angle/src/libGLESv2/Renderbuffer.h
+++ b/gfx/angle/src/libGLESv2/Renderbuffer.h
@@ -1,120 +1,170 @@
 //
 // 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.
 //
 
-// Renderbuffer.h: Defines the virtual gl::Renderbuffer class and its derived
-// classes Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
+// Renderbuffer.h: Defines the wrapper class gl::Renderbuffer, as well as the
+// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
+// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
 
 #ifndef LIBGLESV2_RENDERBUFFER_H_
 #define LIBGLESV2_RENDERBUFFER_H_
 
 #define GL_APICALL
 #include <GLES2/gl2.h>
 #include <d3d9.h>
 
 #include "common/angleutils.h"
+#include "libGLESv2/RefCountObject.h"
 
 namespace gl
 {
-class Renderbuffer
+
+// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
+// is called. The specific concrete type depends on whether the internal format is
+// colour depth, stencil or packed depth/stencil.
+class RenderbufferStorage
 {
   public:
-    Renderbuffer();
+    RenderbufferStorage();
 
-    virtual ~Renderbuffer();
+    virtual ~RenderbufferStorage() = 0;
 
-    virtual bool isColorbuffer();
-    virtual bool isDepthbuffer();
-    virtual bool isStencilbuffer();
+    virtual bool isColorbuffer() const;
+    virtual bool isDepthbuffer() const;
+    virtual bool isStencilbuffer() const;
 
     virtual IDirect3DSurface9 *getRenderTarget();
     virtual IDirect3DSurface9 *getDepthStencil();
 
-    virtual int getWidth();
-    virtual int getHeight();
-    GLenum getFormat();
+    virtual int getWidth() const;
+    virtual int getHeight() const;
+    GLenum getFormat() const;
     unsigned int getSerial() const;
 
     static unsigned int issueSerial();
 
   protected:
     void setSize(int width, int height);
     GLenum mFormat;
     unsigned int mSerial;
 
   private:
-    DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
+    DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
 
     static unsigned int mCurrentSerial;
 
     int mWidth;
     int mHeight;
 };
 
-class Colorbuffer : public Renderbuffer
+// Renderbuffer implements the GL renderbuffer object.
+// It's only a wrapper for a RenderbufferStorage, but the internal object
+// can change whenever glRenderbufferStorage is called.
+class Renderbuffer : public RefCountObject
+{
+  public:
+    Renderbuffer(GLuint id, RenderbufferStorage *storage);
+
+    ~Renderbuffer();
+
+    bool isColorbuffer() const;
+    bool isDepthbuffer() const;
+    bool isStencilbuffer() const;
+
+    IDirect3DSurface9 *getRenderTarget();
+    IDirect3DSurface9 *getDepthStencil();
+
+    int getWidth() const;
+    int getHeight() const;
+    GLenum getFormat() const;
+    unsigned int getSerial() const;
+
+    void setStorage(RenderbufferStorage *newStorage);
+    RenderbufferStorage *getStorage() { return mStorage; }
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
+
+    RenderbufferStorage *mStorage;
+};
+
+class Colorbuffer : public RenderbufferStorage
 {
   public:
     explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
     Colorbuffer(int width, int height, GLenum format);
 
     ~Colorbuffer();
 
-    bool isColorbuffer();
+    bool isColorbuffer() const;
 
-    GLuint getRedSize();
-    GLuint getGreenSize();
-    GLuint getBlueSize();
-    GLuint getAlphaSize();
+    GLuint getRedSize() const;
+    GLuint getGreenSize() const;
+    GLuint getBlueSize() const;
+    GLuint getAlphaSize() const;
 
     IDirect3DSurface9 *getRenderTarget();
 
   protected:
     IDirect3DSurface9 *mRenderTarget;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
 };
 
-class Depthbuffer : public Renderbuffer
+class DepthStencilbuffer : public RenderbufferStorage
+{
+  public:
+    explicit DepthStencilbuffer(IDirect3DSurface9 *depthStencil);
+    DepthStencilbuffer(int width, int height);
+
+    ~DepthStencilbuffer();
+
+    virtual bool isDepthbuffer() const;
+    virtual bool isStencilbuffer() const;
+
+    GLuint getDepthSize() const;
+    GLuint getStencilSize() const;
+
+    IDirect3DSurface9 *getDepthStencil();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer);
+    IDirect3DSurface9 *mDepthStencil;
+};
+
+class Depthbuffer : public DepthStencilbuffer
 {
   public:
     explicit Depthbuffer(IDirect3DSurface9 *depthStencil);
     Depthbuffer(int width, int height);
 
     ~Depthbuffer();
 
-    bool isDepthbuffer();
-
-    GLuint getDepthSize();
-
-    IDirect3DSurface9 *getDepthStencil();
+    bool isDepthbuffer() const;
+    bool isStencilbuffer() const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
-    IDirect3DSurface9 *mDepthStencil;
 };
 
-class Stencilbuffer : public Renderbuffer
+class Stencilbuffer : public DepthStencilbuffer
 {
   public:
     explicit Stencilbuffer(IDirect3DSurface9 *depthStencil);
     Stencilbuffer(int width, int height);
 
     ~Stencilbuffer();
 
-    bool isStencilbuffer();
-
-    GLuint getStencilSize();
-
-    IDirect3DSurface9 *getDepthStencil();
+    bool isDepthbuffer() const;
+    bool isStencilbuffer() const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Stencilbuffer);
-    IDirect3DSurface9 *mDepthStencil;
 };
 }
 
 #endif   // LIBGLESV2_RENDERBUFFER_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/ResourceManager.cpp
@@ -0,0 +1,340 @@
+//
+// 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.
+//
+
+// ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and 
+// retrieves objects which may be shared by multiple Contexts.
+
+#include "libGLESv2/ResourceManager.h"
+
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/Program.h"
+#include "libGLESv2/RenderBuffer.h"
+#include "libGLESv2/Shader.h"
+#include "libGLESv2/Texture.h"
+
+namespace gl
+{
+ResourceManager::ResourceManager()
+{
+    mRefCount = 1;
+}
+
+ResourceManager::~ResourceManager()
+{
+    while (!mBufferMap.empty())
+    {
+        deleteBuffer(mBufferMap.begin()->first);
+    }
+
+    while (!mProgramMap.empty())
+    {
+        deleteProgram(mProgramMap.begin()->first);
+    }
+
+    while (!mShaderMap.empty())
+    {
+        deleteShader(mShaderMap.begin()->first);
+    }
+
+    while (!mRenderbufferMap.empty())
+    {
+        deleteRenderbuffer(mRenderbufferMap.begin()->first);
+    }
+
+    while (!mTextureMap.empty())
+    {
+        deleteTexture(mTextureMap.begin()->first);
+    }
+}
+
+void ResourceManager::addRef()
+{
+    mRefCount++;
+}
+
+void ResourceManager::release()
+{
+    if (--mRefCount == 0)
+    {
+        delete this;
+    }
+}
+
+// Returns an unused buffer name
+GLuint ResourceManager::createBuffer()
+{
+    unsigned int handle = 1;
+
+    while (mBufferMap.find(handle) != mBufferMap.end())
+    {
+        handle++;
+    }
+
+    mBufferMap[handle] = NULL;
+
+    return handle;
+}
+
+// Returns an unused shader/program name
+GLuint ResourceManager::createShader(GLenum type)
+{
+    unsigned int handle = 1;
+
+    while (mShaderMap.find(handle) != mShaderMap.end() || mProgramMap.find(handle) != mProgramMap.end())   // Shared name space
+    {
+        handle++;
+    }
+
+    if (type == GL_VERTEX_SHADER)
+    {
+        mShaderMap[handle] = new VertexShader(this, handle);
+    }
+    else if (type == GL_FRAGMENT_SHADER)
+    {
+        mShaderMap[handle] = new FragmentShader(this, handle);
+    }
+    else UNREACHABLE();
+
+    return handle;
+}
+
+// Returns an unused program/shader name
+GLuint ResourceManager::createProgram()
+{
+    unsigned int handle = 1;
+
+    while (mProgramMap.find(handle) != mProgramMap.end() || mShaderMap.find(handle) != mShaderMap.end())   // Shared name space
+    {
+        handle++;
+    }
+
+    mProgramMap[handle] = new Program(this, handle);
+
+    return handle;
+}
+
+// Returns an unused texture name
+GLuint ResourceManager::createTexture()
+{
+    unsigned int handle = 1;
+
+    while (mTextureMap.find(handle) != mTextureMap.end())
+    {
+        handle++;
+    }
+
+    mTextureMap[handle] = NULL;
+
+    return handle;
+}
+
+// Returns an unused renderbuffer name
+GLuint ResourceManager::createRenderbuffer()
+{
+    unsigned int handle = 1;
+
+    while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
+    {
+        handle++;
+    }
+
+    mRenderbufferMap[handle] = NULL;
+
+    return handle;
+}
+
+void ResourceManager::deleteBuffer(GLuint buffer)
+{
+    BufferMap::iterator bufferObject = mBufferMap.find(buffer);
+
+    if (bufferObject != mBufferMap.end())
+    {
+        if (bufferObject->second) bufferObject->second->release();
+        mBufferMap.erase(bufferObject);
+    }
+}
+
+void ResourceManager::deleteShader(GLuint shader)
+{
+    ShaderMap::iterator shaderObject = mShaderMap.find(shader);
+
+    if (shaderObject != mShaderMap.end())
+    {
+        if (shaderObject->second->getRefCount() == 0)
+        {
+            delete shaderObject->second;
+            mShaderMap.erase(shaderObject);
+        }
+        else
+        {
+            shaderObject->second->flagForDeletion();
+        }
+    }
+}
+
+void ResourceManager::deleteProgram(GLuint program)
+{
+    ProgramMap::iterator programObject = mProgramMap.find(program);
+
+    if (programObject != mProgramMap.end())
+    {
+        if (programObject->second->getRefCount() == 0)
+        {
+            delete programObject->second;
+            mProgramMap.erase(programObject);
+        }
+        else
+        { 
+            programObject->second->flagForDeletion();
+        }
+    }
+}
+
+void ResourceManager::deleteTexture(GLuint texture)
+{
+    TextureMap::iterator textureObject = mTextureMap.find(texture);
+
+    if (textureObject != mTextureMap.end())
+    {
+        if (textureObject->second) textureObject->second->release();
+        mTextureMap.erase(textureObject);
+    }
+}
+
+void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
+{
+    RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
+
+    if (renderbufferObject != mRenderbufferMap.end())
+    {
+        if (renderbufferObject->second) renderbufferObject->second->release();
+        mRenderbufferMap.erase(renderbufferObject);
+    }
+}
+
+Buffer *ResourceManager::getBuffer(unsigned int handle)
+{
+    BufferMap::iterator buffer = mBufferMap.find(handle);
+
+    if (buffer == mBufferMap.end())
+    {
+        return NULL;
+    }
+    else
+    {
+        return buffer->second;
+    }
+}
+
+Shader *ResourceManager::getShader(unsigned int handle)
+{
+    ShaderMap::iterator shader = mShaderMap.find(handle);
+
+    if (shader == mShaderMap.end())
+    {
+        return NULL;
+    }
+    else
+    {
+        return shader->second;
+    }
+}
+
+Texture *ResourceManager::getTexture(unsigned int handle)
+{
+    if (handle == 0) return NULL;
+
+    TextureMap::iterator texture = mTextureMap.find(handle);
+
+    if (texture == mTextureMap.end())
+    {
+        return NULL;
+    }
+    else
+    {
+        return texture->second;
+    }
+}
+
+Program *ResourceManager::getProgram(unsigned int handle)
+{
+    ProgramMap::iterator program = mProgramMap.find(handle);
+
+    if (program == mProgramMap.end())
+    {
+        return NULL;
+    }
+    else
+    {
+        return program->second;
+    }
+}
+
+Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
+{
+    RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
+
+    if (renderbuffer == mRenderbufferMap.end())
+    {
+        return NULL;
+    }
+    else
+    {
+        return renderbuffer->second;
+    }
+}
+
+void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
+{
+    mRenderbufferMap[handle] = buffer;
+}
+
+void ResourceManager::checkBufferAllocation(unsigned int buffer)
+{
+    if (buffer != 0 && !getBuffer(buffer))
+    {
+        Buffer *bufferObject = new Buffer(buffer);
+        mBufferMap[buffer] = bufferObject;
+        bufferObject->addRef();
+    }
+}
+
+void ResourceManager::checkTextureAllocation(GLuint texture, SamplerType type)
+{
+    if (!getTexture(texture) && texture != 0)
+    {
+        Texture *textureObject;
+
+        if (type == SAMPLER_2D)
+        {
+            textureObject = new Texture2D(texture);
+        }
+        else if (type == SAMPLER_CUBE)
+        {
+            textureObject = new TextureCubeMap(texture);
+        }
+        else
+        {
+            UNREACHABLE();
+            return;
+        }
+
+        mTextureMap[texture] = textureObject;
+        textureObject->addRef();
+    }
+}
+
+void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
+{
+    if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
+    {
+        Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4));
+        mRenderbufferMap[renderbuffer] = renderbufferObject;
+        renderbufferObject->addRef();
+    }
+}
+
+}
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/ResourceManager.h
@@ -0,0 +1,92 @@
+//
+// 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.
+//
+
+// ResourceManager.h : Defines the ResourceManager class, which tracks objects
+// shared by multiple GL contexts.
+
+#ifndef LIBGLESV2_RESOURCEMANAGER_H_
+#define LIBGLESV2_RESOURCEMANAGER_H_
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+
+#include <map>
+
+#include "common/angleutils.h"
+
+namespace gl
+{
+class Buffer;
+class Shader;
+class Program;
+class Texture;
+class Renderbuffer;
+
+enum SamplerType
+{
+    SAMPLER_2D,
+    SAMPLER_CUBE,
+
+    SAMPLER_TYPE_COUNT
+};
+
+class ResourceManager
+{
+  public:
+    ResourceManager();
+    ~ResourceManager();
+
+    void addRef();
+    void release();
+
+    GLuint createBuffer();
+    GLuint createShader(GLenum type);
+    GLuint createProgram();
+    GLuint createTexture();
+    GLuint createRenderbuffer();
+
+    void deleteBuffer(GLuint buffer);
+    void deleteShader(GLuint shader);
+    void deleteProgram(GLuint program);
+    void deleteTexture(GLuint texture);
+    void deleteRenderbuffer(GLuint renderbuffer);
+
+    Buffer *getBuffer(GLuint handle);
+    Shader *getShader(GLuint handle);
+    Program *getProgram(GLuint handle);
+    Texture *getTexture(GLuint handle);
+    Renderbuffer *getRenderbuffer(GLuint handle);
+    
+    void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
+
+    void checkBufferAllocation(unsigned int buffer);
+    void checkTextureAllocation(GLuint texture, SamplerType type);
+    void checkRenderbufferAllocation(GLuint renderbuffer);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(ResourceManager);
+
+    std::size_t mRefCount;
+
+    typedef std::map<GLuint, Buffer*> BufferMap;
+    BufferMap mBufferMap;
+
+    typedef std::map<GLuint, Shader*> ShaderMap;
+    ShaderMap mShaderMap;
+
+    typedef std::map<GLuint, Program*> ProgramMap;
+    ProgramMap mProgramMap;
+
+    typedef std::map<GLuint, Texture*> TextureMap;
+    TextureMap mTextureMap;
+
+    typedef std::map<GLuint, Renderbuffer*> RenderbufferMap;
+    RenderbufferMap mRenderbufferMap;
+};
+
+}
+
+#endif // LIBGLESV2_RESOURCEMANAGER_H_
--- a/gfx/angle/src/libGLESv2/Shader.cpp
+++ b/gfx/angle/src/libGLESv2/Shader.cpp
@@ -16,35 +16,45 @@
 #include "libGLESv2/main.h"
 #include "libGLESv2/utilities.h"
 
 namespace gl
 {
 void *Shader::mFragmentCompiler = NULL;
 void *Shader::mVertexCompiler = NULL;
 
-Shader::Shader(Context *context, GLuint handle) : mHandle(handle), mContext(context)
+Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
 {
     mSource = NULL;
     mHlsl = NULL;
     mInfoLog = NULL;
 
     // Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
     if (!mFragmentCompiler)
     {
         int result = ShInitialize();
 
         if (result)
         {
-            mFragmentCompiler = ShConstructCompiler(EShLangFragment, EDebugOpObjectCode);
-            mVertexCompiler = ShConstructCompiler(EShLangVertex, EDebugOpObjectCode);
+            TBuiltInResource resources;
+            resources.maxVertexAttribs = MAX_VERTEX_ATTRIBS;
+            resources.maxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
+            resources.maxVaryingVectors = MAX_VARYING_VECTORS;
+            resources.maxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
+            resources.maxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
+            resources.maxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+            resources.maxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
+            resources.maxDrawBuffers = MAX_DRAW_BUFFERS;
+
+            mFragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecGLES2, &resources);
+            mVertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecGLES2, &resources);
         }
     }
 
-    mAttachCount = 0;
+    mRefCount = 0;
     mDeleteStatus = false;
 }
 
 Shader::~Shader()
 {
     delete[] mSource;
     delete[] mHlsl;
     delete[] mInfoLog;
@@ -172,34 +182,34 @@ bool Shader::isCompiled()
     return mHlsl != NULL;
 }
 
 const char *Shader::getHLSL()
 {
     return mHlsl;
 }
 
-void Shader::attach()
+void Shader::addRef()
 {
-    mAttachCount++;
+    mRefCount++;
 }
 
-void Shader::detach()
+void Shader::release()
 {
-    mAttachCount--;
+    mRefCount--;
 
-    if (mAttachCount == 0 && mDeleteStatus)
+    if (mRefCount == 0 && mDeleteStatus)
     {
-        mContext->deleteShader(mHandle);
+        mResourceManager->deleteShader(mHandle);
     }
 }
 
-bool Shader::isAttached() const
+unsigned int Shader::getRefCount() const
 {
-    return mAttachCount > 0;
+    return mRefCount;
 }
 
 bool Shader::isFlaggedForDeletion() const
 {
     return mDeleteStatus;
 }
 
 void Shader::flagForDeletion()
@@ -247,43 +257,34 @@ void Shader::parseVaryings()
 
             varyings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
 
             input = strstr(input, ";") + 2;
         }
 
         mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
         mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
+        mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
+        mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
     }
 }
 
 void Shader::compileToHLSL(void *compiler)
 {
     if (isCompiled() || !mSource)
     {
         return;
     }
 
     TRACE("\n%s", mSource);
 
     delete[] mInfoLog;
     mInfoLog = NULL;
 
-    TBuiltInResource resources;
-
-    resources.maxVertexAttribs = MAX_VERTEX_ATTRIBS;
-    resources.maxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
-    resources.maxVaryingVectors = MAX_VARYING_VECTORS;
-    resources.maxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
-    resources.maxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
-    resources.maxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
-    resources.maxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
-    resources.maxDrawBuffers = MAX_DRAW_BUFFERS;
-
-    int result = ShCompile(compiler, &mSource, 1, EShOptNone, &resources, EDebugOpObjectCode);
+    int result = ShCompile(compiler, &mSource, 1, EShOptNone, EDebugOpNone);
     const char *obj = ShGetObjectCode(compiler);
     const char *info = ShGetInfoLog(compiler);
 
     if (result)
     {
         mHlsl = new char[strlen(obj) + 1];
         strcpy(mHlsl, obj);
 
@@ -411,17 +412,17 @@ bool Shader::compareVarying(const Varyin
         break;
       case GL_FLOAT: return false;
       default: UNREACHABLE();
     }
 
     return false;
 }
 
-VertexShader::VertexShader(Context *context, GLuint handle) : Shader(context, handle)
+VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
 {
 }
 
 VertexShader::~VertexShader()
 {
 }
 
 GLenum VertexShader::getType()
@@ -475,17 +476,17 @@ void VertexShader::parseAttributes()
 
             mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
 
             input = strstr(input, ";") + 2;
         }
     }
 }
 
-FragmentShader::FragmentShader(Context *context, GLuint handle) : Shader(context, handle)
+FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
 {
 }
 
 FragmentShader::~FragmentShader()
 {
 }
 
 GLenum FragmentShader::getType()
--- a/gfx/angle/src/libGLESv2/Shader.h
+++ b/gfx/angle/src/libGLESv2/Shader.h
@@ -13,17 +13,17 @@
 #define LIBGLESV2_SHADER_H_
 
 #define GL_APICALL
 #include <GLES2/gl2.h>
 #include <d3dx9.h>
 #include <list>
 #include <vector>
 
-#include "libGLESv2/Context.h"
+#include "libGLESv2/ResourceManager.h"
 
 namespace gl
 {
 struct Varying
 {
     Varying(GLenum type, const std::string &name, int size, bool array)
         : type(type), name(name), size(size), array(array), reg(-1), col(-1)
     {
@@ -40,17 +40,17 @@ struct Varying
 
 typedef std::list<Varying> VaryingList;
 
 class Shader
 {
     friend Program;
 
   public:
-    Shader(Context *context, GLuint handle);
+    Shader(ResourceManager *manager, GLuint handle);
 
     virtual ~Shader();
 
     virtual GLenum getType() = 0;
     GLuint getHandle() const;
 
     void deleteSource();
     void setSource(GLsizei count, const char **string, const GLint *length);
@@ -58,48 +58,50 @@ class Shader
     void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
     int getSourceLength() const;
     void getSource(GLsizei bufSize, GLsizei *length, char *source);
 
     virtual void compile() = 0;
     bool isCompiled();
     const char *getHLSL();
 
-    void attach();
-    void detach();
-    bool isAttached() const;
+    void addRef();
+    void release();
+    unsigned int getRefCount() const;
     bool isFlaggedForDeletion() const;
     void flagForDeletion();
 
     static void releaseCompiler();
 
   protected:
     DISALLOW_COPY_AND_ASSIGN(Shader);
 
     void parseVaryings();
 
     void compileToHLSL(void *compiler);
 
     static GLenum parseType(const std::string &type);
     static bool compareVarying(const Varying &x, const Varying &y);
 
     const GLuint mHandle;
-    int mAttachCount;     // Number of program objects this shader is attached to
-    bool mDeleteStatus;   // Flag to indicate that the shader can be deleted when no longer in use
+    unsigned int mRefCount;     // Number of program objects this shader is attached to
+    bool mDeleteStatus;         // Flag to indicate that the shader can be deleted when no longer in use
 
     char *mSource;
     char *mHlsl;
     char *mInfoLog;
 
     VaryingList varyings;
 
     bool mUsesFragCoord;
     bool mUsesFrontFacing;
+    bool mUsesPointSize;
+    bool mUsesPointCoord;
 
-    Context *mContext;
+    ResourceManager *mResourceManager;
 
     static void *mFragmentCompiler;
     static void *mVertexCompiler;
 };
 
 struct Attribute
 {
     Attribute() : type(GL_NONE), name("")
@@ -116,17 +118,17 @@ struct Attribute
 
 typedef std::vector<Attribute> AttributeArray;
 
 class VertexShader : public Shader
 {
     friend Program;
 
   public:
-    VertexShader(Context *context, GLuint handle);
+    VertexShader(ResourceManager *manager, GLuint handle);
 
     ~VertexShader();
 
     GLenum getType();
     void compile();
     int getSemanticIndex(const std::string &attributeName);
 
   private:
@@ -135,17 +137,17 @@ class VertexShader : public Shader
     void parseAttributes();
 
     AttributeArray mAttributes;
 };
 
 class FragmentShader : public Shader
 {
   public:
-    FragmentShader(Context *context, GLuint handle);
+    FragmentShader(ResourceManager *manager, GLuint handle);
 
     ~FragmentShader();
 
     GLenum getType();
     void compile();
 
   private:
     DISALLOW_COPY_AND_ASSIGN(FragmentShader);
--- a/gfx/angle/src/libGLESv2/Texture.cpp
+++ b/gfx/angle/src/libGLESv2/Texture.cpp
@@ -27,17 +27,17 @@ Texture::Image::Image()
 {
 }
 
 Texture::Image::~Image()
 {
   if (surface) surface->Release();
 }
 
-Texture::Texture(Context *context) : mContext(context)
+Texture::Texture(GLuint id) : RefCountObject(id)
 {
     mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
     mMagFilter = GL_LINEAR;
     mWrapS = GL_REPEAT;
     mWrapT = GL_REPEAT;
 
     mDirtyMetaData = true;
     mDirty = true;
@@ -46,17 +46,18 @@ Texture::Texture(Context *context) : mCo
 }
 
 Texture::~Texture()
 {
 }
 
 Blit *Texture::getBlitter()
 {
-    return mContext->getBlitter();
+    Context *context = getContext();
+    return context->getBlitter();
 }
 
 // Returns true on successful filter state update (valid enum parameter)
 bool Texture::setMinFilter(GLenum filter)
 {
     switch (filter)
     {
       case GL_NEAREST:
@@ -437,17 +438,17 @@ GLint Texture::creationLevels(GLsizei si
     return creationLevels(size, size, maxlevel);
 }
 
 int Texture::levelCount() const
 {
     return mBaseTexture ? mBaseTexture->GetLevelCount() : 0;
 }
 
-Texture2D::Texture2D(Context *context) : Texture(context)
+Texture2D::Texture2D(GLuint id) : Texture(id)
 {
     mTexture = NULL;
     mColorbufferProxy = NULL;
 }
 
 Texture2D::~Texture2D()
 {
     delete mColorbufferProxy;
@@ -558,17 +559,17 @@ void Texture2D::commitRect(GLint level, 
 }
 
 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);
 }
 
-void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+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);
     }
 
     if (width != 0 && height != 0 && level < levelCount())
@@ -586,17 +587,17 @@ void Texture2D::copyImage(GLint level, G
         dest->Release();
     }
 
     mImageArray[level].width = width;
     mImageArray[level].height = height;
     mImageArray[level].format = internalFormat;
 }
 
-void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
 {
     if (xoffset + width > mImageArray[level].width || yoffset + height > mImageArray[level].height)
     {
         return error(GL_INVALID_VALUE);
     }
 
     if (redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height))
     {
@@ -866,26 +867,27 @@ void Texture2D::generateMipmaps()
             getBlitter()->boxFilter(upper, lower);
         }
 
         if (upper != NULL) upper->Release();
         if (lower != NULL) lower->Release();
     }
 }
 
-Colorbuffer *Texture2D::getColorbuffer(GLenum target)
+Renderbuffer *Texture2D::getColorbuffer(GLenum target)
 {
     if (target != GL_TEXTURE_2D)
     {
-        return error(GL_INVALID_OPERATION, (Colorbuffer *)NULL);
+        return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
     }
 
     if (mColorbufferProxy == NULL)
     {
-        mColorbufferProxy = new TextureColorbufferProxy(this, target);
+        mColorbufferProxy = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
+        mColorbufferProxy->addRef();
     }
 
     return mColorbufferProxy;
 }
 
 IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
 {
     ASSERT(target == GL_TEXTURE_2D);
@@ -893,17 +895,17 @@ IDirect3DSurface9 *Texture2D::getRenderT
     needRenderTarget();
 
     IDirect3DSurface9 *renderTarget = NULL;
     mTexture->GetSurfaceLevel(0, &renderTarget);
 
     return renderTarget;
 }
 
-TextureCubeMap::TextureCubeMap(Context *context) : Texture(context)
+TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id)
 {
     mTexture = NULL;
 
     for (int i = 0; i < 6; i++)
     {
         mFaceProxies[i] = NULL;
     }
 }
@@ -1273,17 +1275,17 @@ bool TextureCubeMap::redefineTexture(GLi
         mImageArray[0][0].height = width << level;
 
         mImageArray[0][0].format = internalFormat;
     }
 
     return !textureOkay;
 }
 
-void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
 {
     unsigned int faceindex = faceIndex(face);
 
     if (redefineTexture(level, internalFormat, width))
     {
         convertToRenderTarget();
         pushTexture(mTexture, true);
     }
@@ -1335,17 +1337,17 @@ IDirect3DSurface9 *TextureCubeMap::getCu
 
     IDirect3DSurface9 *surface = NULL;
 
     HRESULT hr = mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(faceIndex), level, &surface);
 
     return (SUCCEEDED(hr)) ? surface : NULL;
 }
 
-void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
 {
     GLsizei size = mImageArray[faceIndex(face)][level].width;
 
     if (xoffset + width > size || yoffset + height > size)
     {
         return error(GL_INVALID_VALUE);
     }
 
@@ -1435,28 +1437,29 @@ void TextureCubeMap::generateMipmaps()
             }
 
             if (upper != NULL) upper->Release();
             if (lower != NULL) lower->Release();
         }
     }
 }
 
-Colorbuffer *TextureCubeMap::getColorbuffer(GLenum target)
+Renderbuffer *TextureCubeMap::getColorbuffer(GLenum target)
 {
     if (!IsCubemapTextureTarget(target))
     {
-        return error(GL_INVALID_OPERATION, (Colorbuffer *)NULL);
+        return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
     }
 
     unsigned int face = faceIndex(target);
 
     if (mFaceProxies[face] == NULL)
     {
-        mFaceProxies[face] = new TextureColorbufferProxy(this, target);
+        mFaceProxies[face] = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
+        mFaceProxies[face]->addRef();
     }
 
     return mFaceProxies[face];
 }
 
 IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
 {
     ASSERT(IsCubemapTextureTarget(target));
@@ -1470,28 +1473,38 @@ IDirect3DSurface9 *TextureCubeMap::getRe
 }
 
 Texture::TextureColorbufferProxy::TextureColorbufferProxy(Texture *texture, GLenum target)
   : Colorbuffer(NULL), mTexture(texture), mTarget(target)
 {
     ASSERT(target == GL_TEXTURE_2D || IsCubemapTextureTarget(target));
 }
 
+void Texture::TextureColorbufferProxy::addRef() const
+{
+    mTexture->addRef();
+}
+
+void Texture::TextureColorbufferProxy::release() const
+{
+    mTexture->release();
+}
+
 IDirect3DSurface9 *Texture::TextureColorbufferProxy::getRenderTarget()
 {
     if (mRenderTarget) mRenderTarget->Release();
 
     mRenderTarget = mTexture->getRenderTarget(mTarget);
 
     return mRenderTarget;
 }
 
-int Texture::TextureColorbufferProxy::getWidth()
+int Texture::TextureColorbufferProxy::getWidth() const
 {
     return mTexture->getWidth();
 }
 
-int Texture::TextureColorbufferProxy::getHeight()
+int Texture::TextureColorbufferProxy::getHeight() const
 {
     return mTexture->getHeight();
 }
 
 }
--- a/gfx/angle/src/libGLESv2/Texture.h
+++ b/gfx/angle/src/libGLESv2/Texture.h
@@ -18,31 +18,30 @@
 #include <d3d9.h>
 
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/utilities.h"
 #include "common/debug.h"
 
 namespace gl
 {
-class Context;
 class Blit;
 
 enum
 {
     MAX_TEXTURE_SIZE = 2048,
     MAX_CUBE_MAP_TEXTURE_SIZE = 2048,
 
     MAX_TEXTURE_LEVELS = 12   // 1+log2 of MAX_TEXTURE_SIZE
 };
 
-class Texture
+class Texture : public RefCountObject
 {
   public:
-    explicit Texture(Context *context);
+    explicit Texture(GLuint id);
 
     virtual ~Texture();
 
     virtual GLenum getTarget() const = 0;
 
     bool setMinFilter(GLenum filter);
     bool setMagFilter(GLenum filter);
     bool setWrapS(GLenum wrap);
@@ -54,35 +53,40 @@ class Texture
     GLenum getWrapT() const;
 
     GLuint getWidth() const;
     GLuint getHeight() const;
 
     virtual bool isComplete() const = 0;
 
     IDirect3DBaseTexture9 *getTexture();
-    virtual Colorbuffer *getColorbuffer(GLenum target) = 0;
+    virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
 
     virtual void generateMipmaps() = 0;
 
     bool isDirty() const;
 
+    static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
+
   protected:
     class TextureColorbufferProxy;
     friend class TextureColorbufferProxy;
     class TextureColorbufferProxy : public Colorbuffer
     {
       public:
         TextureColorbufferProxy(Texture *texture, GLenum target);
             // target is a 2D-like texture target (GL_TEXTURE_2D or one of the cube face targets)
 
+        virtual void addRef() const;
+        virtual void release() const;
+
         virtual IDirect3DSurface9 *getRenderTarget();
 
-        virtual int getWidth();
-        virtual int getHeight();
+        virtual int getWidth() const;
+        virtual int getHeight() const;
 
       private:
         Texture *mTexture;
         GLenum mTarget;
     };
 
     // Helper structure representing a single image layer
     struct Image
@@ -131,95 +135,93 @@ class Texture
     unsigned int mWidth;
     unsigned int mHeight;
 
     int levelCount() const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture);
 
-    Context *mContext;
-
     IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
     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(Context *context);
+    explicit Texture2D(GLuint id);
 
     ~Texture2D();
 
     GLenum getTarget() const;
 
     void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
     void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
-    void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
-    void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
+    void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+    void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
 
     bool isComplete() const;
 
     virtual void generateMipmaps();
 
-    virtual Colorbuffer *getColorbuffer(GLenum target);
+    virtual Renderbuffer *getColorbuffer(GLenum target);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture2D);
 
     virtual IDirect3DBaseTexture9 *createTexture();
     virtual void updateTexture();
     virtual IDirect3DBaseTexture9 *convertToRenderTarget();
 
     virtual bool dirtyImageData() const;
 
     void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
 
     Image mImageArray[MAX_TEXTURE_LEVELS];
 
     IDirect3DTexture9 *mTexture;
 
-    TextureColorbufferProxy *mColorbufferProxy;
+    Renderbuffer *mColorbufferProxy;
 
     bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
 
     virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
 };
 
 class TextureCubeMap : public Texture
 {
   public:
-    explicit TextureCubeMap(Context *context);
+    explicit TextureCubeMap(GLuint id);
 
     ~TextureCubeMap();
 
     GLenum getTarget() const;
 
     void setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
     void setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
     void setImagePosY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
     void setImageNegY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
     void setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
     void setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
 
     void subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
-    void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
-    void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
+    void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+    void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
 
     bool isComplete() const;
 
     virtual void generateMipmaps();
 
-    virtual Colorbuffer *getColorbuffer(GLenum target);
+    virtual Renderbuffer *getColorbuffer(GLenum target);
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
 
     virtual IDirect3DBaseTexture9 *createTexture();
     virtual void updateTexture();
     virtual IDirect3DBaseTexture9 *convertToRenderTarget();
 
@@ -236,15 +238,15 @@ class TextureCubeMap : public Texture
     void setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
     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;
 
-    TextureColorbufferProxy *mFaceProxies[6];
+    Renderbuffer *mFaceProxies[6];
 
     virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
 };
 }
 
 #endif   // LIBGLESV2_TEXTURE_H_
--- a/gfx/angle/src/libGLESv2/geometry/VertexDataManager.cpp
+++ b/gfx/angle/src/libGLESv2/geometry/VertexDataManager.cpp
@@ -65,22 +65,16 @@ std::bitset<MAX_VERTEX_ATTRIBS> VertexDa
 GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count,
                                             TranslatedAttribute *translated)
 {
     const AttributeState *attribs = mContext->getVertexAttribBlock();
     const std::bitset<MAX_VERTEX_ATTRIBS> activeAttribs = getActiveAttribs();
 
     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
     {
-        if (!activeAttribs[i] && attribs[i].mEnabled && attribs[i].mBoundBuffer != 0 && !mContext->getBuffer(attribs[i].mBoundBuffer))
-            return GL_INVALID_OPERATION;
-    }
-
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-    {
         translated[i].enabled = activeAttribs[i];
     }
 
     bool usesCurrentValues = false;
 
     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
     {
         if (activeAttribs[i] && !attribs[i].mEnabled)
@@ -129,19 +123,19 @@ GLenum VertexDataManager::preRenderValid
             translated[i].buffer = mStreamBuffer;
 
             size_t inputStride = interpretGlStride(attribs[i]);
             size_t elementSize = typeSize(attribs[i].mType) * attribs[i].mSize;
 
             void *output = mStreamBuffer->map(spaceRequired(attribs[i], count), &translated[i].offset);
 
             const void *input;
-            if (attribs[i].mBoundBuffer)
+            if (attribs[i].mBoundBuffer.get())
             {
-                Buffer *buffer = mContext->getBuffer(attribs[i].mBoundBuffer);
+                Buffer *buffer = attribs[i].mBoundBuffer.get();
 
                 size_t offset = reinterpret_cast<size_t>(attribs[i].mPointer);
 
                 // Before we calculate the required size below, make sure it can be computed without integer overflow.
                 if (std::numeric_limits<std::size_t>::max() - start < static_cast<std::size_t>(count)
                     || std::numeric_limits<std::size_t>::max() / inputStride < static_cast<std::size_t>(start + count - 1) // it's a prerequisite that count >= 1, so start+count-1 >= 0.
                     || std::numeric_limits<std::size_t>::max() - offset < inputStride * (start + count - 1)
                     || std::numeric_limits<std::size_t>::max() - elementSize < offset + inputStride * (start + count - 1) + elementSize)
--- a/gfx/angle/src/libGLESv2/geometry/backend.h
+++ b/gfx/angle/src/libGLESv2/geometry/backend.h
@@ -60,16 +60,18 @@ class BufferBackEnd
     virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size, GLenum type) = 0;
     virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize) = 0;
 
     // For an identity-mappable stream, verify that the stride and offset are okay.
     virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const = 0;
 
     virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo) = 0;
     virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes) = 0;
+
+    virtual void invalidate() = 0;
 };
 
 class TranslatedBuffer
 {
   public:
     explicit TranslatedBuffer(std::size_t size) : mBufferSize(size), mCurrentPoint(0) { }
     virtual ~TranslatedBuffer() { }
 
--- a/gfx/angle/src/libGLESv2/geometry/dx9.cpp
+++ b/gfx/angle/src/libGLESv2/geometry/dx9.cpp
@@ -466,16 +466,24 @@ GLenum Dx9BackEnd::setupAttributesPreDra
                 }
             }
         }
     }
 
     return GL_NO_ERROR;
 }
 
+void Dx9BackEnd::invalidate()
+{
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS + 1; i++)
+    {
+        mStreamFrequency[i] = STREAM_FREQUENCY_DIRTY;
+    }
+}
+
 Dx9BackEnd::Dx9VertexBuffer::Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size)
     : TranslatedVertexBuffer(size)
 {
     HRESULT hr = device->CreateVertexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mVertexBuffer, NULL);
     if (hr != S_OK)
     {
         ERR("Out of memory allocating a vertex buffer of size %lu.", size);
         throw std::bad_alloc();
--- a/gfx/angle/src/libGLESv2/geometry/dx9.h
+++ b/gfx/angle/src/libGLESv2/geometry/dx9.h
@@ -30,32 +30,35 @@ class Dx9BackEnd : public BufferBackEnd
     virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size, GLenum type);
     virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize);
 
     virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const;
 
     virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo);
     virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes);
 
+    void invalidate();
+
   private:
     IDirect3DDevice9 *mDevice;
 
     bool mUseInstancingForStrideZero;
     bool mSupportIntIndices;
 
     bool mAppliedAttribEnabled[MAX_VERTEX_ATTRIBS];
 
     enum StreamFrequency
     {
         STREAM_FREQUENCY_UNINSTANCED = 0,
         STREAM_FREQUENCY_INDEXED,
-        STREAM_FREQUENCY_INSTANCED
+        STREAM_FREQUENCY_INSTANCED,
+        STREAM_FREQUENCY_DIRTY
     };
 
-    StreamFrequency mStreamFrequency[MAX_VERTEX_ATTRIBS+1];
+    StreamFrequency mStreamFrequency[MAX_VERTEX_ATTRIBS+1]; // Stream frequencies as last set.
 
     struct TranslationInfo
     {
         FormatConverter formatConverter;
         D3DDECLTYPE d3dDeclType;
     };
 
     enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
--- a/gfx/angle/src/libGLESv2/libGLESv2.cpp
+++ b/gfx/angle/src/libGLESv2/libGLESv2.cpp
@@ -843,18 +843,23 @@ void __stdcall glCopyTexImage2D(GLenum t
         {
             return error(GL_INVALID_VALUE);
         }
 
         gl::Context *context = gl::getContext();
 
         if (context)
         {
-            gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
-
+            gl::Framebuffer *framebuffer = context->getFramebuffer();
+            if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+            {
+                return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+            }
+
+            gl::Colorbuffer *source = framebuffer->getColorbuffer();
             if (target == GL_TEXTURE_2D)
             {
                 gl::Texture2D *texture = context->getTexture2D();
 
                 if (!texture)
                 {
                     return error(GL_INVALID_OPERATION);
                 }
@@ -911,18 +916,23 @@ void __stdcall glCopyTexSubImage2D(GLenu
         {
             return;
         }
 
         gl::Context *context = gl::getContext();
 
         if (context)
         {
-            gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
-
+            gl::Framebuffer *framebuffer = context->getFramebuffer();
+            if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+            {
+                return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+            }
+
+            gl::Colorbuffer *source = framebuffer->getColorbuffer();
             if (target == GL_TEXTURE_2D)
             {
                 gl::Texture2D *texture = context->getTexture2D();
 
                 if (!texture)
                 {
                     return error(GL_INVALID_OPERATION);
                 }
@@ -2503,67 +2513,67 @@ void __stdcall glGetRenderbufferParamete
                 *params = renderbuffer->getHeight();
                 break;
               case GL_RENDERBUFFER_INTERNAL_FORMAT:
                 *params = renderbuffer->getFormat();
                 break;
               case GL_RENDERBUFFER_RED_SIZE:
                 if (renderbuffer->isColorbuffer())
                 {
-                    *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
+                    *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
                 }
                 else
                 {
                     *params = 0;
                 }
                 break;
               case GL_RENDERBUFFER_GREEN_SIZE:
                 if (renderbuffer->isColorbuffer())
                 {
-                    *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
+                    *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
                 }
                 else
                 {
                     *params = 0;
                 }
                 break;
               case GL_RENDERBUFFER_BLUE_SIZE:
                 if (renderbuffer->isColorbuffer())
                 {
-                    *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
+                    *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
                 }
                 else
                 {
                     *params = 0;
                 }
                 break;
               case GL_RENDERBUFFER_ALPHA_SIZE:
                 if (renderbuffer->isColorbuffer())
                 {
-                    *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
+                    *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
                 }
                 else
                 {
                     *params = 0;
                 }
                 break;
               case GL_RENDERBUFFER_DEPTH_SIZE:
                 if (renderbuffer->isDepthbuffer())
                 {
-                    *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
+                    *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
                 }
                 else
                 {
                     *params = 0;
                 }
                 break;
               case GL_RENDERBUFFER_STENCIL_SIZE:
                 if (renderbuffer->isStencilbuffer())
                 {
-                    *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
+                    *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
                 }
                 else
                 {
                     *params = 0;
                 }
                 break;
               default:
                 return error(GL_INVALID_ENUM);
@@ -2988,17 +2998,17 @@ void __stdcall glGetVertexAttribfv(GLuin
 
         if (context)
         {
             if (index >= gl::MAX_VERTEX_ATTRIBS)
             {
                 return error(GL_INVALID_VALUE);
             }
 
-            gl::AttributeState attribState = context->getVertexAttribState(index);
+            const gl::AttributeState &attribState = context->getVertexAttribState(index);
 
             switch (pname)
             {
               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
                 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
                 break;
               case GL_VERTEX_ATTRIB_ARRAY_SIZE:
                 *params = (GLfloat)attribState.mSize;
@@ -3008,17 +3018,17 @@ void __stdcall glGetVertexAttribfv(GLuin
                 break;
               case GL_VERTEX_ATTRIB_ARRAY_TYPE:
                 *params = (GLfloat)attribState.mType;
                 break;
               case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
                 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
                 break;
               case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
-                *params = (GLfloat)attribState.mBoundBuffer;
+                *params = (GLfloat)attribState.mBoundBuffer.id();
                 break;
               case GL_CURRENT_VERTEX_ATTRIB:
                 for (int i = 0; i < 4; ++i)
                 {
                     params[i] = attribState.mCurrentValue[i];
                 }
                 break;
               default: return error(GL_INVALID_ENUM);
@@ -3041,17 +3051,17 @@ void __stdcall glGetVertexAttribiv(GLuin
 
         if (context)
         {
             if (index >= gl::MAX_VERTEX_ATTRIBS)
             {
                 return error(GL_INVALID_VALUE);
             }
 
-            gl::AttributeState attribState = context->getVertexAttribState(index);
+            const gl::AttributeState &attribState = context->getVertexAttribState(index);
 
             switch (pname)
             {
               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
                 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
                 break;
               case GL_VERTEX_ATTRIB_ARRAY_SIZE:
                 *params = attribState.mSize;
@@ -3061,17 +3071,17 @@ void __stdcall glGetVertexAttribiv(GLuin
                 break;
               case GL_VERTEX_ATTRIB_ARRAY_TYPE:
                 *params = attribState.mType;
                 break;
               case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
                 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
                 break;
               case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
-                *params = attribState.mBoundBuffer;
+                *params = attribState.mBoundBuffer.id();
                 break;
               case GL_CURRENT_VERTEX_ATTRIB:
                 for (int i = 0; i < 4; ++i)
                 {
                     float currentValue = attribState.mCurrentValue[i];
                     params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
                 }
                 break;
@@ -3538,47 +3548,52 @@ void __stdcall glRenderbufferStorage(GLe
 
         switch (internalformat)
         {
           case GL_DEPTH_COMPONENT16:
           case GL_RGBA4:
           case GL_RGB5_A1:
           case GL_RGB565:
           case GL_STENCIL_INDEX8:
+          case GL_DEPTH24_STENCIL8_OES:
             break;
           default:
             return error(GL_INVALID_ENUM);
         }
 
         if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
         {
             return error(GL_INVALID_VALUE);
         }
 
         gl::Context *context = gl::getContext();
 
         if (context)
         {
-            if (context->getRenderbufferHandle() == 0)
+            GLuint handle = context->getRenderbufferHandle();
+            if (handle == 0)
             {
                 return error(GL_INVALID_OPERATION);
             }
 
             switch (internalformat)
             {
               case GL_DEPTH_COMPONENT16:
-                context->setRenderbuffer(new gl::Depthbuffer(width, height));
+                context->setRenderbufferStorage(new gl::Depthbuffer(width, height));
                 break;
               case GL_RGBA4:
               case GL_RGB5_A1:
               case GL_RGB565:
-                context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
+                context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat));
                 break;
               case GL_STENCIL_INDEX8:
-                context->setRenderbuffer(new gl::Stencilbuffer(width, height));
+                context->setRenderbufferStorage(new gl::Stencilbuffer(width, height));
+                break;
+              case GL_DEPTH24_STENCIL8_OES:
+                context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height));
                 break;
               default:
                 return error(GL_INVALID_ENUM);
             }
         }
     }
     catch(std::bad_alloc&)
     {
@@ -4960,17 +4975,17 @@ void __stdcall glVertexAttribPointer(GLu
         {
             return error(GL_INVALID_VALUE);
         }
 
         gl::Context *context = gl::getContext();
 
         if (context)
         {
-            context->setVertexAttribState(index, context->getArrayBufferHandle(), size, type, (normalized == GL_TRUE), stride, ptr);
+            context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
         }
     }
     catch(std::bad_alloc&)
     {
         return error(GL_OUT_OF_MEMORY);
     }
 }
 
--- a/gfx/angle/src/libGLESv2/libGLESv2.vcproj
+++ b/gfx/angle/src/libGLESv2/libGLESv2.vcproj
@@ -212,20 +212,28 @@
 				RelativePath=".\main.cpp"
 				>
 			</File>
 			<File
 				RelativePath=".\Program.cpp"
 				>
 			</File>
 			<File
+				RelativePath=".\RefCountObject.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\Renderbuffer.cpp"
 				>
 			</File>
 			<File
+				RelativePath=".\ResourceManager.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\Shader.cpp"
 				>
 			</File>
 			<File
 				RelativePath=".\Texture.cpp"
 				>
 			</File>
 			<File
@@ -294,20 +302,28 @@
 				RelativePath=".\mathutil.h"
 				>
 			</File>
 			<File
 				RelativePath=".\Program.h"
 				>
 			</File>
 			<File
+				RelativePath=".\RefCountObject.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Renderbuffer.h"
 				>
 			</File>
 			<File
+				RelativePath=".\ResourceManager.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Shader.h"
 				>
 			</File>
 			<File
 				RelativePath=".\Texture.h"
 				>
 			</File>
 			<File
--- a/gfx/angle/src/libGLESv2/main.h
+++ b/gfx/angle/src/libGLESv2/main.h
@@ -6,16 +6,17 @@
 
 // main.h: Management of thread-local data.
 
 #ifndef LIBGLESV2_MAIN_H_
 #define LIBGLESV2_MAIN_H_
 
 #define GL_APICALL
 #include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 
 #include "common/debug.h"
 #include "libEGL/Display.h"
 
 #include "libGLESv2/Context.h"
 
 namespace gl
 {