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 idunknown
push userunknown
push dateunknown
reviewersvlad
bugs583375
milestone2.0b3pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
b=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
 {