Fix ResourceManager create-on-bind reallocations.

*re-land with build fix for Clang*

We had a funny bug where the Handle Allocator would re-allocate
reserved handles after the app layer creates one with Bind rather
than using Gen. This affects Textures, Buffers and Renderbuffers.

Fix this by using a different allocation scheme. It should still
be fast on the "good" case (using Gen) and use tree lookups on the
bind case. Also add some unit tests.

BUG=angleproject:942

Change-Id: I63ce608fcd6a11f92e2b5421f090551934e729ed
Reviewed-on: https://chromium-review.googlesource.com/261591
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/ResourceManager.cpp b/src/libANGLE/ResourceManager.cpp
index 71a6a32..aaf144c 100644
--- a/src/libANGLE/ResourceManager.cpp
+++ b/src/libANGLE/ResourceManager.cpp
@@ -356,33 +356,84 @@
     mRenderbufferMap[handle] = buffer;
 }
 
-void ResourceManager::checkBufferAllocation(unsigned int buffer)
+void ResourceManager::checkBufferAllocation(GLuint handle)
 {
-    if (buffer != 0 && !getBuffer(buffer))
+    if (handle != 0)
     {
-        Buffer *bufferObject = new Buffer(mFactory->createBuffer(), buffer);
-        mBufferMap[buffer] = bufferObject;
-        bufferObject->addRef();
+        auto bufferMapIt = mBufferMap.find(handle);
+        bool handleAllocated = (bufferMapIt != mBufferMap.end());
+
+        if (handleAllocated && bufferMapIt->second != nullptr)
+        {
+            return;
+        }
+
+        Buffer *buffer = new Buffer(mFactory->createBuffer(), handle);
+        buffer->addRef();
+
+        if (handleAllocated)
+        {
+            bufferMapIt->second = buffer;
+        }
+        else
+        {
+            mBufferHandleAllocator.reserve(handle);
+            mBufferMap[handle] = buffer;
+        }
     }
 }
 
-void ResourceManager::checkTextureAllocation(GLuint texture, GLenum type)
+void ResourceManager::checkTextureAllocation(GLuint handle, GLenum type)
 {
-    if (!getTexture(texture) && texture != 0)
+    if (handle != 0)
     {
-        Texture *textureObject = new Texture(mFactory->createTexture(type), texture, type);
-        mTextureMap[texture] = textureObject;
-        textureObject->addRef();
+        auto textureMapIt = mTextureMap.find(handle);
+        bool handleAllocated = (textureMapIt != mTextureMap.end());
+
+        if (handleAllocated && textureMapIt->second != nullptr)
+        {
+            return;
+        }
+
+        Texture *texture = new Texture(mFactory->createTexture(type), handle, type);
+        texture->addRef();
+
+        if (handleAllocated)
+        {
+            textureMapIt->second = texture;
+        }
+        else
+        {
+            mTextureHandleAllocator.reserve(handle);
+            mTextureMap[handle] = texture;
+        }
     }
 }
 
-void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
+void ResourceManager::checkRenderbufferAllocation(GLuint handle)
 {
-    if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
+    if (handle != 0)
     {
-        Renderbuffer *renderbufferObject = new Renderbuffer(mFactory->createRenderbuffer(), renderbuffer);
-        mRenderbufferMap[renderbuffer] = renderbufferObject;
-        renderbufferObject->addRef();
+        auto renderbufferMapIt = mRenderbufferMap.find(handle);
+        bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end());
+
+        if (handleAllocated && renderbufferMapIt->second != nullptr)
+        {
+            return;
+        }
+
+        Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle);
+        renderbuffer->addRef();
+
+        if (handleAllocated)
+        {
+            renderbufferMapIt->second = renderbuffer;
+        }
+        else
+        {
+            mRenderbufferHandleAllocator.reserve(handle);
+            mRenderbufferMap[handle] = renderbuffer;
+        }
     }
 }
 
@@ -393,6 +444,7 @@
         Sampler *samplerObject = new Sampler(sampler);
         mSamplerMap[sampler] = samplerObject;
         samplerObject->addRef();
+        // Samplers cannot be created via Bind
     }
 }