diff options
author | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-06-02 15:38:06 +0000 |
---|---|---|
committer | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-06-02 15:38:06 +0000 |
commit | 3b0a8da8a5b484b981cbf73bfbaca1945b5b83c2 (patch) | |
tree | 478527450811a6c38e67cd5cf914826a0310104c /src/utils/win | |
parent | 0d831725f6d3e68650c8d3cbcafd7f4986b4b2cc (diff) |
Add EGL context for Windows.
http://codereview.appspot.com/4517133/
git-svn-id: http://skia.googlecode.com/svn/trunk@1481 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/utils/win')
-rw-r--r-- | src/utils/win/SkEGLContext_Win.cpp | 195 |
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; +} |