Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: webkit/api/src/GraphicsContext3D.cpp

Issue 219001: Incorporated initial WebGL implementation for Chrome, currently... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/glew/src/glew.c ('k') | webkit/webkit.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2009 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 "GraphicsContext3D.h"
36
37 #include "CachedImage.h"
38 #include "CanvasBuffer.h"
39 #include "CanvasByteArray.h"
40 #include "CanvasFloatArray.h"
41 #include "CanvasFramebuffer.h"
42 #include "CanvasIntArray.h"
43 #include "CanvasObject.h"
44 #include "CanvasProgram.h"
45 #include "CanvasRenderbuffer.h"
46 #include "CanvasRenderingContext3D.h"
47 #include "CanvasShader.h"
48 #include "CanvasTexture.h"
49 #include "CanvasUnsignedByteArray.h"
50 #include "CString.h"
51 #include "HTMLCanvasElement.h"
52 #include "HTMLImageElement.h"
53 #include "ImageBuffer.h"
54 #include "ImageData.h"
55 #include "NotImplemented.h"
56 #include <wtf/FastMalloc.h>
57
58 #include <stdio.h>
59
60 #if PLATFORM(WIN_OS)
61 #include <windows.h>
62 #endif
63
64 #include "GL/glew.h"
65
66 #include "NativeImageSkia.h"
67
68 using namespace std;
69
70 namespace WebCore {
71
72 // GraphicsContext3DInternal -----------------------------------------------------
73
74 // Uncomment this to render to a separate window for debugging
75 // #define RENDER_TO_DEBUGGING_WINDOW
76
77 #define EXTRACT(val) (val == NULL ? 0 : val->object())
78
79 class GraphicsContext3DInternal {
80 public:
81 GraphicsContext3DInternal();
82 ~GraphicsContext3DInternal();
83
84 void checkError() const;
85 bool makeContextCurrent();
86
87 PlatformGraphicsContext3D platformGraphicsContext3D() const;
88 Platform3DObject platformTexture() const;
89
90 void reshape(int width, int height);
91
92 void beginPaint(CanvasRenderingContext3D* context);
93
94 bool validateTextureTarget(int target);
95 bool validateTextureParameter(int param);
96
97 void activeTexture(unsigned long texture);
98 void bindBuffer(unsigned long target,
99 CanvasBuffer* buffer);
100 void bindTexture(unsigned long target,
101 CanvasTexture* texture);
102 void bufferDataImpl(unsigned long target, int size, const void* data, unsigned long usage);
103 void colorMask(bool red, bool green, bool blue, bool alpha);
104 void depthMask(bool flag);
105 void disable(unsigned long cap);
106 void disableVertexAttribArray(unsigned long index);
107 void enable(unsigned long cap);
108 void enableVertexAttribArray(unsigned long index);
109 void useProgram(CanvasProgram* program);
110 void vertexAttribPointer(unsigned long indx, int size, int type, bool normalized,
111 unsigned long stride, unsigned long offset);
112 void viewportImpl(long x, long y, unsigned long width, unsigned long height);
113
114 private:
115 unsigned int m_texture;
116 unsigned int m_fbo;
117 unsigned int m_depthBuffer;
118
119 // Objects for flipping the render output vertically
120 unsigned int m_altTexture;
121 unsigned int m_quadVBO;
122 unsigned int m_quadProgram;
123 unsigned int m_quadTexLocation;
124
125 // Storage for saving/restoring buffer, vertex attribute,
126 // blending, and program state when drawing flipped quad
127 unsigned int m_currentProgram;
128 bool m_blendEnabled;
129 bool m_depthTestEnabled;
130 bool m_depthMaskEnabled;
131 bool m_colorMask[4];
132 unsigned int m_boundArrayBuffer;
133 class VertexAttribPointerState {
134 public:
135 VertexAttribPointerState();
136
137 bool enabled;
138 unsigned long buffer;
139 unsigned long indx;
140 int size;
141 int type;
142 bool normalized;
143 unsigned long stride;
144 unsigned long offset;
145 };
146 VertexAttribPointerState m_vertexAttribPointerState[1];
147 unsigned int m_activeTextureUnit;
148 class TextureUnitState {
149 public:
150 TextureUnitState();
151
152 unsigned long target;
153 unsigned int texture;
154 };
155 TextureUnitState m_textureUnitState[1];
156 int m_viewport[4];
157
158 #if PLATFORM(WIN_OS)
159 HWND m_canvasWindow;
160 HDC m_canvasDC;
161 HGLRC m_contextObj;
162 #else
163 #error Must port GraphicsContext3D to your platform
164 #endif
165 };
166
167 GraphicsContext3DInternal::VertexAttribPointerState::VertexAttribPointerState()
168 : enabled(false)
169 , buffer(0)
170 , indx(0)
171 , size(0)
172 , type(0)
173 , normalized(false)
174 , stride(0)
175 , offset(0)
176 {
177 }
178
179 GraphicsContext3DInternal::TextureUnitState::TextureUnitState()
180 : target(0)
181 , texture(0)
182 {
183 }
184
185 GraphicsContext3DInternal::GraphicsContext3DInternal()
186 : m_texture(0)
187 , m_fbo(0)
188 , m_depthBuffer(0)
189 , m_altTexture(0)
190 , m_quadVBO(0)
191 , m_quadProgram(0)
192 , m_quadTexLocation(0)
193 , m_currentProgram(0)
194 , m_blendEnabled(false)
195 , m_depthTestEnabled(false)
196 , m_depthMaskEnabled(true)
197 , m_boundArrayBuffer(0)
198 , m_activeTextureUnit(0)
199 #if PLATFORM(WIN_OS)
200 , m_canvasWindow(NULL)
201 , m_canvasDC(NULL)
202 , m_contextObj(NULL)
203 #else
204 #error Must port to your platform
205 #endif
206 {
207 for (int i = 0; i < 4; i++) {
208 m_viewport[i] = 0;
209 m_colorMask[i] = true;
210 }
211 #if PLATFORM(WIN_OS)
212 WNDCLASS wc;
213 if (!GetClassInfo(GetModuleHandle(NULL), L"CANVASGL", &wc)) {
214 ZeroMemory(&wc, sizeof(WNDCLASS));
215 wc.style = CS_OWNDC;
216 wc.hInstance = GetModuleHandle(NULL);
217 wc.lpfnWndProc = DefWindowProc;
218 wc.lpszClassName = L"CANVASGL";
219
220 if (!RegisterClass(&wc)) {
221 printf("GraphicsContext3D: RegisterClass failed\n");
222 return;
223 }
224 }
225
226 m_canvasWindow = CreateWindow(L"CANVASGL", L"CANVASGL",
227 WS_CAPTION,
228 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
229 CW_USEDEFAULT, NULL, NULL, GetModuleHandle(NULL), NULL);
230 if (!m_canvasWindow) {
231 printf("GraphicsContext3DInternal: CreateWindow failed\n");
232 return;
233 }
234
235 // get the device context
236 m_canvasDC = GetDC(m_canvasWindow);
237 if (!m_canvasDC) {
238 printf("GraphicsContext3DInternal: GetDC failed\n");
239 return;
240 }
241
242 // find default pixel format
243 PIXELFORMATDESCRIPTOR pfd;
244 ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
245 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
246 pfd.nVersion = 1;
247 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL
248 #ifdef RENDER_TO_DEBUGGING_WINDOW
249 | PFD_DOUBLEBUFFER
250 #endif // RENDER_TO_DEBUGGING_WINDOW
251 ;
252 int pixelformat = ChoosePixelFormat(m_canvasDC, &pfd);
253
254 // set the pixel format for the dc
255 if (!SetPixelFormat(m_canvasDC, pixelformat, &pfd)) {
256 printf("GraphicsContext3D: SetPixelFormat failed\n");
257 return;
258 }
259
260 // create rendering context
261 m_contextObj = wglCreateContext(m_canvasDC);
262 if (!m_contextObj) {
263 printf("GraphicsContext3D: wglCreateContext failed\n");
264 return;
265 }
266
267 if (!wglMakeCurrent(m_canvasDC, m_contextObj)) {
268 printf("GraphicsContext3D: wglMakeCurrent failed\n");
269 return;
270 }
271
272 #ifdef RENDER_TO_DEBUGGING_WINDOW
273 typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
274 PFNWGLSWAPINTERVALEXTPROC setSwapInterval = NULL;
275 setSwapInterval = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT");
276 if (setSwapInterval != NULL)
277 setSwapInterval(1);
278 #endif // RENDER_TO_DEBUGGING_WINDOW
279
280 #else
281 #error Must port to your platform
282 #endif
283
284 // Initialize GLEW and check for GL 2.0 support by the drivers.
285 GLenum glewInitResult = glewInit();
286 if (!glewIsSupported("GL_VERSION_2_0")) {
287 printf("GraphicsContext3D: OpenGL 2.0 not supported\n");
288 return;
289 }
290 }
291
292 GraphicsContext3DInternal::~GraphicsContext3DInternal()
293 {
294 makeContextCurrent();
295 #ifndef RENDER_TO_DEBUGGING_WINDOW
296 glDeleteRenderbuffersEXT(1, &m_depthBuffer);
297 glDeleteTextures(1, &m_texture);
298 glDeleteTextures(1, &m_altTexture);
299 glDeleteFramebuffersEXT(1, &m_fbo);
300 #endif // !RENDER_TO_DEBUGGING_WINDOW
301 #if PLATFORM(WIN_OS)
302 wglMakeCurrent(NULL, NULL);
303 wglDeleteContext(m_contextObj);
304 ReleaseDC(m_canvasWindow, m_canvasDC);
305 DestroyWindow(m_canvasWindow);
306 #else
307 #error Must port to your platform
308 #endif
309 m_contextObj = NULL;
310 }
311
312 void GraphicsContext3DInternal::checkError() const
313 {
314 // FIXME: This needs to only be done in the debug context. It
315 // will need to throw an exception on error.
316 GLenum error = glGetError();
317 if (error != GL_NO_ERROR) {
318 printf("GL Error : %x\n", error);
319 notImplemented();
320 }
321 }
322
323 bool GraphicsContext3DInternal::makeContextCurrent()
324 {
325 #if PLATFORM(WIN_OS)
326 if (wglGetCurrentContext() != m_contextObj)
327 if (wglMakeCurrent(m_canvasDC, m_contextObj))
328 return true;
329 #else
330 #error Must port to your platform
331 #endif
332 return false;
333 }
334
335 PlatformGraphicsContext3D GraphicsContext3DInternal::platformGraphicsContext3D() const
336 {
337 return m_contextObj;
338 }
339
340 Platform3DObject GraphicsContext3DInternal::platformTexture() const
341 {
342 return m_texture;
343 }
344
345 static int createTextureObject()
346 {
347 GLuint texture = 0;
348 glGenTextures(1, &texture);
349 glBindTexture(GL_TEXTURE_2D, texture);
350 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
351 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
352 return texture;
353 }
354
355 void GraphicsContext3DInternal::reshape(int width, int height)
356 {
357 #ifdef RENDER_TO_DEBUGGING_WINDOW
358 SetWindowPos(m_canvasWindow, HWND_TOP, 0, 0, width, height,
359 SWP_NOMOVE);
360 ShowWindow(m_canvasWindow, SW_SHOW);
361 #endif
362
363 makeContextCurrent();
364
365 #ifndef RENDER_TO_DEBUGGING_WINDOW
366 if (m_texture == 0) {
367 // Generate the texture objects
368 m_texture = createTextureObject();
369 m_altTexture = createTextureObject();
370
371 // Generate the framebuffer object
372 glGenFramebuffersEXT(1, &m_fbo);
373
374 // Generate the depth buffer
375 glGenRenderbuffersEXT(1, &m_depthBuffer);
376
377 checkError();
378 }
379
380 // Reallocate the color and depth buffers
381 glBindTexture(GL_TEXTURE_2D, m_texture);
382 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
383 glBindTexture(GL_TEXTURE_2D, m_altTexture);
384 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
385 glBindTexture(GL_TEXTURE_2D, 0);
386
387 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
388 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
389 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
390 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
391
392 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
393 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
394 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
395 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
396 printf("GraphicsContext3D: framebuffer was incomplete\n");
397
398 // FIXME: cleanup.
399 notImplemented();
400 }
401 #endif // RENDER_TO_DEBUGGING_WINDOW
402
403 glClear(GL_COLOR_BUFFER_BIT);
404 viewportImpl(0, 0, width, height);
405 }
406
407 void GraphicsContext3DInternal::beginPaint(CanvasRenderingContext3D* context)
408 {
409 makeContextCurrent();
410
411 #ifdef RENDER_TO_DEBUGGING_WINDOW
412 SwapBuffers(m_canvasDC);
413 #else
414 if (m_quadVBO == 0) {
415 // Prepare necessary objects for rendering.
416 glGenBuffers(1, &m_quadVBO);
417 GLfloat vertices[] = {-1.0f, -1.0f,
418 1.0f, -1.0f,
419 1.0f, 1.0f,
420 -1.0f, -1.0f,
421 1.0f, 1.0f,
422 -1.0f, 1.0f};
423 glBindBuffer(GL_ARRAY_BUFFER, m_quadVBO);
424 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
425 // Vertex shader does vertical flip.
426 const GLchar* vertexShaderSrc =
427 "attribute vec2 g_Position;\n"
428 "varying vec2 texCoord;\n"
429 "void main()\n"
430 "{\n"
431 " texCoord = vec2((g_Position.x + 1.0) * 0.5,\n"
432 " (1.0 - g_Position.y) * 0.5);\n"
433 " gl_Position = vec4(g_Position, 0.0, 1.0);\n"
434 "}\n";
435 // Fragment shader does optional premultiplication of alpha
436 // into color channels.
437 const GLchar* fragmentShaderNoPremultSrc =
438 "varying vec2 texCoord;\n"
439 "uniform sampler2D texSampler;\n"
440 "void main()\n"
441 "{\n"
442 " gl_FragColor = texture2D(texSampler, texCoord);\n"
443 "}\n";
444 const GLchar* fragmentShaderPremultSrc =
445 "varying vec2 texCoord;\n"
446 "uniform sampler2D texSampler;\n"
447 "void main()\n"
448 "{\n"
449 " vec4 color = texture2D(texSampler, texCoord);\n"
450 " gl_FragColor = vec4(color.r * color.a,\n"
451 " color.g * color.a,\n"
452 " color.b * color.a,\n"
453 " color.a);\n"
454 "}\n";
455 GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
456 glShaderSource(vertexShader, 1, &vertexShaderSrc, NULL);
457 checkError();
458 GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
459 // FIXME: hook up fragmentShaderPremultSrc based on canvas
460 // context attributes.
461 glShaderSource(fragmentShader, 1, &fragmentShaderNoPremultSrc, NULL);
462 checkError();
463 m_quadProgram = glCreateProgram();
464 glAttachShader(m_quadProgram, vertexShader);
465 glAttachShader(m_quadProgram, fragmentShader);
466 glBindAttribLocation(m_quadProgram, 0, "g_Position");
467 glLinkProgram(m_quadProgram);
468 checkError();
469 glDeleteShader(vertexShader);
470 glDeleteShader(fragmentShader);
471 m_quadTexLocation = glGetUniformLocation(m_quadProgram, "texSampler");
472 checkError();
473 }
474
475 // We've just rendered a frame into m_texture. Bind m_altTexture
476 // as the framebuffer texture, and draw m_texture on to a quad,
477 // flipping it vertically and performing alpha premultiplication
478 // and color channel swizzling. Then read back the FBO.
479 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_altTexture, 0);
480 glUseProgram(m_quadProgram);
481 glActiveTexture(GL_TEXTURE0);
482 glBindTexture(GL_TEXTURE_2D, m_texture);
483 glUniform1i(m_quadTexLocation, 0);
484 glBindBuffer(GL_ARRAY_BUFFER, m_quadVBO);
485 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
486 glEnableVertexAttribArray(0);
487 glDisable(GL_DEPTH_TEST);
488 glDisable(GL_BLEND);
489 glDepthMask(false);
490 glColorMask(true, true, true, true);
491
492 HTMLCanvasElement* canvas = context->canvas();
493 ImageBuffer* imageBuffer = canvas->buffer();
494 const SkBitmap& bitmap = *imageBuffer->context()->platformContext()->bitmap();
495 ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
496 glViewport(0, 0, bitmap.width(), bitmap.height());
497
498 glDrawArrays(GL_TRIANGLES, 0, 6);
499
500 // Read back the frame buffer.
501 SkAutoLockPixels bitmapLock(bitmap);
502 glReadPixels(0, 0, bitmap.width(), bitmap.height(), GL_BGRA, GL_UNSIGNED_BYTE, bitmap.getPixels());
503
504 // Restore the previous FBO state.
505 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
506
507 // Restore the user's OpenGL state.
508 glUseProgram(m_currentProgram);
509 const VertexAttribPointerState& state = m_vertexAttribPointerState[0];
510 if (state.buffer) {
511 glBindBuffer(GL_ARRAY_BUFFER, state.buffer);
512 glVertexAttribPointer(state.indx, state.size, state.type, state.normalized,
513 state.stride, reinterpret_cast<void*>(static_cast<intptr_t>(state.offset)));
514 }
515 glBindBuffer(GL_ARRAY_BUFFER, m_boundArrayBuffer);
516 if (state.enabled)
517 glEnableVertexAttribArray(0);
518 else
519 glDisableVertexAttribArray(0);
520 const TextureUnitState& texState = m_textureUnitState[0];
521 glBindTexture(texState.target, texState.texture);
522 glActiveTexture(m_activeTextureUnit);
523 if (m_blendEnabled)
524 glEnable(GL_BLEND);
525 if (m_depthTestEnabled)
526 glEnable(GL_DEPTH_TEST);
527 glDepthMask(m_depthMaskEnabled);
528 glColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], m_colorMask[3]);
529 glViewport(m_viewport[0], m_viewport[1],
530 m_viewport[2], m_viewport[3]);
531 #endif // RENDER_TO_DEBUGGING_WINDOW
532 }
533
534 bool GraphicsContext3DInternal::validateTextureTarget(int target)
535 {
536 return (target == GL_TEXTURE_2D ||
537 target == GL_TEXTURE_CUBE_MAP);
538 }
539
540 bool GraphicsContext3DInternal::validateTextureParameter(int param)
541 {
542 return (param == GL_TEXTURE_MAG_FILTER ||
543 param == GL_TEXTURE_MIN_FILTER ||
544 param == GL_TEXTURE_WRAP_S ||
545 param == GL_TEXTURE_WRAP_T);
546 }
547
548 void GraphicsContext3DInternal::activeTexture(unsigned long texture)
549 {
550 // FIXME: query number of textures available.
551 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32)
552 // FIXME: raise exception.
553 return;
554
555 makeContextCurrent();
556 m_activeTextureUnit = texture;
557 glActiveTexture(texture);
558 }
559
560 void GraphicsContext3DInternal::bindBuffer(unsigned long target,
561 CanvasBuffer* buffer)
562 {
563 makeContextCurrent();
564 GLuint bufID = EXTRACT(buffer);
565 if (target == GL_ARRAY_BUFFER)
566 m_boundArrayBuffer = bufID;
567 glBindBuffer(target, bufID);
568 }
569
570 // If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps,
571 // we could just use:
572 // GL_SAME_METHOD_2_X2(BindTexture, bindTexture, unsigned long, CanvasTexture*)
573 void GraphicsContext3DInternal::bindTexture(unsigned long target,
574 CanvasTexture* texture)
575 {
576 makeContextCurrent();
577 unsigned int textureObject = EXTRACT(texture);
578
579 if (m_activeTextureUnit == 0) {
580 TextureUnitState& state = m_textureUnitState[m_activeTextureUnit];
581 state.target = target;
582 state.texture = textureObject;
583 }
584
585 glBindTexture(target, textureObject);
586
587 // FIXME: GL_TEXTURE_WRAP_R isn't exposed in the OpenGL ES 2.0
588 // API. On desktop OpenGL implementations it seems necessary to
589 // set this wrap mode to GL_CLAMP_TO_EDGE to get correct behavior
590 // of cube maps.
591 if (texture != NULL) {
592 if (target == GL_TEXTURE_CUBE_MAP) {
593 if (!texture->isCubeMapRWrapModeInitialized()) {
594 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
595 texture->setCubeMapRWrapModeInitialized(true);
596 }
597 } else
598 texture->setCubeMapRWrapModeInitialized(false);
599 }
600 }
601
602 void GraphicsContext3DInternal::bufferDataImpl(unsigned long target, int size, const void* data, unsigned long usage)
603 {
604 makeContextCurrent();
605 // FIXME: make this verification more efficient.
606 GLint binding = 0;
607 GLenum binding_target = GL_ARRAY_BUFFER_BINDING;
608 if (target == GL_ELEMENT_ARRAY_BUFFER)
609 binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING;
610 glGetIntegerv(binding_target, &binding);
611 if (binding <= 0) {
612 // FIXME: raise exception.
613 // LogMessagef(("bufferData: no buffer bound"));
614 return;
615 }
616
617 glBufferData(target,
618 size,
619 data,
620 usage);
621 }
622
623 void GraphicsContext3DInternal::colorMask(bool red, bool green, bool blue, bool alpha)
624 {
625 makeContextCurrent();
626 m_colorMask[0] = red;
627 m_colorMask[1] = green;
628 m_colorMask[2] = blue;
629 m_colorMask[3] = alpha;
630 glColorMask(red, green, blue, alpha);
631 }
632
633 void GraphicsContext3DInternal::depthMask(bool flag)
634 {
635 makeContextCurrent();
636 m_depthMaskEnabled = flag;
637 glDepthMask(flag);
638 }
639
640 void GraphicsContext3DInternal::disable(unsigned long cap)
641 {
642 makeContextCurrent();
643 switch (cap) {
644 case GL_BLEND:
645 m_blendEnabled = false;
646 case GL_DEPTH_TEST:
647 m_depthTestEnabled = false;
648 default:
649 break;
650 }
651 glDisable(cap);
652 }
653
654 void GraphicsContext3DInternal::disableVertexAttribArray(unsigned long index)
655 {
656 makeContextCurrent();
657 if (index == 0) {
658 m_vertexAttribPointerState[0].enabled = false;
659 }
660 glDisableVertexAttribArray(index);
661 }
662
663 void GraphicsContext3DInternal::enable(unsigned long cap)
664 {
665 makeContextCurrent();
666 switch (cap) {
667 case GL_BLEND:
668 m_blendEnabled = true;
669 case GL_DEPTH_TEST:
670 m_depthTestEnabled = true;
671 default:
672 break;
673 }
674 glEnable(cap);
675 }
676
677 void GraphicsContext3DInternal::enableVertexAttribArray(unsigned long index)
678 {
679 makeContextCurrent();
680 if (index == 0)
681 m_vertexAttribPointerState[0].enabled = true;
682 glEnableVertexAttribArray(index);
683 }
684
685 void GraphicsContext3DInternal::useProgram(CanvasProgram* program)
686 {
687 makeContextCurrent();
688 m_currentProgram = EXTRACT(program);
689 glUseProgram(m_currentProgram);
690 }
691
692 void GraphicsContext3DInternal::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized,
693 unsigned long stride, unsigned long offset)
694 {
695 makeContextCurrent();
696
697 if (m_boundArrayBuffer <= 0) {
698 // FIXME: raise exception.
699 // LogMessagef(("bufferData: no buffer bound"));
700 return;
701 }
702
703 if (indx == 0) {
704 VertexAttribPointerState& state = m_vertexAttribPointerState[0];
705 state.buffer = m_boundArrayBuffer;
706 state.indx = indx;
707 state.size = size;
708 state.type = type;
709 state.normalized = normalized;
710 state.stride = stride;
711 state.offset = offset;
712 }
713
714 glVertexAttribPointer(indx, size, type, normalized, stride,
715 reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
716 }
717
718 void GraphicsContext3DInternal::viewportImpl(long x, long y, unsigned long width, unsigned long height)
719 {
720 m_viewport[0] = x;
721 m_viewport[1] = y;
722 m_viewport[2] = width;
723 m_viewport[3] = height;
724 glViewport(x, y, width, height);
725 }
726
727 // GraphicsContext3D -----------------------------------------------------
728
729 #define GRAPHICS_CONTEXT_NAME GraphicsContext3D
730
731 /* Helper macros for when we're just wrapping a gl method, so that
732 * we can avoid having to type this 500 times. Note that these MUST
733 * NOT BE USED if we need to check any of the parameters.
734 */
735
736 #define GL_SAME_METHOD_0(glname, name) \
737 void GRAPHICS_CONTEXT_NAME::##name() \
738 { \
739 makeContextCurrent(); gl##glname(); \
740 }
741
742 #define GL_SAME_METHOD_1(glname, name, t1) \
743 void GRAPHICS_CONTEXT_NAME::##name(t1 a1) \
744 { \
745 makeContextCurrent(); gl##glname(a1); \
746 }
747
748 #define GL_SAME_METHOD_1_X(glname, name, t1) \
749 void GRAPHICS_CONTEXT_NAME::##name(t1 a1) \
750 { \
751 makeContextCurrent(); gl##glname(EXTRACT(a1)); \
752 }
753
754 #define GL_SAME_METHOD_2(glname, name, t1, t2) \
755 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2) \
756 { \
757 makeContextCurrent(); gl##glname(a1,a2); \
758 }
759
760 #define GL_SAME_METHOD_2_X12(glname, name, t1, t2) \
761 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2) \
762 { \
763 makeContextCurrent(); gl##glname(EXTRACT(a1),EXTRACT(a2)); \
764 }
765
766 #define GL_SAME_METHOD_2_X2(glname, name, t1, t2) \
767 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2) \
768 { \
769 makeContextCurrent(); gl##glname(a1,EXTRACT(a2)); \
770 }
771
772 #define GL_SAME_METHOD_3(glname, name, t1, t2, t3) \
773 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2, t3 a3) \
774 { \
775 makeContextCurrent(); gl##glname(a1,a2,a3); \
776 }
777
778 #define GL_SAME_METHOD_3_X12(glname, name, t1, t2, t3) \
779 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2, t3 a3) \
780 { \
781 makeContextCurrent(); gl##glname(EXTRACT(a1),EXTRACT(a2),a3); \
782 }
783
784 #define GL_SAME_METHOD_3_X2(glname, name, t1, t2, t3) \
785 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2, t3 a3) \
786 { \
787 makeContextCurrent(); gl##glname(a1,EXTRACT(a2),a3); \
788 }
789
790 #define GL_SAME_METHOD_4(glname, name, t1, t2, t3, t4) \
791 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2, t3 a3, t4 a4) \
792 { \
793 makeContextCurrent(); gl##glname(a1,a2,a3,a4); \
794 }
795
796 #define GL_SAME_METHOD_4_X4(glname, name, t1, t2, t3, t4) \
797 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2, t3 a3, t4 a4) \
798 { \
799 makeContextCurrent(); gl##glname(a1,a2,a3,EXTRACT(a4)); \
800 }
801
802 #define GL_SAME_METHOD_5(glname, name, t1, t2, t3, t4, t5) \
803 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \
804 { \
805 makeContextCurrent(); gl##glname(a1,a2,a3,a4,a5); \
806 }
807
808 #define GL_SAME_METHOD_5_X4(glname, name, t1, t2, t3, t4, t5) \
809 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \
810 { \
811 makeContextCurrent(); gl##glname(a1,a2,a3,EXTRACT(a4),a5); \
812 }
813
814 #define GL_SAME_METHOD_6(glname, name, t1, t2, t3, t4, t5, t6) \
815 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
816 { \
817 makeContextCurrent(); gl##glname(a1,a2,a3,a4,a5,a6); \
818 }
819
820 #define GL_SAME_METHOD_8(glname, name, t1, t2, t3, t4, t5, t6, t7, t8) \
821 void GRAPHICS_CONTEXT_NAME::##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \
822 { \
823 makeContextCurrent(); gl##glname(a1,a2,a3,a4,a5,a6,a7,a8); \
824 }
825
826 GraphicsContext3D::GraphicsContext3D()
827 : m_currentWidth(0)
828 , m_currentHeight(0)
829 , m_internal(new GraphicsContext3DInternal())
830 {
831 }
832
833 GraphicsContext3D::~GraphicsContext3D()
834 {
835 }
836
837 PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D() const
838 {
839 return m_internal->platformGraphicsContext3D();
840 }
841
842 Platform3DObject GraphicsContext3D::platformTexture() const
843 {
844 return m_internal->platformTexture();
845 }
846
847 void GraphicsContext3D::checkError() const
848 {
849 m_internal->checkError();
850 }
851
852 void GraphicsContext3D::makeContextCurrent()
853 {
854 m_internal->makeContextCurrent();
855 }
856
857 void GraphicsContext3D::reshape(int width, int height)
858 {
859 if (width == m_currentWidth && height == m_currentHeight)
860 return;
861
862 m_currentWidth = width;
863 m_currentHeight = height;
864
865 m_internal->reshape(width, height);
866 }
867
868 void GraphicsContext3D::beginPaint(CanvasRenderingContext3D* context)
869 {
870 m_internal->beginPaint(context);
871 }
872
873 void GraphicsContext3D::endPaint()
874 {
875 }
876
877 int GraphicsContext3D::sizeInBytes(int type)
878 {
879 switch (type) {
880 case GL_BYTE:
881 return sizeof(GLbyte);
882 case GL_UNSIGNED_BYTE:
883 return sizeof(GLubyte);
884 case GL_SHORT:
885 return sizeof(GLshort);
886 case GL_UNSIGNED_SHORT:
887 return sizeof(GLushort);
888 case GL_INT:
889 return sizeof(GLint);
890 case GL_UNSIGNED_INT:
891 return sizeof(GLuint);
892 case GL_FLOAT:
893 return sizeof(GLfloat);
894 default:
895 return 0;
896 }
897 }
898
899 unsigned GraphicsContext3D::createBuffer()
900 {
901 makeContextCurrent();
902 GLuint o;
903 glGenBuffers(1, &o);
904 return o;
905 }
906
907 unsigned GraphicsContext3D::createFramebuffer()
908 {
909 makeContextCurrent();
910 GLuint o;
911 glGenFramebuffers(1, &o);
912 return o;
913 }
914
915 unsigned GraphicsContext3D::createProgram()
916 {
917 makeContextCurrent();
918 return glCreateProgram();
919 }
920
921 unsigned GraphicsContext3D::createRenderbuffer()
922 {
923 makeContextCurrent();
924 GLuint o;
925 glGenRenderbuffers(1, &o);
926 return o;
927 }
928
929 unsigned GraphicsContext3D::createShader(ShaderType type)
930 {
931 makeContextCurrent();
932 return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER);
933 }
934
935 unsigned GraphicsContext3D::createTexture()
936 {
937 makeContextCurrent();
938 GLuint o;
939 glGenTextures(1, &o);
940 return o;
941 }
942
943 void GraphicsContext3D::deleteBuffer(unsigned buffer)
944 {
945 makeContextCurrent();
946 glDeleteBuffers(1, &buffer);
947 }
948
949 void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer)
950 {
951 makeContextCurrent();
952 glDeleteFramebuffers(1, &framebuffer);
953 }
954
955 void GraphicsContext3D::deleteProgram(unsigned program)
956 {
957 makeContextCurrent();
958 glDeleteProgram(program);
959 }
960
961 void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer)
962 {
963 makeContextCurrent();
964 glDeleteRenderbuffers(1, &renderbuffer);
965 }
966
967 void GraphicsContext3D::deleteShader(unsigned shader)
968 {
969 makeContextCurrent();
970 glDeleteShader(shader);
971 }
972
973 void GraphicsContext3D::deleteTexture(unsigned texture)
974 {
975 makeContextCurrent();
976 glDeleteTextures(1, &texture);
977 }
978
979 void GraphicsContext3D::activeTexture(unsigned long texture)
980 {
981 m_internal->activeTexture(texture);
982 }
983
984 GL_SAME_METHOD_2_X12(AttachShader, attachShader, CanvasProgram*, CanvasShader*)
985
986 void GraphicsContext3D::bindAttribLocation(CanvasProgram* program,
987 unsigned long index,
988 const String& name)
989 {
990 if (!program)
991 return;
992 makeContextCurrent();
993 glBindAttribLocation(EXTRACT(program), index, name.utf8().data());
994 }
995
996 void GraphicsContext3D::bindBuffer(unsigned long target,
997 CanvasBuffer* buffer)
998 {
999 m_internal->bindBuffer(target, buffer);
1000 }
1001
1002 GL_SAME_METHOD_2_X2(BindFramebuffer, bindFramebuffer, unsigned long, CanvasFramebuffer*)
1003
1004 GL_SAME_METHOD_2_X2(BindRenderbuffer, bindRenderbuffer, unsigned long, CanvasRenderbuffer*)
1005
1006 // If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps,
1007 // we could just use:
1008 // GL_SAME_METHOD_2_X2(BindTexture, bindTexture, unsigned long, CanvasTexture*)
1009 void GraphicsContext3D::bindTexture(unsigned long target,
1010 CanvasTexture* texture)
1011 {
1012 m_internal->bindTexture(target, texture);
1013 }
1014
1015 GL_SAME_METHOD_4(BlendColor, blendColor, double, double, double, double)
1016
1017 GL_SAME_METHOD_1(BlendEquation, blendEquation, unsigned long)
1018
1019 GL_SAME_METHOD_2(BlendEquationSeparate, blendEquationSeparate, unsigned long, unsigned long)
1020
1021 GL_SAME_METHOD_2(BlendFunc, blendFunc, unsigned long, unsigned long)
1022
1023 GL_SAME_METHOD_4(BlendFuncSeparate, blendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long)
1024
1025 void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long usage)
1026 {
1027 m_internal->bufferDataImpl(target, size, NULL, usage);
1028 }
1029
1030 void GraphicsContext3D::bufferData(unsigned long target, CanvasArray* array, unsigned long usage)
1031 {
1032 m_internal->bufferDataImpl(target, array->sizeInBytes(), array->baseAddress(), usage);
1033 }
1034
1035 void GraphicsContext3D::bufferSubData(unsigned long target, long offset, CanvasArray* array)
1036 {
1037 if (!array || !array->length())
1038 return;
1039
1040 makeContextCurrent();
1041 // FIXME: make this verification more efficient.
1042 GLint binding = 0;
1043 GLenum binding_target = GL_ARRAY_BUFFER_BINDING;
1044 if (target == GL_ELEMENT_ARRAY_BUFFER)
1045 binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING;
1046 glGetIntegerv(binding_target, &binding);
1047 if (binding <= 0) {
1048 // FIXME: raise exception.
1049 // LogMessagef(("bufferSubData: no buffer bound"));
1050 return;
1051 }
1052 glBufferSubData(target, offset, array->sizeInBytes(), array->baseAddress());
1053 }
1054
1055 unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target)
1056 {
1057 makeContextCurrent();
1058 return glCheckFramebufferStatus(target);
1059 }
1060
1061 GL_SAME_METHOD_1(Clear, clear, unsigned long)
1062
1063 GL_SAME_METHOD_4(ClearColor, clearColor, double, double, double, double)
1064
1065 GL_SAME_METHOD_1(ClearDepth, clearDepth, double)
1066
1067 GL_SAME_METHOD_1(ClearStencil, clearStencil, long)
1068
1069 void GraphicsContext3D::colorMask(bool red, bool green, bool blue, bool alpha)
1070 {
1071 m_internal->colorMask(red, green, blue, alpha);
1072 }
1073
1074 GL_SAME_METHOD_1_X(CompileShader, compileShader, CanvasShader*)
1075
1076 GL_SAME_METHOD_8(CopyTexImage2D, copyTexImage2D, unsigned long, long, unsigned long, long, long, unsigned long, unsigned long, long)
1077
1078 GL_SAME_METHOD_8(CopyTexSubImage2D, copyTexSubImage2D, unsigned long, long, long, long, long, long, unsigned long, unsigned long)
1079
1080 GL_SAME_METHOD_1(CullFace, cullFace, unsigned long)
1081
1082 GL_SAME_METHOD_1(DepthFunc, depthFunc, unsigned long)
1083
1084 void GraphicsContext3D::depthMask(bool flag)
1085 {
1086 m_internal->depthMask(flag);
1087 }
1088
1089 GL_SAME_METHOD_2(DepthRange, depthRange, double, double)
1090
1091 void GraphicsContext3D::detachShader(CanvasProgram* program, CanvasShader* shader)
1092 {
1093 if (!program || !shader)
1094 return;
1095
1096 makeContextCurrent();
1097 glDetachShader(EXTRACT(program), EXTRACT(shader));
1098 }
1099
1100 void GraphicsContext3D::disable(unsigned long cap)
1101 {
1102 m_internal->disable(cap);
1103 }
1104
1105 void GraphicsContext3D::disableVertexAttribArray(unsigned long index)
1106 {
1107 m_internal->disableVertexAttribArray(index);
1108 }
1109
1110 void GraphicsContext3D::drawArrays(unsigned long mode, long first, long count)
1111 {
1112 switch (mode) {
1113 case GL_TRIANGLES:
1114 case GL_TRIANGLE_STRIP:
1115 case GL_TRIANGLE_FAN:
1116 case GL_POINTS:
1117 case GL_LINE_STRIP:
1118 case GL_LINE_LOOP:
1119 case GL_LINES:
1120 break;
1121 default:
1122 // FIXME: output log message, raise exception.
1123 // LogMessage(NS_LITERAL_CSTRING("drawArrays: invalid mode"));
1124 // return NS_ERROR_DOM_SYNTAX_ERR;
1125 return;
1126 }
1127
1128 if (first+count < first || first+count < count) {
1129 // FIXME: output log message, raise exception.
1130 // LogMessage(NS_LITERAL_CSTRING("drawArrays: overflow in first+count"));
1131 // return NS_ERROR_INVALID_ARG;
1132 return;
1133 }
1134
1135 // FIXME: validate against currently bound buffer.
1136 // if (!ValidateBuffers(first+count))
1137 // return NS_ERROR_INVALID_ARG;
1138
1139 makeContextCurrent();
1140 glDrawArrays(mode, first, count);
1141 }
1142
1143 void GraphicsContext3D::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset)
1144 {
1145 makeContextCurrent();
1146 // FIXME: make this verification more efficient.
1147 GLint binding = 0;
1148 GLenum binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING;
1149 glGetIntegerv(binding_target, &binding);
1150 if (binding <= 0) {
1151 // FIXME: raise exception.
1152 // LogMessagef(("bufferData: no buffer bound"));
1153 return;
1154 }
1155 glDrawElements(mode, count, type,
1156 reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
1157 }
1158
1159 void GraphicsContext3D::enable(unsigned long cap)
1160 {
1161 m_internal->enable(cap);
1162 }
1163
1164 void GraphicsContext3D::enableVertexAttribArray(unsigned long index)
1165 {
1166 m_internal->enableVertexAttribArray(index);
1167 }
1168
1169 GL_SAME_METHOD_0(Finish, finish)
1170
1171 GL_SAME_METHOD_0(Flush, flush)
1172
1173 GL_SAME_METHOD_4_X4(FramebufferRenderbuffer, framebufferRenderbuffer, unsigned long, unsigned long, unsigned long, CanvasRenderbuffer*)
1174
1175 GL_SAME_METHOD_5_X4(FramebufferTexture2D, framebufferTexture2D, unsigned long, unsigned long, unsigned long, CanvasTexture*, long)
1176
1177 GL_SAME_METHOD_1(FrontFace, frontFace, unsigned long)
1178
1179 void GraphicsContext3D::generateMipmap(unsigned long target)
1180 {
1181 makeContextCurrent();
1182 if (glGenerateMipmapEXT) {
1183 glGenerateMipmapEXT(target);
1184 }
1185 // FIXME: provide alternative code path? This will be unpleasant
1186 // to implement if glGenerateMipmapEXT is not available -- it will
1187 // require a texture readback and re-upload.
1188 }
1189
1190 int GraphicsContext3D::getAttribLocation(CanvasProgram* program, const String& name)
1191 {
1192 if (!program)
1193 return -1;
1194
1195 makeContextCurrent();
1196 return glGetAttribLocation(EXTRACT(program), name.utf8().data());
1197 }
1198
1199 bool GraphicsContext3D::getBoolean(unsigned long pname)
1200 {
1201 makeContextCurrent();
1202 GLboolean val;
1203 // FIXME: validate pname to ensure it returns only a single value.
1204 glGetBooleanv(pname, &val);
1205 return static_cast<bool>(val);
1206 }
1207
1208 PassRefPtr<CanvasUnsignedByteArray> GraphicsContext3D::getBooleanv(unsigned long pname)
1209 {
1210 // FIXME: implement.
1211 notImplemented();
1212 return NULL;
1213 }
1214
1215 int GraphicsContext3D::getBufferParameteri(unsigned long target, unsigned long pname)
1216 {
1217 makeContextCurrent();
1218 GLint data;
1219 glGetBufferParameteriv(target, pname, &data);
1220 return static_cast<int>(data);
1221 }
1222
1223 PassRefPtr<CanvasIntArray> GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long pname)
1224 {
1225 // FIXME: implement.
1226 notImplemented();
1227 return NULL;
1228 }
1229
1230 unsigned long GraphicsContext3D::getError()
1231 {
1232 makeContextCurrent();
1233 return glGetError();
1234 }
1235
1236 float GraphicsContext3D::getFloat(unsigned long pname)
1237 {
1238 makeContextCurrent();
1239 GLfloat val;
1240 // FIXME: validate pname to ensure it returns only a single value.
1241 glGetFloatv(pname, &val);
1242 return static_cast<float>(val);
1243 }
1244
1245 PassRefPtr<CanvasFloatArray> GraphicsContext3D::getFloatv(unsigned long pname)
1246 {
1247 // FIXME: implement.
1248 notImplemented();
1249 return NULL;
1250 }
1251
1252 int GraphicsContext3D::getFramebufferAttachmentParameteri(unsigned long target,
1253 unsigned long attachment,
1254 unsigned long pname)
1255 {
1256 makeContextCurrent();
1257 GLint data;
1258 glGetFramebufferAttachmentParameteriv(target, attachment, pname, &data);
1259 return static_cast<int>(data);
1260 }
1261
1262 PassRefPtr<CanvasIntArray> GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target,
1263 unsigned long attachment,
1264 unsigned long pname)
1265 {
1266 // FIXME: implement.
1267 notImplemented();
1268 return NULL;
1269 }
1270
1271 int GraphicsContext3D::getInteger(unsigned long pname)
1272 {
1273 makeContextCurrent();
1274 GLint val;
1275 // FIXME: validate pname to ensure it returns only a single value.
1276 glGetIntegerv(pname, &val);
1277 return static_cast<int>(val);
1278 }
1279
1280 PassRefPtr<CanvasIntArray> GraphicsContext3D::getIntegerv(unsigned long pname)
1281 {
1282 // FIXME: implement.
1283 notImplemented();
1284 return NULL;
1285 }
1286
1287 int GraphicsContext3D::getProgrami(CanvasProgram* program,
1288 unsigned long pname)
1289 {
1290 makeContextCurrent();
1291 GLint param;
1292 glGetProgramiv(EXTRACT(program), pname, &param);
1293 return static_cast<int>(param);
1294 }
1295
1296 PassRefPtr<CanvasIntArray> GraphicsContext3D::getProgramiv(CanvasProgram* program,
1297 unsigned long pname)
1298 {
1299 // FIXME: implement.
1300 notImplemented();
1301 return NULL;
1302 }
1303
1304 String GraphicsContext3D::getProgramInfoLog(CanvasProgram* program)
1305 {
1306 makeContextCurrent();
1307 GLuint programID = EXTRACT(program);
1308 GLint logLength;
1309 glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logLength);
1310 if (logLength == 0)
1311 return String();
1312 GLchar* log = NULL;
1313 if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log))
1314 return String();
1315 GLsizei returnedLogLength;
1316 glGetProgramInfoLog(programID, logLength, &returnedLogLength, log);
1317 ASSERT(logLength == returnedLogLength + 1);
1318 String res = String::fromUTF8(log, returnedLogLength);
1319 fastFree(log);
1320 return res;
1321 }
1322
1323 int GraphicsContext3D::getRenderbufferParameteri(unsigned long target,
1324 unsigned long pname)
1325 {
1326 makeContextCurrent();
1327 GLint param;
1328 glGetRenderbufferParameteriv(target, pname, &param);
1329 return static_cast<int>(param);
1330 }
1331
1332 PassRefPtr<CanvasIntArray> GraphicsContext3D::getRenderbufferParameteriv(unsigned long target,
1333 unsigned long pname)
1334 {
1335 // FIXME: implement.
1336 notImplemented();
1337 return NULL;
1338 }
1339
1340 int GraphicsContext3D::getShaderi(CanvasShader* shader,
1341 unsigned long pname)
1342 {
1343 makeContextCurrent();
1344 GLint param;
1345 glGetShaderiv(EXTRACT(shader), pname, &param);
1346 return static_cast<int>(param);
1347 }
1348
1349 PassRefPtr<CanvasIntArray> GraphicsContext3D::getShaderiv(CanvasShader* shader,
1350 unsigned long pname)
1351 {
1352 // FIXME: implement.
1353 notImplemented();
1354 return NULL;
1355 }
1356
1357 String GraphicsContext3D::getShaderInfoLog(CanvasShader* shader)
1358 {
1359 makeContextCurrent();
1360 GLuint shaderID = EXTRACT(shader);
1361 GLint logLength;
1362 glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength);
1363 if (logLength == 0)
1364 return String();
1365 GLchar* log = NULL;
1366 if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log))
1367 return String();
1368 GLsizei returnedLogLength;
1369 glGetShaderInfoLog(shaderID, logLength, &returnedLogLength, log);
1370 ASSERT(logLength == returnedLogLength + 1);
1371 String res = String::fromUTF8(log, returnedLogLength);
1372 fastFree(log);
1373 return res;
1374 }
1375
1376 String GraphicsContext3D::getShaderSource(CanvasShader* shader)
1377 {
1378 makeContextCurrent();
1379 GLuint shaderID = EXTRACT(shader);
1380 GLint logLength;
1381 glGetShaderiv(shaderID, GL_SHADER_SOURCE_LENGTH, &logLength);
1382 if (logLength == 0)
1383 return String();
1384 GLchar* log = NULL;
1385 if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log))
1386 return String();
1387 GLsizei returnedLogLength;
1388 glGetShaderSource(shaderID, logLength, &returnedLogLength, log);
1389 ASSERT(logLength == returnedLogLength + 1);
1390 String res = String::fromUTF8(log, returnedLogLength);
1391 fastFree(log);
1392 return res;
1393 }
1394
1395 String GraphicsContext3D::getString(unsigned long name)
1396 {
1397 makeContextCurrent();
1398 return String::fromUTF8(reinterpret_cast<const char*>(glGetString(name)));
1399 }
1400
1401 float GraphicsContext3D::getTexParameterf(unsigned long target, unsigned long pname)
1402 {
1403 makeContextCurrent();
1404 if (!m_internal->validateTextureTarget(target)) {
1405 // FIXME: throw exception.
1406 return 0;
1407 }
1408
1409 if (!m_internal->validateTextureParameter(pname)) {
1410 // FIXME: throw exception.
1411 return 0;
1412 }
1413
1414 GLfloat param;
1415 glGetTexParameterfv(target, pname, &param);
1416 return static_cast<float>(param);
1417 }
1418
1419 PassRefPtr<CanvasFloatArray> GraphicsContext3D::getTexParameterfv(unsigned long target, unsigned long pname)
1420 {
1421 // FIXME: implement.
1422 notImplemented();
1423 return NULL;
1424 }
1425
1426 int GraphicsContext3D::getTexParameteri(unsigned long target, unsigned long pname)
1427 {
1428 makeContextCurrent();
1429 if (!m_internal->validateTextureTarget(target)) {
1430 // FIXME: throw exception.
1431 return 0;
1432 }
1433
1434 if (!m_internal->validateTextureParameter(pname)) {
1435 // FIXME: throw exception.
1436 return 0;
1437 }
1438
1439 GLint param;
1440 glGetTexParameteriv(target, pname, &param);
1441 return static_cast<int>(param);
1442 }
1443
1444 PassRefPtr<CanvasIntArray> GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pname)
1445 {
1446 // FIXME: implement.
1447 notImplemented();
1448 return NULL;
1449 }
1450
1451 float GraphicsContext3D::getUniformf(CanvasProgram* program, long location)
1452 {
1453 // FIXME: implement.
1454 notImplemented();
1455 return 0;
1456 }
1457
1458 PassRefPtr<CanvasFloatArray> GraphicsContext3D::getUniformfv(CanvasProgram* program, long location)
1459 {
1460 // FIXME: implement.
1461 notImplemented();
1462 return NULL;
1463 }
1464
1465 int GraphicsContext3D::getUniformi(CanvasProgram* program, long location)
1466 {
1467 // FIXME: implement.
1468 notImplemented();
1469 return 0;
1470 }
1471
1472 PassRefPtr<CanvasIntArray> GraphicsContext3D::getUniformiv(CanvasProgram* program, long location)
1473 {
1474 // FIXME: implement.
1475 notImplemented();
1476 return NULL;
1477 }
1478
1479 long GraphicsContext3D::getUniformLocation(CanvasProgram* program, const String& name)
1480 {
1481 if (!program)
1482 return -1;
1483
1484 makeContextCurrent();
1485 return glGetUniformLocation(EXTRACT(program), name.utf8().data());
1486 }
1487
1488 float GraphicsContext3D::getVertexAttribf(unsigned long index,
1489 unsigned long pname)
1490 {
1491 // FIXME: implement.
1492 notImplemented();
1493 return 0;
1494 }
1495
1496 PassRefPtr<CanvasFloatArray> GraphicsContext3D::getVertexAttribfv(unsigned long index,
1497 unsigned long pname)
1498 {
1499 // FIXME: implement.
1500 notImplemented();
1501 return NULL;
1502 }
1503
1504 int GraphicsContext3D::getVertexAttribi(unsigned long index,
1505 unsigned long pname)
1506 {
1507 // FIXME: implement.
1508 notImplemented();
1509 return NULL;
1510 }
1511
1512 PassRefPtr<CanvasIntArray> GraphicsContext3D::getVertexAttribiv(unsigned long index,
1513 unsigned long pname)
1514 {
1515 // FIXME: implement.
1516 notImplemented();
1517 return NULL;
1518 }
1519
1520 long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long pname)
1521 {
1522 // FIXME: implement.
1523 notImplemented();
1524 return 0;
1525 }
1526
1527 GL_SAME_METHOD_2(Hint, hint, unsigned long, unsigned long);
1528
1529 bool GraphicsContext3D::isBuffer(CanvasBuffer* buffer)
1530 {
1531 makeContextCurrent();
1532 return glIsBuffer(EXTRACT(buffer));
1533 }
1534
1535 bool GraphicsContext3D::isEnabled(unsigned long cap)
1536 {
1537 makeContextCurrent();
1538 return glIsEnabled(cap);
1539 }
1540
1541 bool GraphicsContext3D::isFramebuffer(CanvasFramebuffer* framebuffer)
1542 {
1543 makeContextCurrent();
1544 return glIsFramebuffer(EXTRACT(framebuffer));
1545 }
1546
1547 bool GraphicsContext3D::isProgram(CanvasProgram* program)
1548 {
1549 makeContextCurrent();
1550 return glIsProgram(EXTRACT(program));
1551 }
1552
1553 bool GraphicsContext3D::isRenderbuffer(CanvasRenderbuffer* renderbuffer)
1554 {
1555 makeContextCurrent();
1556 return glIsRenderbuffer(EXTRACT(renderbuffer));
1557 }
1558
1559 bool GraphicsContext3D::isShader(CanvasShader* shader)
1560 {
1561 makeContextCurrent();
1562 return glIsShader(EXTRACT(shader));
1563 }
1564
1565 bool GraphicsContext3D::isTexture(CanvasTexture* texture)
1566 {
1567 makeContextCurrent();
1568 return glIsTexture(EXTRACT(texture));
1569 }
1570
1571 GL_SAME_METHOD_1(LineWidth, lineWidth, double)
1572
1573 GL_SAME_METHOD_1_X(LinkProgram, linkProgram, CanvasProgram*)
1574
1575 void GraphicsContext3D::pixelStorei(unsigned long pname, long param)
1576 {
1577 if (pname != GL_PACK_ALIGNMENT &&
1578 pname != GL_UNPACK_ALIGNMENT) {
1579 // FIXME: force fake GL error to be produced and throw
1580 // exception.
1581 return;
1582 }
1583
1584 makeContextCurrent();
1585 glPixelStorei(pname, param);
1586 }
1587
1588 GL_SAME_METHOD_2(PolygonOffset, polygonOffset, double, double)
1589
1590 void GraphicsContext3D::releaseShaderCompiler()
1591 {
1592 }
1593
1594 GL_SAME_METHOD_4(RenderbufferStorage, renderbufferStorage, unsigned long, unsigned long, unsigned long, unsigned long)
1595
1596 GL_SAME_METHOD_2(SampleCoverage, sampleCoverage, double, bool)
1597
1598 GL_SAME_METHOD_4(Scissor, scissor, long, long, unsigned long, unsigned long)
1599
1600 void GraphicsContext3D::shaderSource(CanvasShader* shader, const String& source)
1601 {
1602 makeContextCurrent();
1603 CString str = source.utf8();
1604 const char* data = str.data();
1605 GLint length = str.length();
1606 glShaderSource(EXTRACT(shader), 1, &data, &length);
1607 }
1608
1609 GL_SAME_METHOD_3(StencilFunc, stencilFunc, unsigned long, long, unsigned long)
1610
1611 GL_SAME_METHOD_4(StencilFuncSeparate, stencilFuncSeparate, unsigned long, unsigned long, long, unsigned long)
1612
1613 GL_SAME_METHOD_1(StencilMask, stencilMask, unsigned long)
1614
1615 GL_SAME_METHOD_2(StencilMaskSeparate, stencilMaskSeparate, unsigned long, unsigned long)
1616
1617 GL_SAME_METHOD_3(StencilOp, stencilOp, unsigned long, unsigned long, unsigned long)
1618
1619 GL_SAME_METHOD_4(StencilOpSeparate, stencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long)
1620
1621 int GraphicsContext3D::texImage2D(unsigned target,
1622 unsigned level,
1623 unsigned internalformat,
1624 unsigned width,
1625 unsigned height,
1626 unsigned border,
1627 unsigned format,
1628 unsigned type,
1629 CanvasArray* pixels)
1630 {
1631 // FIXME: must do validation similar to JOGL's to ensure that
1632 // the incoming array is of the appropriate length.
1633 glTexImage2D(target,
1634 level,
1635 internalformat,
1636 width,
1637 height,
1638 border,
1639 format,
1640 type,
1641 pixels->baseAddress());
1642 return 0;
1643 }
1644
1645 int GraphicsContext3D::texImage2D(unsigned target,
1646 unsigned level,
1647 unsigned internalformat,
1648 unsigned width,
1649 unsigned height,
1650 unsigned border,
1651 unsigned format,
1652 unsigned type,
1653 ImageData* pixels)
1654 {
1655 // FIXME: implement.
1656 notImplemented();
1657 return -1;
1658 }
1659
1660 // Remove premultiplied alpha from color channels.
1661 // FIXME: this is lossy. Must retrieve original values from HTMLImageElement.
1662 static void unmultiplyAlpha(unsigned char* rgbaData, int numPixels)
1663 {
1664 for (int j = 0; j < numPixels; j++) {
1665 float b = rgbaData[4*j+0] / 255.0f;
1666 float g = rgbaData[4*j+1] / 255.0f;
1667 float r = rgbaData[4*j+2] / 255.0f;
1668 float a = rgbaData[4*j+3] / 255.0f;
1669 if (a > 0.0f) {
1670 b /= a;
1671 g /= a;
1672 r /= a;
1673 b = (b > 1.0f) ? 1.0f : b;
1674 g = (g > 1.0f) ? 1.0f : g;
1675 r = (r > 1.0f) ? 1.0f : r;
1676 rgbaData[4*j+0] = (unsigned char) (b * 255.0f);
1677 rgbaData[4*j+1] = (unsigned char) (g * 255.0f);
1678 rgbaData[4*j+2] = (unsigned char) (r * 255.0f);
1679 }
1680 }
1681 }
1682
1683 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
1684 bool flipY, bool premultiplyAlpha)
1685 {
1686 CachedImage* cachedImage = image->cachedImage();
1687 if (cachedImage == NULL) {
1688 ASSERT_NOT_REACHED();
1689 return -1;
1690 }
1691 Image* img = cachedImage->image();
1692 NativeImageSkia* skiaImage = img->nativeImageForCurrentFrame();
1693 if (skiaImage == NULL) {
1694 ASSERT_NOT_REACHED();
1695 return -1;
1696 }
1697 SkBitmap::Config skiaConfig = skiaImage->config();
1698 // FIXME: must support more image configurations.
1699 if (skiaConfig != SkBitmap::kARGB_8888_Config) {
1700 ASSERT_NOT_REACHED();
1701 return -1;
1702 }
1703 SkBitmap& skiaImageRef = *skiaImage;
1704 SkAutoLockPixels lock(skiaImageRef);
1705 int width = skiaImage->width();
1706 int height = skiaImage->height();
1707 if (flipY) {
1708 // Need to flip images vertically. To avoid making a copy of
1709 // the entire image, we perform a ton of glTexSubImage2D
1710 // calls. FIXME: should rethink this strategy for efficiency.
1711 glTexImage2D(target, level, GL_RGBA8,
1712 width,
1713 height,
1714 0,
1715 GL_BGRA,
1716 GL_UNSIGNED_BYTE,
1717 NULL);
1718 unsigned char* pixels =
1719 reinterpret_cast<unsigned char*>(skiaImage->getPixels());
1720 int rowBytes = skiaImage->rowBytes();
1721
1722 unsigned char* row = NULL;
1723 bool allocatedRow = false;
1724 if (!premultiplyAlpha) {
1725 row = new unsigned char[rowBytes];
1726 allocatedRow = true;
1727 }
1728 for (int i = 0; i < height; i++) {
1729 if (premultiplyAlpha)
1730 row = pixels + (rowBytes * i);
1731 else {
1732 memcpy(row, pixels + (rowBytes * i), rowBytes);
1733 unmultiplyAlpha(row, width);
1734 }
1735 glTexSubImage2D(target, level, 0, height - i - 1,
1736 width, 1,
1737 GL_BGRA,
1738 GL_UNSIGNED_BYTE,
1739 row);
1740 }
1741 if (allocatedRow)
1742 delete[] row;
1743 } else {
1744 // The pixels of cube maps' faces are defined with a top-down
1745 // scanline ordering, unlike GL_TEXTURE_2D, so when uploading
1746 // these, the above vertical flip is the wrong thing to do.
1747 if (premultiplyAlpha)
1748 glTexImage2D(target, level, GL_RGBA8,
1749 width,
1750 height,
1751 0,
1752 GL_BGRA,
1753 GL_UNSIGNED_BYTE,
1754 skiaImage->getPixels());
1755 else {
1756 glTexImage2D(target, level, GL_RGBA8,
1757 width,
1758 height,
1759 0,
1760 GL_BGRA,
1761 GL_UNSIGNED_BYTE,
1762 NULL);
1763 unsigned char* pixels =
1764 reinterpret_cast<unsigned char*>(skiaImage->getPixels());
1765 int rowBytes = skiaImage->rowBytes();
1766 unsigned char* row = new unsigned char[rowBytes];
1767 for (int i = 0; i < height; i++) {
1768 memcpy(row, pixels + (rowBytes * i), rowBytes);
1769 unmultiplyAlpha(row, width);
1770 glTexSubImage2D(target, level, 0, i,
1771 width, 1,
1772 GL_BGRA,
1773 GL_UNSIGNED_BYTE,
1774 row);
1775 }
1776 delete[] row;
1777 }
1778 }
1779 return 0;
1780 }
1781
1782 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
1783 bool flipY, bool premultiplyAlpha)
1784 {
1785 // FIXME: implement.
1786 notImplemented();
1787 return -1;
1788 }
1789
1790 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
1791 bool flipY, bool premultiplyAlpha)
1792 {
1793 // FIXME: implement.
1794 notImplemented();
1795 return -1;
1796 }
1797
1798 GL_SAME_METHOD_3(TexParameterf, texParameterf, unsigned, unsigned, float);
1799
1800 GL_SAME_METHOD_3(TexParameteri, texParameteri, unsigned, unsigned, int);
1801
1802 int GraphicsContext3D::texSubImage2D(unsigned target,
1803 unsigned level,
1804 unsigned xoffset,
1805 unsigned yoffset,
1806 unsigned width,
1807 unsigned height,
1808 unsigned format,
1809 unsigned type,
1810 CanvasArray* pixels)
1811 {
1812 // FIXME: implement.
1813 notImplemented();
1814 return -1;
1815 }
1816
1817 int GraphicsContext3D::texSubImage2D(unsigned target,
1818 unsigned level,
1819 unsigned xoffset,
1820 unsigned yoffset,
1821 unsigned width,
1822 unsigned height,
1823 unsigned format,
1824 unsigned type,
1825 ImageData* pixels)
1826 {
1827 // FIXME: implement.
1828 notImplemented();
1829 return -1;
1830 }
1831
1832 int GraphicsContext3D::texSubImage2D(unsigned target,
1833 unsigned level,
1834 unsigned xoffset,
1835 unsigned yoffset,
1836 unsigned width,
1837 unsigned height,
1838 HTMLImageElement* image,
1839 bool flipY,
1840 bool premultiplyAlpha)
1841 {
1842 // FIXME: implement.
1843 notImplemented();
1844 return -1;
1845 }
1846
1847 int GraphicsContext3D::texSubImage2D(unsigned target,
1848 unsigned level,
1849 unsigned xoffset,
1850 unsigned yoffset,
1851 unsigned width,
1852 unsigned height,
1853 HTMLCanvasElement* canvas,
1854 bool flipY,
1855 bool premultiplyAlpha)
1856 {
1857 // FIXME: implement.
1858 notImplemented();
1859 return -1;
1860 }
1861
1862 int GraphicsContext3D::texSubImage2D(unsigned target,
1863 unsigned level,
1864 unsigned xoffset,
1865 unsigned yoffset,
1866 unsigned width,
1867 unsigned height,
1868 HTMLVideoElement* video,
1869 bool flipY,
1870 bool premultiplyAlpha)
1871 {
1872 // FIXME: implement.
1873 notImplemented();
1874 return -1;
1875 }
1876
1877 GL_SAME_METHOD_2(Uniform1f, uniform1f, long, float)
1878
1879 void GraphicsContext3D::uniform1fv(long location, float* v, int size)
1880 {
1881 makeContextCurrent();
1882 glUniform1fv(location, size, v);
1883 }
1884
1885 GL_SAME_METHOD_2(Uniform1i, uniform1i, long, int)
1886
1887 void GraphicsContext3D::uniform1iv(long location, int* v, int size)
1888 {
1889 makeContextCurrent();
1890 glUniform1iv(location, size, v);
1891 }
1892
1893 GL_SAME_METHOD_3(Uniform2f, uniform2f, long, float, float)
1894
1895 void GraphicsContext3D::uniform2fv(long location, float* v, int size)
1896 {
1897 makeContextCurrent();
1898 glUniform2fv(location, size, v);
1899 }
1900
1901 GL_SAME_METHOD_3(Uniform2i, uniform2i, long, int, int)
1902
1903 void GraphicsContext3D::uniform2iv(long location, int* v, int size)
1904 {
1905 makeContextCurrent();
1906 glUniform2iv(location, size, v);
1907 }
1908
1909 GL_SAME_METHOD_4(Uniform3f, uniform3f, long, float, float, float)
1910
1911 void GraphicsContext3D::uniform3fv(long location, float* v, int size)
1912 {
1913 makeContextCurrent();
1914 glUniform3fv(location, size, v);
1915 }
1916
1917 GL_SAME_METHOD_4(Uniform3i, uniform3i, long, int, int, int)
1918
1919 void GraphicsContext3D::uniform3iv(long location, int* v, int size)
1920 {
1921 makeContextCurrent();
1922 glUniform3iv(location, size, v);
1923 }
1924
1925 GL_SAME_METHOD_5(Uniform4f, uniform4f, long, float, float, float, float)
1926
1927 void GraphicsContext3D::uniform4fv(long location, float* v, int size)
1928 {
1929 makeContextCurrent();
1930 glUniform4fv(location, size, v);
1931 }
1932
1933 GL_SAME_METHOD_5(Uniform4i, uniform4i, long, int, int, int, int)
1934
1935 void GraphicsContext3D::uniform4iv(long location, int* v, int size)
1936 {
1937 makeContextCurrent();
1938 glUniform4iv(location, size, v);
1939 }
1940
1941 void GraphicsContext3D::uniformMatrix2fv(long location, bool transpose, float* value, int size)
1942 {
1943 makeContextCurrent();
1944 glUniformMatrix2fv(location, size, transpose, value);
1945 }
1946
1947 void GraphicsContext3D::uniformMatrix3fv(long location, bool transpose, float* value, int size)
1948 {
1949 makeContextCurrent();
1950 glUniformMatrix3fv(location, size, transpose, value);
1951 }
1952
1953 void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* value, int size)
1954 {
1955 makeContextCurrent();
1956 glUniformMatrix4fv(location, size, transpose, value);
1957 }
1958
1959 void GraphicsContext3D::useProgram(CanvasProgram* program)
1960 {
1961 m_internal->useProgram(program);
1962 }
1963
1964 GL_SAME_METHOD_1_X(ValidateProgram, validateProgram, CanvasProgram*)
1965
1966 GL_SAME_METHOD_2(VertexAttrib1f, vertexAttrib1f, unsigned long, float)
1967
1968 void GraphicsContext3D::vertexAttrib1fv(unsigned long indx, float* values)
1969 {
1970 makeContextCurrent();
1971 glVertexAttrib1fv(indx, values);
1972 }
1973
1974 GL_SAME_METHOD_3(VertexAttrib2f, vertexAttrib2f, unsigned long, float, float)
1975
1976 void GraphicsContext3D::vertexAttrib2fv(unsigned long indx, float* values)
1977 {
1978 makeContextCurrent();
1979 glVertexAttrib2fv(indx, values);
1980 }
1981
1982 GL_SAME_METHOD_4(VertexAttrib3f, vertexAttrib3f, unsigned long, float, float, float)
1983
1984 void GraphicsContext3D::vertexAttrib3fv(unsigned long indx, float* values)
1985 {
1986 makeContextCurrent();
1987 glVertexAttrib3fv(indx, values);
1988 }
1989
1990 GL_SAME_METHOD_5(VertexAttrib4f, vertexAttrib4f, unsigned long, float, float, float, float)
1991
1992 void GraphicsContext3D::vertexAttrib4fv(unsigned long indx, float* values)
1993 {
1994 makeContextCurrent();
1995 glVertexAttrib4fv(indx, values);
1996 }
1997
1998 void GraphicsContext3D::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized,
1999 unsigned long stride, unsigned long offset)
2000 {
2001 m_internal->vertexAttribPointer(indx, size, type, normalized, stride, offset);
2002 }
2003
2004 void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height)
2005 {
2006 makeContextCurrent();
2007 m_internal->viewportImpl(x, y, width, height);
2008 }
2009
2010 }
2011
2012 #endif // ENABLE(3D_CANVAS)
OLDNEW
« no previous file with comments | « third_party/glew/src/glew.c ('k') | webkit/webkit.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698