| Index: webkit/api/src/GraphicsContext3D.cpp
|
| diff --git a/webkit/api/src/GraphicsContext3D.cpp b/webkit/api/src/GraphicsContext3D.cpp
|
| deleted file mode 100644
|
| index 465656ac2fc4127f42e9f07e6c8efe59c0ff44ea..0000000000000000000000000000000000000000
|
| --- a/webkit/api/src/GraphicsContext3D.cpp
|
| +++ /dev/null
|
| @@ -1,2287 +0,0 @@
|
| -/*
|
| - * Copyright (C) 2009 Google Inc. All rights reserved.
|
| - *
|
| - * Redistribution and use in source and binary forms, with or without
|
| - * modification, are permitted provided that the following conditions are
|
| - * met:
|
| - *
|
| - * * Redistributions of source code must retain the above copyright
|
| - * notice, this list of conditions and the following disclaimer.
|
| - * * Redistributions in binary form must reproduce the above
|
| - * copyright notice, this list of conditions and the following disclaimer
|
| - * in the documentation and/or other materials provided with the
|
| - * distribution.
|
| - * * Neither the name of Google Inc. nor the names of its
|
| - * contributors may be used to endorse or promote products derived from
|
| - * this software without specific prior written permission.
|
| - *
|
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| - */
|
| -
|
| -#include "config.h"
|
| -
|
| -#if ENABLE(3D_CANVAS)
|
| -
|
| -#include "GraphicsContext3D.h"
|
| -
|
| -#include "CachedImage.h"
|
| -#include "CString.h"
|
| -#include "HTMLCanvasElement.h"
|
| -#include "HTMLImageElement.h"
|
| -#include "ImageBuffer.h"
|
| -#include "ImageData.h"
|
| -#include "NotImplemented.h"
|
| -#include "WebGLBuffer.h"
|
| -#include "WebGLByteArray.h"
|
| -#include "WebGLFloatArray.h"
|
| -#include "WebGLFramebuffer.h"
|
| -#include "WebGLIntArray.h"
|
| -#include "WebGLProgram.h"
|
| -#include "WebGLRenderbuffer.h"
|
| -#include "WebGLRenderingContext.h"
|
| -#include "WebGLShader.h"
|
| -#include "WebGLTexture.h"
|
| -#include "WebGLUnsignedByteArray.h"
|
| -
|
| -#include <stdio.h>
|
| -#include <wtf/FastMalloc.h>
|
| -
|
| -#if PLATFORM(WIN_OS)
|
| -#include <windows.h>
|
| -#endif
|
| -
|
| -#include "GL/glew.h"
|
| -
|
| -#if PLATFORM(CG)
|
| -#include "GraphicsContext.h"
|
| -#include <CoreGraphics/CGContext.h>
|
| -#include <CoreGraphics/CGBitmapContext.h>
|
| -#include <CoreGraphics/CGImage.h>
|
| -#include <OpenGL/OpenGL.h>
|
| -#else
|
| -#define FLIP_FRAMEBUFFER_VERTICALLY
|
| -#endif
|
| -
|
| -#if PLATFORM(SKIA)
|
| -#include "NativeImageSkia.h"
|
| -#endif
|
| -
|
| -#if PLATFORM(DARWIN)
|
| -#define USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER
|
| -#endif
|
| -
|
| -#if PLATFORM(LINUX)
|
| -#include <dlfcn.h>
|
| -#include "GL/glxew.h"
|
| -#endif
|
| -
|
| -using namespace std;
|
| -
|
| -namespace WebCore {
|
| -
|
| -// GraphicsContext3DInternal -----------------------------------------------------
|
| -
|
| -// Uncomment this to render to a separate window for debugging
|
| -// #define RENDER_TO_DEBUGGING_WINDOW
|
| -
|
| -#define EXTRACT(val) (!val ? 0 : val->object())
|
| -
|
| -class GraphicsContext3DInternal {
|
| -public:
|
| - GraphicsContext3DInternal();
|
| - ~GraphicsContext3DInternal();
|
| -
|
| - void checkError() const;
|
| - bool makeContextCurrent();
|
| -
|
| - PlatformGraphicsContext3D platformGraphicsContext3D() const;
|
| - Platform3DObject platformTexture() const;
|
| -
|
| - void reshape(int width, int height);
|
| -
|
| - void beginPaint(WebGLRenderingContext* context);
|
| -
|
| - bool validateTextureTarget(int target);
|
| - bool validateTextureParameter(int param);
|
| -
|
| - void activeTexture(unsigned long texture);
|
| - void bindBuffer(unsigned long target,
|
| - WebGLBuffer* buffer);
|
| - void bindTexture(unsigned long target,
|
| - WebGLTexture* texture);
|
| - void bufferDataImpl(unsigned long target, int size, const void* data, unsigned long usage);
|
| - void disableVertexAttribArray(unsigned long index);
|
| - void enableVertexAttribArray(unsigned long index);
|
| - void vertexAttribPointer(unsigned long indx, int size, int type, bool normalized,
|
| - unsigned long stride, unsigned long offset);
|
| - void viewportImpl(long x, long y, unsigned long width, unsigned long height);
|
| -
|
| -private:
|
| - unsigned int m_texture;
|
| - unsigned int m_fbo;
|
| - unsigned int m_depthBuffer;
|
| - unsigned int m_cachedWidth, m_cachedHeight;
|
| -
|
| -#ifdef FLIP_FRAMEBUFFER_VERTICALLY
|
| - unsigned char* m_scanline;
|
| - void flipVertically(unsigned char* framebuffer,
|
| - unsigned int width,
|
| - unsigned int height);
|
| -#endif
|
| -
|
| - // Note: we aren't currently using this information, but we will
|
| - // need to in order to verify that all enabled vertex arrays have
|
| - // a valid buffer bound -- to avoid crashes on certain cards.
|
| - unsigned int m_boundArrayBuffer;
|
| - class VertexAttribPointerState {
|
| - public:
|
| - VertexAttribPointerState();
|
| -
|
| - bool enabled;
|
| - unsigned long buffer;
|
| - unsigned long indx;
|
| - int size;
|
| - int type;
|
| - bool normalized;
|
| - unsigned long stride;
|
| - unsigned long offset;
|
| - };
|
| -
|
| - enum {
|
| - NumTrackedPointerStates = 2
|
| - };
|
| - VertexAttribPointerState m_vertexAttribPointerState[NumTrackedPointerStates];
|
| -
|
| -#if PLATFORM(SKIA)
|
| - // If the width and height of the Canvas's backing store don't
|
| - // match those that we were given in the most recent call to
|
| - // reshape(), then we need an intermediate bitmap to read back the
|
| - // frame buffer into. This seems to happen when CSS styles are
|
| - // used to resize the Canvas.
|
| - SkBitmap* m_resizingBitmap;
|
| -#endif
|
| -
|
| -#if PLATFORM(WIN_OS)
|
| - HWND m_canvasWindow;
|
| - HDC m_canvasDC;
|
| - HGLRC m_contextObj;
|
| -#elif PLATFORM(CG)
|
| - CGLPBufferObj m_pbuffer;
|
| - CGLContextObj m_contextObj;
|
| - unsigned char* m_renderOutput;
|
| - CGContextRef m_cgContext;
|
| -#elif PLATFORM(LINUX)
|
| - Display* m_display;
|
| - GLXContext m_contextObj;
|
| - GLXPbuffer m_pbuffer;
|
| - // In order to avoid problems caused by linking against libGL, we
|
| - // dynamically look up all the symbols we need.
|
| - // http://code.google.com/p/chromium/issues/detail?id=16800
|
| - void* m_libGL;
|
| - PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig;
|
| - PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext;
|
| - PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer;
|
| - PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer;
|
| - typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx);
|
| - PFNGLXMAKECURRENTPROC m_glXMakeCurrent;
|
| - typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx);
|
| - PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext;
|
| - typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void);
|
| - PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext;
|
| -#else
|
| - #error Must port GraphicsContext3D to your platform
|
| -#endif
|
| -};
|
| -
|
| -GraphicsContext3DInternal::VertexAttribPointerState::VertexAttribPointerState()
|
| - : enabled(false)
|
| - , buffer(0)
|
| - , indx(0)
|
| - , size(0)
|
| - , type(0)
|
| - , normalized(false)
|
| - , stride(0)
|
| - , offset(0)
|
| -{
|
| -}
|
| -
|
| -#if PLATFORM(LINUX)
|
| -static void* tryLoad(const char* libName)
|
| -{
|
| - // We use RTLD_GLOBAL semantics so that GLEW initialization works;
|
| - // GLEW expects to be able to open the current process's handle
|
| - // and do dlsym's of GL entry points from there.
|
| - return dlopen(libName, RTLD_LAZY | RTLD_GLOBAL);
|
| -}
|
| -#endif
|
| -
|
| -GraphicsContext3DInternal::GraphicsContext3DInternal()
|
| - : m_texture(0)
|
| - , m_fbo(0)
|
| - , m_depthBuffer(0)
|
| -#ifdef FLIP_FRAMEBUFFER_VERTICALLY
|
| - , m_scanline(0)
|
| -#endif
|
| - , m_boundArrayBuffer(0)
|
| -#if PLATFORM(SKIA)
|
| - , m_resizingBitmap(0)
|
| -#endif
|
| -#if PLATFORM(WIN_OS)
|
| - , m_canvasWindow(0)
|
| - , m_canvasDC(0)
|
| - , m_contextObj(0)
|
| -#elif PLATFORM(CG)
|
| - , m_pbuffer(0)
|
| - , m_contextObj(0)
|
| - , m_renderOutput(0)
|
| - , m_cgContext(0)
|
| -#elif PLATFORM(LINUX)
|
| - , m_display(0)
|
| - , m_contextObj(0)
|
| - , m_pbuffer(0)
|
| - , m_glXChooseFBConfig(0)
|
| - , m_glXCreateNewContext(0)
|
| - , m_glXCreatePbuffer(0)
|
| - , m_glXDestroyPbuffer(0)
|
| - , m_glXMakeCurrent(0)
|
| - , m_glXDestroyContext(0)
|
| - , m_glXGetCurrentContext(0)
|
| -#else
|
| -#error Must port to your platform
|
| -#endif
|
| -{
|
| -#if PLATFORM(WIN_OS)
|
| - WNDCLASS wc;
|
| - if (!GetClassInfo(GetModuleHandle(0), L"CANVASGL", &wc)) {
|
| - ZeroMemory(&wc, sizeof(WNDCLASS));
|
| - wc.style = CS_OWNDC;
|
| - wc.hInstance = GetModuleHandle(0);
|
| - wc.lpfnWndProc = DefWindowProc;
|
| - wc.lpszClassName = L"CANVASGL";
|
| -
|
| - if (!RegisterClass(&wc)) {
|
| - printf("GraphicsContext3D: RegisterClass failed\n");
|
| - return;
|
| - }
|
| - }
|
| -
|
| - m_canvasWindow = CreateWindow(L"CANVASGL", L"CANVASGL",
|
| - WS_CAPTION,
|
| - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
| - CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0);
|
| - if (!m_canvasWindow) {
|
| - printf("GraphicsContext3DInternal: CreateWindow failed\n");
|
| - return;
|
| - }
|
| -
|
| - // get the device context
|
| - m_canvasDC = GetDC(m_canvasWindow);
|
| - if (!m_canvasDC) {
|
| - printf("GraphicsContext3DInternal: GetDC failed\n");
|
| - return;
|
| - }
|
| -
|
| - // find default pixel format
|
| - PIXELFORMATDESCRIPTOR pfd;
|
| - ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
|
| - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
| - pfd.nVersion = 1;
|
| - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL
|
| -#ifdef RENDER_TO_DEBUGGING_WINDOW
|
| - | PFD_DOUBLEBUFFER
|
| -#endif // RENDER_TO_DEBUGGING_WINDOW
|
| - ;
|
| - int pixelformat = ChoosePixelFormat(m_canvasDC, &pfd);
|
| -
|
| - // set the pixel format for the dc
|
| - if (!SetPixelFormat(m_canvasDC, pixelformat, &pfd)) {
|
| - printf("GraphicsContext3D: SetPixelFormat failed\n");
|
| - return;
|
| - }
|
| -
|
| - // create rendering context
|
| - m_contextObj = wglCreateContext(m_canvasDC);
|
| - if (!m_contextObj) {
|
| - printf("GraphicsContext3D: wglCreateContext failed\n");
|
| - return;
|
| - }
|
| -
|
| - if (!wglMakeCurrent(m_canvasDC, m_contextObj)) {
|
| - printf("GraphicsContext3D: wglMakeCurrent failed\n");
|
| - return;
|
| - }
|
| -
|
| -#ifdef RENDER_TO_DEBUGGING_WINDOW
|
| - typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
|
| - PFNWGLSWAPINTERVALEXTPROC setSwapInterval = 0;
|
| - setSwapInterval = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT");
|
| - if (setSwapInterval)
|
| - setSwapInterval(1);
|
| -#endif // RENDER_TO_DEBUGGING_WINDOW
|
| -
|
| -#elif PLATFORM(CG)
|
| - // Create a 1x1 pbuffer and associated context to bootstrap things
|
| - CGLPixelFormatAttribute attribs[] = {
|
| - (CGLPixelFormatAttribute) kCGLPFAPBuffer,
|
| - (CGLPixelFormatAttribute) 0
|
| - };
|
| - CGLPixelFormatObj pixelFormat;
|
| - GLint numPixelFormats;
|
| - if (CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats) != kCGLNoError) {
|
| - printf("GraphicsContext3D: error choosing pixel format\n");
|
| - return;
|
| - }
|
| - if (!pixelFormat) {
|
| - printf("GraphicsContext3D: no pixel format selected\n");
|
| - return;
|
| - }
|
| - CGLContextObj context;
|
| - CGLError res = CGLCreateContext(pixelFormat, 0, &context);
|
| - CGLDestroyPixelFormat(pixelFormat);
|
| - if (res != kCGLNoError) {
|
| - printf("GraphicsContext3D: error creating context\n");
|
| - return;
|
| - }
|
| - CGLPBufferObj pbuffer;
|
| - if (CGLCreatePBuffer(1, 1, GL_TEXTURE_2D, GL_RGBA, 0, &pbuffer) != kCGLNoError) {
|
| - CGLDestroyContext(context);
|
| - printf("GraphicsContext3D: error creating pbuffer\n");
|
| - return;
|
| - }
|
| - if (CGLSetPBuffer(context, pbuffer, 0, 0, 0) != kCGLNoError) {
|
| - CGLDestroyContext(context);
|
| - CGLDestroyPBuffer(pbuffer);
|
| - printf("GraphicsContext3D: error attaching pbuffer to context\n");
|
| - return;
|
| - }
|
| - if (CGLSetCurrentContext(context) != kCGLNoError) {
|
| - CGLDestroyContext(context);
|
| - CGLDestroyPBuffer(pbuffer);
|
| - printf("GraphicsContext3D: error making context current\n");
|
| - return;
|
| - }
|
| - m_pbuffer = pbuffer;
|
| - m_contextObj = context;
|
| -#elif PLATFORM(LINUX)
|
| - m_display = XOpenDisplay(0);
|
| - if (!m_display) {
|
| - printf("GraphicsContext3D: error opening X display\n");
|
| - return;
|
| - }
|
| -
|
| - const char* libNames[] = {
|
| - "/usr/lib/libGL.so.1",
|
| - "/usr/lib32/libGL.so.1",
|
| - "/usr/lib64/libGL.so.1",
|
| - };
|
| - for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) {
|
| - m_libGL = tryLoad(libNames[i]);
|
| - if (m_libGL)
|
| - break;
|
| - }
|
| - if (!m_libGL) {
|
| - printf("GraphicsContext3D: error opening libGL.so.1\n");
|
| - printf("GraphicsContext3D: tried:");
|
| - for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++)
|
| - printf(" %s", libNames[i]);
|
| - return;
|
| - }
|
| - m_glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(m_libGL, "glXChooseFBConfig");
|
| - m_glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(m_libGL, "glXCreateNewContext");
|
| - m_glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(m_libGL, "glXCreatePbuffer");
|
| - m_glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(m_libGL, "glXDestroyPbuffer");
|
| - m_glXMakeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(m_libGL, "glXMakeCurrent");
|
| - m_glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(m_libGL, "glXDestroyContext");
|
| - m_glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(m_libGL, "glXGetCurrentContext");
|
| - if (!m_glXChooseFBConfig || !m_glXCreateNewContext || !m_glXCreatePbuffer
|
| - || !m_glXDestroyPbuffer || !m_glXMakeCurrent || !m_glXDestroyContext
|
| - || !m_glXGetCurrentContext) {
|
| - printf("GraphicsContext3D: error looking up bootstrapping entry points\n");
|
| - return;
|
| - }
|
| - int configAttrs[] = {
|
| - GLX_DRAWABLE_TYPE,
|
| - GLX_PBUFFER_BIT,
|
| - GLX_RENDER_TYPE,
|
| - GLX_RGBA_BIT,
|
| - GLX_DOUBLEBUFFER,
|
| - 0,
|
| - 0
|
| - };
|
| - int nelements = 0;
|
| - GLXFBConfig* config = m_glXChooseFBConfig(m_display, 0, configAttrs, &nelements);
|
| - if (!config) {
|
| - printf("GraphicsContext3D: glXChooseFBConfig failed\n");
|
| - return;
|
| - }
|
| - if (!nelements) {
|
| - printf("GraphicsContext3D: glXChooseFBConfig returned 0 elements\n");
|
| - XFree(config);
|
| - return;
|
| - }
|
| - GLXContext context = m_glXCreateNewContext(m_display, config[0], GLX_RGBA_TYPE, 0, True);
|
| - if (!context) {
|
| - printf("GraphicsContext3D: glXCreateNewContext failed\n");
|
| - XFree(config);
|
| - return;
|
| - }
|
| - int pbufferAttrs[] = {
|
| - GLX_PBUFFER_WIDTH,
|
| - 1,
|
| - GLX_PBUFFER_HEIGHT,
|
| - 1,
|
| - 0
|
| - };
|
| - GLXPbuffer pbuffer = m_glXCreatePbuffer(m_display, config[0], pbufferAttrs);
|
| - XFree(config);
|
| - if (!pbuffer) {
|
| - printf("GraphicsContext3D: glxCreatePbuffer failed\n");
|
| - return;
|
| - }
|
| - if (!m_glXMakeCurrent(m_display, pbuffer, context)) {
|
| - printf("GraphicsContext3D: glXMakeCurrent failed\n");
|
| - return;
|
| - }
|
| - m_contextObj = context;
|
| - m_pbuffer = pbuffer;
|
| -#else
|
| -#error Must port to your platform
|
| -#endif
|
| -
|
| - static bool initializedGLEW = false;
|
| - if (!initializedGLEW) {
|
| - // Initialize GLEW and check for GL 2.0 support by the drivers.
|
| - GLenum glewInitResult = glewInit();
|
| - if (glewInitResult != GLEW_OK) {
|
| - printf("GraphicsContext3D: GLEW initialization failed\n");
|
| - return;
|
| - }
|
| - if (!glewIsSupported("GL_VERSION_2_0")) {
|
| - printf("GraphicsContext3D: OpenGL 2.0 not supported\n");
|
| - return;
|
| - }
|
| - initializedGLEW = true;
|
| - }
|
| -}
|
| -
|
| -GraphicsContext3DInternal::~GraphicsContext3DInternal()
|
| -{
|
| - makeContextCurrent();
|
| -#ifndef RENDER_TO_DEBUGGING_WINDOW
|
| - glDeleteRenderbuffersEXT(1, &m_depthBuffer);
|
| - glDeleteTextures(1, &m_texture);
|
| -#ifdef FLIP_FRAMEBUFFER_VERTICALLY
|
| - if (m_scanline)
|
| - delete[] m_scanline;
|
| -#endif
|
| - glDeleteFramebuffersEXT(1, &m_fbo);
|
| -#endif // !RENDER_TO_DEBUGGING_WINDOW
|
| -#if PLATFORM(SKIA)
|
| - if (m_resizingBitmap)
|
| - delete m_resizingBitmap;
|
| -#endif
|
| -#if PLATFORM(WIN_OS)
|
| - wglMakeCurrent(0, 0);
|
| - wglDeleteContext(m_contextObj);
|
| - ReleaseDC(m_canvasWindow, m_canvasDC);
|
| - DestroyWindow(m_canvasWindow);
|
| -#elif PLATFORM(CG)
|
| - CGLSetCurrentContext(0);
|
| - CGLDestroyContext(m_contextObj);
|
| - CGLDestroyPBuffer(m_pbuffer);
|
| - if (m_cgContext)
|
| - CGContextRelease(m_cgContext);
|
| - if (m_renderOutput)
|
| - delete[] m_renderOutput;
|
| -#elif PLATFORM(LINUX)
|
| - m_glXMakeCurrent(m_display, 0, 0);
|
| - m_glXDestroyContext(m_display, m_contextObj);
|
| - m_glXDestroyPbuffer(m_display, m_pbuffer);
|
| - XCloseDisplay(m_display);
|
| - dlclose(m_libGL);
|
| -#else
|
| -#error Must port to your platform
|
| -#endif
|
| - m_contextObj = 0;
|
| -}
|
| -
|
| -void GraphicsContext3DInternal::checkError() const
|
| -{
|
| - // FIXME: This needs to only be done in the debug context. It
|
| - // will need to throw an exception on error.
|
| - GLenum error = glGetError();
|
| - if (error != GL_NO_ERROR) {
|
| - printf("GraphicsContext3DInternal: GL Error : %x\n", error);
|
| - notImplemented();
|
| - }
|
| -}
|
| -
|
| -bool GraphicsContext3DInternal::makeContextCurrent()
|
| -{
|
| -#if PLATFORM(WIN_OS)
|
| - if (wglGetCurrentContext() != m_contextObj)
|
| - if (wglMakeCurrent(m_canvasDC, m_contextObj))
|
| - return true;
|
| -#elif PLATFORM(CG)
|
| - if (CGLGetCurrentContext() != m_contextObj)
|
| - if (CGLSetCurrentContext(m_contextObj) == kCGLNoError)
|
| - return true;
|
| -#elif PLATFORM(LINUX)
|
| - if (m_glXGetCurrentContext() != m_contextObj)
|
| - if (m_glXMakeCurrent(m_display, m_pbuffer, m_contextObj))
|
| - return true;
|
| -#else
|
| -#error Must port to your platform
|
| -#endif
|
| - return false;
|
| -}
|
| -
|
| -PlatformGraphicsContext3D GraphicsContext3DInternal::platformGraphicsContext3D() const
|
| -{
|
| - return m_contextObj;
|
| -}
|
| -
|
| -Platform3DObject GraphicsContext3DInternal::platformTexture() const
|
| -{
|
| - return m_texture;
|
| -}
|
| -
|
| -static int createTextureObject(GLenum target)
|
| -{
|
| - GLuint texture = 0;
|
| - glGenTextures(1, &texture);
|
| - glBindTexture(target, texture);
|
| - glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| - glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| - return texture;
|
| -}
|
| -
|
| -void GraphicsContext3DInternal::reshape(int width, int height)
|
| -{
|
| -#ifdef RENDER_TO_DEBUGGING_WINDOW
|
| - SetWindowPos(m_canvasWindow, HWND_TOP, 0, 0, width, height,
|
| - SWP_NOMOVE);
|
| - ShowWindow(m_canvasWindow, SW_SHOW);
|
| -#endif
|
| -
|
| - m_cachedWidth = width;
|
| - m_cachedHeight = height;
|
| - makeContextCurrent();
|
| -
|
| -#ifndef RENDER_TO_DEBUGGING_WINDOW
|
| -#ifdef USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER
|
| - // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on Mac OS X
|
| - GLenum target = GL_TEXTURE_RECTANGLE_ARB;
|
| -#else
|
| - GLenum target = GL_TEXTURE_2D;
|
| -#endif
|
| - if (!m_texture) {
|
| - // Generate the texture object
|
| - m_texture = createTextureObject(target);
|
| - // Generate the framebuffer object
|
| - glGenFramebuffersEXT(1, &m_fbo);
|
| - // Generate the depth buffer
|
| - glGenRenderbuffersEXT(1, &m_depthBuffer);
|
| - checkError();
|
| - }
|
| -
|
| - // Reallocate the color and depth buffers
|
| - glBindTexture(target, m_texture);
|
| - glTexImage2D(target, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
| - glBindTexture(target, 0);
|
| -
|
| - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
| - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
|
| - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
|
| - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
| -
|
| - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0);
|
| - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
|
| - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
| - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
|
| - printf("GraphicsContext3D: framebuffer was incomplete\n");
|
| -
|
| - // FIXME: cleanup.
|
| - notImplemented();
|
| - }
|
| -#endif // RENDER_TO_DEBUGGING_WINDOW
|
| -
|
| -#ifdef FLIP_FRAMEBUFFER_VERTICALLY
|
| - if (m_scanline) {
|
| - delete[] m_scanline;
|
| - m_scanline = 0;
|
| - }
|
| - m_scanline = new unsigned char[width * 4];
|
| -#endif // FLIP_FRAMEBUFFER_VERTICALLY
|
| -
|
| - glClear(GL_COLOR_BUFFER_BIT);
|
| - viewportImpl(0, 0, width, height);
|
| -
|
| -#if PLATFORM(CG)
|
| - // Need to reallocate the client-side backing store.
|
| - // FIXME: make this more efficient.
|
| - if (m_cgContext) {
|
| - CGContextRelease(m_cgContext);
|
| - m_cgContext = 0;
|
| - }
|
| - if (m_renderOutput) {
|
| - delete[] m_renderOutput;
|
| - m_renderOutput = 0;
|
| - }
|
| - int rowBytes = width * 4;
|
| - m_renderOutput = new unsigned char[height * rowBytes];
|
| - CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
| - m_cgContext = CGBitmapContextCreate(m_renderOutput, width, height, 8, rowBytes,
|
| - colorSpace, kCGImageAlphaPremultipliedLast);
|
| - CGColorSpaceRelease(colorSpace);
|
| -#endif // PLATFORM(CG)
|
| -}
|
| -
|
| -#ifdef FLIP_FRAMEBUFFER_VERTICALLY
|
| -void GraphicsContext3DInternal::flipVertically(unsigned char* framebuffer,
|
| - unsigned int width,
|
| - unsigned int height)
|
| -{
|
| - unsigned char* scanline = m_scanline;
|
| - if (!scanline)
|
| - return;
|
| - unsigned int rowBytes = width * 4;
|
| - unsigned int count = height / 2;
|
| - for (unsigned int i = 0; i < count; i++) {
|
| - unsigned char* rowA = framebuffer + i * rowBytes;
|
| - unsigned char* rowB = framebuffer + (height - i - 1) * rowBytes;
|
| - // FIXME: this is where the multiplication of the alpha
|
| - // channel into the color buffer will need to occur if the
|
| - // user specifies the "premultiplyAlpha" flag in the context
|
| - // creation attributes.
|
| - memcpy(scanline, rowB, rowBytes);
|
| - memcpy(rowB, rowA, rowBytes);
|
| - memcpy(rowA, scanline, rowBytes);
|
| - }
|
| -}
|
| -#endif
|
| -
|
| -void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context)
|
| -{
|
| - makeContextCurrent();
|
| -
|
| -#ifdef RENDER_TO_DEBUGGING_WINDOW
|
| - SwapBuffers(m_canvasDC);
|
| -#else
|
| - // Earlier versions of this code used the GPU to flip the
|
| - // framebuffer vertically before reading it back for compositing
|
| - // via software. This code was quite complicated, used a lot of
|
| - // GPU memory, and didn't provide an obvious speedup. Since this
|
| - // vertical flip is only a temporary solution anyway until Chrome
|
| - // is fully GPU composited, it wasn't worth the complexity.
|
| -
|
| - HTMLCanvasElement* canvas = context->canvas();
|
| - ImageBuffer* imageBuffer = canvas->buffer();
|
| - unsigned char* pixels = 0;
|
| -#if PLATFORM(SKIA)
|
| - const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap();
|
| - const SkBitmap* readbackBitmap = 0;
|
| - ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config);
|
| - if (canvasBitmap->width() == m_cachedWidth && canvasBitmap->height() == m_cachedHeight) {
|
| - // This is the fastest and most common case. We read back
|
| - // directly into the canvas's backing store.
|
| - readbackBitmap = canvasBitmap;
|
| - if (m_resizingBitmap) {
|
| - delete m_resizingBitmap;
|
| - m_resizingBitmap = 0;
|
| - }
|
| - } else {
|
| - // We need to allocate a temporary bitmap for reading back the
|
| - // pixel data. We will then use Skia to rescale this bitmap to
|
| - // the size of the canvas's backing store.
|
| - if (m_resizingBitmap && (m_resizingBitmap->width() != m_cachedWidth || m_resizingBitmap->height() != m_cachedHeight)) {
|
| - delete m_resizingBitmap;
|
| - m_resizingBitmap = 0;
|
| - }
|
| - if (!m_resizingBitmap) {
|
| - m_resizingBitmap = new SkBitmap();
|
| - m_resizingBitmap->setConfig(SkBitmap::kARGB_8888_Config,
|
| - m_cachedWidth,
|
| - m_cachedHeight);
|
| - if (!m_resizingBitmap->allocPixels()) {
|
| - delete m_resizingBitmap;
|
| - m_resizingBitmap = 0;
|
| - return;
|
| - }
|
| - }
|
| - readbackBitmap = m_resizingBitmap;
|
| - }
|
| -
|
| - // Read back the frame buffer.
|
| - SkAutoLockPixels bitmapLock(*readbackBitmap);
|
| - pixels = static_cast<unsigned char*>(readbackBitmap->getPixels());
|
| - glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
|
| -#elif PLATFORM(CG)
|
| - if (m_renderOutput) {
|
| - ASSERT(CGBitmapContextGetWidth(m_cgContext) == m_cachedWidth);
|
| - ASSERT(CGBitmapContextGetHeight(m_cgContext) == m_cachedHeight);
|
| - pixels = m_renderOutput;
|
| - glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
| - }
|
| -#else
|
| -#error Must port to your platform
|
| -#endif
|
| -
|
| -#ifdef FLIP_FRAMEBUFFER_VERTICALLY
|
| - if (pixels)
|
| - flipVertically(pixels, m_cachedWidth, m_cachedHeight);
|
| -#endif
|
| -
|
| -#if PLATFORM(SKIA)
|
| - if (m_resizingBitmap) {
|
| - // We need to draw the resizing bitmap into the canvas's backing store.
|
| - SkCanvas canvas(*canvasBitmap);
|
| - SkRect dst;
|
| - dst.set(0, 0, canvasBitmap->width(), canvasBitmap->height());
|
| - canvas.drawBitmapRect(*m_resizingBitmap, 0, dst);
|
| - }
|
| -#elif PLATFORM(CG)
|
| - if (m_renderOutput) {
|
| - CGImageRef cgImage = CGBitmapContextCreateImage(m_cgContext);
|
| - // CSS styling may cause the canvas's content to be resized on
|
| - // the page. Go back to the Canvas to figure out the correct
|
| - // width and height to draw.
|
| - CGRect rect = CGRectMake(0, 0,
|
| - context->canvas()->width(),
|
| - context->canvas()->height());
|
| - // We want to completely overwrite the previous frame's
|
| - // rendering results.
|
| - CGContextSetBlendMode(imageBuffer->context()->platformContext(),
|
| - kCGBlendModeCopy);
|
| - CGContextDrawImage(imageBuffer->context()->platformContext(),
|
| - rect, cgImage);
|
| - CGImageRelease(cgImage);
|
| - }
|
| -#else
|
| -#error Must port to your platform
|
| -#endif
|
| -
|
| -#endif // RENDER_TO_DEBUGGING_WINDOW
|
| -}
|
| -
|
| -bool GraphicsContext3DInternal::validateTextureTarget(int target)
|
| -{
|
| - return (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP);
|
| -}
|
| -
|
| -bool GraphicsContext3DInternal::validateTextureParameter(int param)
|
| -{
|
| - return (param == GL_TEXTURE_MAG_FILTER
|
| - || param == GL_TEXTURE_MIN_FILTER
|
| - || param == GL_TEXTURE_WRAP_S
|
| - || param == GL_TEXTURE_WRAP_T);
|
| -}
|
| -
|
| -void GraphicsContext3DInternal::activeTexture(unsigned long texture)
|
| -{
|
| - // FIXME: query number of textures available.
|
| - if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32)
|
| - // FIXME: raise exception.
|
| - return;
|
| -
|
| - makeContextCurrent();
|
| - glActiveTexture(texture);
|
| -}
|
| -
|
| -void GraphicsContext3DInternal::bindBuffer(unsigned long target,
|
| - WebGLBuffer* buffer)
|
| -{
|
| - makeContextCurrent();
|
| - GLuint bufID = EXTRACT(buffer);
|
| - if (target == GL_ARRAY_BUFFER)
|
| - m_boundArrayBuffer = bufID;
|
| - glBindBuffer(target, bufID);
|
| -}
|
| -
|
| -// If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps,
|
| -// we could just use:
|
| -// GL_SAME_METHOD_2_X2(BindTexture, bindTexture, unsigned long, WebGLTexture*)
|
| -void GraphicsContext3DInternal::bindTexture(unsigned long target,
|
| - WebGLTexture* texture)
|
| -{
|
| - makeContextCurrent();
|
| - unsigned int textureObject = EXTRACT(texture);
|
| -
|
| - glBindTexture(target, textureObject);
|
| -
|
| - // FIXME: GL_TEXTURE_WRAP_R isn't exposed in the OpenGL ES 2.0
|
| - // API. On desktop OpenGL implementations it seems necessary to
|
| - // set this wrap mode to GL_CLAMP_TO_EDGE to get correct behavior
|
| - // of cube maps.
|
| - if (texture) {
|
| - if (target == GL_TEXTURE_CUBE_MAP) {
|
| - if (!texture->isCubeMapRWrapModeInitialized()) {
|
| - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
| - texture->setCubeMapRWrapModeInitialized(true);
|
| - }
|
| - } else
|
| - texture->setCubeMapRWrapModeInitialized(false);
|
| - }
|
| -}
|
| -
|
| -void GraphicsContext3DInternal::bufferDataImpl(unsigned long target, int size, const void* data, unsigned long usage)
|
| -{
|
| - makeContextCurrent();
|
| - // FIXME: make this verification more efficient.
|
| - GLint binding = 0;
|
| - GLenum binding_target = GL_ARRAY_BUFFER_BINDING;
|
| - if (target == GL_ELEMENT_ARRAY_BUFFER)
|
| - binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING;
|
| - glGetIntegerv(binding_target, &binding);
|
| - if (binding <= 0) {
|
| - // FIXME: raise exception.
|
| - // LogMessagef(("bufferData: no buffer bound"));
|
| - return;
|
| - }
|
| -
|
| - glBufferData(target,
|
| - size,
|
| - data,
|
| - usage);
|
| -}
|
| -
|
| -void GraphicsContext3DInternal::disableVertexAttribArray(unsigned long index)
|
| -{
|
| - makeContextCurrent();
|
| - if (index < NumTrackedPointerStates)
|
| - m_vertexAttribPointerState[index].enabled = false;
|
| - glDisableVertexAttribArray(index);
|
| -}
|
| -
|
| -void GraphicsContext3DInternal::enableVertexAttribArray(unsigned long index)
|
| -{
|
| - makeContextCurrent();
|
| - if (index < NumTrackedPointerStates)
|
| - m_vertexAttribPointerState[index].enabled = true;
|
| - glEnableVertexAttribArray(index);
|
| -}
|
| -
|
| -void GraphicsContext3DInternal::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized,
|
| - unsigned long stride, unsigned long offset)
|
| -{
|
| - makeContextCurrent();
|
| -
|
| - if (m_boundArrayBuffer <= 0) {
|
| - // FIXME: raise exception.
|
| - // LogMessagef(("bufferData: no buffer bound"));
|
| - return;
|
| - }
|
| -
|
| - if (indx < NumTrackedPointerStates) {
|
| - VertexAttribPointerState& state = m_vertexAttribPointerState[indx];
|
| - state.buffer = m_boundArrayBuffer;
|
| - state.indx = indx;
|
| - state.size = size;
|
| - state.type = type;
|
| - state.normalized = normalized;
|
| - state.stride = stride;
|
| - state.offset = offset;
|
| - }
|
| -
|
| - glVertexAttribPointer(indx, size, type, normalized, stride,
|
| - reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
|
| -}
|
| -
|
| -void GraphicsContext3DInternal::viewportImpl(long x, long y, unsigned long width, unsigned long height)
|
| -{
|
| - glViewport(x, y, width, height);
|
| -}
|
| -
|
| -// GraphicsContext3D -----------------------------------------------------
|
| -
|
| -/* Helper macros for when we're just wrapping a gl method, so that
|
| - * we can avoid having to type this 500 times. Note that these MUST
|
| - * NOT BE USED if we need to check any of the parameters.
|
| - */
|
| -
|
| -#define GL_SAME_METHOD_0(glname, name) \
|
| -void GraphicsContext3D::name() \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_1(glname, name, t1) \
|
| -void GraphicsContext3D::name(t1 a1) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_1_X(glname, name, t1) \
|
| -void GraphicsContext3D::name(t1 a1) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(EXTRACT(a1)); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_2(glname, name, t1, t2) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1, a2); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_2_X12(glname, name, t1, t2) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(EXTRACT(a1), EXTRACT(a2)); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_2_X2(glname, name, t1, t2) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1, EXTRACT(a2)); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_3(glname, name, t1, t2, t3) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1, a2, a3); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_3_X12(glname, name, t1, t2, t3) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(EXTRACT(a1), EXTRACT(a2), a3); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_3_X2(glname, name, t1, t2, t3) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1, EXTRACT(a2), a3); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_4(glname, name, t1, t2, t3, t4) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1, a2, a3, a4); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_4_X4(glname, name, t1, t2, t3, t4) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1, a2, a3, EXTRACT(a4)); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_5(glname, name, t1, t2, t3, t4, t5) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1, a2, a3, a4, a5); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_5_X4(glname, name, t1, t2, t3, t4, t5) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1, a2, a3, EXTRACT(a4), a5); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_6(glname, name, t1, t2, t3, t4, t5, t6) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1, a2, a3, a4, a5, a6); \
|
| -}
|
| -
|
| -#define GL_SAME_METHOD_8(glname, name, t1, t2, t3, t4, t5, t6, t7, t8) \
|
| -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \
|
| -{ \
|
| - makeContextCurrent(); \
|
| - gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \
|
| -}
|
| -
|
| -PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create()
|
| -{
|
| - PassOwnPtr<GraphicsContext3D> context = new GraphicsContext3D();
|
| - // FIXME: add error checking
|
| - return context;
|
| -}
|
| -
|
| -GraphicsContext3D::GraphicsContext3D()
|
| - : m_currentWidth(0)
|
| - , m_currentHeight(0)
|
| - , m_internal(new GraphicsContext3DInternal())
|
| -{
|
| -}
|
| -
|
| -GraphicsContext3D::~GraphicsContext3D()
|
| -{
|
| -}
|
| -
|
| -PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D() const
|
| -{
|
| - return m_internal->platformGraphicsContext3D();
|
| -}
|
| -
|
| -Platform3DObject GraphicsContext3D::platformTexture() const
|
| -{
|
| - return m_internal->platformTexture();
|
| -}
|
| -
|
| -void GraphicsContext3D::checkError() const
|
| -{
|
| - m_internal->checkError();
|
| -}
|
| -
|
| -void GraphicsContext3D::makeContextCurrent()
|
| -{
|
| - m_internal->makeContextCurrent();
|
| -}
|
| -
|
| -void GraphicsContext3D::reshape(int width, int height)
|
| -{
|
| - if (width == m_currentWidth && height == m_currentHeight)
|
| - return;
|
| -
|
| - m_currentWidth = width;
|
| - m_currentHeight = height;
|
| -
|
| - m_internal->reshape(width, height);
|
| -}
|
| -
|
| -void GraphicsContext3D::beginPaint(WebGLRenderingContext* context)
|
| -{
|
| - m_internal->beginPaint(context);
|
| -}
|
| -
|
| -void GraphicsContext3D::endPaint()
|
| -{
|
| -}
|
| -
|
| -int GraphicsContext3D::sizeInBytes(int type)
|
| -{
|
| - switch (type) {
|
| - case GL_BYTE:
|
| - return sizeof(GLbyte);
|
| - case GL_UNSIGNED_BYTE:
|
| - return sizeof(GLubyte);
|
| - case GL_SHORT:
|
| - return sizeof(GLshort);
|
| - case GL_UNSIGNED_SHORT:
|
| - return sizeof(GLushort);
|
| - case GL_INT:
|
| - return sizeof(GLint);
|
| - case GL_UNSIGNED_INT:
|
| - return sizeof(GLuint);
|
| - case GL_FLOAT:
|
| - return sizeof(GLfloat);
|
| - default: // FIXME: default cases are discouraged in WebKit.
|
| - return 0;
|
| - }
|
| -}
|
| -
|
| -unsigned GraphicsContext3D::createBuffer()
|
| -{
|
| - makeContextCurrent();
|
| - GLuint o;
|
| - glGenBuffers(1, &o);
|
| - return o;
|
| -}
|
| -
|
| -unsigned GraphicsContext3D::createFramebuffer()
|
| -{
|
| - makeContextCurrent();
|
| - GLuint o;
|
| - glGenFramebuffers(1, &o);
|
| - return o;
|
| -}
|
| -
|
| -unsigned GraphicsContext3D::createProgram()
|
| -{
|
| - makeContextCurrent();
|
| - return glCreateProgram();
|
| -}
|
| -
|
| -unsigned GraphicsContext3D::createRenderbuffer()
|
| -{
|
| - makeContextCurrent();
|
| - GLuint o;
|
| - glGenRenderbuffers(1, &o);
|
| - return o;
|
| -}
|
| -
|
| -unsigned GraphicsContext3D::createShader(ShaderType type)
|
| -{
|
| - makeContextCurrent();
|
| - return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER);
|
| -}
|
| -
|
| -unsigned GraphicsContext3D::createTexture()
|
| -{
|
| - makeContextCurrent();
|
| - GLuint o;
|
| - glGenTextures(1, &o);
|
| - return o;
|
| -}
|
| -
|
| -void GraphicsContext3D::deleteBuffer(unsigned buffer)
|
| -{
|
| - makeContextCurrent();
|
| - glDeleteBuffers(1, &buffer);
|
| -}
|
| -
|
| -void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer)
|
| -{
|
| - makeContextCurrent();
|
| - glDeleteFramebuffers(1, &framebuffer);
|
| -}
|
| -
|
| -void GraphicsContext3D::deleteProgram(unsigned program)
|
| -{
|
| - makeContextCurrent();
|
| - glDeleteProgram(program);
|
| -}
|
| -
|
| -void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer)
|
| -{
|
| - makeContextCurrent();
|
| - glDeleteRenderbuffers(1, &renderbuffer);
|
| -}
|
| -
|
| -void GraphicsContext3D::deleteShader(unsigned shader)
|
| -{
|
| - makeContextCurrent();
|
| - glDeleteShader(shader);
|
| -}
|
| -
|
| -void GraphicsContext3D::deleteTexture(unsigned texture)
|
| -{
|
| - makeContextCurrent();
|
| - glDeleteTextures(1, &texture);
|
| -}
|
| -
|
| -void GraphicsContext3D::activeTexture(unsigned long texture)
|
| -{
|
| - m_internal->activeTexture(texture);
|
| -}
|
| -
|
| -GL_SAME_METHOD_2_X12(AttachShader, attachShader, WebGLProgram*, WebGLShader*)
|
| -
|
| -void GraphicsContext3D::bindAttribLocation(WebGLProgram* program,
|
| - unsigned long index,
|
| - const String& name)
|
| -{
|
| - if (!program)
|
| - return;
|
| - makeContextCurrent();
|
| - glBindAttribLocation(EXTRACT(program), index, name.utf8().data());
|
| -}
|
| -
|
| -void GraphicsContext3D::bindBuffer(unsigned long target,
|
| - WebGLBuffer* buffer)
|
| -{
|
| - m_internal->bindBuffer(target, buffer);
|
| -}
|
| -
|
| -GL_SAME_METHOD_2_X2(BindFramebuffer, bindFramebuffer, unsigned long, WebGLFramebuffer*)
|
| -
|
| -GL_SAME_METHOD_2_X2(BindRenderbuffer, bindRenderbuffer, unsigned long, WebGLRenderbuffer*)
|
| -
|
| -// If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps,
|
| -// we could just use:
|
| -// GL_SAME_METHOD_2_X2(BindTexture, bindTexture, unsigned long, WebGLTexture*)
|
| -void GraphicsContext3D::bindTexture(unsigned long target,
|
| - WebGLTexture* texture)
|
| -{
|
| - m_internal->bindTexture(target, texture);
|
| -}
|
| -
|
| -GL_SAME_METHOD_4(BlendColor, blendColor, double, double, double, double)
|
| -
|
| -GL_SAME_METHOD_1(BlendEquation, blendEquation, unsigned long)
|
| -
|
| -GL_SAME_METHOD_2(BlendEquationSeparate, blendEquationSeparate, unsigned long, unsigned long)
|
| -
|
| -GL_SAME_METHOD_2(BlendFunc, blendFunc, unsigned long, unsigned long)
|
| -
|
| -GL_SAME_METHOD_4(BlendFuncSeparate, blendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long)
|
| -
|
| -void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long usage)
|
| -{
|
| - m_internal->bufferDataImpl(target, size, 0, usage);
|
| -}
|
| -
|
| -void GraphicsContext3D::bufferData(unsigned long target, WebGLArray* array, unsigned long usage)
|
| -{
|
| - m_internal->bufferDataImpl(target, array->sizeInBytes(), array->baseAddress(), usage);
|
| -}
|
| -
|
| -void GraphicsContext3D::bufferSubData(unsigned long target, long offset, WebGLArray* array)
|
| -{
|
| - if (!array || !array->length())
|
| - return;
|
| -
|
| - makeContextCurrent();
|
| - // FIXME: make this verification more efficient.
|
| - GLint binding = 0;
|
| - GLenum binding_target = GL_ARRAY_BUFFER_BINDING;
|
| - if (target == GL_ELEMENT_ARRAY_BUFFER)
|
| - binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING;
|
| - glGetIntegerv(binding_target, &binding);
|
| - if (binding <= 0) {
|
| - // FIXME: raise exception.
|
| - // LogMessagef(("bufferSubData: no buffer bound"));
|
| - return;
|
| - }
|
| - glBufferSubData(target, offset, array->sizeInBytes(), array->baseAddress());
|
| -}
|
| -
|
| -unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target)
|
| -{
|
| - makeContextCurrent();
|
| - return glCheckFramebufferStatus(target);
|
| -}
|
| -
|
| -GL_SAME_METHOD_1(Clear, clear, unsigned long)
|
| -
|
| -GL_SAME_METHOD_4(ClearColor, clearColor, double, double, double, double)
|
| -
|
| -GL_SAME_METHOD_1(ClearDepth, clearDepth, double)
|
| -
|
| -GL_SAME_METHOD_1(ClearStencil, clearStencil, long)
|
| -
|
| -GL_SAME_METHOD_4(ColorMask, colorMask, bool, bool, bool, bool)
|
| -
|
| -GL_SAME_METHOD_1_X(CompileShader, compileShader, WebGLShader*)
|
| -
|
| -GL_SAME_METHOD_8(CopyTexImage2D, copyTexImage2D, unsigned long, long, unsigned long, long, long, unsigned long, unsigned long, long)
|
| -
|
| -GL_SAME_METHOD_8(CopyTexSubImage2D, copyTexSubImage2D, unsigned long, long, long, long, long, long, unsigned long, unsigned long)
|
| -
|
| -GL_SAME_METHOD_1(CullFace, cullFace, unsigned long)
|
| -
|
| -GL_SAME_METHOD_1(DepthFunc, depthFunc, unsigned long)
|
| -
|
| -GL_SAME_METHOD_1(DepthMask, depthMask, bool)
|
| -
|
| -GL_SAME_METHOD_2(DepthRange, depthRange, double, double)
|
| -
|
| -void GraphicsContext3D::detachShader(WebGLProgram* program, WebGLShader* shader)
|
| -{
|
| - if (!program || !shader)
|
| - return;
|
| -
|
| - makeContextCurrent();
|
| - glDetachShader(EXTRACT(program), EXTRACT(shader));
|
| -}
|
| -
|
| -GL_SAME_METHOD_1(Disable, disable, unsigned long)
|
| -
|
| -void GraphicsContext3D::disableVertexAttribArray(unsigned long index)
|
| -{
|
| - m_internal->disableVertexAttribArray(index);
|
| -}
|
| -
|
| -void GraphicsContext3D::drawArrays(unsigned long mode, long first, long count)
|
| -{
|
| - switch (mode) {
|
| - case GL_TRIANGLES:
|
| - case GL_TRIANGLE_STRIP:
|
| - case GL_TRIANGLE_FAN:
|
| - case GL_POINTS:
|
| - case GL_LINE_STRIP:
|
| - case GL_LINE_LOOP:
|
| - case GL_LINES:
|
| - break;
|
| - default: // FIXME: default cases are discouraged in WebKit.
|
| - // FIXME: output log message, raise exception.
|
| - // LogMessage(NS_LITERAL_CSTRING("drawArrays: invalid mode"));
|
| - // return NS_ERROR_DOM_SYNTAX_ERR;
|
| - return;
|
| - }
|
| -
|
| - if (first+count < first || first+count < count) {
|
| - // FIXME: output log message, raise exception.
|
| - // LogMessage(NS_LITERAL_CSTRING("drawArrays: overflow in first+count"));
|
| - // return NS_ERROR_INVALID_ARG;
|
| - return;
|
| - }
|
| -
|
| - // FIXME: validate against currently bound buffer.
|
| - // if (!ValidateBuffers(first+count))
|
| - // return NS_ERROR_INVALID_ARG;
|
| -
|
| - makeContextCurrent();
|
| - glDrawArrays(mode, first, count);
|
| -}
|
| -
|
| -void GraphicsContext3D::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset)
|
| -{
|
| - makeContextCurrent();
|
| - // FIXME: make this verification more efficient.
|
| - GLint binding = 0;
|
| - GLenum binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING;
|
| - glGetIntegerv(binding_target, &binding);
|
| - if (binding <= 0) {
|
| - // FIXME: raise exception.
|
| - // LogMessagef(("bufferData: no buffer bound"));
|
| - return;
|
| - }
|
| - glDrawElements(mode, count, type,
|
| - reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
|
| -}
|
| -
|
| -GL_SAME_METHOD_1(Enable, enable, unsigned long)
|
| -
|
| -void GraphicsContext3D::enableVertexAttribArray(unsigned long index)
|
| -{
|
| - m_internal->enableVertexAttribArray(index);
|
| -}
|
| -
|
| -GL_SAME_METHOD_0(Finish, finish)
|
| -
|
| -GL_SAME_METHOD_0(Flush, flush)
|
| -
|
| -GL_SAME_METHOD_4_X4(FramebufferRenderbuffer, framebufferRenderbuffer, unsigned long, unsigned long, unsigned long, WebGLRenderbuffer*)
|
| -
|
| -GL_SAME_METHOD_5_X4(FramebufferTexture2D, framebufferTexture2D, unsigned long, unsigned long, unsigned long, WebGLTexture*, long)
|
| -
|
| -GL_SAME_METHOD_1(FrontFace, frontFace, unsigned long)
|
| -
|
| -void GraphicsContext3D::generateMipmap(unsigned long target)
|
| -{
|
| - makeContextCurrent();
|
| - if (glGenerateMipmapEXT)
|
| - glGenerateMipmapEXT(target);
|
| - // FIXME: provide alternative code path? This will be unpleasant
|
| - // to implement if glGenerateMipmapEXT is not available -- it will
|
| - // require a texture readback and re-upload.
|
| -}
|
| -
|
| -bool GraphicsContext3D::getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo& info)
|
| -{
|
| - if (!program)
|
| - return false;
|
| - GLint maxNameLength = -1;
|
| - glGetProgramiv(EXTRACT(program), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength);
|
| - if (maxNameLength < 0)
|
| - return false;
|
| - GLchar* name = 0;
|
| - if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name))
|
| - return false;
|
| - GLsizei length = 0;
|
| - GLint size = -1;
|
| - GLenum type = 0;
|
| - glGetActiveAttrib(EXTRACT(program), index, maxNameLength,
|
| - &length, &size, &type, name);
|
| - if (size < 0) {
|
| - fastFree(name);
|
| - return false;
|
| - }
|
| - info.name = String(name, length);
|
| - info.type = type;
|
| - info.size = size;
|
| - fastFree(name);
|
| - return true;
|
| -}
|
| -
|
| -bool GraphicsContext3D::getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo& info)
|
| -{
|
| - if (!program)
|
| - return false;
|
| - GLint maxNameLength = -1;
|
| - glGetProgramiv(EXTRACT(program), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
|
| - if (maxNameLength < 0)
|
| - return false;
|
| - GLchar* name = 0;
|
| - if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name))
|
| - return false;
|
| - GLsizei length = 0;
|
| - GLint size = -1;
|
| - GLenum type = 0;
|
| - glGetActiveUniform(EXTRACT(program), index, maxNameLength,
|
| - &length, &size, &type, name);
|
| - if (size < 0) {
|
| - fastFree(name);
|
| - return false;
|
| - }
|
| - info.name = String(name, length);
|
| - info.type = type;
|
| - info.size = size;
|
| - fastFree(name);
|
| - return true;
|
| -}
|
| -
|
| -int GraphicsContext3D::getAttribLocation(WebGLProgram* program, const String& name)
|
| -{
|
| - if (!program)
|
| - return -1;
|
| -
|
| - makeContextCurrent();
|
| - return glGetAttribLocation(EXTRACT(program), name.utf8().data());
|
| -}
|
| -
|
| -bool GraphicsContext3D::getBoolean(unsigned long pname)
|
| -{
|
| - makeContextCurrent();
|
| - GLboolean val;
|
| - // FIXME: validate pname to ensure it returns only a single value.
|
| - glGetBooleanv(pname, &val);
|
| - return static_cast<bool>(val);
|
| -}
|
| -
|
| -PassRefPtr<WebGLUnsignedByteArray> GraphicsContext3D::getBooleanv(unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -int GraphicsContext3D::getBufferParameteri(unsigned long target, unsigned long pname)
|
| -{
|
| - makeContextCurrent();
|
| - GLint data;
|
| - glGetBufferParameteriv(target, pname, &data);
|
| - return static_cast<int>(data);
|
| -}
|
| -
|
| -PassRefPtr<WebGLIntArray> GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -unsigned long GraphicsContext3D::getError()
|
| -{
|
| - makeContextCurrent();
|
| - return glGetError();
|
| -}
|
| -
|
| -float GraphicsContext3D::getFloat(unsigned long pname)
|
| -{
|
| - makeContextCurrent();
|
| - GLfloat val;
|
| - // FIXME: validate pname to ensure it returns only a single value.
|
| - glGetFloatv(pname, &val);
|
| - return static_cast<float>(val);
|
| -}
|
| -
|
| -PassRefPtr<WebGLFloatArray> GraphicsContext3D::getFloatv(unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -int GraphicsContext3D::getFramebufferAttachmentParameteri(unsigned long target,
|
| - unsigned long attachment,
|
| - unsigned long pname)
|
| -{
|
| - makeContextCurrent();
|
| - GLint data;
|
| - glGetFramebufferAttachmentParameteriv(target, attachment, pname, &data);
|
| - return static_cast<int>(data);
|
| -}
|
| -
|
| -PassRefPtr<WebGLIntArray> GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target,
|
| - unsigned long attachment,
|
| - unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -int GraphicsContext3D::getInteger(unsigned long pname)
|
| -{
|
| - makeContextCurrent();
|
| - GLint val;
|
| - // FIXME: validate pname to ensure it returns only a single value.
|
| - glGetIntegerv(pname, &val);
|
| - return static_cast<int>(val);
|
| -}
|
| -
|
| -PassRefPtr<WebGLIntArray> GraphicsContext3D::getIntegerv(unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -int GraphicsContext3D::getProgrami(WebGLProgram* program,
|
| - unsigned long pname)
|
| -{
|
| - makeContextCurrent();
|
| - GLint param;
|
| - glGetProgramiv(EXTRACT(program), pname, ¶m);
|
| - return static_cast<int>(param);
|
| -}
|
| -
|
| -PassRefPtr<WebGLIntArray> GraphicsContext3D::getProgramiv(WebGLProgram* program,
|
| - unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -String GraphicsContext3D::getProgramInfoLog(WebGLProgram* program)
|
| -{
|
| - makeContextCurrent();
|
| - GLuint programID = EXTRACT(program);
|
| - GLint logLength;
|
| - glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logLength);
|
| - if (!logLength)
|
| - return String();
|
| - GLchar* log = 0;
|
| - if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log))
|
| - return String();
|
| - GLsizei returnedLogLength;
|
| - glGetProgramInfoLog(programID, logLength, &returnedLogLength, log);
|
| - ASSERT(logLength == returnedLogLength + 1);
|
| - String res = String(log, returnedLogLength);
|
| - fastFree(log);
|
| - return res;
|
| -}
|
| -
|
| -int GraphicsContext3D::getRenderbufferParameteri(unsigned long target,
|
| - unsigned long pname)
|
| -{
|
| - makeContextCurrent();
|
| - GLint param;
|
| - glGetRenderbufferParameteriv(target, pname, ¶m);
|
| - return static_cast<int>(param);
|
| -}
|
| -
|
| -PassRefPtr<WebGLIntArray> GraphicsContext3D::getRenderbufferParameteriv(unsigned long target,
|
| - unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -int GraphicsContext3D::getShaderi(WebGLShader* shader,
|
| - unsigned long pname)
|
| -{
|
| - makeContextCurrent();
|
| - GLint param;
|
| - glGetShaderiv(EXTRACT(shader), pname, ¶m);
|
| - return static_cast<int>(param);
|
| -}
|
| -
|
| -PassRefPtr<WebGLIntArray> GraphicsContext3D::getShaderiv(WebGLShader* shader,
|
| - unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -String GraphicsContext3D::getShaderInfoLog(WebGLShader* shader)
|
| -{
|
| - makeContextCurrent();
|
| - GLuint shaderID = EXTRACT(shader);
|
| - GLint logLength;
|
| - glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength);
|
| - if (!logLength)
|
| - return String();
|
| - GLchar* log = 0;
|
| - if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log))
|
| - return String();
|
| - GLsizei returnedLogLength;
|
| - glGetShaderInfoLog(shaderID, logLength, &returnedLogLength, log);
|
| - ASSERT(logLength == returnedLogLength + 1);
|
| - String res = String(log, returnedLogLength);
|
| - fastFree(log);
|
| - return res;
|
| -}
|
| -
|
| -String GraphicsContext3D::getShaderSource(WebGLShader* shader)
|
| -{
|
| - makeContextCurrent();
|
| - GLuint shaderID = EXTRACT(shader);
|
| - GLint logLength;
|
| - glGetShaderiv(shaderID, GL_SHADER_SOURCE_LENGTH, &logLength);
|
| - if (!logLength)
|
| - return String();
|
| - GLchar* log = 0;
|
| - if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log))
|
| - return String();
|
| - GLsizei returnedLogLength;
|
| - glGetShaderSource(shaderID, logLength, &returnedLogLength, log);
|
| - ASSERT(logLength == returnedLogLength + 1);
|
| - String res = String(log, returnedLogLength);
|
| - fastFree(log);
|
| - return res;
|
| -}
|
| -
|
| -String GraphicsContext3D::getString(unsigned long name)
|
| -{
|
| - makeContextCurrent();
|
| - return String(reinterpret_cast<const char*>(glGetString(name)));
|
| -}
|
| -
|
| -float GraphicsContext3D::getTexParameterf(unsigned long target, unsigned long pname)
|
| -{
|
| - makeContextCurrent();
|
| - if (!m_internal->validateTextureTarget(target)) {
|
| - // FIXME: throw exception.
|
| - return 0;
|
| - }
|
| -
|
| - if (!m_internal->validateTextureParameter(pname)) {
|
| - // FIXME: throw exception.
|
| - return 0;
|
| - }
|
| -
|
| - GLfloat param;
|
| - glGetTexParameterfv(target, pname, ¶m);
|
| - return static_cast<float>(param);
|
| -}
|
| -
|
| -PassRefPtr<WebGLFloatArray> GraphicsContext3D::getTexParameterfv(unsigned long target, unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -int GraphicsContext3D::getTexParameteri(unsigned long target, unsigned long pname)
|
| -{
|
| - makeContextCurrent();
|
| - if (!m_internal->validateTextureTarget(target)) {
|
| - // FIXME: throw exception.
|
| - return 0;
|
| - }
|
| -
|
| - if (!m_internal->validateTextureParameter(pname)) {
|
| - // FIXME: throw exception.
|
| - return 0;
|
| - }
|
| -
|
| - GLint param;
|
| - glGetTexParameteriv(target, pname, ¶m);
|
| - return static_cast<int>(param);
|
| -}
|
| -
|
| -PassRefPtr<WebGLIntArray> GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -float GraphicsContext3D::getUniformf(WebGLProgram* program, long location)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -PassRefPtr<WebGLFloatArray> GraphicsContext3D::getUniformfv(WebGLProgram* program, long location)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -int GraphicsContext3D::getUniformi(WebGLProgram* program, long location)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -PassRefPtr<WebGLIntArray> GraphicsContext3D::getUniformiv(WebGLProgram* program, long location)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -long GraphicsContext3D::getUniformLocation(WebGLProgram* program, const String& name)
|
| -{
|
| - if (!program)
|
| - return -1;
|
| -
|
| - makeContextCurrent();
|
| - return glGetUniformLocation(EXTRACT(program), name.utf8().data());
|
| -}
|
| -
|
| -float GraphicsContext3D::getVertexAttribf(unsigned long index,
|
| - unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -PassRefPtr<WebGLFloatArray> GraphicsContext3D::getVertexAttribfv(unsigned long index,
|
| - unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -int GraphicsContext3D::getVertexAttribi(unsigned long index,
|
| - unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -PassRefPtr<WebGLIntArray> GraphicsContext3D::getVertexAttribiv(unsigned long index,
|
| - unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long pname)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return 0;
|
| -}
|
| -
|
| -GL_SAME_METHOD_2(Hint, hint, unsigned long, unsigned long);
|
| -
|
| -bool GraphicsContext3D::isBuffer(WebGLBuffer* buffer)
|
| -{
|
| - makeContextCurrent();
|
| - return glIsBuffer(EXTRACT(buffer));
|
| -}
|
| -
|
| -bool GraphicsContext3D::isEnabled(unsigned long cap)
|
| -{
|
| - makeContextCurrent();
|
| - return glIsEnabled(cap);
|
| -}
|
| -
|
| -bool GraphicsContext3D::isFramebuffer(WebGLFramebuffer* framebuffer)
|
| -{
|
| - makeContextCurrent();
|
| - return glIsFramebuffer(EXTRACT(framebuffer));
|
| -}
|
| -
|
| -bool GraphicsContext3D::isProgram(WebGLProgram* program)
|
| -{
|
| - makeContextCurrent();
|
| - return glIsProgram(EXTRACT(program));
|
| -}
|
| -
|
| -bool GraphicsContext3D::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
|
| -{
|
| - makeContextCurrent();
|
| - return glIsRenderbuffer(EXTRACT(renderbuffer));
|
| -}
|
| -
|
| -bool GraphicsContext3D::isShader(WebGLShader* shader)
|
| -{
|
| - makeContextCurrent();
|
| - return glIsShader(EXTRACT(shader));
|
| -}
|
| -
|
| -bool GraphicsContext3D::isTexture(WebGLTexture* texture)
|
| -{
|
| - makeContextCurrent();
|
| - return glIsTexture(EXTRACT(texture));
|
| -}
|
| -
|
| -GL_SAME_METHOD_1(LineWidth, lineWidth, double)
|
| -
|
| -GL_SAME_METHOD_1_X(LinkProgram, linkProgram, WebGLProgram*)
|
| -
|
| -void GraphicsContext3D::pixelStorei(unsigned long pname, long param)
|
| -{
|
| - if (pname != GL_PACK_ALIGNMENT && pname != GL_UNPACK_ALIGNMENT) {
|
| - // FIXME: Create a fake GL error and throw an exception.
|
| - return;
|
| - }
|
| -
|
| - makeContextCurrent();
|
| - glPixelStorei(pname, param);
|
| -}
|
| -
|
| -GL_SAME_METHOD_2(PolygonOffset, polygonOffset, double, double)
|
| -
|
| -PassRefPtr<WebGLArray> GraphicsContext3D::readPixels(long x, long y,
|
| - unsigned long width, unsigned long height,
|
| - unsigned long format, unsigned long type) {
|
| - // FIXME: support more pixel formats and types.
|
| - if (!((format == GL_RGBA) && (type == GL_UNSIGNED_BYTE)))
|
| - return 0;
|
| -
|
| - // FIXME: take into account pack alignment.
|
| - RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4);
|
| - glReadPixels(x, y, width, height, format, type, array->baseAddress());
|
| - return array;
|
| -}
|
| -
|
| -void GraphicsContext3D::releaseShaderCompiler()
|
| -{
|
| -}
|
| -
|
| -GL_SAME_METHOD_4(RenderbufferStorage, renderbufferStorage, unsigned long, unsigned long, unsigned long, unsigned long)
|
| -
|
| -GL_SAME_METHOD_2(SampleCoverage, sampleCoverage, double, bool)
|
| -
|
| -GL_SAME_METHOD_4(Scissor, scissor, long, long, unsigned long, unsigned long)
|
| -
|
| -void GraphicsContext3D::shaderSource(WebGLShader* shader, const String& source)
|
| -{
|
| - makeContextCurrent();
|
| - CString str = source.utf8();
|
| - const char* data = str.data();
|
| - GLint length = str.length();
|
| - glShaderSource(EXTRACT(shader), 1, &data, &length);
|
| -}
|
| -
|
| -GL_SAME_METHOD_3(StencilFunc, stencilFunc, unsigned long, long, unsigned long)
|
| -
|
| -GL_SAME_METHOD_4(StencilFuncSeparate, stencilFuncSeparate, unsigned long, unsigned long, long, unsigned long)
|
| -
|
| -GL_SAME_METHOD_1(StencilMask, stencilMask, unsigned long)
|
| -
|
| -GL_SAME_METHOD_2(StencilMaskSeparate, stencilMaskSeparate, unsigned long, unsigned long)
|
| -
|
| -GL_SAME_METHOD_3(StencilOp, stencilOp, unsigned long, unsigned long, unsigned long)
|
| -
|
| -GL_SAME_METHOD_4(StencilOpSeparate, stencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long)
|
| -
|
| -int GraphicsContext3D::texImage2D(unsigned target,
|
| - unsigned level,
|
| - unsigned internalformat,
|
| - unsigned width,
|
| - unsigned height,
|
| - unsigned border,
|
| - unsigned format,
|
| - unsigned type,
|
| - WebGLArray* pixels)
|
| -{
|
| - // FIXME: must do validation similar to JOGL's to ensure that
|
| - // the incoming array is of the appropriate length.
|
| - glTexImage2D(target,
|
| - level,
|
| - internalformat,
|
| - width,
|
| - height,
|
| - border,
|
| - format,
|
| - type,
|
| - pixels->baseAddress());
|
| - return 0;
|
| -}
|
| -
|
| -int GraphicsContext3D::texImage2D(unsigned target,
|
| - unsigned level,
|
| - unsigned internalformat,
|
| - unsigned width,
|
| - unsigned height,
|
| - unsigned border,
|
| - unsigned format,
|
| - unsigned type,
|
| - ImageData* pixels)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return -1;
|
| -}
|
| -
|
| -// Remove premultiplied alpha from color channels.
|
| -// FIXME: this is lossy. Must retrieve original values from HTMLImageElement.
|
| -static void unmultiplyAlpha(unsigned char* rgbaData, int numPixels)
|
| -{
|
| - for (int j = 0; j < numPixels; j++) {
|
| - float b = rgbaData[4*j+0] / 255.0f;
|
| - float g = rgbaData[4*j+1] / 255.0f;
|
| - float r = rgbaData[4*j+2] / 255.0f;
|
| - float a = rgbaData[4*j+3] / 255.0f;
|
| - if (a > 0.0f) {
|
| - b /= a;
|
| - g /= a;
|
| - r /= a;
|
| - b = (b > 1.0f) ? 1.0f : b;
|
| - g = (g > 1.0f) ? 1.0f : g;
|
| - r = (r > 1.0f) ? 1.0f : r;
|
| - rgbaData[4*j+0] = (unsigned char) (b * 255.0f);
|
| - rgbaData[4*j+1] = (unsigned char) (g * 255.0f);
|
| - rgbaData[4*j+2] = (unsigned char) (r * 255.0f);
|
| - }
|
| - }
|
| -}
|
| -
|
| -// FIXME: this must be changed to refer to the original image data
|
| -// rather than unmultiplying the alpha channel.
|
| -static int texImage2DHelper(unsigned target, unsigned level,
|
| - int width, int height,
|
| - int rowBytes,
|
| - bool flipY,
|
| - bool premultiplyAlpha,
|
| - GLenum format,
|
| - bool skipAlpha,
|
| - unsigned char* pixels)
|
| -{
|
| - ASSERT(format == GL_RGBA || format == GL_BGRA);
|
| - GLint internalFormat = GL_RGBA8;
|
| - if (skipAlpha) {
|
| - internalFormat = GL_RGB8;
|
| - // Ignore the alpha channel
|
| - premultiplyAlpha = true;
|
| - }
|
| - if (flipY) {
|
| - // Need to flip images vertically. To avoid making a copy of
|
| - // the entire image, we perform a ton of glTexSubImage2D
|
| - // calls. FIXME: should rethink this strategy for efficiency.
|
| - glTexImage2D(target, level, internalFormat,
|
| - width,
|
| - height,
|
| - 0,
|
| - format,
|
| - GL_UNSIGNED_BYTE,
|
| - 0);
|
| - unsigned char* row = 0;
|
| - bool allocatedRow = false;
|
| - if (!premultiplyAlpha) {
|
| - row = new unsigned char[rowBytes];
|
| - allocatedRow = true;
|
| - }
|
| - for (int i = 0; i < height; i++) {
|
| - if (premultiplyAlpha)
|
| - row = pixels + (rowBytes * i);
|
| - else {
|
| - memcpy(row, pixels + (rowBytes * i), rowBytes);
|
| - unmultiplyAlpha(row, width);
|
| - }
|
| - glTexSubImage2D(target, level, 0, height - i - 1,
|
| - width, 1,
|
| - format,
|
| - GL_UNSIGNED_BYTE,
|
| - row);
|
| - }
|
| - if (allocatedRow)
|
| - delete[] row;
|
| - } else {
|
| - // The pixels of cube maps' faces are defined with a top-down
|
| - // scanline ordering, unlike GL_TEXTURE_2D, so when uploading
|
| - // these, the above vertical flip is the wrong thing to do.
|
| - if (premultiplyAlpha)
|
| - glTexImage2D(target, level, internalFormat,
|
| - width,
|
| - height,
|
| - 0,
|
| - format,
|
| - GL_UNSIGNED_BYTE,
|
| - pixels);
|
| - else {
|
| - glTexImage2D(target, level, internalFormat,
|
| - width,
|
| - height,
|
| - 0,
|
| - format,
|
| - GL_UNSIGNED_BYTE,
|
| - 0);
|
| - unsigned char* row = new unsigned char[rowBytes];
|
| - for (int i = 0; i < height; i++) {
|
| - memcpy(row, pixels + (rowBytes * i), rowBytes);
|
| - unmultiplyAlpha(row, width);
|
| - glTexSubImage2D(target, level, 0, i,
|
| - width, 1,
|
| - format,
|
| - GL_UNSIGNED_BYTE,
|
| - row);
|
| - }
|
| - delete[] row;
|
| - }
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image,
|
| - bool flipY, bool premultiplyAlpha)
|
| -{
|
| - ASSERT(image);
|
| -
|
| - int res = -1;
|
| -#if PLATFORM(SKIA)
|
| - NativeImageSkia* skiaImage = image->nativeImageForCurrentFrame();
|
| - if (!skiaImage) {
|
| - ASSERT_NOT_REACHED();
|
| - return -1;
|
| - }
|
| - SkBitmap::Config skiaConfig = skiaImage->config();
|
| - // FIXME: must support more image configurations.
|
| - if (skiaConfig != SkBitmap::kARGB_8888_Config) {
|
| - ASSERT_NOT_REACHED();
|
| - return -1;
|
| - }
|
| - SkBitmap& skiaImageRef = *skiaImage;
|
| - SkAutoLockPixels lock(skiaImageRef);
|
| - int width = skiaImage->width();
|
| - int height = skiaImage->height();
|
| - unsigned char* pixels =
|
| - reinterpret_cast<unsigned char*>(skiaImage->getPixels());
|
| - int rowBytes = skiaImage->rowBytes();
|
| - res = texImage2DHelper(target, level,
|
| - width, height,
|
| - rowBytes,
|
| - flipY, premultiplyAlpha,
|
| - GL_BGRA,
|
| - false,
|
| - pixels);
|
| -#elif PLATFORM(CG)
|
| - CGImageRef cgImage = image->nativeImageForCurrentFrame();
|
| - if (!cgImage) {
|
| - ASSERT_NOT_REACHED();
|
| - return -1;
|
| - }
|
| - int width = CGImageGetWidth(cgImage);
|
| - int height = CGImageGetHeight(cgImage);
|
| - int rowBytes = width * 4;
|
| - CGImageAlphaInfo info = CGImageGetAlphaInfo(cgImage);
|
| - bool skipAlpha = (info == kCGImageAlphaNone
|
| - || info == kCGImageAlphaNoneSkipLast
|
| - || info == kCGImageAlphaNoneSkipFirst);
|
| - unsigned char* imageData = new unsigned char[height * rowBytes];
|
| - CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
| - CGContextRef tmpContext = CGBitmapContextCreate(imageData, width, height, 8, rowBytes,
|
| - colorSpace,
|
| - kCGImageAlphaPremultipliedLast);
|
| - CGColorSpaceRelease(colorSpace);
|
| - CGContextDrawImage(tmpContext,
|
| - CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)),
|
| - cgImage);
|
| - CGContextRelease(tmpContext);
|
| - res = texImage2DHelper(target, level, width, height, rowBytes,
|
| - flipY, premultiplyAlpha, GL_RGBA, skipAlpha, imageData);
|
| - delete[] imageData;
|
| -#else
|
| -#error Must port to your platform
|
| -#endif
|
| - return res;
|
| -}
|
| -
|
| -int GraphicsContext3D::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
|
| - bool flipY, bool premultiplyAlpha)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return -1;
|
| -}
|
| -
|
| -GL_SAME_METHOD_3(TexParameterf, texParameterf, unsigned, unsigned, float);
|
| -
|
| -GL_SAME_METHOD_3(TexParameteri, texParameteri, unsigned, unsigned, int);
|
| -
|
| -int GraphicsContext3D::texSubImage2D(unsigned target,
|
| - unsigned level,
|
| - unsigned xoffset,
|
| - unsigned yoffset,
|
| - unsigned width,
|
| - unsigned height,
|
| - unsigned format,
|
| - unsigned type,
|
| - WebGLArray* pixels)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return -1;
|
| -}
|
| -
|
| -int GraphicsContext3D::texSubImage2D(unsigned target,
|
| - unsigned level,
|
| - unsigned xoffset,
|
| - unsigned yoffset,
|
| - unsigned width,
|
| - unsigned height,
|
| - unsigned format,
|
| - unsigned type,
|
| - ImageData* pixels)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return -1;
|
| -}
|
| -
|
| -int GraphicsContext3D::texSubImage2D(unsigned target,
|
| - unsigned level,
|
| - unsigned xoffset,
|
| - unsigned yoffset,
|
| - unsigned width,
|
| - unsigned height,
|
| - Image* image,
|
| - bool flipY,
|
| - bool premultiplyAlpha)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return -1;
|
| -}
|
| -
|
| -int GraphicsContext3D::texSubImage2D(unsigned target,
|
| - unsigned level,
|
| - unsigned xoffset,
|
| - unsigned yoffset,
|
| - unsigned width,
|
| - unsigned height,
|
| - HTMLVideoElement* video,
|
| - bool flipY,
|
| - bool premultiplyAlpha)
|
| -{
|
| - // FIXME: implement.
|
| - notImplemented();
|
| - return -1;
|
| -}
|
| -
|
| -GL_SAME_METHOD_2(Uniform1f, uniform1f, long, float)
|
| -
|
| -void GraphicsContext3D::uniform1fv(long location, float* v, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniform1fv(location, size, v);
|
| -}
|
| -
|
| -GL_SAME_METHOD_2(Uniform1i, uniform1i, long, int)
|
| -
|
| -void GraphicsContext3D::uniform1iv(long location, int* v, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniform1iv(location, size, v);
|
| -}
|
| -
|
| -GL_SAME_METHOD_3(Uniform2f, uniform2f, long, float, float)
|
| -
|
| -void GraphicsContext3D::uniform2fv(long location, float* v, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniform2fv(location, size, v);
|
| -}
|
| -
|
| -GL_SAME_METHOD_3(Uniform2i, uniform2i, long, int, int)
|
| -
|
| -void GraphicsContext3D::uniform2iv(long location, int* v, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniform2iv(location, size, v);
|
| -}
|
| -
|
| -GL_SAME_METHOD_4(Uniform3f, uniform3f, long, float, float, float)
|
| -
|
| -void GraphicsContext3D::uniform3fv(long location, float* v, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniform3fv(location, size, v);
|
| -}
|
| -
|
| -GL_SAME_METHOD_4(Uniform3i, uniform3i, long, int, int, int)
|
| -
|
| -void GraphicsContext3D::uniform3iv(long location, int* v, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniform3iv(location, size, v);
|
| -}
|
| -
|
| -GL_SAME_METHOD_5(Uniform4f, uniform4f, long, float, float, float, float)
|
| -
|
| -void GraphicsContext3D::uniform4fv(long location, float* v, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniform4fv(location, size, v);
|
| -}
|
| -
|
| -GL_SAME_METHOD_5(Uniform4i, uniform4i, long, int, int, int, int)
|
| -
|
| -void GraphicsContext3D::uniform4iv(long location, int* v, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniform4iv(location, size, v);
|
| -}
|
| -
|
| -void GraphicsContext3D::uniformMatrix2fv(long location, bool transpose, float* value, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniformMatrix2fv(location, size, transpose, value);
|
| -}
|
| -
|
| -void GraphicsContext3D::uniformMatrix3fv(long location, bool transpose, float* value, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniformMatrix3fv(location, size, transpose, value);
|
| -}
|
| -
|
| -void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* value, int size)
|
| -{
|
| - makeContextCurrent();
|
| - glUniformMatrix4fv(location, size, transpose, value);
|
| -}
|
| -
|
| -GL_SAME_METHOD_1_X(UseProgram, useProgram, WebGLProgram*)
|
| -
|
| -GL_SAME_METHOD_1_X(ValidateProgram, validateProgram, WebGLProgram*)
|
| -
|
| -GL_SAME_METHOD_2(VertexAttrib1f, vertexAttrib1f, unsigned long, float)
|
| -
|
| -void GraphicsContext3D::vertexAttrib1fv(unsigned long indx, float* values)
|
| -{
|
| - makeContextCurrent();
|
| - glVertexAttrib1fv(indx, values);
|
| -}
|
| -
|
| -GL_SAME_METHOD_3(VertexAttrib2f, vertexAttrib2f, unsigned long, float, float)
|
| -
|
| -void GraphicsContext3D::vertexAttrib2fv(unsigned long indx, float* values)
|
| -{
|
| - makeContextCurrent();
|
| - glVertexAttrib2fv(indx, values);
|
| -}
|
| -
|
| -GL_SAME_METHOD_4(VertexAttrib3f, vertexAttrib3f, unsigned long, float, float, float)
|
| -
|
| -void GraphicsContext3D::vertexAttrib3fv(unsigned long indx, float* values)
|
| -{
|
| - makeContextCurrent();
|
| - glVertexAttrib3fv(indx, values);
|
| -}
|
| -
|
| -GL_SAME_METHOD_5(VertexAttrib4f, vertexAttrib4f, unsigned long, float, float, float, float)
|
| -
|
| -void GraphicsContext3D::vertexAttrib4fv(unsigned long indx, float* values)
|
| -{
|
| - makeContextCurrent();
|
| - glVertexAttrib4fv(indx, values);
|
| -}
|
| -
|
| -void GraphicsContext3D::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized,
|
| - unsigned long stride, unsigned long offset)
|
| -{
|
| - m_internal->vertexAttribPointer(indx, size, type, normalized, stride, offset);
|
| -}
|
| -
|
| -void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height)
|
| -{
|
| - makeContextCurrent();
|
| - m_internal->viewportImpl(x, y, width, height);
|
| -}
|
| -
|
| -}
|
| -
|
| -#endif // ENABLE(3D_CANVAS)
|
|
|