Add an ImplFactory base class.

This class helps make mocking easier for unit tests.

Also update the back-end generator script.

BUG=angleproject:942

Change-Id: Ib0cee2b40c3a0faaac32b22c986b824b7b2dddde
Reviewed-on: https://chromium-review.googlesource.com/258900
Reviewed-by: Brandon Jones <bajones@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Framebuffer.h b/src/libANGLE/Framebuffer.h
index 241d1c8..08fab9d 100644
--- a/src/libANGLE/Framebuffer.h
+++ b/src/libANGLE/Framebuffer.h
@@ -53,7 +53,7 @@
     class Data final
     {
       public:
-        Data(const Caps &caps);
+        explicit Data(const Caps &caps);
         ~Data();
 
         FramebufferAttachment *getReadAttachment() const;
diff --git a/src/libANGLE/renderer/FramebufferImpl.h b/src/libANGLE/renderer/FramebufferImpl.h
index 71cffac..8e296b8 100644
--- a/src/libANGLE/renderer/FramebufferImpl.h
+++ b/src/libANGLE/renderer/FramebufferImpl.h
@@ -28,7 +28,7 @@
 class FramebufferImpl
 {
   public:
-    FramebufferImpl(const gl::Framebuffer::Data &data) : mData(data) { }
+    explicit FramebufferImpl(const gl::Framebuffer::Data &data) : mData(data) { }
     virtual ~FramebufferImpl() { }
 
     virtual void setColorAttachment(size_t index, const gl::FramebufferAttachment *attachment) = 0;
diff --git a/src/libANGLE/renderer/ImplFactory.h b/src/libANGLE/renderer/ImplFactory.h
new file mode 100644
index 0000000..aa57117
--- /dev/null
+++ b/src/libANGLE/renderer/ImplFactory.h
@@ -0,0 +1,71 @@
+//
+// 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.
+//
+// ImplFactory.h:
+//   Factory interface for Impl objects.
+//
+
+#ifndef LIBANGLE_RENDERER_IMPLFACTORY_H_
+#define LIBANGLE_RENDERER_IMPLFACTORY_H_
+
+#include "libANGLE/Framebuffer.h"
+
+namespace rx
+{
+class BufferImpl;
+class CompilerImpl;
+class DefaultAttachmentImpl;
+class FenceNVImpl;
+class FenceSyncImpl;
+class FramebufferImpl;
+class ProgramImpl;
+class QueryImpl;
+class RenderbufferImpl;
+class ShaderImpl;
+class TextureImpl;
+class TransformFeedbackImpl;
+class VertexArrayImpl;
+
+class ImplFactory
+{
+  public:
+    ImplFactory() {}
+    virtual ~ImplFactory() {}
+
+    // Shader creation
+    virtual CompilerImpl *createCompiler(const gl::Data &data) = 0;
+    virtual ShaderImpl *createShader(GLenum type) = 0;
+    virtual ProgramImpl *createProgram() = 0;
+
+    // Framebuffer creation
+    virtual DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) = 0;
+    virtual FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) = 0;
+
+    // Texture creation
+    virtual TextureImpl *createTexture(GLenum target) = 0;
+
+    // Renderbuffer creation
+    virtual RenderbufferImpl *createRenderbuffer() = 0;
+
+    // Buffer creation
+    virtual BufferImpl *createBuffer() = 0;
+
+    // Vertex Array creation
+    virtual VertexArrayImpl *createVertexArray() = 0;
+
+    // Query and Fence creation
+    virtual QueryImpl *createQuery(GLenum type) = 0;
+    virtual FenceNVImpl *createFenceNV() = 0;
+    virtual FenceSyncImpl *createFenceSync() = 0;
+
+    // Transform Feedback creation
+    virtual TransformFeedbackImpl *createTransformFeedback() = 0;
+
+    DISALLOW_COPY_AND_ASSIGN(ImplFactory);
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_IMPLFACTORY_H_
diff --git a/src/libANGLE/renderer/Renderer.h b/src/libANGLE/renderer/Renderer.h
index 27e1a6a..eaef368 100644
--- a/src/libANGLE/renderer/Renderer.h
+++ b/src/libANGLE/renderer/Renderer.h
@@ -15,6 +15,7 @@
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/Uniform.h"
 #include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/ImplFactory.h"
 #include "libANGLE/renderer/Workarounds.h"
 #include "common/mathutil.h"
 
@@ -37,24 +38,11 @@
 
 namespace rx
 {
-class QueryImpl;
-class FenceNVImpl;
-class FenceSyncImpl;
-class BufferImpl;
-class VertexArrayImpl;
-class ShaderImpl;
-class ProgramImpl;
-class TextureImpl;
-class TransformFeedbackImpl;
-class RenderbufferImpl;
-class DefaultAttachmentImpl;
-class FramebufferImpl;
-class CompilerImpl;
 struct TranslatedIndexData;
 struct Workarounds;
 class DisplayImpl;
 
-class Renderer
+class Renderer : public ImplFactory
 {
   public:
     Renderer();
@@ -69,35 +57,6 @@
                                    const GLvoid *indices, GLsizei instances,
                                    const RangeUI &indexRange) = 0;
 
-    // Shader creation
-    virtual CompilerImpl *createCompiler(const gl::Data &data) = 0;
-    virtual ShaderImpl *createShader(GLenum type) = 0;
-    virtual ProgramImpl *createProgram() = 0;
-
-    // Framebuffer creation
-    virtual DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) = 0;
-    virtual FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) = 0;
-
-    // Texture creation
-    virtual TextureImpl *createTexture(GLenum target) = 0;
-
-    // Renderbuffer creation
-    virtual RenderbufferImpl *createRenderbuffer() = 0;
-
-    // Buffer creation
-    virtual BufferImpl *createBuffer() = 0;
-
-    // Vertex Array creation
-    virtual VertexArrayImpl *createVertexArray() = 0;
-
-    // Query and Fence creation
-    virtual QueryImpl *createQuery(GLenum type) = 0;
-    virtual FenceNVImpl *createFenceNV() = 0;
-    virtual FenceSyncImpl *createFenceSync() = 0;
-
-    // Transform Feedback creation
-    virtual TransformFeedbackImpl *createTransformFeedback() = 0;
-
     // lost device
     //TODO(jmadill): investigate if this stuff is necessary in GL
     virtual void notifyDeviceLost() = 0;
diff --git a/src/libANGLE/renderer/generate_new_renderer.py b/src/libANGLE/renderer/generate_new_renderer.py
index fdb701c..f4a0833 100644
--- a/src/libANGLE/renderer/generate_new_renderer.py
+++ b/src/libANGLE/renderer/generate_new_renderer.py
@@ -152,23 +152,9 @@
     args = ', '.join(re.findall(r'[^\w]?(\w+)(?:\,|$)', params))
     return params, args
 
-for impl_class in impl_classes:
-
-    base_impl = impl_class
-
-    # special case for Renderer
-    if impl_class != 'Renderer':
-        base_impl += 'Impl'
-
-    typed_impl = impl_class + renderer_suffix
-
+def parse_impl_header(base_impl):
     impl_h_file_path = base_impl + '.h'
-    h_file_path = os.path.join(renderer_name, typed_impl + '.h')
-    cpp_file_path = os.path.join(renderer_name, typed_impl + '.cpp')
-
     impl_h_file = open(impl_h_file_path, 'r')
-    h_file = open(h_file_path, 'w')
-    cpp_file = open(cpp_file_path, 'w')
 
     # extract impl stubs
     copy = False
@@ -179,8 +165,9 @@
     for line in impl_h_file:
         clean_line = line.strip()
 
-        if re.search(r'[^~]' + base_impl + r'\(', clean_line):
-            constructor = clean_line
+        match = re.search(r'^(?:explicit )?(' + base_impl + r'\([^\)]*\))', clean_line);
+        if match:
+            constructor = match.group(1)
 
         # begin capture when reading the destructor.
         # begin capture also in the private scope (a few special cases)
@@ -202,6 +189,36 @@
         elif copy_private:
             private_impl_stubs += line
 
+    impl_h_file.close()
+
+    return impl_stubs, private_impl_stubs, constructor
+
+for impl_class in impl_classes:
+
+    base_impl = impl_class
+
+    # special case for Renderer
+    if impl_class != 'Renderer':
+        base_impl += 'Impl'
+
+    typed_impl = impl_class + renderer_suffix
+
+    h_file_path = os.path.join(renderer_name, typed_impl + '.h')
+    cpp_file_path = os.path.join(renderer_name, typed_impl + '.cpp')
+
+    h_file = open(h_file_path, 'w')
+    cpp_file = open(cpp_file_path, 'w')
+
+    # extract impl stubs
+    impl_stubs, private_impl_stubs, constructor = parse_impl_header(base_impl)
+
+    # more special case for Renderer
+    # TODO(jmadill): general case for base classes
+    if impl_class == 'Renderer':
+        base_impl_stubs, base_private_impl_stubs, base_constructor = parse_impl_header('ImplFactory')
+        impl_stubs += base_impl_stubs
+        private_impl_stubs += base_private_impl_stubs
+
     impl_method_declarations = ''
     impl_method_definitions = ''
     private_impl_method_declarations = ''
@@ -238,6 +255,5 @@
     h_file.write(string.Template(h_file_template).substitute(substitutions))
     cpp_file.write(string.Template(cpp_file_template).substitute(substitutions))
 
-    impl_h_file.close()
     h_file.close()
     cpp_file.close()
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi
index 3a91ce4..97b0d54 100644
--- a/src/libGLESv2.gypi
+++ b/src/libGLESv2.gypi
@@ -120,6 +120,7 @@
             'libANGLE/renderer/FenceNVImpl.h',
             'libANGLE/renderer/FenceSyncImpl.h',
             'libANGLE/renderer/FramebufferImpl.h',
+            'libANGLE/renderer/ImplFactory.h',
             'libANGLE/renderer/IndexRangeCache.cpp',
             'libANGLE/renderer/IndexRangeCache.h',
             'libANGLE/renderer/ProgramImpl.cpp',