1/*
2 * Copyright (C) 2009 Apple 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
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef WebGLRenderingContext_h
27#define WebGLRenderingContext_h
28
29#include "CanvasRenderingContext.h"
30#include "ExceptionCode.h"
31#include "WebGLFloatArray.h"
32#include "WebGLGetInfo.h"
33#include "WebGLIntArray.h"
34#include "WebGLUnsignedByteArray.h"
35#include "GraphicsContext3D.h"
36#include "PlatformString.h"
37
38namespace WebCore {
39
40class WebGLActiveInfo;
41class WebGLBuffer;
42class WebGLContextAttributes;
43class WebGLFramebuffer;
44class CanvasObject;
45class WebGLProgram;
46class WebGLRenderbuffer;
47class WebGLShader;
48class WebGLTexture;
49class WebGLUniformLocation;
50class HTMLImageElement;
51class HTMLVideoElement;
52class ImageData;
53class WebKitCSSMatrix;
54
55    class WebGLRenderingContext : public CanvasRenderingContext {
56    public:
57        static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
58        virtual ~WebGLRenderingContext();
59
60        virtual bool is3d() const { return true; }
61
62        // Helper to return the size in bytes of OpenGL data types
63        // like GL_FLOAT, GL_INT, etc.
64        int sizeInBytes(int type, ExceptionCode& ec);
65
66        void activeTexture(unsigned long texture, ExceptionCode& ec);
67        void attachShader(WebGLProgram*, WebGLShader*, ExceptionCode& ec);
68        void bindAttribLocation(WebGLProgram*, unsigned long index, const String& name, ExceptionCode& ec);
69        void bindBuffer(unsigned long target, WebGLBuffer*, ExceptionCode& ec);
70        void bindFramebuffer(unsigned long target, WebGLFramebuffer*, ExceptionCode& ec);
71        void bindRenderbuffer(unsigned long target, WebGLRenderbuffer*, ExceptionCode& ec);
72        void bindTexture(unsigned long target, WebGLTexture*, ExceptionCode& ec);
73        void blendColor(double red, double green, double blue, double alpha);
74        void blendEquation(unsigned long mode);
75        void blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha);
76        void blendFunc(unsigned long sfactor, unsigned long dfactor);
77        void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha);
78
79        void bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode&);
80        void bufferData(unsigned long target, WebGLArray* data, unsigned long usage, ExceptionCode&);
81        void bufferSubData(unsigned long target, long offset, WebGLArray* data, ExceptionCode&);
82
83        unsigned long checkFramebufferStatus(unsigned long target);
84        void clear(unsigned long mask);
85        void clearColor(double red, double green, double blue, double alpha);
86        void clearDepth(double);
87        void clearStencil(long);
88        void colorMask(bool red, bool green, bool blue, bool alpha);
89        void compileShader(WebGLShader*, ExceptionCode& ec);
90
91        //void compressedTexImage2D(unsigned long target, long level, unsigned long internalformat, unsigned long width, unsigned long height, long border, unsigned long imageSize, const void* data);
92        //void compressedTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, unsigned long width, unsigned long height, unsigned long format, unsigned long imageSize, const void* data);
93
94        void copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border);
95        void copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height);
96
97        PassRefPtr<WebGLBuffer> createBuffer();
98        PassRefPtr<WebGLFramebuffer> createFramebuffer();
99        PassRefPtr<WebGLProgram> createProgram();
100        PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
101        PassRefPtr<WebGLShader> createShader(unsigned long type, ExceptionCode&);
102        PassRefPtr<WebGLTexture> createTexture();
103
104        void cullFace(unsigned long mode);
105
106        void deleteBuffer(WebGLBuffer*);
107        void deleteFramebuffer(WebGLFramebuffer*);
108        void deleteProgram(WebGLProgram*);
109        void deleteRenderbuffer(WebGLRenderbuffer*);
110        void deleteShader(WebGLShader*);
111        void deleteTexture(WebGLTexture*);
112
113        void depthFunc(unsigned long);
114        void depthMask(bool);
115        void depthRange(double zNear, double zFar);
116        void detachShader(WebGLProgram*, WebGLShader*, ExceptionCode&);
117        void disable(unsigned long cap);
118        void disableVertexAttribArray(unsigned long index, ExceptionCode&);
119        void drawArrays(unsigned long mode, long first, long count, ExceptionCode&);
120        void drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset, ExceptionCode&);
121
122        void enable(unsigned long cap);
123        void enableVertexAttribArray(unsigned long index, ExceptionCode&);
124        void finish();
125        void flush();
126        void framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer*, ExceptionCode& ec);
127        void framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture*, long level, ExceptionCode& ec);
128        void frontFace(unsigned long mode);
129        void generateMipmap(unsigned long target);
130
131        PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, unsigned long index, ExceptionCode&);
132        PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, unsigned long index, ExceptionCode&);
133
134        int  getAttribLocation(WebGLProgram*, const String& name);
135
136        WebGLGetInfo getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode&);
137
138        PassRefPtr<WebGLContextAttributes> getContextAttributes();
139
140        unsigned long getError();
141
142        WebGLGetInfo getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode&);
143
144        WebGLGetInfo getParameter(unsigned long pname, ExceptionCode&);
145
146        WebGLGetInfo getProgramParameter(WebGLProgram*, unsigned long pname, ExceptionCode&);
147
148        String getProgramInfoLog(WebGLProgram*, ExceptionCode& ec);
149
150        WebGLGetInfo getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode&);
151
152        WebGLGetInfo getShaderParameter(WebGLShader*, unsigned long pname, ExceptionCode& ec);
153
154        String getShaderInfoLog(WebGLShader*, ExceptionCode& ec);
155
156        // TBD
157        // void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
158
159        String getShaderSource(WebGLShader*, ExceptionCode&);
160        String getString(unsigned long name);
161
162        WebGLGetInfo getTexParameter(unsigned long target, unsigned long pname, ExceptionCode&);
163
164        WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*, ExceptionCode&);
165
166        PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&, ExceptionCode&);
167
168        WebGLGetInfo getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode&);
169
170        long getVertexAttribOffset(unsigned long index, unsigned long pname);
171
172        void hint(unsigned long target, unsigned long mode);
173        bool isBuffer(WebGLBuffer*);
174        bool isEnabled(unsigned long cap);
175        bool isFramebuffer(WebGLFramebuffer*);
176        bool isProgram(WebGLProgram*);
177        bool isRenderbuffer(WebGLRenderbuffer*);
178        bool isShader(WebGLShader*);
179        bool isTexture(WebGLTexture*);
180        void lineWidth(double);
181        void linkProgram(WebGLProgram*, ExceptionCode&);
182        void pixelStorei(unsigned long pname, long param);
183        void polygonOffset(double factor, double units);
184
185        PassRefPtr<WebGLArray> readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type);
186
187        void releaseShaderCompiler();
188        void renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height);
189        void sampleCoverage(double value, bool invert);
190        void scissor(long x, long y, unsigned long width, unsigned long height);
191        void shaderSource(WebGLShader*, const String&, ExceptionCode&);
192        void stencilFunc(unsigned long func, long ref, unsigned long mask);
193        void stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask);
194        void stencilMask(unsigned long);
195        void stencilMaskSeparate(unsigned long face, unsigned long mask);
196        void stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass);
197        void stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass);
198
199        void texImage2D(unsigned target, unsigned level, unsigned internalformat,
200                        unsigned width, unsigned height, unsigned border,
201                        unsigned format, unsigned type, WebGLArray* pixels, ExceptionCode&);
202        void texImage2D(unsigned target, unsigned level, ImageData* pixels,
203                        bool flipY, bool premultiplyAlpha, ExceptionCode&);
204        void texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
205                        bool flipY, bool premultiplyAlpha, ExceptionCode&);
206        void texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
207                        bool flipY, bool premultiplyAlpha, ExceptionCode&);
208        void texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
209                        bool flipY, bool premultiplyAlpha, ExceptionCode&);
210
211        void texParameterf(unsigned target, unsigned pname, float param);
212        void texParameteri(unsigned target, unsigned pname, int param);
213
214        void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
215                           unsigned width, unsigned height,
216                           unsigned format, unsigned type, WebGLArray* pixels, ExceptionCode&);
217        void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
218                           ImageData* pixels, bool flipY, bool premultiplyAlpha, ExceptionCode&);
219        void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
220                           HTMLImageElement* image, bool flipY, bool premultiplyAlpha, ExceptionCode&);
221        void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
222                           HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha, ExceptionCode&);
223        void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
224                           HTMLVideoElement* video, bool flipY, bool premultiplyAlpha, ExceptionCode&);
225
226        void uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode&);
227        void uniform1fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode&);
228        void uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode&);
229        void uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode&);
230        void uniform1iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode&);
231        void uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode&);
232        void uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode&);
233        void uniform2fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode&);
234        void uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode&);
235        void uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode&);
236        void uniform2iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode&);
237        void uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode&);
238        void uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode&);
239        void uniform3fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode&);
240        void uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode&);
241        void uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode&);
242        void uniform3iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode&);
243        void uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode&);
244        void uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode&);
245        void uniform4fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode&);
246        void uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode&);
247        void uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode&);
248        void uniform4iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode&);
249        void uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode&);
250        void uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, WebGLFloatArray* value, ExceptionCode&);
251        void uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* value, int size, ExceptionCode&);
252        void uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, WebGLFloatArray* value, ExceptionCode&);
253        void uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* value, int size, ExceptionCode&);
254        void uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, WebGLFloatArray* value, ExceptionCode&);
255        void uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* value, int size, ExceptionCode&);
256
257        void useProgram(WebGLProgram*, ExceptionCode&);
258        void validateProgram(WebGLProgram*, ExceptionCode&);
259
260        void vertexAttrib1f(unsigned long indx, float x);
261        void vertexAttrib1fv(unsigned long indx, WebGLFloatArray* values);
262        void vertexAttrib1fv(unsigned long indx, float* values, int size);
263        void vertexAttrib2f(unsigned long indx, float x, float y);
264        void vertexAttrib2fv(unsigned long indx, WebGLFloatArray* values);
265        void vertexAttrib2fv(unsigned long indx, float* values, int size);
266        void vertexAttrib3f(unsigned long indx, float x, float y, float z);
267        void vertexAttrib3fv(unsigned long indx, WebGLFloatArray* values);
268        void vertexAttrib3fv(unsigned long indx, float* values, int size);
269        void vertexAttrib4f(unsigned long indx, float x, float y, float z, float w);
270        void vertexAttrib4fv(unsigned long indx, WebGLFloatArray* values);
271        void vertexAttrib4fv(unsigned long indx, float* values, int size);
272        void vertexAttribPointer(unsigned long indx, long size, unsigned long type, bool normalized,
273                                 unsigned long stride, unsigned long offset, ExceptionCode&);
274
275        void viewport(long x, long y, unsigned long width, unsigned long height);
276
277        GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
278
279        void reshape(int width, int height);
280
281        // Helpers for notification about paint events.
282        void beginPaint();
283        void endPaint();
284
285        void removeObject(CanvasObject*);
286
287    private:
288        friend class CanvasObject;
289
290        WebGLRenderingContext(HTMLCanvasElement*, PassOwnPtr<GraphicsContext3D>);
291
292        void addObject(CanvasObject*);
293        void detachAndRemoveAllObjects();
294
295        void markContextChanged();
296        void cleanupAfterGraphicsCall(bool changed)
297        {
298            if (changed)
299                markContextChanged();
300        }
301
302        // Basic validation of count and offset against number of elements in element array buffer
303        bool validateElementArraySize(unsigned long count, unsigned long type, long offset);
304
305        // Conservative but quick index validation
306        bool validateIndexArrayConservative(unsigned long type, long& numElementsRequired);
307
308        // Precise but slow index validation -- only done if conservative checks fail
309        bool validateIndexArrayPrecise(unsigned long count, unsigned long type, long offset, long& numElementsRequired);
310        bool validateRenderingState(long numElements);
311
312        OwnPtr<GraphicsContext3D> m_context;
313        bool m_needsUpdate;
314        bool m_markedCanvasDirty;
315        // FIXME: I think this is broken -- it does not increment any
316        // reference counts, so may refer to destroyed objects.
317        HashSet<RefPtr<CanvasObject> > m_canvasObjects;
318
319        // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
320        RefPtr<WebGLBuffer> m_boundArrayBuffer;
321        RefPtr<WebGLBuffer> m_boundElementArrayBuffer;
322
323        // Cached values for vertex attrib range checks
324        class VertexAttribState {
325        public:
326            VertexAttribState() : enabled(false), numElements(0) { }
327            bool enabled;
328            long numElements;
329        };
330
331        Vector<VertexAttribState> m_vertexAttribState;
332        unsigned m_maxVertexAttribs;
333
334        RefPtr<WebGLProgram> m_currentProgram;
335        RefPtr<WebGLFramebuffer> m_framebufferBinding;
336        RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
337        class TextureUnitState {
338        public:
339            RefPtr<WebGLTexture> m_texture2DBinding;
340            RefPtr<WebGLTexture> m_textureCubeMapBinding;
341        };
342        TextureUnitState m_textureUnits[32];
343        unsigned long m_activeTextureUnit;
344
345        // Helpers for getParameter and others
346        WebGLGetInfo getBooleanParameter(unsigned long pname);
347        WebGLGetInfo getFloatParameter(unsigned long pname);
348        WebGLGetInfo getIntParameter(unsigned long pname);
349        WebGLGetInfo getLongParameter(unsigned long pname);
350        WebGLGetInfo getUnsignedLongParameter(unsigned long pname);
351        WebGLGetInfo getWebGLFloatArrayParameter(unsigned long pname);
352        WebGLGetInfo getWebGLIntArrayParameter(unsigned long pname);
353        WebGLGetInfo getWebGLUnsignedByteArrayParameter(unsigned long pname);
354
355        friend class WebGLStateRestorer;
356    };
357
358} // namespace WebCore
359
360#endif
361