Return pointers from check*Allocation.

This avoids the need to consult the resource maps twice per bind.
It improves performance in applications which call Bind* often.

BUG=angleproject:1333

Change-Id: I7b733cc89e50e24a2e38a2eb2dc7fd658d612e27
Reviewed-on: https://chromium-review.googlesource.com/331386
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/TransformFeedback_unittest.cpp b/src/libANGLE/TransformFeedback_unittest.cpp
index 2883d76..c304970 100644
--- a/src/libANGLE/TransformFeedback_unittest.cpp
+++ b/src/libANGLE/TransformFeedback_unittest.cpp
@@ -11,6 +11,7 @@
 #include "libANGLE/TransformFeedback.h"
 #include "libANGLE/renderer/BufferImpl_mock.h"
 #include "libANGLE/renderer/TransformFeedbackImpl_mock.h"
+#include "tests/angle_unittests_utils.h"
 
 using ::testing::_;
 using ::testing::Return;
@@ -19,45 +20,51 @@
 namespace
 {
 
+class MockFactory : public rx::NullFactory
+{
+  public:
+    MOCK_METHOD0(createTransformFeedback, rx::TransformFeedbackImpl *());
+};
+
 class TransformFeedbackTest : public testing::Test
 {
   protected:
-    virtual void SetUp()
+    TransformFeedbackTest() : mImpl(nullptr), mFeedback(nullptr) {}
+
+    void SetUp() override
     {
+        mImpl = new rx::MockTransformFeedbackImpl;
+        EXPECT_CALL(mMockFactory, createTransformFeedback())
+            .WillOnce(Return(mImpl))
+            .RetiresOnSaturation();
+
         // Set a reasonable number of tf attributes
         mCaps.maxTransformFeedbackSeparateAttributes = 8;
 
-        mImpl = new rx::MockTransformFeedbackImpl;
         EXPECT_CALL(*mImpl, destructor());
-        mFeedback = new gl::TransformFeedback(mImpl, 1, mCaps);
+        mFeedback = new gl::TransformFeedback(&mMockFactory, 1, mCaps);
         mFeedback->addRef();
     }
 
-    virtual void TearDown()
+    void TearDown() override
     {
-        mFeedback->release();
+        if (mFeedback)
+        {
+            mFeedback->release();
+        }
+
+        // Only needed because the mock is leaked if bugs are present,
+        // which logs an error, but does not cause the test to fail.
+        // Ordinarily mocks are verified when destroyed.
+        testing::Mock::VerifyAndClear(mImpl);
     }
 
+    MockFactory mMockFactory;
     rx::MockTransformFeedbackImpl* mImpl;
     gl::TransformFeedback* mFeedback;
     gl::Caps mCaps;
 };
 
-TEST_F(TransformFeedbackTest, DestructionDeletesImpl)
-{
-    rx::MockTransformFeedbackImpl* impl = new rx::MockTransformFeedbackImpl;
-    EXPECT_CALL(*impl, destructor()).Times(1).RetiresOnSaturation();
-
-    gl::TransformFeedback* feedback = new gl::TransformFeedback(impl, 1, mCaps);
-    feedback->addRef();
-    feedback->release();
-
-    // Only needed because the mock is leaked if bugs are present,
-    // which logs an error, but does not cause the test to fail.
-    // Ordinarily mocks are verified when destroyed.
-    testing::Mock::VerifyAndClear(impl);
-}
-
 TEST_F(TransformFeedbackTest, SideEffectsOfStartAndStop)
 {
     testing::InSequence seq;
@@ -98,35 +105,36 @@
 
     static const size_t bindIndex = 0;
 
-    rx::MockTransformFeedbackImpl *feedbackImpl = new rx::MockTransformFeedbackImpl;
-    EXPECT_CALL(*feedbackImpl, destructor()).Times(1).RetiresOnSaturation();
+    EXPECT_EQ(mFeedback->getIndexedBufferCount(), mCaps.maxTransformFeedbackSeparateAttributes);
 
-    gl::TransformFeedback *feedback = new gl::TransformFeedback(feedbackImpl, 1, mCaps);
+    EXPECT_CALL(*mImpl, bindGenericBuffer(_));
+    mFeedback->bindGenericBuffer(buffer);
+    EXPECT_EQ(mFeedback->getGenericBuffer().get(), buffer);
 
-    EXPECT_EQ(feedback->getIndexedBufferCount(), mCaps.maxTransformFeedbackSeparateAttributes);
-
-    EXPECT_CALL(*feedbackImpl, bindGenericBuffer(_));
-    feedback->bindGenericBuffer(buffer);
-    EXPECT_EQ(feedback->getGenericBuffer().get(), buffer);
-
-    EXPECT_CALL(*feedbackImpl, bindIndexedBuffer(_, _));
-    feedback->bindIndexedBuffer(bindIndex, buffer, 0, 1);
-    for (size_t i = 0; i < feedback->getIndexedBufferCount(); i++)
+    EXPECT_CALL(*mImpl, bindIndexedBuffer(_, _));
+    mFeedback->bindIndexedBuffer(bindIndex, buffer, 0, 1);
+    for (size_t i = 0; i < mFeedback->getIndexedBufferCount(); i++)
     {
         if (i == bindIndex)
         {
-            EXPECT_EQ(feedback->getIndexedBuffer(i).get(), buffer);
+            EXPECT_EQ(mFeedback->getIndexedBuffer(i).get(), buffer);
         }
         else
         {
-            EXPECT_EQ(feedback->getIndexedBuffer(i).get(), nullptr);
+            EXPECT_EQ(mFeedback->getIndexedBuffer(i).get(), nullptr);
         }
     }
 
-    feedback->addRef();
-    feedback->release();
+    // force-release the feedback object to ensure the buffer is released.
+    const size_t releaseCount = mFeedback->getRefCount();
+    for (size_t count = 0; count < releaseCount; ++count)
+    {
+        mFeedback->release();
+    }
+
+    mFeedback = nullptr;
 
     testing::Mock::VerifyAndClear(bufferImpl);
 }
 
-} // namespace
+}  // anonymous namespace