|
1 /* |
|
2 * Copyright (C) 2010 Google Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions are |
|
6 * met: |
|
7 * |
|
8 * * Redistributions of source code must retain the above copyright |
|
9 * notice, this list of conditions and the following disclaimer. |
|
10 * * Redistributions in binary form must reproduce the above |
|
11 * copyright notice, this list of conditions and the following disclaimer |
|
12 * in the documentation and/or other materials provided with the |
|
13 * distribution. |
|
14 * * Neither the name of Google Inc. nor the names of its |
|
15 * contributors may be used to endorse or promote products derived from |
|
16 * this software without specific prior written permission. |
|
17 * |
|
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
29 */ |
|
30 |
|
31 #include "config.h" |
|
32 |
|
33 #if ENABLE(3D_CANVAS) |
|
34 |
|
35 #include <stdio.h> |
|
36 #include <string.h> |
|
37 |
|
38 #include "WebGraphicsContext3DDefaultImpl.h" |
|
39 |
|
40 #include "NotImplemented.h" |
|
41 |
|
42 #if OS(LINUX) |
|
43 #include <dlfcn.h> |
|
44 #endif |
|
45 |
|
46 namespace WebKit { |
|
47 |
|
48 // Uncomment this to render to a separate window for debugging |
|
49 // #define RENDER_TO_DEBUGGING_WINDOW |
|
50 |
|
51 #if OS(DARWIN) |
|
52 #define USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER |
|
53 #endif |
|
54 |
|
55 bool WebGraphicsContext3DDefaultImpl::s_initializedGLEW = false; |
|
56 |
|
57 #if OS(LINUX) |
|
58 WebGraphicsContext3DDefaultImpl::GLConnection* WebGraphicsContext3DDefaultImpl::s_gl = 0; |
|
59 |
|
60 WebGraphicsContext3DDefaultImpl::GLConnection* WebGraphicsContext3DDefaultImpl::GLConnection::create() |
|
61 { |
|
62 Display* dpy = XOpenDisplay(0); |
|
63 if (!dpy) { |
|
64 printf("GraphicsContext3D: error opening X display\n"); |
|
65 return 0; |
|
66 } |
|
67 |
|
68 // We use RTLD_GLOBAL semantics so that GLEW initialization works; |
|
69 // GLEW expects to be able to open the current process's handle |
|
70 // and do dlsym's of GL entry points from there. |
|
71 void* libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); |
|
72 if (!libGL) { |
|
73 XCloseDisplay(dpy); |
|
74 printf("GraphicsContext3D: error opening libGL.so.1: %s\n", dlerror()); |
|
75 return 0; |
|
76 } |
|
77 |
|
78 PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(libGL, "glXChooseFBConfig"); |
|
79 PFNGLXCREATENEWCONTEXTPROC createNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(libGL, "glXCreateNewContext"); |
|
80 PFNGLXCREATEPBUFFERPROC createPbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(libGL, "glXCreatePbuffer"); |
|
81 PFNGLXDESTROYPBUFFERPROC destroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(libGL, "glXDestroyPbuffer"); |
|
82 PFNGLXMAKECURRENTPROC makeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(libGL, "glXMakeCurrent"); |
|
83 PFNGLXDESTROYCONTEXTPROC destroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(libGL, "glXDestroyContext"); |
|
84 PFNGLXGETCURRENTCONTEXTPROC getCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(libGL, "glXGetCurrentContext"); |
|
85 if (!chooseFBConfig || !createNewContext || !createPbuffer |
|
86 || !destroyPbuffer || !makeCurrent || !destroyContext |
|
87 || !getCurrentContext) { |
|
88 XCloseDisplay(dpy); |
|
89 dlclose(libGL); |
|
90 printf("GraphicsContext3D: error looking up bootstrapping entry points\n"); |
|
91 return 0; |
|
92 } |
|
93 return new GLConnection(dpy, |
|
94 libGL, |
|
95 chooseFBConfig, |
|
96 createNewContext, |
|
97 createPbuffer, |
|
98 destroyPbuffer, |
|
99 makeCurrent, |
|
100 destroyContext, |
|
101 getCurrentContext); |
|
102 } |
|
103 |
|
104 WebGraphicsContext3DDefaultImpl::GLConnection::~GLConnection() |
|
105 { |
|
106 XCloseDisplay(m_display); |
|
107 dlclose(m_libGL); |
|
108 } |
|
109 |
|
110 #endif // OS(LINUX) |
|
111 |
|
112 WebGraphicsContext3DDefaultImpl::VertexAttribPointerState::VertexAttribPointerState() |
|
113 : enabled(false) |
|
114 , buffer(0) |
|
115 , indx(0) |
|
116 , size(0) |
|
117 , type(0) |
|
118 , normalized(false) |
|
119 , stride(0) |
|
120 , offset(0) |
|
121 { |
|
122 } |
|
123 |
|
124 WebGraphicsContext3DDefaultImpl::WebGraphicsContext3DDefaultImpl() |
|
125 : m_initialized(false) |
|
126 , m_texture(0) |
|
127 , m_fbo(0) |
|
128 , m_depthStencilBuffer(0) |
|
129 , m_multisampleFBO(0) |
|
130 , m_multisampleDepthStencilBuffer(0) |
|
131 , m_multisampleColorBuffer(0) |
|
132 , m_boundFBO(0) |
|
133 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
|
134 , m_scanline(0) |
|
135 #endif |
|
136 , m_boundArrayBuffer(0) |
|
137 #if OS(WINDOWS) |
|
138 , m_canvasWindow(0) |
|
139 , m_canvasDC(0) |
|
140 , m_contextObj(0) |
|
141 #elif PLATFORM(CG) |
|
142 , m_pbuffer(0) |
|
143 , m_contextObj(0) |
|
144 , m_renderOutput(0) |
|
145 #elif OS(LINUX) |
|
146 , m_contextObj(0) |
|
147 , m_pbuffer(0) |
|
148 #else |
|
149 #error Must port to your platform |
|
150 #endif |
|
151 { |
|
152 } |
|
153 |
|
154 WebGraphicsContext3DDefaultImpl::~WebGraphicsContext3DDefaultImpl() |
|
155 { |
|
156 if (m_initialized) { |
|
157 makeContextCurrent(); |
|
158 #ifndef RENDER_TO_DEBUGGING_WINDOW |
|
159 if (m_attributes.antialias) { |
|
160 glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer); |
|
161 if (m_attributes.depth || m_attributes.stencil) |
|
162 glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer); |
|
163 glDeleteFramebuffersEXT(1, &m_multisampleFBO); |
|
164 } else { |
|
165 if (m_attributes.depth || m_attributes.stencil) |
|
166 glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer); |
|
167 } |
|
168 glDeleteTextures(1, &m_texture); |
|
169 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
|
170 if (m_scanline) |
|
171 delete[] m_scanline; |
|
172 #endif |
|
173 glDeleteFramebuffersEXT(1, &m_fbo); |
|
174 #endif // !RENDER_TO_DEBUGGING_WINDOW |
|
175 #if OS(WINDOWS) |
|
176 wglewMakeCurrent(0, 0); |
|
177 wglewDeleteContext(m_contextObj); |
|
178 ReleaseDC(m_canvasWindow, m_canvasDC); |
|
179 DestroyWindow(m_canvasWindow); |
|
180 #elif PLATFORM(CG) |
|
181 CGLSetCurrentContext(0); |
|
182 CGLDestroyContext(m_contextObj); |
|
183 CGLDestroyPBuffer(m_pbuffer); |
|
184 if (m_renderOutput) |
|
185 delete[] m_renderOutput; |
|
186 #elif OS(LINUX) |
|
187 s_gl->makeCurrent(0, 0); |
|
188 s_gl->destroyContext(m_contextObj); |
|
189 s_gl->destroyPbuffer(m_pbuffer); |
|
190 #else |
|
191 #error Must port to your platform |
|
192 #endif |
|
193 m_contextObj = 0; |
|
194 } |
|
195 } |
|
196 |
|
197 bool WebGraphicsContext3DDefaultImpl::initialize(WebGraphicsContext3D::Attributes attributes, WebView* webView) |
|
198 { |
|
199 #if OS(WINDOWS) |
|
200 if (!s_initializedGLEW) { |
|
201 // Do this only the first time through. |
|
202 if (!wglewInit()) { |
|
203 printf("WebGraphicsContext3DDefaultImpl: wglewInit failed\n"); |
|
204 return false; |
|
205 } |
|
206 } |
|
207 |
|
208 WNDCLASS wc; |
|
209 if (!GetClassInfo(GetModuleHandle(0), L"CANVASGL", &wc)) { |
|
210 ZeroMemory(&wc, sizeof(WNDCLASS)); |
|
211 wc.style = CS_OWNDC; |
|
212 wc.hInstance = GetModuleHandle(0); |
|
213 wc.lpfnWndProc = DefWindowProc; |
|
214 wc.lpszClassName = L"CANVASGL"; |
|
215 |
|
216 if (!RegisterClass(&wc)) { |
|
217 printf("WebGraphicsContext3DDefaultImpl: RegisterClass failed\n"); |
|
218 return false; |
|
219 } |
|
220 } |
|
221 |
|
222 m_canvasWindow = CreateWindow(L"CANVASGL", L"CANVASGL", |
|
223 WS_CAPTION, |
|
224 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, |
|
225 CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0); |
|
226 if (!m_canvasWindow) { |
|
227 printf("WebGraphicsContext3DDefaultImpl: CreateWindow failed\n"); |
|
228 return false; |
|
229 } |
|
230 |
|
231 // get the device context |
|
232 m_canvasDC = GetDC(m_canvasWindow); |
|
233 if (!m_canvasDC) { |
|
234 printf("WebGraphicsContext3DDefaultImpl: GetDC failed\n"); |
|
235 return false; |
|
236 } |
|
237 |
|
238 // find default pixel format |
|
239 PIXELFORMATDESCRIPTOR pfd; |
|
240 ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); |
|
241 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); |
|
242 pfd.nVersion = 1; |
|
243 #ifdef RENDER_TO_DEBUGGING_WINDOW |
|
244 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; |
|
245 #else |
|
246 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; |
|
247 #endif |
|
248 int pixelformat = ChoosePixelFormat(m_canvasDC, &pfd); |
|
249 |
|
250 // set the pixel format for the dc |
|
251 if (!SetPixelFormat(m_canvasDC, pixelformat, &pfd)) { |
|
252 printf("WebGraphicsContext3DDefaultImpl: SetPixelFormat failed\n"); |
|
253 return false; |
|
254 } |
|
255 |
|
256 // create rendering context |
|
257 m_contextObj = wglewCreateContext(m_canvasDC); |
|
258 if (!m_contextObj) { |
|
259 printf("WebGraphicsContext3DDefaultImpl: wglCreateContext failed\n"); |
|
260 return false; |
|
261 } |
|
262 |
|
263 if (!wglewMakeCurrent(m_canvasDC, m_contextObj)) { |
|
264 printf("WebGraphicsContext3DDefaultImpl: wglMakeCurrent failed\n"); |
|
265 return false; |
|
266 } |
|
267 |
|
268 #ifdef RENDER_TO_DEBUGGING_WINDOW |
|
269 typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); |
|
270 PFNWGLSWAPINTERVALEXTPROC setSwapInterval = 0; |
|
271 setSwapInterval = (PFNWGLSWAPINTERVALEXTPROC) wglewGetProcAddress("wglSwapIntervalEXT"); |
|
272 if (setSwapInterval) |
|
273 setSwapInterval(1); |
|
274 #endif // RENDER_TO_DEBUGGING_WINDOW |
|
275 |
|
276 #elif PLATFORM(CG) |
|
277 // Create a 1x1 pbuffer and associated context to bootstrap things |
|
278 CGLPixelFormatAttribute attribs[] = { |
|
279 (CGLPixelFormatAttribute) kCGLPFAPBuffer, |
|
280 (CGLPixelFormatAttribute) 0 |
|
281 }; |
|
282 CGLPixelFormatObj pixelFormat; |
|
283 GLint numPixelFormats; |
|
284 if (CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats) != kCGLNoError) { |
|
285 printf("WebGraphicsContext3DDefaultImpl: error choosing pixel format\n"); |
|
286 return false; |
|
287 } |
|
288 if (!pixelFormat) { |
|
289 printf("WebGraphicsContext3DDefaultImpl: no pixel format selected\n"); |
|
290 return false; |
|
291 } |
|
292 CGLContextObj context; |
|
293 CGLError res = CGLCreateContext(pixelFormat, 0, &context); |
|
294 CGLDestroyPixelFormat(pixelFormat); |
|
295 if (res != kCGLNoError) { |
|
296 printf("WebGraphicsContext3DDefaultImpl: error creating context\n"); |
|
297 return false; |
|
298 } |
|
299 CGLPBufferObj pbuffer; |
|
300 if (CGLCreatePBuffer(1, 1, GL_TEXTURE_2D, GL_RGBA, 0, &pbuffer) != kCGLNoError) { |
|
301 CGLDestroyContext(context); |
|
302 printf("WebGraphicsContext3DDefaultImpl: error creating pbuffer\n"); |
|
303 return false; |
|
304 } |
|
305 if (CGLSetPBuffer(context, pbuffer, 0, 0, 0) != kCGLNoError) { |
|
306 CGLDestroyContext(context); |
|
307 CGLDestroyPBuffer(pbuffer); |
|
308 printf("WebGraphicsContext3DDefaultImpl: error attaching pbuffer to context\n"); |
|
309 return false; |
|
310 } |
|
311 if (CGLSetCurrentContext(context) != kCGLNoError) { |
|
312 CGLDestroyContext(context); |
|
313 CGLDestroyPBuffer(pbuffer); |
|
314 printf("WebGraphicsContext3DDefaultImpl: error making context current\n"); |
|
315 return false; |
|
316 } |
|
317 m_pbuffer = pbuffer; |
|
318 m_contextObj = context; |
|
319 #elif OS(LINUX) |
|
320 if (!s_gl) { |
|
321 s_gl = GLConnection::create(); |
|
322 if (!s_gl) |
|
323 return false; |
|
324 } |
|
325 |
|
326 int configAttrs[] = { |
|
327 GLX_DRAWABLE_TYPE, |
|
328 GLX_PBUFFER_BIT, |
|
329 GLX_RENDER_TYPE, |
|
330 GLX_RGBA_BIT, |
|
331 GLX_DOUBLEBUFFER, |
|
332 0, |
|
333 0 |
|
334 }; |
|
335 int nelements = 0; |
|
336 GLXFBConfig* config = s_gl->chooseFBConfig(0, configAttrs, &nelements); |
|
337 if (!config) { |
|
338 printf("WebGraphicsContext3DDefaultImpl: glXChooseFBConfig failed\n"); |
|
339 return false; |
|
340 } |
|
341 if (!nelements) { |
|
342 printf("WebGraphicsContext3DDefaultImpl: glXChooseFBConfig returned 0 elements\n"); |
|
343 XFree(config); |
|
344 return false; |
|
345 } |
|
346 GLXContext context = s_gl->createNewContext(config[0], GLX_RGBA_TYPE, 0, True); |
|
347 if (!context) { |
|
348 printf("WebGraphicsContext3DDefaultImpl: glXCreateNewContext failed\n"); |
|
349 XFree(config); |
|
350 return false; |
|
351 } |
|
352 int pbufferAttrs[] = { |
|
353 GLX_PBUFFER_WIDTH, |
|
354 1, |
|
355 GLX_PBUFFER_HEIGHT, |
|
356 1, |
|
357 0 |
|
358 }; |
|
359 GLXPbuffer pbuffer = s_gl->createPbuffer(config[0], pbufferAttrs); |
|
360 XFree(config); |
|
361 if (!pbuffer) { |
|
362 printf("WebGraphicsContext3DDefaultImpl: glxCreatePbuffer failed\n"); |
|
363 return false; |
|
364 } |
|
365 if (!s_gl->makeCurrent(pbuffer, context)) { |
|
366 printf("WebGraphicsContext3DDefaultImpl: glXMakeCurrent failed\n"); |
|
367 return false; |
|
368 } |
|
369 m_contextObj = context; |
|
370 m_pbuffer = pbuffer; |
|
371 #else |
|
372 #error Must port to your platform |
|
373 #endif |
|
374 |
|
375 if (!s_initializedGLEW) { |
|
376 // Initialize GLEW and check for GL 2.0 support by the drivers. |
|
377 GLenum glewInitResult = glewInit(); |
|
378 if (glewInitResult != GLEW_OK) { |
|
379 printf("WebGraphicsContext3DDefaultImpl: GLEW initialization failed\n"); |
|
380 return false; |
|
381 } |
|
382 if (!glewIsSupported("GL_VERSION_2_0")) { |
|
383 printf("WebGraphicsContext3DDefaultImpl: OpenGL 2.0 not supported\n"); |
|
384 return false; |
|
385 } |
|
386 s_initializedGLEW = true; |
|
387 } |
|
388 |
|
389 m_attributes = attributes; |
|
390 validateAttributes(); |
|
391 |
|
392 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); |
|
393 m_initialized = true; |
|
394 return true; |
|
395 } |
|
396 |
|
397 void WebGraphicsContext3DDefaultImpl::validateAttributes() |
|
398 { |
|
399 const char* extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); |
|
400 |
|
401 if (m_attributes.stencil) { |
|
402 if (strstr(extensions, "GL_EXT_packed_depth_stencil")) { |
|
403 if (!m_attributes.depth) |
|
404 m_attributes.depth = true; |
|
405 } else |
|
406 m_attributes.stencil = false; |
|
407 } |
|
408 if (m_attributes.antialias) { |
|
409 bool isValidVendor = true; |
|
410 #if PLATFORM(CG) |
|
411 // Currently in Mac we only turn on antialias if vendor is NVIDIA. |
|
412 const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); |
|
413 if (!strstr(vendor, "NVIDIA")) |
|
414 isValidVendor = false; |
|
415 #endif |
|
416 if (!isValidVendor || !strstr(extensions, "GL_EXT_framebuffer_multisample")) |
|
417 m_attributes.antialias = false; |
|
418 } |
|
419 // FIXME: instead of enforcing premultipliedAlpha = true, implement the |
|
420 // correct behavior when premultipliedAlpha = false is requested. |
|
421 m_attributes.premultipliedAlpha = true; |
|
422 } |
|
423 |
|
424 bool WebGraphicsContext3DDefaultImpl::makeContextCurrent() |
|
425 { |
|
426 #if OS(WINDOWS) |
|
427 if (wglewGetCurrentContext() != m_contextObj) |
|
428 if (wglewMakeCurrent(m_canvasDC, m_contextObj)) |
|
429 return true; |
|
430 #elif PLATFORM(CG) |
|
431 if (CGLGetCurrentContext() != m_contextObj) |
|
432 if (CGLSetCurrentContext(m_contextObj) == kCGLNoError) |
|
433 return true; |
|
434 #elif OS(LINUX) |
|
435 if (s_gl->getCurrentContext() != m_contextObj) |
|
436 if (s_gl->makeCurrent(m_pbuffer, m_contextObj)) |
|
437 return true; |
|
438 #else |
|
439 #error Must port to your platform |
|
440 #endif |
|
441 return false; |
|
442 } |
|
443 |
|
444 int WebGraphicsContext3DDefaultImpl::width() |
|
445 { |
|
446 return m_cachedWidth; |
|
447 } |
|
448 |
|
449 int WebGraphicsContext3DDefaultImpl::height() |
|
450 { |
|
451 return m_cachedHeight; |
|
452 } |
|
453 |
|
454 int WebGraphicsContext3DDefaultImpl::sizeInBytes(int type) |
|
455 { |
|
456 switch (type) { |
|
457 case GL_BYTE: |
|
458 return sizeof(GLbyte); |
|
459 case GL_UNSIGNED_BYTE: |
|
460 return sizeof(GLubyte); |
|
461 case GL_SHORT: |
|
462 return sizeof(GLshort); |
|
463 case GL_UNSIGNED_SHORT: |
|
464 return sizeof(GLushort); |
|
465 case GL_INT: |
|
466 return sizeof(GLint); |
|
467 case GL_UNSIGNED_INT: |
|
468 return sizeof(GLuint); |
|
469 case GL_FLOAT: |
|
470 return sizeof(GLfloat); |
|
471 } |
|
472 return 0; |
|
473 } |
|
474 |
|
475 bool WebGraphicsContext3DDefaultImpl::isGLES2Compliant() |
|
476 { |
|
477 return false; |
|
478 } |
|
479 |
|
480 unsigned int WebGraphicsContext3DDefaultImpl::getPlatformTextureId() |
|
481 { |
|
482 ASSERT_NOT_REACHED(); |
|
483 return 0; |
|
484 } |
|
485 |
|
486 void WebGraphicsContext3DDefaultImpl::prepareTexture() |
|
487 { |
|
488 ASSERT_NOT_REACHED(); |
|
489 } |
|
490 |
|
491 static int createTextureObject(GLenum target) |
|
492 { |
|
493 GLuint texture = 0; |
|
494 glGenTextures(1, &texture); |
|
495 glBindTexture(target, texture); |
|
496 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
497 glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
498 return texture; |
|
499 } |
|
500 |
|
501 void WebGraphicsContext3DDefaultImpl::reshape(int width, int height) |
|
502 { |
|
503 #ifdef RENDER_TO_DEBUGGING_WINDOW |
|
504 SetWindowPos(m_canvasWindow, HWND_TOP, 0, 0, width, height, |
|
505 SWP_NOMOVE); |
|
506 ShowWindow(m_canvasWindow, SW_SHOW); |
|
507 #endif |
|
508 |
|
509 m_cachedWidth = width; |
|
510 m_cachedHeight = height; |
|
511 makeContextCurrent(); |
|
512 |
|
513 #ifndef RENDER_TO_DEBUGGING_WINDOW |
|
514 #ifdef USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER |
|
515 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on Mac OS X |
|
516 GLenum target = GL_TEXTURE_RECTANGLE_ARB; |
|
517 #else |
|
518 GLenum target = GL_TEXTURE_2D; |
|
519 #endif |
|
520 if (!m_texture) { |
|
521 // Generate the texture object |
|
522 m_texture = createTextureObject(target); |
|
523 // Generate the framebuffer object |
|
524 glGenFramebuffersEXT(1, &m_fbo); |
|
525 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); |
|
526 m_boundFBO = m_fbo; |
|
527 if (m_attributes.depth || m_attributes.stencil) |
|
528 glGenRenderbuffersEXT(1, &m_depthStencilBuffer); |
|
529 // Generate the multisample framebuffer object |
|
530 if (m_attributes.antialias) { |
|
531 glGenFramebuffersEXT(1, &m_multisampleFBO); |
|
532 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); |
|
533 m_boundFBO = m_multisampleFBO; |
|
534 glGenRenderbuffersEXT(1, &m_multisampleColorBuffer); |
|
535 if (m_attributes.depth || m_attributes.stencil) |
|
536 glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer); |
|
537 } |
|
538 } |
|
539 |
|
540 GLint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; |
|
541 if (m_attributes.alpha) { |
|
542 internalColorFormat = GL_RGBA8; |
|
543 colorFormat = GL_RGBA; |
|
544 } else { |
|
545 internalColorFormat = GL_RGB8; |
|
546 colorFormat = GL_RGB; |
|
547 } |
|
548 if (m_attributes.stencil || m_attributes.depth) { |
|
549 // We don't allow the logic where stencil is required and depth is not. |
|
550 // See GraphicsContext3DInternal constructor. |
|
551 if (m_attributes.stencil && m_attributes.depth) |
|
552 internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT; |
|
553 else |
|
554 internalDepthStencilFormat = GL_DEPTH_COMPONENT; |
|
555 } |
|
556 |
|
557 bool mustRestoreFBO = false; |
|
558 |
|
559 // Resize multisampling FBO |
|
560 if (m_attributes.antialias) { |
|
561 GLint maxSampleCount; |
|
562 glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount); |
|
563 GLint sampleCount = std::min(8, maxSampleCount); |
|
564 if (m_boundFBO != m_multisampleFBO) { |
|
565 mustRestoreFBO = true; |
|
566 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); |
|
567 } |
|
568 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); |
|
569 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height); |
|
570 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); |
|
571 if (m_attributes.stencil || m_attributes.depth) { |
|
572 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); |
|
573 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); |
|
574 if (m_attributes.stencil) |
|
575 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); |
|
576 if (m_attributes.depth) |
|
577 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); |
|
578 } |
|
579 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); |
|
580 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); |
|
581 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { |
|
582 printf("GraphicsContext3D: multisampling framebuffer was incomplete\n"); |
|
583 |
|
584 // FIXME: cleanup. |
|
585 notImplemented(); |
|
586 } |
|
587 } |
|
588 |
|
589 // Resize regular FBO |
|
590 if (m_boundFBO != m_fbo) { |
|
591 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); |
|
592 mustRestoreFBO = true; |
|
593 } |
|
594 glBindTexture(target, m_texture); |
|
595 glTexImage2D(target, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0); |
|
596 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0); |
|
597 glBindTexture(target, 0); |
|
598 if (!m_attributes.antialias && (m_attributes.stencil || m_attributes.depth)) { |
|
599 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); |
|
600 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height); |
|
601 if (m_attributes.stencil) |
|
602 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); |
|
603 if (m_attributes.depth) |
|
604 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); |
|
605 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); |
|
606 } |
|
607 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); |
|
608 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { |
|
609 printf("WebGraphicsContext3DDefaultImpl: framebuffer was incomplete\n"); |
|
610 |
|
611 // FIXME: cleanup. |
|
612 notImplemented(); |
|
613 } |
|
614 |
|
615 if (m_attributes.antialias) { |
|
616 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); |
|
617 if (m_boundFBO == m_multisampleFBO) |
|
618 mustRestoreFBO = false; |
|
619 } |
|
620 |
|
621 // Initialize renderbuffers to 0. |
|
622 GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE, stencilMask = GL_TRUE; |
|
623 GLboolean isScissorEnabled = GL_FALSE; |
|
624 GLboolean isDitherEnabled = GL_FALSE; |
|
625 GLbitfield clearMask = GL_COLOR_BUFFER_BIT; |
|
626 glGetBooleanv(GL_COLOR_WRITEMASK, colorMask); |
|
627 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
|
628 if (m_attributes.depth) { |
|
629 glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); |
|
630 glDepthMask(GL_TRUE); |
|
631 clearMask |= GL_DEPTH_BUFFER_BIT; |
|
632 } |
|
633 if (m_attributes.stencil) { |
|
634 glGetBooleanv(GL_STENCIL_WRITEMASK, &stencilMask); |
|
635 glStencilMask(GL_TRUE); |
|
636 clearMask |= GL_STENCIL_BUFFER_BIT; |
|
637 } |
|
638 isScissorEnabled = glIsEnabled(GL_SCISSOR_TEST); |
|
639 glDisable(GL_SCISSOR_TEST); |
|
640 isDitherEnabled = glIsEnabled(GL_DITHER); |
|
641 glDisable(GL_DITHER); |
|
642 |
|
643 glClear(clearMask); |
|
644 |
|
645 glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]); |
|
646 if (m_attributes.depth) |
|
647 glDepthMask(depthMask); |
|
648 if (m_attributes.stencil) |
|
649 glStencilMask(stencilMask); |
|
650 if (isScissorEnabled) |
|
651 glEnable(GL_SCISSOR_TEST); |
|
652 else |
|
653 glDisable(GL_SCISSOR_TEST); |
|
654 if (isDitherEnabled) |
|
655 glEnable(GL_DITHER); |
|
656 else |
|
657 glDisable(GL_DITHER); |
|
658 |
|
659 if (mustRestoreFBO) |
|
660 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); |
|
661 #endif // RENDER_TO_DEBUGGING_WINDOW |
|
662 |
|
663 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
|
664 if (m_scanline) { |
|
665 delete[] m_scanline; |
|
666 m_scanline = 0; |
|
667 } |
|
668 m_scanline = new unsigned char[width * 4]; |
|
669 #endif // FLIP_FRAMEBUFFER_VERTICALLY |
|
670 } |
|
671 |
|
672 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
|
673 void WebGraphicsContext3DDefaultImpl::flipVertically(unsigned char* framebuffer, |
|
674 unsigned int width, |
|
675 unsigned int height) |
|
676 { |
|
677 unsigned char* scanline = m_scanline; |
|
678 if (!scanline) |
|
679 return; |
|
680 unsigned int rowBytes = width * 4; |
|
681 unsigned int count = height / 2; |
|
682 for (unsigned int i = 0; i < count; i++) { |
|
683 unsigned char* rowA = framebuffer + i * rowBytes; |
|
684 unsigned char* rowB = framebuffer + (height - i - 1) * rowBytes; |
|
685 // FIXME: this is where the multiplication of the alpha |
|
686 // channel into the color buffer will need to occur if the |
|
687 // user specifies the "premultiplyAlpha" flag in the context |
|
688 // creation attributes. |
|
689 memcpy(scanline, rowB, rowBytes); |
|
690 memcpy(rowB, rowA, rowBytes); |
|
691 memcpy(rowA, scanline, rowBytes); |
|
692 } |
|
693 } |
|
694 #endif |
|
695 |
|
696 bool WebGraphicsContext3DDefaultImpl::readBackFramebuffer(unsigned char* pixels, size_t bufferSize) |
|
697 { |
|
698 if (bufferSize != static_cast<size_t>(4 * width() * height())) |
|
699 return false; |
|
700 |
|
701 makeContextCurrent(); |
|
702 |
|
703 #ifdef RENDER_TO_DEBUGGING_WINDOW |
|
704 SwapBuffers(m_canvasDC); |
|
705 #else |
|
706 // Earlier versions of this code used the GPU to flip the |
|
707 // framebuffer vertically before reading it back for compositing |
|
708 // via software. This code was quite complicated, used a lot of |
|
709 // GPU memory, and didn't provide an obvious speedup. Since this |
|
710 // vertical flip is only a temporary solution anyway until Chrome |
|
711 // is fully GPU composited, it wasn't worth the complexity. |
|
712 |
|
713 bool mustRestoreFBO = false; |
|
714 if (m_attributes.antialias) { |
|
715 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); |
|
716 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); |
|
717 glBlitFramebufferEXT(0, 0, m_cachedWidth, m_cachedHeight, 0, 0, m_cachedWidth, m_cachedHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); |
|
718 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); |
|
719 mustRestoreFBO = true; |
|
720 } else { |
|
721 if (m_boundFBO != m_fbo) { |
|
722 mustRestoreFBO = true; |
|
723 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); |
|
724 } |
|
725 } |
|
726 |
|
727 GLint packAlignment = 4; |
|
728 bool mustRestorePackAlignment = false; |
|
729 glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); |
|
730 if (packAlignment > 4) { |
|
731 glPixelStorei(GL_PACK_ALIGNMENT, 4); |
|
732 mustRestorePackAlignment = true; |
|
733 } |
|
734 |
|
735 #if PLATFORM(SKIA) |
|
736 glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); |
|
737 #elif PLATFORM(CG) |
|
738 glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels); |
|
739 #else |
|
740 #error Must port to your platform |
|
741 #endif |
|
742 |
|
743 if (mustRestorePackAlignment) |
|
744 glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); |
|
745 |
|
746 if (mustRestoreFBO) |
|
747 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); |
|
748 |
|
749 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
|
750 if (pixels) |
|
751 flipVertically(pixels, m_cachedWidth, m_cachedHeight); |
|
752 #endif |
|
753 |
|
754 #endif // RENDER_TO_DEBUGGING_WINDOW |
|
755 return true; |
|
756 } |
|
757 |
|
758 void WebGraphicsContext3DDefaultImpl::synthesizeGLError(unsigned long error) |
|
759 { |
|
760 m_syntheticErrors.add(error); |
|
761 } |
|
762 |
|
763 // Helper macros to reduce the amount of code. |
|
764 |
|
765 #define DELEGATE_TO_GL(name, glname) \ |
|
766 void WebGraphicsContext3DDefaultImpl::name() \ |
|
767 { \ |
|
768 makeContextCurrent(); \ |
|
769 gl##glname(); \ |
|
770 } |
|
771 |
|
772 #define DELEGATE_TO_GL_1(name, glname, t1) \ |
|
773 void WebGraphicsContext3DDefaultImpl::name(t1 a1) \ |
|
774 { \ |
|
775 makeContextCurrent(); \ |
|
776 gl##glname(a1); \ |
|
777 } |
|
778 |
|
779 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ |
|
780 rt WebGraphicsContext3DDefaultImpl::name(t1 a1) \ |
|
781 { \ |
|
782 makeContextCurrent(); \ |
|
783 return gl##glname(a1); \ |
|
784 } |
|
785 |
|
786 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \ |
|
787 void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2) \ |
|
788 { \ |
|
789 makeContextCurrent(); \ |
|
790 gl##glname(a1, a2); \ |
|
791 } |
|
792 |
|
793 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ |
|
794 rt WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2) \ |
|
795 { \ |
|
796 makeContextCurrent(); \ |
|
797 return gl##glname(a1, a2); \ |
|
798 } |
|
799 |
|
800 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ |
|
801 void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3) \ |
|
802 { \ |
|
803 makeContextCurrent(); \ |
|
804 gl##glname(a1, a2, a3); \ |
|
805 } |
|
806 |
|
807 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ |
|
808 void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4) \ |
|
809 { \ |
|
810 makeContextCurrent(); \ |
|
811 gl##glname(a1, a2, a3, a4); \ |
|
812 } |
|
813 |
|
814 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ |
|
815 void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ |
|
816 { \ |
|
817 makeContextCurrent(); \ |
|
818 gl##glname(a1, a2, a3, a4, a5); \ |
|
819 } |
|
820 |
|
821 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ |
|
822 void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ |
|
823 { \ |
|
824 makeContextCurrent(); \ |
|
825 gl##glname(a1, a2, a3, a4, a5, a6); \ |
|
826 } |
|
827 |
|
828 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ |
|
829 void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ |
|
830 { \ |
|
831 makeContextCurrent(); \ |
|
832 gl##glname(a1, a2, a3, a4, a5, a6, a7); \ |
|
833 } |
|
834 |
|
835 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ |
|
836 void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \ |
|
837 { \ |
|
838 makeContextCurrent(); \ |
|
839 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \ |
|
840 } |
|
841 |
|
842 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ |
|
843 void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) \ |
|
844 { \ |
|
845 makeContextCurrent(); \ |
|
846 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ |
|
847 } |
|
848 |
|
849 void WebGraphicsContext3DDefaultImpl::activeTexture(unsigned long texture) |
|
850 { |
|
851 // FIXME: query number of textures available. |
|
852 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32) |
|
853 // FIXME: raise exception. |
|
854 return; |
|
855 |
|
856 makeContextCurrent(); |
|
857 glActiveTexture(texture); |
|
858 } |
|
859 |
|
860 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId) |
|
861 |
|
862 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId, unsigned long, const char*) |
|
863 |
|
864 void WebGraphicsContext3DDefaultImpl::bindBuffer(unsigned long target, WebGLId buffer) |
|
865 { |
|
866 makeContextCurrent(); |
|
867 if (target == GL_ARRAY_BUFFER) |
|
868 m_boundArrayBuffer = buffer; |
|
869 glBindBuffer(target, buffer); |
|
870 } |
|
871 |
|
872 void WebGraphicsContext3DDefaultImpl::bindFramebuffer(unsigned long target, WebGLId framebuffer) |
|
873 { |
|
874 makeContextCurrent(); |
|
875 if (!framebuffer) |
|
876 framebuffer = (m_attributes.antialias ? m_multisampleFBO : m_fbo); |
|
877 if (framebuffer != m_boundFBO) { |
|
878 glBindFramebufferEXT(target, framebuffer); |
|
879 m_boundFBO = framebuffer; |
|
880 } |
|
881 } |
|
882 |
|
883 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbufferEXT, unsigned long, WebGLId) |
|
884 |
|
885 DELEGATE_TO_GL_2(bindTexture, BindTexture, unsigned long, WebGLId) |
|
886 |
|
887 DELEGATE_TO_GL_4(blendColor, BlendColor, double, double, double, double) |
|
888 |
|
889 DELEGATE_TO_GL_1(blendEquation, BlendEquation, unsigned long) |
|
890 |
|
891 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate, unsigned long, unsigned long) |
|
892 |
|
893 DELEGATE_TO_GL_2(blendFunc, BlendFunc, unsigned long, unsigned long) |
|
894 |
|
895 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long) |
|
896 |
|
897 DELEGATE_TO_GL_4(bufferData, BufferData, unsigned long, int, const void*, unsigned long) |
|
898 |
|
899 DELEGATE_TO_GL_4(bufferSubData, BufferSubData, unsigned long, long, int, const void*) |
|
900 |
|
901 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatusEXT, unsigned long, unsigned long) |
|
902 |
|
903 DELEGATE_TO_GL_1(clear, Clear, unsigned long) |
|
904 |
|
905 DELEGATE_TO_GL_4(clearColor, ClearColor, double, double, double, double) |
|
906 |
|
907 DELEGATE_TO_GL_1(clearDepth, ClearDepth, double) |
|
908 |
|
909 DELEGATE_TO_GL_1(clearStencil, ClearStencil, long) |
|
910 |
|
911 DELEGATE_TO_GL_4(colorMask, ColorMask, bool, bool, bool, bool) |
|
912 |
|
913 DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId) |
|
914 |
|
915 void WebGraphicsContext3DDefaultImpl::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, |
|
916 long x, long y, unsigned long width, unsigned long height, long border) |
|
917 { |
|
918 makeContextCurrent(); |
|
919 #ifndef RENDER_TO_DEBUGGING_WINDOW |
|
920 if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { |
|
921 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); |
|
922 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); |
|
923 glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); |
|
924 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); |
|
925 } |
|
926 #endif |
|
927 glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); |
|
928 #ifndef RENDER_TO_DEBUGGING_WINDOW |
|
929 if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) |
|
930 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); |
|
931 #endif |
|
932 } |
|
933 |
|
934 void WebGraphicsContext3DDefaultImpl::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, |
|
935 long x, long y, unsigned long width, unsigned long height) |
|
936 { |
|
937 makeContextCurrent(); |
|
938 #ifndef RENDER_TO_DEBUGGING_WINDOW |
|
939 if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { |
|
940 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); |
|
941 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); |
|
942 glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); |
|
943 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); |
|
944 } |
|
945 #endif |
|
946 glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); |
|
947 #ifndef RENDER_TO_DEBUGGING_WINDOW |
|
948 if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) |
|
949 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); |
|
950 #endif |
|
951 } |
|
952 |
|
953 DELEGATE_TO_GL_1(cullFace, CullFace, unsigned long) |
|
954 |
|
955 DELEGATE_TO_GL_1(depthFunc, DepthFunc, unsigned long) |
|
956 |
|
957 DELEGATE_TO_GL_1(depthMask, DepthMask, bool) |
|
958 |
|
959 DELEGATE_TO_GL_2(depthRange, DepthRange, double, double) |
|
960 |
|
961 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId) |
|
962 |
|
963 DELEGATE_TO_GL_1(disable, Disable, unsigned long) |
|
964 |
|
965 void WebGraphicsContext3DDefaultImpl::disableVertexAttribArray(unsigned long index) |
|
966 { |
|
967 makeContextCurrent(); |
|
968 if (index < NumTrackedPointerStates) |
|
969 m_vertexAttribPointerState[index].enabled = false; |
|
970 glDisableVertexAttribArray(index); |
|
971 } |
|
972 |
|
973 DELEGATE_TO_GL_3(drawArrays, DrawArrays, unsigned long, long, long) |
|
974 |
|
975 void WebGraphicsContext3DDefaultImpl::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset) |
|
976 { |
|
977 makeContextCurrent(); |
|
978 glDrawElements(mode, count, type, |
|
979 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); |
|
980 } |
|
981 |
|
982 DELEGATE_TO_GL_1(enable, Enable, unsigned long) |
|
983 |
|
984 void WebGraphicsContext3DDefaultImpl::enableVertexAttribArray(unsigned long index) |
|
985 { |
|
986 makeContextCurrent(); |
|
987 if (index < NumTrackedPointerStates) |
|
988 m_vertexAttribPointerState[index].enabled = true; |
|
989 glEnableVertexAttribArray(index); |
|
990 } |
|
991 |
|
992 DELEGATE_TO_GL(finish, Finish) |
|
993 |
|
994 DELEGATE_TO_GL(flush, Flush) |
|
995 |
|
996 void WebGraphicsContext3DDefaultImpl::framebufferRenderbuffer(unsigned long target, unsigned long attachment, |
|
997 unsigned long renderbuffertarget, WebGLId buffer) |
|
998 { |
|
999 makeContextCurrent(); |
|
1000 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { |
|
1001 glFramebufferRenderbufferEXT(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, buffer); |
|
1002 glFramebufferRenderbufferEXT(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, buffer); |
|
1003 } else |
|
1004 glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, buffer); |
|
1005 } |
|
1006 |
|
1007 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2DEXT, unsigned long, unsigned long, unsigned long, WebGLId, long) |
|
1008 |
|
1009 DELEGATE_TO_GL_1(frontFace, FrontFace, unsigned long) |
|
1010 |
|
1011 void WebGraphicsContext3DDefaultImpl::generateMipmap(unsigned long target) |
|
1012 { |
|
1013 makeContextCurrent(); |
|
1014 if (glGenerateMipmapEXT) |
|
1015 glGenerateMipmapEXT(target); |
|
1016 // FIXME: provide alternative code path? This will be unpleasant |
|
1017 // to implement if glGenerateMipmapEXT is not available -- it will |
|
1018 // require a texture readback and re-upload. |
|
1019 } |
|
1020 |
|
1021 bool WebGraphicsContext3DDefaultImpl::getActiveAttrib(WebGLId program, unsigned long index, ActiveInfo& info) |
|
1022 { |
|
1023 makeContextCurrent(); |
|
1024 if (!program) { |
|
1025 synthesizeGLError(GL_INVALID_VALUE); |
|
1026 return false; |
|
1027 } |
|
1028 GLint maxNameLength = -1; |
|
1029 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength); |
|
1030 if (maxNameLength < 0) |
|
1031 return false; |
|
1032 GLchar* name = 0; |
|
1033 if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { |
|
1034 synthesizeGLError(GL_OUT_OF_MEMORY); |
|
1035 return false; |
|
1036 } |
|
1037 GLsizei length = 0; |
|
1038 GLint size = -1; |
|
1039 GLenum type = 0; |
|
1040 glGetActiveAttrib(program, index, maxNameLength, |
|
1041 &length, &size, &type, name); |
|
1042 if (size < 0) { |
|
1043 fastFree(name); |
|
1044 return false; |
|
1045 } |
|
1046 info.name = WebString::fromUTF8(name, length); |
|
1047 info.type = type; |
|
1048 info.size = size; |
|
1049 fastFree(name); |
|
1050 return true; |
|
1051 } |
|
1052 |
|
1053 bool WebGraphicsContext3DDefaultImpl::getActiveUniform(WebGLId program, unsigned long index, ActiveInfo& info) |
|
1054 { |
|
1055 makeContextCurrent(); |
|
1056 GLint maxNameLength = -1; |
|
1057 glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); |
|
1058 if (maxNameLength < 0) |
|
1059 return false; |
|
1060 GLchar* name = 0; |
|
1061 if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { |
|
1062 synthesizeGLError(GL_OUT_OF_MEMORY); |
|
1063 return false; |
|
1064 } |
|
1065 GLsizei length = 0; |
|
1066 GLint size = -1; |
|
1067 GLenum type = 0; |
|
1068 glGetActiveUniform(program, index, maxNameLength, |
|
1069 &length, &size, &type, name); |
|
1070 if (size < 0) { |
|
1071 fastFree(name); |
|
1072 return false; |
|
1073 } |
|
1074 info.name = WebString::fromUTF8(name, length); |
|
1075 info.type = type; |
|
1076 info.size = size; |
|
1077 fastFree(name); |
|
1078 return true; |
|
1079 } |
|
1080 |
|
1081 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders, WebGLId, int, int*, unsigned int*) |
|
1082 |
|
1083 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation, WebGLId, const char*, int) |
|
1084 |
|
1085 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, unsigned long, unsigned char*) |
|
1086 |
|
1087 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv, unsigned long, unsigned long, int*) |
|
1088 |
|
1089 WebGraphicsContext3D::Attributes WebGraphicsContext3DDefaultImpl::getContextAttributes() |
|
1090 { |
|
1091 return m_attributes; |
|
1092 } |
|
1093 |
|
1094 unsigned long WebGraphicsContext3DDefaultImpl::getError() |
|
1095 { |
|
1096 if (m_syntheticErrors.size() > 0) { |
|
1097 ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin(); |
|
1098 unsigned long err = *iter; |
|
1099 m_syntheticErrors.remove(iter); |
|
1100 return err; |
|
1101 } |
|
1102 |
|
1103 makeContextCurrent(); |
|
1104 return glGetError(); |
|
1105 } |
|
1106 |
|
1107 DELEGATE_TO_GL_2(getFloatv, GetFloatv, unsigned long, float*) |
|
1108 |
|
1109 void WebGraphicsContext3DDefaultImpl::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, |
|
1110 unsigned long pname, int* value) |
|
1111 { |
|
1112 makeContextCurrent(); |
|
1113 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) |
|
1114 attachment = GL_DEPTH_ATTACHMENT; // Or GL_STENCIL_ATTACHMENT, either works. |
|
1115 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); |
|
1116 } |
|
1117 |
|
1118 void WebGraphicsContext3DDefaultImpl::getIntegerv(unsigned long pname, int* value) |
|
1119 { |
|
1120 // Need to emulate IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for GL. Any valid |
|
1121 // combination should work, but GL_RGB/GL_UNSIGNED_BYTE might be the most |
|
1122 // useful for desktop WebGL users. |
|
1123 // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS |
|
1124 // because desktop GL's corresponding queries return the number of components |
|
1125 // whereas GLES2 return the number of vectors (each vector has 4 components). |
|
1126 // Therefore, the value returned by desktop GL needs to be divided by 4. |
|
1127 makeContextCurrent(); |
|
1128 switch (pname) { |
|
1129 case 0x8B9B: // IMPLEMENTATION_COLOR_READ_FORMAT |
|
1130 *value = GL_RGB; |
|
1131 break; |
|
1132 case 0x8B9A: // IMPLEMENTATION_COLOR_READ_TYPE |
|
1133 *value = GL_UNSIGNED_BYTE; |
|
1134 break; |
|
1135 case 0x8DFD: // MAX_FRAGMENT_UNIFORM_VECTORS |
|
1136 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value); |
|
1137 *value /= 4; |
|
1138 break; |
|
1139 case 0x8DFB: // MAX_VERTEX_UNIFORM_VECTORS |
|
1140 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value); |
|
1141 *value /= 4; |
|
1142 break; |
|
1143 case 0x8DFC: // MAX_VARYING_VECTORS |
|
1144 glGetIntegerv(GL_MAX_VARYING_FLOATS, value); |
|
1145 *value /= 4; |
|
1146 break; |
|
1147 default: |
|
1148 glGetIntegerv(pname, value); |
|
1149 } |
|
1150 } |
|
1151 |
|
1152 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, unsigned long, int*) |
|
1153 |
|
1154 WebString WebGraphicsContext3DDefaultImpl::getProgramInfoLog(WebGLId program) |
|
1155 { |
|
1156 makeContextCurrent(); |
|
1157 GLint logLength; |
|
1158 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); |
|
1159 if (!logLength) |
|
1160 return WebString(); |
|
1161 GLchar* log = 0; |
|
1162 if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) |
|
1163 return WebString(); |
|
1164 GLsizei returnedLogLength; |
|
1165 glGetProgramInfoLog(program, logLength, &returnedLogLength, log); |
|
1166 ASSERT(logLength == returnedLogLength + 1); |
|
1167 WebString res = WebString::fromUTF8(log, returnedLogLength); |
|
1168 fastFree(log); |
|
1169 return res; |
|
1170 } |
|
1171 |
|
1172 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameterivEXT, unsigned long, unsigned long, int*) |
|
1173 |
|
1174 DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, unsigned long, int*) |
|
1175 |
|
1176 WebString WebGraphicsContext3DDefaultImpl::getShaderInfoLog(WebGLId shader) |
|
1177 { |
|
1178 makeContextCurrent(); |
|
1179 GLint logLength; |
|
1180 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); |
|
1181 if (!logLength) |
|
1182 return WebString(); |
|
1183 GLchar* log = 0; |
|
1184 if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) |
|
1185 return WebString(); |
|
1186 GLsizei returnedLogLength; |
|
1187 glGetShaderInfoLog(shader, logLength, &returnedLogLength, log); |
|
1188 ASSERT(logLength == returnedLogLength + 1); |
|
1189 WebString res = WebString::fromUTF8(log, returnedLogLength); |
|
1190 fastFree(log); |
|
1191 return res; |
|
1192 } |
|
1193 |
|
1194 WebString WebGraphicsContext3DDefaultImpl::getShaderSource(WebGLId shader) |
|
1195 { |
|
1196 makeContextCurrent(); |
|
1197 GLint logLength; |
|
1198 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength); |
|
1199 if (!logLength) |
|
1200 return WebString(); |
|
1201 GLchar* log = 0; |
|
1202 if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) |
|
1203 return WebString(); |
|
1204 GLsizei returnedLogLength; |
|
1205 glGetShaderSource(shader, logLength, &returnedLogLength, log); |
|
1206 ASSERT(logLength == returnedLogLength + 1); |
|
1207 WebString res = WebString::fromUTF8(log, returnedLogLength); |
|
1208 fastFree(log); |
|
1209 return res; |
|
1210 } |
|
1211 |
|
1212 WebString WebGraphicsContext3DDefaultImpl::getString(unsigned long name) |
|
1213 { |
|
1214 makeContextCurrent(); |
|
1215 return WebString::fromUTF8(reinterpret_cast<const char*>(glGetString(name))); |
|
1216 } |
|
1217 |
|
1218 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, unsigned long, unsigned long, float*) |
|
1219 |
|
1220 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv, unsigned long, unsigned long, int*) |
|
1221 |
|
1222 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, long, float*) |
|
1223 |
|
1224 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, long, int*) |
|
1225 |
|
1226 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation, WebGLId, const char*, long) |
|
1227 |
|
1228 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv, unsigned long, unsigned long, float*) |
|
1229 |
|
1230 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv, unsigned long, unsigned long, int*) |
|
1231 |
|
1232 long WebGraphicsContext3DDefaultImpl::getVertexAttribOffset(unsigned long index, unsigned long pname) |
|
1233 { |
|
1234 // FIXME: implement. |
|
1235 notImplemented(); |
|
1236 return 0; |
|
1237 } |
|
1238 |
|
1239 DELEGATE_TO_GL_2(hint, Hint, unsigned long, unsigned long) |
|
1240 |
|
1241 DELEGATE_TO_GL_1R(isBuffer, IsBuffer, WebGLId, bool) |
|
1242 |
|
1243 DELEGATE_TO_GL_1R(isEnabled, IsEnabled, unsigned long, bool) |
|
1244 |
|
1245 DELEGATE_TO_GL_1R(isFramebuffer, IsFramebuffer, WebGLId, bool) |
|
1246 |
|
1247 DELEGATE_TO_GL_1R(isProgram, IsProgram, WebGLId, bool) |
|
1248 |
|
1249 DELEGATE_TO_GL_1R(isRenderbuffer, IsRenderbuffer, WebGLId, bool) |
|
1250 |
|
1251 DELEGATE_TO_GL_1R(isShader, IsShader, WebGLId, bool) |
|
1252 |
|
1253 DELEGATE_TO_GL_1R(isTexture, IsTexture, WebGLId, bool) |
|
1254 |
|
1255 DELEGATE_TO_GL_1(lineWidth, LineWidth, double) |
|
1256 |
|
1257 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId) |
|
1258 |
|
1259 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, unsigned long, long) |
|
1260 |
|
1261 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, double, double) |
|
1262 |
|
1263 void WebGraphicsContext3DDefaultImpl::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* pixels) |
|
1264 { |
|
1265 makeContextCurrent(); |
|
1266 // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e., |
|
1267 // all previous rendering calls should be done before reading pixels. |
|
1268 glFlush(); |
|
1269 #ifndef RENDER_TO_DEBUGGING_WINDOW |
|
1270 if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { |
|
1271 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); |
|
1272 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); |
|
1273 glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); |
|
1274 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); |
|
1275 glFlush(); |
|
1276 } |
|
1277 #endif |
|
1278 glReadPixels(x, y, width, height, format, type, pixels); |
|
1279 #ifndef RENDER_TO_DEBUGGING_WINDOW |
|
1280 if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) |
|
1281 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); |
|
1282 #endif |
|
1283 } |
|
1284 |
|
1285 void WebGraphicsContext3DDefaultImpl::releaseShaderCompiler() |
|
1286 { |
|
1287 } |
|
1288 |
|
1289 void WebGraphicsContext3DDefaultImpl::renderbufferStorage(unsigned long target, |
|
1290 unsigned long internalformat, |
|
1291 unsigned long width, |
|
1292 unsigned long height) |
|
1293 { |
|
1294 makeContextCurrent(); |
|
1295 switch (internalformat) { |
|
1296 case GL_DEPTH_STENCIL: |
|
1297 internalformat = GL_DEPTH24_STENCIL8_EXT; |
|
1298 break; |
|
1299 case GL_DEPTH_COMPONENT16: |
|
1300 internalformat = GL_DEPTH_COMPONENT; |
|
1301 break; |
|
1302 case GL_RGBA4: |
|
1303 case GL_RGB5_A1: |
|
1304 internalformat = GL_RGBA; |
|
1305 break; |
|
1306 case 0x8D62: // GL_RGB565 |
|
1307 internalformat = GL_RGB; |
|
1308 break; |
|
1309 } |
|
1310 glRenderbufferStorageEXT(target, internalformat, width, height); |
|
1311 } |
|
1312 |
|
1313 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, double, bool) |
|
1314 |
|
1315 DELEGATE_TO_GL_4(scissor, Scissor, long, long, unsigned long, unsigned long) |
|
1316 |
|
1317 void WebGraphicsContext3DDefaultImpl::shaderSource(WebGLId shader, const char* string) |
|
1318 { |
|
1319 makeContextCurrent(); |
|
1320 GLint length = strlen(string); |
|
1321 glShaderSource(shader, 1, &string, &length); |
|
1322 } |
|
1323 |
|
1324 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, unsigned long, long, unsigned long) |
|
1325 |
|
1326 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate, unsigned long, unsigned long, long, unsigned long) |
|
1327 |
|
1328 DELEGATE_TO_GL_1(stencilMask, StencilMask, unsigned long) |
|
1329 |
|
1330 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate, unsigned long, unsigned long) |
|
1331 |
|
1332 DELEGATE_TO_GL_3(stencilOp, StencilOp, unsigned long, unsigned long, unsigned long) |
|
1333 |
|
1334 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long) |
|
1335 |
|
1336 DELEGATE_TO_GL_9(texImage2D, TexImage2D, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, const void*) |
|
1337 |
|
1338 DELEGATE_TO_GL_3(texParameterf, TexParameterf, unsigned, unsigned, float); |
|
1339 |
|
1340 DELEGATE_TO_GL_3(texParameteri, TexParameteri, unsigned, unsigned, int); |
|
1341 |
|
1342 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, const void*) |
|
1343 |
|
1344 DELEGATE_TO_GL_2(uniform1f, Uniform1f, long, float) |
|
1345 |
|
1346 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, long, int, float*) |
|
1347 |
|
1348 DELEGATE_TO_GL_2(uniform1i, Uniform1i, long, int) |
|
1349 |
|
1350 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, long, int, int*) |
|
1351 |
|
1352 DELEGATE_TO_GL_3(uniform2f, Uniform2f, long, float, float) |
|
1353 |
|
1354 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, long, int, float*) |
|
1355 |
|
1356 DELEGATE_TO_GL_3(uniform2i, Uniform2i, long, int, int) |
|
1357 |
|
1358 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, long, int, int*) |
|
1359 |
|
1360 DELEGATE_TO_GL_4(uniform3f, Uniform3f, long, float, float, float) |
|
1361 |
|
1362 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, long, int, float*) |
|
1363 |
|
1364 DELEGATE_TO_GL_4(uniform3i, Uniform3i, long, int, int, int) |
|
1365 |
|
1366 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, long, int, int*) |
|
1367 |
|
1368 DELEGATE_TO_GL_5(uniform4f, Uniform4f, long, float, float, float, float) |
|
1369 |
|
1370 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, long, int, float*) |
|
1371 |
|
1372 DELEGATE_TO_GL_5(uniform4i, Uniform4i, long, int, int, int, int) |
|
1373 |
|
1374 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, long, int, int*) |
|
1375 |
|
1376 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv, long, int, bool, const float*) |
|
1377 |
|
1378 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv, long, int, bool, const float*) |
|
1379 |
|
1380 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv, long, int, bool, const float*) |
|
1381 |
|
1382 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId) |
|
1383 |
|
1384 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId) |
|
1385 |
|
1386 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, unsigned long, float) |
|
1387 |
|
1388 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, unsigned long, const float*) |
|
1389 |
|
1390 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, unsigned long, float, float) |
|
1391 |
|
1392 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, unsigned long, const float*) |
|
1393 |
|
1394 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, unsigned long, float, float, float) |
|
1395 |
|
1396 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, unsigned long, const float*) |
|
1397 |
|
1398 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, unsigned long, float, float, float, float) |
|
1399 |
|
1400 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, unsigned long, const float*) |
|
1401 |
|
1402 void WebGraphicsContext3DDefaultImpl::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, |
|
1403 unsigned long stride, unsigned long offset) |
|
1404 { |
|
1405 makeContextCurrent(); |
|
1406 |
|
1407 if (m_boundArrayBuffer <= 0) { |
|
1408 // FIXME: raise exception. |
|
1409 // LogMessagef(("bufferData: no buffer bound")); |
|
1410 return; |
|
1411 } |
|
1412 |
|
1413 if (indx < NumTrackedPointerStates) { |
|
1414 VertexAttribPointerState& state = m_vertexAttribPointerState[indx]; |
|
1415 state.buffer = m_boundArrayBuffer; |
|
1416 state.indx = indx; |
|
1417 state.size = size; |
|
1418 state.type = type; |
|
1419 state.normalized = normalized; |
|
1420 state.stride = stride; |
|
1421 state.offset = offset; |
|
1422 } |
|
1423 |
|
1424 glVertexAttribPointer(indx, size, type, normalized, stride, |
|
1425 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); |
|
1426 } |
|
1427 |
|
1428 DELEGATE_TO_GL_4(viewport, Viewport, long, long, unsigned long, unsigned long) |
|
1429 |
|
1430 unsigned WebGraphicsContext3DDefaultImpl::createBuffer() |
|
1431 { |
|
1432 makeContextCurrent(); |
|
1433 GLuint o; |
|
1434 glGenBuffers(1, &o); |
|
1435 return o; |
|
1436 } |
|
1437 |
|
1438 unsigned WebGraphicsContext3DDefaultImpl::createFramebuffer() |
|
1439 { |
|
1440 makeContextCurrent(); |
|
1441 GLuint o = 0; |
|
1442 glGenFramebuffersEXT(1, &o); |
|
1443 return o; |
|
1444 } |
|
1445 |
|
1446 unsigned WebGraphicsContext3DDefaultImpl::createProgram() |
|
1447 { |
|
1448 makeContextCurrent(); |
|
1449 return glCreateProgram(); |
|
1450 } |
|
1451 |
|
1452 unsigned WebGraphicsContext3DDefaultImpl::createRenderbuffer() |
|
1453 { |
|
1454 makeContextCurrent(); |
|
1455 GLuint o; |
|
1456 glGenRenderbuffersEXT(1, &o); |
|
1457 return o; |
|
1458 } |
|
1459 |
|
1460 DELEGATE_TO_GL_1R(createShader, CreateShader, unsigned long, unsigned); |
|
1461 |
|
1462 unsigned WebGraphicsContext3DDefaultImpl::createTexture() |
|
1463 { |
|
1464 makeContextCurrent(); |
|
1465 GLuint o; |
|
1466 glGenTextures(1, &o); |
|
1467 return o; |
|
1468 } |
|
1469 |
|
1470 void WebGraphicsContext3DDefaultImpl::deleteBuffer(unsigned buffer) |
|
1471 { |
|
1472 makeContextCurrent(); |
|
1473 glDeleteBuffers(1, &buffer); |
|
1474 } |
|
1475 |
|
1476 void WebGraphicsContext3DDefaultImpl::deleteFramebuffer(unsigned framebuffer) |
|
1477 { |
|
1478 makeContextCurrent(); |
|
1479 glDeleteFramebuffersEXT(1, &framebuffer); |
|
1480 } |
|
1481 |
|
1482 void WebGraphicsContext3DDefaultImpl::deleteProgram(unsigned program) |
|
1483 { |
|
1484 makeContextCurrent(); |
|
1485 glDeleteProgram(program); |
|
1486 } |
|
1487 |
|
1488 void WebGraphicsContext3DDefaultImpl::deleteRenderbuffer(unsigned renderbuffer) |
|
1489 { |
|
1490 makeContextCurrent(); |
|
1491 glDeleteRenderbuffersEXT(1, &renderbuffer); |
|
1492 } |
|
1493 |
|
1494 void WebGraphicsContext3DDefaultImpl::deleteShader(unsigned shader) |
|
1495 { |
|
1496 makeContextCurrent(); |
|
1497 glDeleteShader(shader); |
|
1498 } |
|
1499 |
|
1500 void WebGraphicsContext3DDefaultImpl::deleteTexture(unsigned texture) |
|
1501 { |
|
1502 makeContextCurrent(); |
|
1503 glDeleteTextures(1, &texture); |
|
1504 } |
|
1505 |
|
1506 } // namespace WebKit |
|
1507 |
|
1508 #endif // ENABLE(3D_CANVAS) |