Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / win / SkCreatePlatformGLContext_win.cpp
1
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9 #include "gl/SkGLContext.h"
10
11 #include <windows.h>
12 #include <GL/GL.h>
13 #include "SkWGL.h"
14
15 #define WIN32_LEAN_AND_MEAN
16 #include <windows.h>
17
18 namespace {
19
20 class WinGLContext : public SkGLContext {
21 public:
22     WinGLContext(GrGLStandard forcedGpuAPI);
23         virtual ~WinGLContext() SK_OVERRIDE;
24     virtual void makeCurrent() const SK_OVERRIDE;
25     virtual void swapBuffers() const SK_OVERRIDE;
26
27 private:
28     void destroyGLContext();
29
30     HWND fWindow;
31     HDC fDeviceContext;
32     HGLRC fGlRenderContext;
33     static ATOM gWC;
34     SkWGLPbufferContext* fPbufferContext;
35 };
36
37 ATOM WinGLContext::gWC = 0;
38
39 WinGLContext::WinGLContext(GrGLStandard forcedGpuAPI)
40     : fWindow(NULL)
41     , fDeviceContext(NULL)
42     , fGlRenderContext(0)
43     , fPbufferContext(NULL) {
44     HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
45
46     if (!gWC) {
47         WNDCLASS wc;
48         wc.cbClsExtra = 0;
49         wc.cbWndExtra = 0;
50         wc.hbrBackground = NULL;
51         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
52         wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
53         wc.hInstance = hInstance;
54         wc.lpfnWndProc = (WNDPROC) DefWindowProc;
55         wc.lpszClassName = TEXT("Griffin");
56         wc.lpszMenuName = NULL;
57         wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
58
59         gWC = RegisterClass(&wc);
60         if (!gWC) {
61             SkDebugf("Could not register window class.\n");
62             return;
63         }
64     }
65
66     if (!(fWindow = CreateWindow(TEXT("Griffin"),
67                                  TEXT("The Invisible Man"),
68                                  WS_OVERLAPPEDWINDOW,
69                                  0, 0, 1, 1,
70                                  NULL, NULL,
71                                  hInstance, NULL))) {
72         SkDebugf("Could not create window.\n");
73         return;
74     }
75
76     if (!(fDeviceContext = GetDC(fWindow))) {
77         SkDebugf("Could not get device context.\n");
78         this->destroyGLContext();
79         return;
80     }
81     // Requesting a Core profile would bar us from using NVPR. So we request
82     // compatibility profile or GL ES.
83     SkWGLContextRequest contextType =
84         kGLES_GrGLStandard == forcedGpuAPI ?
85         kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
86
87     fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType);
88
89     HDC dc;
90     HGLRC glrc;
91
92     if (NULL == fPbufferContext) {
93         if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, contextType))) {
94             SkDebugf("Could not create rendering context.\n");
95             this->destroyGLContext();
96             return;
97         }
98         dc = fDeviceContext;
99         glrc = fGlRenderContext;
100     } else {
101         ReleaseDC(fWindow, fDeviceContext);
102         fDeviceContext = 0;
103         DestroyWindow(fWindow);
104         fWindow = 0;
105
106         dc = fPbufferContext->getDC();
107         glrc = fPbufferContext->getGLRC();
108     }
109
110     if (!(wglMakeCurrent(dc, glrc))) {
111         SkDebugf("Could not set the context.\n");
112         this->destroyGLContext();
113         return;
114     }
115
116     fGL.reset(GrGLCreateNativeInterface());
117     if (NULL == fGL.get()) {
118         SkDebugf("Could not create GL interface.\n");
119         this->destroyGLContext();
120         return;
121     }
122     if (!fGL->validate()) {
123         SkDebugf("Could not validate GL interface.\n");
124         this->destroyGLContext();
125         return;
126     }
127 }
128
129 WinGLContext::~WinGLContext() {
130     this->destroyGLContext();
131 }
132
133 void WinGLContext::destroyGLContext() {
134     fGL.reset(NULL);
135     SkSafeSetNull(fPbufferContext);
136     if (fGlRenderContext) {
137         wglDeleteContext(fGlRenderContext);
138         fGlRenderContext = 0;
139     }
140     if (fWindow && fDeviceContext) {
141         ReleaseDC(fWindow, fDeviceContext);
142         fDeviceContext = 0;
143     }
144     if (fWindow) {
145         DestroyWindow(fWindow);
146         fWindow = 0;
147     }
148 }
149
150 void WinGLContext::makeCurrent() const {
151     HDC dc;
152     HGLRC glrc;
153
154     if (NULL == fPbufferContext) {
155         dc = fDeviceContext;
156         glrc = fGlRenderContext;
157     } else {
158         dc = fPbufferContext->getDC();
159         glrc = fPbufferContext->getGLRC();
160     }
161
162     if (!wglMakeCurrent(dc, glrc)) {
163         SkDebugf("Could not create rendering context.\n");
164     }
165 }
166
167 void WinGLContext::swapBuffers() const {
168     HDC dc;
169
170     if (NULL == fPbufferContext) {
171         dc = fDeviceContext;
172     } else {
173         dc = fPbufferContext->getDC();
174     }
175     if (!SwapBuffers(dc)) {
176         SkDebugf("Could not complete SwapBuffers.\n");
177     }
178 }
179
180 } // anonymous namespace
181
182 SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) {
183     WinGLContext* ctx = SkNEW_ARGS(WinGLContext, (forcedGpuAPI));
184     if (!ctx->isValid()) {
185         SkDELETE(ctx);
186         return NULL;
187     }
188     return ctx;
189 }
190