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_unittest.cpp b/src/libANGLE/ResourceManager_unittest.cpp
new file mode 100644
index 0000000..589bda9
--- /dev/null
+++ b/src/libANGLE/ResourceManager_unittest.cpp
@@ -0,0 +1,73 @@
+//
+// Copyright 2015 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.
+//
+// Unit tests for ResourceManager.
+//
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "angle_unittests_utils.h"
+#include "libANGLE/ResourceManager.h"
+
+using namespace rx;
+using namespace gl;
+
+namespace
+{
+
+class MockFactory : public NullFactory
+{
+  public:
+    MOCK_METHOD0(createBuffer, BufferImpl*());
+    MOCK_METHOD1(createTexture, TextureImpl*(GLenum));
+    MOCK_METHOD0(createRenderbuffer, RenderbufferImpl*());
+};
+
+class ResourceManagerTest : public testing::Test
+{
+  protected:
+    void SetUp() override
+    {
+        mResourceManager = new ResourceManager(&mMockFactory);
+    }
+
+    void TearDown() override
+    {
+        SafeDelete(mResourceManager);
+    }
+
+    MockFactory mMockFactory;
+    ResourceManager *mResourceManager;
+};
+
+TEST_F(ResourceManagerTest, ReallocateBoundTexture)
+{
+    EXPECT_CALL(mMockFactory, createTexture(GL_TEXTURE_2D)).Times(1).RetiresOnSaturation();
+
+    mResourceManager->checkTextureAllocation(1, GL_TEXTURE_2D);
+    GLuint newTexture = mResourceManager->createTexture();
+    EXPECT_NE(1u, newTexture);
+}
+
+TEST_F(ResourceManagerTest, ReallocateBoundBuffer)
+{
+    EXPECT_CALL(mMockFactory, createBuffer()).Times(1).RetiresOnSaturation();
+
+    mResourceManager->checkBufferAllocation(1);
+    GLuint newBuffer = mResourceManager->createBuffer();
+    EXPECT_NE(1u, newBuffer);
+}
+
+TEST_F(ResourceManagerTest, ReallocateBoundRenderbuffer)
+{
+    EXPECT_CALL(mMockFactory, createRenderbuffer()).Times(1).RetiresOnSaturation();
+
+    mResourceManager->checkRenderbufferAllocation(1);
+    GLuint newRenderbuffer = mResourceManager->createRenderbuffer();
+    EXPECT_NE(1u, newRenderbuffer);
+}
+
+}