WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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)