OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "gl/SkGLContext.h" | 8 #include "gl/SkGLContext.h" |
9 | 9 |
10 #include <X11/Xlib.h> | 10 #include <X11/Xlib.h> |
(...skipping 28 matching lines...) Expand all Loading... |
39 #define NUM_GL_VERSIONS SK_ARRAY_COUNT(gl_versions) | 39 #define NUM_GL_VERSIONS SK_ARRAY_COUNT(gl_versions) |
40 | 40 |
41 static bool ctxErrorOccurred = false; | 41 static bool ctxErrorOccurred = false; |
42 static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) { | 42 static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) { |
43 ctxErrorOccurred = true; | 43 ctxErrorOccurred = true; |
44 return 0; | 44 return 0; |
45 } | 45 } |
46 | 46 |
47 class GLXGLContext : public SkGLContext { | 47 class GLXGLContext : public SkGLContext { |
48 public: | 48 public: |
49 GLXGLContext(); | 49 GLXGLContext(GrGLStandard forcedGpuAPI); |
50 | 50 virtual ~GLXGLContext() SK_OVERRIDE; |
51 virtual ~GLXGLContext(); | |
52 | |
53 virtual void makeCurrent() const SK_OVERRIDE; | 51 virtual void makeCurrent() const SK_OVERRIDE; |
54 virtual void swapBuffers() const SK_OVERRIDE; | 52 virtual void swapBuffers() const SK_OVERRIDE; |
55 protected: | |
56 virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_O
VERRIDE; | |
57 virtual void destroyGLContext() SK_OVERRIDE; | |
58 | 53 |
59 private: | 54 private: |
| 55 void destroyGLContext(); |
| 56 |
60 GLXContext fContext; | 57 GLXContext fContext; |
61 Display* fDisplay; | 58 Display* fDisplay; |
62 Pixmap fPixmap; | 59 Pixmap fPixmap; |
63 GLXPixmap fGlxPixmap; | 60 GLXPixmap fGlxPixmap; |
64 }; | 61 }; |
65 | 62 |
66 GLXGLContext::GLXGLContext() | 63 GLXGLContext::GLXGLContext(GrGLStandard forcedGpuAPI) |
67 : fContext(NULL) | 64 : fContext(NULL) |
68 , fDisplay(NULL) | 65 , fDisplay(NULL) |
69 , fPixmap(0) | 66 , fPixmap(0) |
70 , fGlxPixmap(0) { | 67 , fGlxPixmap(0) { |
71 } | |
72 | 68 |
73 GLXGLContext::~GLXGLContext() { | |
74 this->destroyGLContext(); | |
75 } | |
76 | |
77 void GLXGLContext::destroyGLContext() { | |
78 if (fDisplay) { | |
79 glXMakeCurrent(fDisplay, 0, 0); | |
80 | |
81 if (fContext) { | |
82 glXDestroyContext(fDisplay, fContext); | |
83 fContext = NULL; | |
84 } | |
85 | |
86 if (fGlxPixmap) { | |
87 glXDestroyGLXPixmap(fDisplay, fGlxPixmap); | |
88 fGlxPixmap = 0; | |
89 } | |
90 | |
91 if (fPixmap) { | |
92 XFreePixmap(fDisplay, fPixmap); | |
93 fPixmap = 0; | |
94 } | |
95 | |
96 XCloseDisplay(fDisplay); | |
97 fDisplay = NULL; | |
98 } | |
99 } | |
100 | |
101 const GrGLInterface* GLXGLContext::createGLContext(GrGLStandard forcedGpuAPI) { | |
102 fDisplay = XOpenDisplay(0); | 69 fDisplay = XOpenDisplay(0); |
103 | 70 |
104 if (!fDisplay) { | 71 if (!fDisplay) { |
105 SkDebugf("Failed to open X display.\n"); | 72 SkDebugf("Failed to open X display.\n"); |
106 this->destroyGLContext(); | 73 this->destroyGLContext(); |
107 return NULL; | 74 return; |
108 } | 75 } |
109 | 76 |
110 // Get a matching FB config | 77 // Get a matching FB config |
111 static int visual_attribs[] = { | 78 static int visual_attribs[] = { |
112 GLX_X_RENDERABLE , True, | 79 GLX_X_RENDERABLE , True, |
113 GLX_DRAWABLE_TYPE , GLX_PIXMAP_BIT, | 80 GLX_DRAWABLE_TYPE , GLX_PIXMAP_BIT, |
114 None | 81 None |
115 }; | 82 }; |
116 | 83 |
117 int glx_major, glx_minor; | 84 int glx_major, glx_minor; |
118 | 85 |
119 // FBConfigs were added in GLX version 1.3. | 86 // FBConfigs were added in GLX version 1.3. |
120 if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) || | 87 if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) || |
121 ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) { | 88 ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) { |
122 SkDebugf("GLX version 1.3 or higher required.\n"); | 89 SkDebugf("GLX version 1.3 or higher required.\n"); |
123 this->destroyGLContext(); | 90 this->destroyGLContext(); |
124 return NULL; | 91 return; |
125 } | 92 } |
126 | 93 |
127 //SkDebugf("Getting matching framebuffer configs.\n"); | 94 //SkDebugf("Getting matching framebuffer configs.\n"); |
128 int fbcount; | 95 int fbcount; |
129 GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), | 96 GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), |
130 visual_attribs, &fbcount); | 97 visual_attribs, &fbcount); |
131 if (!fbc) { | 98 if (!fbc) { |
132 SkDebugf("Failed to retrieve a framebuffer config.\n"); | 99 SkDebugf("Failed to retrieve a framebuffer config.\n"); |
133 this->destroyGLContext(); | 100 this->destroyGLContext(); |
134 return NULL; | 101 return; |
135 } | 102 } |
136 //SkDebugf("Found %d matching FB configs.\n", fbcount); | 103 //SkDebugf("Found %d matching FB configs.\n", fbcount); |
137 | 104 |
138 // Pick the FB config/visual with the most samples per pixel | 105 // Pick the FB config/visual with the most samples per pixel |
139 //SkDebugf("Getting XVisualInfos.\n"); | 106 //SkDebugf("Getting XVisualInfos.\n"); |
140 int best_fbc = -1, best_num_samp = -1; | 107 int best_fbc = -1, best_num_samp = -1; |
141 | 108 |
142 int i; | 109 int i; |
143 for (i = 0; i < fbcount; ++i) { | 110 for (i = 0; i < fbcount; ++i) { |
144 XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]); | 111 XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]); |
(...skipping 19 matching lines...) Expand all Loading... |
164 | 131 |
165 // Get a visual | 132 // Get a visual |
166 XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc); | 133 XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc); |
167 //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid); | 134 //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid); |
168 | 135 |
169 fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10,
vi->depth); | 136 fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10,
vi->depth); |
170 | 137 |
171 if (!fPixmap) { | 138 if (!fPixmap) { |
172 SkDebugf("Failed to create pixmap.\n"); | 139 SkDebugf("Failed to create pixmap.\n"); |
173 this->destroyGLContext(); | 140 this->destroyGLContext(); |
174 return NULL; | 141 return; |
175 } | 142 } |
176 | 143 |
177 fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap); | 144 fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap); |
178 | 145 |
179 // Done with the visual info data | 146 // Done with the visual info data |
180 XFree(vi); | 147 XFree(vi); |
181 | 148 |
182 // Create the context | 149 // Create the context |
183 | 150 |
184 // Install an X error handler so the application won't exit if GL 3.0 | 151 // Install an X error handler so the application won't exit if GL 3.0 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 | 243 |
277 // Sync to ensure any errors generated are processed. | 244 // Sync to ensure any errors generated are processed. |
278 XSync(fDisplay, False); | 245 XSync(fDisplay, False); |
279 | 246 |
280 // Restore the original error handler | 247 // Restore the original error handler |
281 XSetErrorHandler(oldHandler); | 248 XSetErrorHandler(oldHandler); |
282 | 249 |
283 if (ctxErrorOccurred || !fContext) { | 250 if (ctxErrorOccurred || !fContext) { |
284 SkDebugf("Failed to create an OpenGL context.\n"); | 251 SkDebugf("Failed to create an OpenGL context.\n"); |
285 this->destroyGLContext(); | 252 this->destroyGLContext(); |
286 return NULL; | 253 return; |
287 } | 254 } |
288 | 255 |
289 // Verify that context is a direct context | 256 // Verify that context is a direct context |
290 if (!glXIsDirect(fDisplay, fContext)) { | 257 if (!glXIsDirect(fDisplay, fContext)) { |
291 //SkDebugf("Indirect GLX rendering context obtained.\n"); | 258 //SkDebugf("Indirect GLX rendering context obtained.\n"); |
292 } else { | 259 } else { |
293 //SkDebugf("Direct GLX rendering context obtained.\n"); | 260 //SkDebugf("Direct GLX rendering context obtained.\n"); |
294 } | 261 } |
295 | 262 |
296 //SkDebugf("Making context current.\n"); | 263 //SkDebugf("Making context current.\n"); |
297 if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { | 264 if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { |
298 SkDebugf("Could not set the context.\n"); | 265 SkDebugf("Could not set the context.\n"); |
299 this->destroyGLContext(); | 266 this->destroyGLContext(); |
300 return NULL; | 267 return; |
301 } | 268 } |
302 | 269 |
303 const GrGLInterface* interface = GrGLCreateNativeInterface(); | 270 fGL.reset(GrGLCreateNativeInterface()); |
304 if (!interface) { | 271 if (NULL == fGL.get()) { |
305 SkDebugf("Failed to create gl interface"); | 272 SkDebugf("Failed to create gl interface"); |
306 this->destroyGLContext(); | 273 this->destroyGLContext(); |
307 return NULL; | 274 return; |
308 } | 275 } |
309 return interface; | 276 |
| 277 if (!fGL->validate()) { |
| 278 SkDebugf("Failed to validate gl interface"); |
| 279 this->destroyGLContext(); |
| 280 return; |
| 281 } |
| 282 } |
| 283 |
| 284 |
| 285 GLXGLContext::~GLXGLContext() { |
| 286 this->destroyGLContext(); |
| 287 } |
| 288 |
| 289 void GLXGLContext::destroyGLContext() { |
| 290 fGL.reset(NULL); |
| 291 if (fDisplay) { |
| 292 glXMakeCurrent(fDisplay, 0, 0); |
| 293 |
| 294 if (fContext) { |
| 295 glXDestroyContext(fDisplay, fContext); |
| 296 fContext = NULL; |
| 297 } |
| 298 |
| 299 if (fGlxPixmap) { |
| 300 glXDestroyGLXPixmap(fDisplay, fGlxPixmap); |
| 301 fGlxPixmap = 0; |
| 302 } |
| 303 |
| 304 if (fPixmap) { |
| 305 XFreePixmap(fDisplay, fPixmap); |
| 306 fPixmap = 0; |
| 307 } |
| 308 |
| 309 XCloseDisplay(fDisplay); |
| 310 fDisplay = NULL; |
| 311 } |
310 } | 312 } |
311 | 313 |
312 void GLXGLContext::makeCurrent() const { | 314 void GLXGLContext::makeCurrent() const { |
313 if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { | 315 if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { |
314 SkDebugf("Could not set the context.\n"); | 316 SkDebugf("Could not set the context.\n"); |
315 } | 317 } |
316 } | 318 } |
317 | 319 |
318 void GLXGLContext::swapBuffers() const { | 320 void GLXGLContext::swapBuffers() const { |
319 glXSwapBuffers(fDisplay, fGlxPixmap); | 321 glXSwapBuffers(fDisplay, fGlxPixmap); |
320 } | 322 } |
321 | 323 |
322 } // anonymous namespace | 324 } // anonymous namespace |
323 | 325 |
324 SkGLContext* SkCreatePlatformGLContext() { | 326 SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) { |
325 return SkNEW(GLXGLContext); | 327 GLXGLContext* ctx = SkNEW_ARGS(GLXGLContext, (forcedGpuAPI)); |
| 328 if (!ctx->isValid()) { |
| 329 SkDELETE(ctx); |
| 330 return NULL; |
| 331 } |
| 332 return ctx; |
326 } | 333 } |
OLD | NEW |