Virtualize SkGLContext with subclasses SkNativeGLContext and SkMesaGLContext, allow both in gm
Review URL: http://codereview.appspot.com/5307045/



git-svn-id: http://skia.googlecode.com/svn/trunk@2499 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/win/GrGLCreateNativeInterface_win.cpp b/src/gpu/win/GrGLCreateNativeInterface_win.cpp
new file mode 100644
index 0000000..d018906
--- /dev/null
+++ b/src/gpu/win/GrGLCreateNativeInterface_win.cpp
@@ -0,0 +1,199 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "GrGLInterface.h"
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <GL/GL.h>
+
+/*
+ * Windows makes the GL funcs all be __stdcall instead of __cdecl :(
+ * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall.
+ * Otherwise, a springboard would be needed that hides the calling convention.
+ */
+
+#define GR_GL_GET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F);
+#define GR_GL_GET_PROC_SUFFIX(F, S) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F #S);
+
+const GrGLInterface* GrGLCreateNativeInterface() {
+    // wglGetProcAddress requires a context.
+    // GL Function pointers retrieved in one context may not be valid in another
+    // context. For that reason we create a new GrGLInterface each time we're 
+    // called.
+    if (NULL != wglGetCurrentContext()) {
+        const char* versionString = (const char*) glGetString(GL_VERSION);
+        const char* extString = (const char*) glGetString(GL_EXTENSIONS);
+        GrGLVersion glVer = GrGLGetVersionFromString(versionString);
+
+        if (glVer < GR_GL_VER(1,5)) {
+            // We must have array and element_array buffer objects.
+            return NULL;
+        }
+        GrGLInterface* interface = new GrGLInterface();
+
+        interface->fNPOTRenderTargetSupport = kProbe_GrGLCapability;
+        interface->fMinRenderTargetHeight = kProbe_GrGLCapability;
+        interface->fMinRenderTargetWidth = kProbe_GrGLCapability;
+
+        // Functions that are part of GL 1.1 will return NULL in
+        // wglGetProcAddress
+        interface->fBindTexture = glBindTexture;
+        interface->fBlendFunc = glBlendFunc;
+        interface->fClear = glClear;
+        interface->fClearColor = glClearColor;
+        interface->fClearStencil = glClearStencil;
+        interface->fColor4ub = glColor4ub;
+        interface->fColorMask = glColorMask;
+        interface->fColorPointer = glColorPointer;
+        interface->fCullFace = glCullFace;
+        interface->fDeleteTextures = glDeleteTextures;
+        interface->fDepthMask = glDepthMask;
+        interface->fDisable = glDisable;
+        interface->fDisableClientState = glDisableClientState;
+        interface->fDrawArrays = glDrawArrays;
+        interface->fDrawElements = glDrawElements;
+        interface->fDrawBuffer = glDrawBuffer;
+        interface->fEnable = glEnable;
+        interface->fEnableClientState = glEnableClientState;
+        interface->fFrontFace = glFrontFace;
+        interface->fFinish = glFinish;
+        interface->fFlush = glFlush;
+        interface->fGenTextures = glGenTextures;
+        interface->fGetError = glGetError;
+        interface->fGetIntegerv = glGetIntegerv;
+        interface->fGetString = glGetString;
+        interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv;
+        interface->fLineWidth = glLineWidth;
+        interface->fLoadMatrixf = glLoadMatrixf;
+        interface->fMatrixMode = glMatrixMode;
+        interface->fPixelStorei = glPixelStorei;
+        interface->fPointSize = glPointSize;
+        interface->fReadBuffer = glReadBuffer;
+        interface->fReadPixels = glReadPixels;
+        interface->fScissor = glScissor;
+        interface->fShadeModel = glShadeModel;
+        interface->fStencilFunc = glStencilFunc;
+        interface->fStencilMask = glStencilMask;
+        interface->fStencilOp = glStencilOp;
+        interface->fTexImage2D = glTexImage2D;
+        interface->fTexParameteri = glTexParameteri;
+        interface->fTexCoordPointer = glTexCoordPointer;
+        interface->fTexEnvi = glTexEnvi;
+        interface->fTexSubImage2D = glTexSubImage2D;
+        interface->fViewport = glViewport;
+        interface->fVertexPointer = glVertexPointer;
+
+        GR_GL_GET_PROC(ActiveTexture);
+        GR_GL_GET_PROC(AttachShader);
+        GR_GL_GET_PROC(BindAttribLocation);
+        GR_GL_GET_PROC(BindBuffer);
+        GR_GL_GET_PROC(BindFragDataLocation);
+        GR_GL_GET_PROC(BlendColor);
+        GR_GL_GET_PROC(BufferData);
+        GR_GL_GET_PROC(BufferSubData);
+        GR_GL_GET_PROC(ClientActiveTexture);
+        GR_GL_GET_PROC(CompileShader);
+        GR_GL_GET_PROC(CompressedTexImage2D);
+        GR_GL_GET_PROC(CreateProgram);
+        GR_GL_GET_PROC(CreateShader);
+        GR_GL_GET_PROC(DeleteBuffers);
+        GR_GL_GET_PROC(DeleteProgram);
+        GR_GL_GET_PROC(DeleteShader);
+        GR_GL_GET_PROC(DisableVertexAttribArray);
+        GR_GL_GET_PROC(DrawBuffers);
+        GR_GL_GET_PROC(EnableVertexAttribArray);
+        GR_GL_GET_PROC(GenBuffers);
+        GR_GL_GET_PROC(GetBufferParameteriv);
+        GR_GL_GET_PROC(GetProgramInfoLog);
+        GR_GL_GET_PROC(GetProgramiv);
+        GR_GL_GET_PROC(GetShaderInfoLog);
+        GR_GL_GET_PROC(GetShaderiv);
+        GR_GL_GET_PROC(GetUniformLocation);
+        GR_GL_GET_PROC(LinkProgram);
+        GR_GL_GET_PROC(ShaderSource);
+        GR_GL_GET_PROC(StencilFuncSeparate);
+        GR_GL_GET_PROC(StencilMaskSeparate);
+        GR_GL_GET_PROC(StencilOpSeparate);
+        GR_GL_GET_PROC(Uniform1f);
+        GR_GL_GET_PROC(Uniform1i);
+        GR_GL_GET_PROC(Uniform1fv);
+        GR_GL_GET_PROC(Uniform1iv);
+        GR_GL_GET_PROC(Uniform2f);
+        GR_GL_GET_PROC(Uniform2i);
+        GR_GL_GET_PROC(Uniform2fv);
+        GR_GL_GET_PROC(Uniform2iv);
+        GR_GL_GET_PROC(Uniform3f);
+        GR_GL_GET_PROC(Uniform3i);
+        GR_GL_GET_PROC(Uniform3fv);
+        GR_GL_GET_PROC(Uniform3iv);
+        GR_GL_GET_PROC(Uniform4f);
+        GR_GL_GET_PROC(Uniform4i);
+        GR_GL_GET_PROC(Uniform4fv);
+        GR_GL_GET_PROC(Uniform4iv);
+        GR_GL_GET_PROC(UniformMatrix2fv);
+        GR_GL_GET_PROC(UniformMatrix3fv);
+        GR_GL_GET_PROC(UniformMatrix4fv);
+        GR_GL_GET_PROC(UseProgram);
+        GR_GL_GET_PROC(VertexAttrib4fv);
+        GR_GL_GET_PROC(VertexAttribPointer);
+        GR_GL_GET_PROC(BindFragDataLocationIndexed);
+
+        // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
+        // GL_ARB_framebuffer_object doesn't use ARB suffix.)
+        if (glVer > GR_GL_VER(3,0) || 
+            GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extString)) {
+            GR_GL_GET_PROC(GenFramebuffers);
+            GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv);
+            GR_GL_GET_PROC(GetRenderbufferParameteriv);
+            GR_GL_GET_PROC(BindFramebuffer);
+            GR_GL_GET_PROC(FramebufferTexture2D);
+            GR_GL_GET_PROC(CheckFramebufferStatus);
+            GR_GL_GET_PROC(DeleteFramebuffers);
+            GR_GL_GET_PROC(RenderbufferStorage);
+            GR_GL_GET_PROC(GenRenderbuffers);
+            GR_GL_GET_PROC(DeleteRenderbuffers);
+            GR_GL_GET_PROC(FramebufferRenderbuffer);
+            GR_GL_GET_PROC(BindRenderbuffer);
+            GR_GL_GET_PROC(RenderbufferStorageMultisample);
+            GR_GL_GET_PROC(BlitFramebuffer);
+        } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object",
+                   extString)) {
+            GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
+            GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
+            GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
+            GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT);
+            GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
+            GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
+            GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
+            GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT);
+            GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT);
+            GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
+            GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
+            GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
+            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extString)) {
+                GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
+            }
+            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", extString)) {
+                GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
+            }
+        } else {
+            // we must have FBOs
+            delete interface;
+            return NULL;
+        }
+        GR_GL_GET_PROC(MapBuffer);
+        GR_GL_GET_PROC(UnmapBuffer);
+
+        interface->fBindingsExported = kDesktop_GrGLBinding;
+
+        return interface;
+    } else {
+        return NULL;
+    }
+}