aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils/win
diff options
context:
space:
mode:
authorGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-06-02 15:38:06 +0000
committerGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-06-02 15:38:06 +0000
commit3b0a8da8a5b484b981cbf73bfbaca1945b5b83c2 (patch)
tree478527450811a6c38e67cd5cf914826a0310104c /src/utils/win
parent0d831725f6d3e68650c8d3cbcafd7f4986b4b2cc (diff)
Add EGL context for Windows.
Diffstat (limited to 'src/utils/win')
-rw-r--r--src/utils/win/SkEGLContext_Win.cpp195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/utils/win/SkEGLContext_Win.cpp b/src/utils/win/SkEGLContext_Win.cpp
new file mode 100644
index 0000000000..2629ac3a5f
--- /dev/null
+++ b/src/utils/win/SkEGLContext_Win.cpp
@@ -0,0 +1,195 @@
+#define WIN32_LEAN_AND_MEAN 1
+#include <Windows.h>
+#include <GL/GL.h>
+
+#include "SkEGLContext.h"
+#include "SkTypes.h"
+
+#define SK_EGL_DECLARE_PROC(F) SkEGL ## F ## Proc SkEGL ## F = NULL;
+#define SK_EGL_GET_PROC(F) SkEGL ## F = (SkEGL ## F ## Proc) \
+ wglGetProcAddress("gl" #F);
+#define SK_EGL_GET_PROC_SUFFIX(F, S) SkEGL ## F = (SkEGL ## F ## Proc) \
+ wglGetProcAddress("gl" #F #S);
+
+#define SK_EGL_FRAMEBUFFER 0x8D40
+#define SK_EGL_RENDERBUFFER 0x8D41
+#define SK_EGL_COLOR_ATTACHMENT0 0x8CE0
+#define SK_EGL_DEPTH_STENCIL 0x84F9
+#define SK_EGL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define SK_EGL_FRAMEBUFFER_COMPLETE 0x8CD5
+
+#define SK_EGL_FUNCTION_TYPE __stdcall
+typedef void (SK_EGL_FUNCTION_TYPE *SkEGLGenFramebuffersProc) (GLsizei n, GLuint *framebuffers);
+typedef void (SK_EGL_FUNCTION_TYPE *SkEGLBindFramebufferProc) (GLenum target, GLuint framebuffer);
+typedef void (SK_EGL_FUNCTION_TYPE *SkEGLGenRenderbuffersProc) (GLsizei n, GLuint *renderbuffers);
+typedef void (SK_EGL_FUNCTION_TYPE *SkEGLBindRenderbufferProc) (GLenum target, GLuint renderbuffer);
+typedef void (SK_EGL_FUNCTION_TYPE *SkEGLRenderbufferStorageProc) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (SK_EGL_FUNCTION_TYPE *SkEGLFramebufferRenderbufferProc) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef GLenum (SK_EGL_FUNCTION_TYPE *SkEGLCheckFramebufferStatusProc) (GLenum target);
+
+SkEGLContext::SkEGLContext() :
+ fWindow(NULL)
+ , fDeviceContext(NULL)
+ , fGlRenderContext(0) {
+}
+
+SkEGLContext::~SkEGLContext() {
+ if (this->fGlRenderContext) {
+ wglDeleteContext(this->fGlRenderContext);
+ }
+ if (this->fWindow && this->fDeviceContext) {
+ ReleaseDC(this->fWindow, this->fDeviceContext);
+ }
+ if (this->fWindow) {
+ DestroyWindow(this->fWindow);
+ }
+}
+
+bool skEGLCheckExtension(const char* ext,
+ const char* extensionString) {
+ int extLength = strlen(ext);
+
+ while (true) {
+ int n = strcspn(extensionString, " ");
+ if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
+ return true;
+ }
+ if (0 == extensionString[n]) {
+ return false;
+ }
+ extensionString += n+1;
+ }
+
+ return false;
+}
+
+bool SkEGLContext::init(const int width, const int height) {
+ HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
+
+ WNDCLASS wc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hbrBackground = NULL;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hInstance = hInstance;
+ wc.lpfnWndProc = (WNDPROC) DefWindowProc;
+ wc.lpszClassName = TEXT("Griffin");
+ wc.lpszMenuName = NULL;
+ wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+
+ if (!RegisterClass(&wc)) {
+ SkDebugf("Could not register window class.\n");
+ return false;
+ }
+
+ if (!(
+ this->fWindow = CreateWindow(
+ TEXT("Griffin"),
+ TEXT("The Invisible Man"),
+ WS_OVERLAPPEDWINDOW,
+ 10, 10, // x, y
+ 200, 200, // width, height
+ NULL, NULL, // parent, menu
+ hInstance, NULL) // hInstance, param
+ ))
+ {
+ SkDebugf("Could not create window.\n");
+ return false;
+ }
+
+ if (!(this->fDeviceContext = GetDC(this->fWindow))) {
+ SkDebugf("Could not get device context.\n");
+ return false;
+ }
+
+ PIXELFORMATDESCRIPTOR pfd;
+ ZeroMemory(&pfd, sizeof(pfd));
+ pfd.nSize = sizeof(pfd);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW |
+ PFD_SUPPORT_OPENGL |
+ PFD_DOUBLEBUFFER;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 32;
+ pfd.cDepthBits = 24;
+ pfd.cStencilBits = 8;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ int pixelFormat = 0;
+ if (!(pixelFormat = ChoosePixelFormat(this->fDeviceContext, &pfd))) {
+ SkDebugf("No matching pixel format descriptor.\n");
+ return false;
+ }
+
+ if (!SetPixelFormat(this->fDeviceContext, pixelFormat, &pfd)) {
+ SkDebugf("Could not set the pixel format %d.\n", pixelFormat);
+ return false;
+ }
+
+ if (!(this->fGlRenderContext = wglCreateContext(this->fDeviceContext))) {
+ SkDebugf("Could not create rendering context.\n");
+ return false;
+ }
+
+ if (!(wglMakeCurrent(this->fDeviceContext, this->fGlRenderContext))) {
+ SkDebugf("Could not set the context.\n");
+ return false;
+ }
+
+ //TODO: in the future we need to use this context
+ // to test for WGL_ARB_create_context
+ // and then create a new window / context.
+
+ //Setup the framebuffers
+ const char* glExts =
+ reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
+ if (!skEGLCheckExtension(
+ "GL_EXT_framebuffer_object"
+ , glExts))
+ {
+ SkDebugf("GL_EXT_framebuffer_object not found.\n");
+ return false;
+ }
+ SK_EGL_DECLARE_PROC(GenFramebuffers)
+ SK_EGL_DECLARE_PROC(BindFramebuffer)
+ SK_EGL_DECLARE_PROC(GenRenderbuffers)
+ SK_EGL_DECLARE_PROC(BindRenderbuffer)
+ SK_EGL_DECLARE_PROC(RenderbufferStorage)
+ SK_EGL_DECLARE_PROC(FramebufferRenderbuffer)
+ SK_EGL_DECLARE_PROC(CheckFramebufferStatus)
+
+ SK_EGL_GET_PROC_SUFFIX(GenFramebuffers, EXT)
+ SK_EGL_GET_PROC_SUFFIX(BindFramebuffer, EXT)
+ SK_EGL_GET_PROC_SUFFIX(GenRenderbuffers, EXT)
+ SK_EGL_GET_PROC_SUFFIX(BindRenderbuffer, EXT)
+ SK_EGL_GET_PROC_SUFFIX(RenderbufferStorage, EXT)
+ SK_EGL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT)
+ SK_EGL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT)
+
+ GLuint fboID;
+ GLuint cbID;
+ GLuint dsID;
+ SkEGLGenFramebuffers(1, &fboID);
+ SkEGLBindFramebuffer(SK_EGL_FRAMEBUFFER, fboID);
+ SkEGLGenRenderbuffers(1, &cbID);
+ SkEGLBindRenderbuffer(SK_EGL_RENDERBUFFER, cbID);
+ SkEGLRenderbufferStorage(SK_EGL_RENDERBUFFER, GL_RGBA, width, height);
+ SkEGLFramebufferRenderbuffer(SK_EGL_FRAMEBUFFER
+ , SK_EGL_COLOR_ATTACHMENT0
+ , SK_EGL_RENDERBUFFER, cbID);
+ SkEGLGenRenderbuffers(1, &dsID);
+ SkEGLBindRenderbuffer(SK_EGL_RENDERBUFFER, dsID);
+ SkEGLRenderbufferStorage(SK_EGL_RENDERBUFFER, SK_EGL_DEPTH_STENCIL
+ , width, height);
+ SkEGLFramebufferRenderbuffer(SK_EGL_FRAMEBUFFER
+ , SK_EGL_DEPTH_STENCIL_ATTACHMENT
+ , SK_EGL_RENDERBUFFER
+ , dsID);
+ glViewport(0, 0, width, height);
+ glClearStencil(0);
+ glClear(GL_STENCIL_BUFFER_BIT);
+
+ GLenum status = SkEGLCheckFramebufferStatus(SK_EGL_FRAMEBUFFER);
+ return SK_EGL_FRAMEBUFFER_COMPLETE == status;
+}