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 "core/dom/ActiveDOMObject.h" 30 #include "core/html/canvas/CanvasRenderingContext.h" 31 #include "core/html/canvas/WebGLGetInfo.h" 32 #include "core/page/Page.h" 33 #include "core/platform/Timer.h" 34 #include "core/platform/graphics/GraphicsContext3D.h" 35 #include "core/platform/graphics/ImageBuffer.h" 36 37 #include "wtf/Float32Array.h" 38 #include "wtf/Int32Array.h" 39 #include "wtf/OwnArrayPtr.h" 40 #include "wtf/text/WTFString.h" 41 42 namespace WebKit { class WebLayer; } 43 44 namespace WebCore { 45 46 class ANGLEInstancedArrays; 47 class DrawingBuffer; 48 class EXTFragDepth; 49 class EXTTextureFilterAnisotropic; 50 class ExceptionState; 51 class HTMLImageElement; 52 class HTMLVideoElement; 53 class ImageBuffer; 54 class ImageData; 55 class IntSize; 56 class OESElementIndexUint; 57 class OESStandardDerivatives; 58 class OESTextureFloat; 59 class OESTextureFloatLinear; 60 class OESTextureHalfFloat; 61 class OESTextureHalfFloatLinear; 62 class OESVertexArrayObject; 63 class WebGLActiveInfo; 64 class WebGLBuffer; 65 class WebGLCompressedTextureATC; 66 class WebGLCompressedTexturePVRTC; 67 class WebGLCompressedTextureS3TC; 68 class WebGLContextAttributes; 69 class WebGLContextGroup; 70 class WebGLContextObject; 71 class WebGLDebugRendererInfo; 72 class WebGLDebugShaders; 73 class WebGLDepthTexture; 74 class WebGLDrawBuffers; 75 class WebGLExtension; 76 class WebGLFramebuffer; 77 class WebGLLoseContext; 78 class WebGLObject; 79 class WebGLProgram; 80 class WebGLRenderbuffer; 81 class WebGLShader; 82 class WebGLShaderPrecisionFormat; 83 class WebGLSharedObject; 84 class WebGLTexture; 85 class WebGLUniformLocation; 86 class WebGLVertexArrayObjectOES; 87 88 class WebGLRenderingContext : public CanvasRenderingContext, public ActiveDOMObject, private Page::MultisamplingChangedObserver { 89 public: 90 static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*); 91 virtual ~WebGLRenderingContext(); 92 93 virtual bool is3d() const { return true; } 94 virtual bool isAccelerated() const { return true; } 95 96 int drawingBufferWidth() const; 97 int drawingBufferHeight() const; 98 99 void activeTexture(GC3Denum texture); 100 void attachShader(WebGLProgram*, WebGLShader*); 101 void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name); 102 void bindBuffer(GC3Denum target, WebGLBuffer*); 103 void bindFramebuffer(GC3Denum target, WebGLFramebuffer*); 104 void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*); 105 void bindTexture(GC3Denum target, WebGLTexture*); 106 void blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha); 107 void blendEquation(GC3Denum mode); 108 void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha); 109 void blendFunc(GC3Denum sfactor, GC3Denum dfactor); 110 void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha); 111 112 void bufferData(GC3Denum target, long long size, GC3Denum usage); 113 void bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage); 114 void bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage); 115 void bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data); 116 void bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data); 117 118 GC3Denum checkFramebufferStatus(GC3Denum target); 119 void clear(GC3Dbitfield mask); 120 void clearColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha); 121 void clearDepth(GC3Dfloat); 122 void clearStencil(GC3Dint); 123 void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha); 124 void compileShader(WebGLShader*); 125 126 void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, 127 GC3Dsizei height, GC3Dint border, ArrayBufferView* data); 128 void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 129 GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data); 130 131 void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border); 132 void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height); 133 134 PassRefPtr<WebGLBuffer> createBuffer(); 135 PassRefPtr<WebGLFramebuffer> createFramebuffer(); 136 PassRefPtr<WebGLProgram> createProgram(); 137 PassRefPtr<WebGLRenderbuffer> createRenderbuffer(); 138 PassRefPtr<WebGLShader> createShader(GC3Denum type); 139 PassRefPtr<WebGLTexture> createTexture(); 140 141 void cullFace(GC3Denum mode); 142 143 void deleteBuffer(WebGLBuffer*); 144 void deleteFramebuffer(WebGLFramebuffer*); 145 void deleteProgram(WebGLProgram*); 146 void deleteRenderbuffer(WebGLRenderbuffer*); 147 void deleteShader(WebGLShader*); 148 void deleteTexture(WebGLTexture*); 149 150 void depthFunc(GC3Denum); 151 void depthMask(GC3Dboolean); 152 void depthRange(GC3Dfloat zNear, GC3Dfloat zFar); 153 void detachShader(WebGLProgram*, WebGLShader*); 154 void disable(GC3Denum cap); 155 void disableVertexAttribArray(GC3Duint index); 156 void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count); 157 void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset); 158 159 void drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount); 160 void drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount); 161 162 void enable(GC3Denum cap); 163 void enableVertexAttribArray(GC3Duint index); 164 void finish(); 165 void flush(); 166 void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*); 167 void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level); 168 void frontFace(GC3Denum mode); 169 void generateMipmap(GC3Denum target); 170 171 PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GC3Duint index); 172 PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GC3Duint index); 173 bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader> >&); 174 GC3Dint getAttribLocation(WebGLProgram*, const String& name); 175 WebGLGetInfo getBufferParameter(GC3Denum target, GC3Denum pname); 176 PassRefPtr<WebGLContextAttributes> getContextAttributes(); 177 GC3Denum getError(); 178 PassRefPtr<WebGLExtension> getExtension(const String& name); 179 WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname); 180 WebGLGetInfo getParameter(GC3Denum pname); 181 WebGLGetInfo getProgramParameter(WebGLProgram*, GC3Denum pname); 182 String getProgramInfoLog(WebGLProgram*); 183 WebGLGetInfo getRenderbufferParameter(GC3Denum target, GC3Denum pname); 184 WebGLGetInfo getShaderParameter(WebGLShader*, GC3Denum pname); 185 String getShaderInfoLog(WebGLShader*); 186 PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType); 187 String getShaderSource(WebGLShader*); 188 Vector<String> getSupportedExtensions(); 189 WebGLGetInfo getTexParameter(GC3Denum target, GC3Denum pname); 190 WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*); 191 PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&); 192 WebGLGetInfo getVertexAttrib(GC3Duint index, GC3Denum pname); 193 long long getVertexAttribOffset(GC3Duint index, GC3Denum pname); 194 195 void hint(GC3Denum target, GC3Denum mode); 196 GC3Dboolean isBuffer(WebGLBuffer*); 197 bool isContextLost(); 198 GC3Dboolean isEnabled(GC3Denum cap); 199 GC3Dboolean isFramebuffer(WebGLFramebuffer*); 200 GC3Dboolean isProgram(WebGLProgram*); 201 GC3Dboolean isRenderbuffer(WebGLRenderbuffer*); 202 GC3Dboolean isShader(WebGLShader*); 203 GC3Dboolean isTexture(WebGLTexture*); 204 205 void lineWidth(GC3Dfloat); 206 void linkProgram(WebGLProgram*); 207 void pixelStorei(GC3Denum pname, GC3Dint param); 208 void polygonOffset(GC3Dfloat factor, GC3Dfloat units); 209 void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels); 210 void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height); 211 void sampleCoverage(GC3Dfloat value, GC3Dboolean invert); 212 void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height); 213 void shaderSource(WebGLShader*, const String&); 214 void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask); 215 void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask); 216 void stencilMask(GC3Duint); 217 void stencilMaskSeparate(GC3Denum face, GC3Duint mask); 218 void stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass); 219 void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass); 220 221 void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, 222 GC3Dsizei width, GC3Dsizei height, GC3Dint border, 223 GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionState&); 224 void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, 225 GC3Denum format, GC3Denum type, ImageData*, ExceptionState&); 226 void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, 227 GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionState&); 228 void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, 229 GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionState&); 230 void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, 231 GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionState&); 232 233 void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param); 234 void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param); 235 236 void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 237 GC3Dsizei width, GC3Dsizei height, 238 GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionState&); 239 void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 240 GC3Denum format, GC3Denum type, ImageData*, ExceptionState&); 241 void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 242 GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionState&); 243 void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 244 GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionState&); 245 void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 246 GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionState&); 247 248 void uniform1f(const WebGLUniformLocation*, GC3Dfloat x); 249 void uniform1fv(const WebGLUniformLocation*, Float32Array* v); 250 void uniform1fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei); 251 void uniform1i(const WebGLUniformLocation*, GC3Dint x); 252 void uniform1iv(const WebGLUniformLocation*, Int32Array* v); 253 void uniform1iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei); 254 void uniform2f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y); 255 void uniform2fv(const WebGLUniformLocation*, Float32Array* v); 256 void uniform2fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei); 257 void uniform2i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y); 258 void uniform2iv(const WebGLUniformLocation*, Int32Array* v); 259 void uniform2iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei); 260 void uniform3f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z); 261 void uniform3fv(const WebGLUniformLocation*, Float32Array* v); 262 void uniform3fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei); 263 void uniform3i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z); 264 void uniform3iv(const WebGLUniformLocation*, Int32Array* v); 265 void uniform3iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei); 266 void uniform4f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w); 267 void uniform4fv(const WebGLUniformLocation*, Float32Array* v); 268 void uniform4fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei); 269 void uniform4i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w); 270 void uniform4iv(const WebGLUniformLocation*, Int32Array* v); 271 void uniform4iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei); 272 void uniformMatrix2fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value); 273 void uniformMatrix2fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei); 274 void uniformMatrix3fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value); 275 void uniformMatrix3fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei); 276 void uniformMatrix4fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value); 277 void uniformMatrix4fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei); 278 279 void useProgram(WebGLProgram*); 280 void validateProgram(WebGLProgram*); 281 282 void vertexAttrib1f(GC3Duint index, GC3Dfloat x); 283 void vertexAttrib1fv(GC3Duint index, Float32Array* values); 284 void vertexAttrib1fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei); 285 void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y); 286 void vertexAttrib2fv(GC3Duint index, Float32Array* values); 287 void vertexAttrib2fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei); 288 void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z); 289 void vertexAttrib3fv(GC3Duint index, Float32Array* values); 290 void vertexAttrib3fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei); 291 void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w); 292 void vertexAttrib4fv(GC3Duint index, Float32Array* values); 293 void vertexAttrib4fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei); 294 void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, 295 GC3Dsizei stride, long long offset); 296 297 void vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor); 298 299 void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height); 300 301 // WEBKIT_lose_context support 302 enum LostContextMode { 303 // Lost context occurred at the graphics system level. 304 RealLostContext, 305 306 // Lost context provoked by WEBKIT_lose_context. 307 SyntheticLostContext, 308 309 // A synthetic lost context that should attempt to recover automatically 310 AutoRecoverSyntheticLostContext 311 }; 312 void forceLostContext(LostContextMode); 313 void forceRestoreContext(); 314 void loseContextImpl(LostContextMode); 315 316 GraphicsContext3D* graphicsContext3D() const { return m_context.get(); } 317 WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); } 318 virtual WebKit::WebLayer* platformLayer() const; 319 320 void reshape(int width, int height); 321 322 void markLayerComposited(); 323 virtual void paintRenderingResultsToCanvas(); 324 virtual PassRefPtr<ImageData> paintRenderingResultsToImageData(); 325 326 void removeSharedObject(WebGLSharedObject*); 327 void removeContextObject(WebGLContextObject*); 328 329 unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; } 330 331 // ActiveDOMObject notifications 332 virtual bool hasPendingActivity() const; 333 virtual void stop(); 334 335 private: 336 friend class WebGLDrawBuffers; 337 friend class WebGLFramebuffer; 338 friend class WebGLObject; 339 friend class OESVertexArrayObject; 340 friend class WebGLDebugShaders; 341 friend class WebGLCompressedTextureATC; 342 friend class WebGLCompressedTexturePVRTC; 343 friend class WebGLCompressedTextureS3TC; 344 friend class WebGLRenderingContextErrorMessageCallback; 345 friend class WebGLVertexArrayObjectOES; 346 347 WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes, GraphicsContext3D::Attributes); 348 void initializeNewContext(); 349 void setupFlags(); 350 351 void addSharedObject(WebGLSharedObject*); 352 void addContextObject(WebGLContextObject*); 353 void detachAndRemoveAllObjects(); 354 355 void destroyGraphicsContext3D(); 356 void markContextChanged(); 357 358 // Query if the GL implementation is NPOT strict. 359 bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; } 360 // Query if depth_stencil buffer is supported. 361 bool isDepthStencilSupported() { return m_isDepthStencilSupported; } 362 363 // Helper to return the size in bytes of OpenGL data types 364 // like GL_FLOAT, GL_INT, etc. 365 unsigned int sizeInBytes(GC3Denum type); 366 367 // Check if each enabled vertex attribute is bound to a buffer. 368 bool validateRenderingState(); 369 370 bool validateWebGLObject(const char*, WebGLObject*); 371 372 // Adds a compressed texture format. 373 void addCompressedTextureFormat(GC3Denum); 374 void removeAllCompressedTextureFormats(); 375 376 PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy); 377 378 WebGLRenderbuffer* ensureEmulatedStencilBuffer(GC3Denum target, WebGLRenderbuffer*); 379 380 RefPtr<GraphicsContext3D> m_context; 381 RefPtr<WebGLContextGroup> m_contextGroup; 382 383 // Structure for rendering to a DrawingBuffer, instead of directly 384 // to the back-buffer of m_context. 385 RefPtr<DrawingBuffer> m_drawingBuffer; 386 387 // Dispatches a context lost event once it is determined that one is needed. 388 // This is used both for synthetic and real context losses. For real ones, it's 389 // likely that there's no JavaScript on the stack, but that might be dependent 390 // on how exactly the platform discovers that the context was lost. For better 391 // portability we always defer the dispatch of the event. 392 Timer<WebGLRenderingContext> m_dispatchContextLostEventTimer; 393 bool m_restoreAllowed; 394 Timer<WebGLRenderingContext> m_restoreTimer; 395 396 bool m_needsUpdate; 397 bool m_markedCanvasDirty; 398 HashSet<WebGLContextObject*> m_contextObjects; 399 400 // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER 401 RefPtr<WebGLBuffer> m_boundArrayBuffer; 402 403 RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject; 404 RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject; 405 void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject) 406 { 407 if (arrayObject) 408 m_boundVertexArrayObject = arrayObject; 409 else 410 m_boundVertexArrayObject = m_defaultVertexArrayObject; 411 } 412 413 class VertexAttribValue { 414 public: 415 VertexAttribValue() 416 { 417 initValue(); 418 } 419 420 void initValue() 421 { 422 value[0] = 0.0f; 423 value[1] = 0.0f; 424 value[2] = 0.0f; 425 value[3] = 1.0f; 426 } 427 428 GC3Dfloat value[4]; 429 }; 430 Vector<VertexAttribValue> m_vertexAttribValue; 431 unsigned m_maxVertexAttribs; 432 RefPtr<WebGLBuffer> m_vertexAttrib0Buffer; 433 long m_vertexAttrib0BufferSize; 434 GC3Dfloat m_vertexAttrib0BufferValue[4]; 435 bool m_forceAttrib0BufferRefill; 436 bool m_vertexAttrib0UsedBefore; 437 438 RefPtr<WebGLProgram> m_currentProgram; 439 RefPtr<WebGLFramebuffer> m_framebufferBinding; 440 RefPtr<WebGLRenderbuffer> m_renderbufferBinding; 441 class TextureUnitState { 442 public: 443 RefPtr<WebGLTexture> m_texture2DBinding; 444 RefPtr<WebGLTexture> m_textureCubeMapBinding; 445 }; 446 Vector<TextureUnitState> m_textureUnits; 447 unsigned long m_activeTextureUnit; 448 449 RefPtr<WebGLTexture> m_blackTexture2D; 450 RefPtr<WebGLTexture> m_blackTextureCubeMap; 451 452 Vector<GC3Denum> m_compressedTextureFormats; 453 454 // Fixed-size cache of reusable image buffers for video texImage2D calls. 455 class LRUImageBufferCache { 456 public: 457 LRUImageBufferCache(int capacity); 458 // The pointer returned is owned by the image buffer map. 459 ImageBuffer* imageBuffer(const IntSize& size); 460 private: 461 void bubbleToFront(int idx); 462 OwnArrayPtr<OwnPtr<ImageBuffer> > m_buffers; 463 int m_capacity; 464 }; 465 LRUImageBufferCache m_videoCache; 466 467 GC3Dint m_maxTextureSize; 468 GC3Dint m_maxCubeMapTextureSize; 469 GC3Dint m_maxRenderbufferSize; 470 GC3Dint m_maxViewportDims[2]; 471 GC3Dint m_maxTextureLevel; 472 GC3Dint m_maxCubeMapTextureLevel; 473 474 GC3Dint m_maxDrawBuffers; 475 GC3Dint m_maxColorAttachments; 476 GC3Denum m_backDrawBuffer; 477 bool m_drawBuffersWebGLRequirementsChecked; 478 bool m_drawBuffersSupported; 479 480 GC3Dint m_packAlignment; 481 GC3Dint m_unpackAlignment; 482 bool m_unpackFlipY; 483 bool m_unpackPremultiplyAlpha; 484 GC3Denum m_unpackColorspaceConversion; 485 bool m_contextLost; 486 LostContextMode m_contextLostMode; 487 GraphicsContext3D::Attributes m_attributes; 488 GraphicsContext3D::Attributes m_requestedAttributes; 489 490 bool m_layerCleared; 491 GC3Dfloat m_clearColor[4]; 492 bool m_scissorEnabled; 493 GC3Dfloat m_clearDepth; 494 GC3Dint m_clearStencil; 495 GC3Dboolean m_colorMask[4]; 496 GC3Dboolean m_depthMask; 497 498 bool m_stencilEnabled; 499 GC3Duint m_stencilMask, m_stencilMaskBack; 500 GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value. 501 GC3Duint m_stencilFuncMask, m_stencilFuncMaskBack; 502 503 bool m_isGLES2NPOTStrict; 504 bool m_isDepthStencilSupported; 505 506 bool m_synthesizedErrorsToConsole; 507 int m_numGLErrorsToConsoleAllowed; 508 509 // Enabled extension objects. 510 RefPtr<ANGLEInstancedArrays> m_angleInstancedArrays; 511 RefPtr<EXTFragDepth> m_extFragDepth; 512 RefPtr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic; 513 RefPtr<OESTextureFloat> m_oesTextureFloat; 514 RefPtr<OESTextureFloatLinear> m_oesTextureFloatLinear; 515 RefPtr<OESTextureHalfFloat> m_oesTextureHalfFloat; 516 RefPtr<OESTextureHalfFloatLinear> m_oesTextureHalfFloatLinear; 517 RefPtr<OESStandardDerivatives> m_oesStandardDerivatives; 518 RefPtr<OESVertexArrayObject> m_oesVertexArrayObject; 519 RefPtr<OESElementIndexUint> m_oesElementIndexUint; 520 RefPtr<WebGLLoseContext> m_webglLoseContext; 521 RefPtr<WebGLDebugRendererInfo> m_webglDebugRendererInfo; 522 RefPtr<WebGLDebugShaders> m_webglDebugShaders; 523 RefPtr<WebGLDrawBuffers> m_webglDrawBuffers; 524 RefPtr<WebGLCompressedTextureATC> m_webglCompressedTextureATC; 525 RefPtr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC; 526 RefPtr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC; 527 RefPtr<WebGLDepthTexture> m_webglDepthTexture; 528 529 class ExtensionTracker { 530 public: 531 ExtensionTracker(bool privileged, bool draft, bool prefixed, const char** prefixes) 532 : m_privileged(privileged) 533 , m_draft(draft) 534 , m_prefixed(prefixed) 535 , m_prefixes(prefixes) 536 { 537 } 538 539 virtual ~ExtensionTracker() 540 { 541 } 542 543 bool getPrefixed() const 544 { 545 return m_prefixed; 546 } 547 548 bool getPrivileged() const 549 { 550 return m_privileged; 551 } 552 553 bool getDraft() const 554 { 555 return m_draft; 556 } 557 558 bool matchesNameWithPrefixes(const String&) const; 559 560 virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext*) const = 0; 561 virtual bool supported(WebGLRenderingContext*) const = 0; 562 virtual const char* getExtensionName() const = 0; 563 virtual void loseExtension() = 0; 564 565 private: 566 bool m_privileged; 567 bool m_draft; 568 bool m_prefixed; 569 const char** m_prefixes; 570 }; 571 572 template <typename T> 573 class TypedExtensionTracker : public ExtensionTracker { 574 public: 575 TypedExtensionTracker(RefPtr<T>& extensionField, bool privileged, bool draft, bool prefixed, const char** prefixes) 576 : ExtensionTracker(privileged, draft, prefixed, prefixes) 577 , m_extensionField(extensionField) 578 { 579 } 580 581 ~TypedExtensionTracker() 582 { 583 if (m_extensionField) { 584 m_extensionField->lose(true); 585 m_extensionField = 0; 586 } 587 } 588 589 virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext* context) const 590 { 591 if (!m_extensionField) 592 m_extensionField = T::create(context); 593 594 return m_extensionField; 595 } 596 597 virtual bool supported(WebGLRenderingContext* context) const 598 { 599 return T::supported(context); 600 } 601 602 virtual const char* getExtensionName() const 603 { 604 return T::getExtensionName(); 605 } 606 607 virtual void loseExtension() 608 { 609 if (m_extensionField) { 610 m_extensionField->lose(false); 611 if (m_extensionField->isLost()) 612 m_extensionField = 0; 613 } 614 } 615 616 private: 617 RefPtr<T>& m_extensionField; 618 }; 619 620 Vector<ExtensionTracker*> m_extensions; 621 622 template <typename T> 623 void registerExtension(RefPtr<T>& extensionPtr, bool privileged, bool draft, bool prefixed, const char** prefixes) 624 { 625 m_extensions.append(new TypedExtensionTracker<T>(extensionPtr, privileged, draft, prefixed, prefixes)); 626 } 627 628 // Errors raised by synthesizeGLError() while the context is lost. 629 Vector<GC3Denum> lost_context_errors_; 630 631 // Helpers for getParameter and others 632 WebGLGetInfo getBooleanParameter(GC3Denum); 633 WebGLGetInfo getBooleanArrayParameter(GC3Denum); 634 WebGLGetInfo getFloatParameter(GC3Denum); 635 WebGLGetInfo getIntParameter(GC3Denum); 636 WebGLGetInfo getUnsignedIntParameter(GC3Denum); 637 WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum); 638 WebGLGetInfo getWebGLIntArrayParameter(GC3Denum); 639 640 // Clear the backbuffer if it was composited since the last operation. 641 // clearMask is set to the bitfield of any clear that would happen anyway at this time 642 // and the function returns true if that clear is now unnecessary. 643 bool clearIfComposited(GC3Dbitfield clearMask = 0); 644 645 // Helper to restore state that clearing the framebuffer may destroy. 646 void restoreStateAfterClear(); 647 648 void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState&); 649 void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&); 650 void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState&); 651 void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&); 652 653 void handleTextureCompleteness(const char*, bool); 654 void createFallbackBlackTextures1x1(); 655 656 // Helper function for copyTex{Sub}Image, check whether the internalformat 657 // and the color buffer format of the current bound framebuffer combination 658 // is valid. 659 bool isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat, 660 GC3Denum colorBufferFormat); 661 662 // Helper function to get the bound framebuffer's color buffer format. 663 GC3Denum getBoundFramebufferColorFormat(); 664 665 // Helper function to get the bound framebuffer's width. 666 int getBoundFramebufferWidth(); 667 668 // Helper function to get the bound framebuffer's height. 669 int getBoundFramebufferHeight(); 670 671 // Helper function to verify limits on the length of uniform and attribute locations. 672 bool validateLocationLength(const char* functionName, const String&); 673 674 // Helper function to check if size is non-negative. 675 // Generate GL error and return false for negative inputs; otherwise, return true. 676 bool validateSize(const char* functionName, GC3Dint x, GC3Dint y); 677 678 // Helper function to check if all characters in the string belong to the 679 // ASCII subset as defined in GLSL ES 1.0 spec section 3.1. 680 bool validateString(const char* functionName, const String&); 681 682 // Helper function to check target and texture bound to the target. 683 // Generate GL errors and return 0 if target is invalid or texture bound is 684 // null. Otherwise, return the texture bound to the target. 685 WebGLTexture* validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap); 686 687 // Helper function to check input format/type for functions {copy}Tex{Sub}Image. 688 // Generates GL error and returns false if parameters are invalid. 689 bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level); 690 691 // Helper function to check input level for functions {copy}Tex{Sub}Image. 692 // Generates GL error and returns false if level is invalid. 693 bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level); 694 695 enum TexFuncValidationFunctionType { 696 NotTexSubImage2D, 697 TexSubImage2D, 698 }; 699 700 enum TexFuncValidationSourceType { 701 SourceArrayBufferView, 702 SourceImageData, 703 SourceHTMLImageElement, 704 SourceHTMLCanvasElement, 705 SourceHTMLVideoElement, 706 }; 707 708 // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid. 709 // Otherwise, it would return quickly without doing other work. 710 bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, 711 GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset); 712 713 // Helper function to check input parameters for functions {copy}Tex{Sub}Image. 714 // Generates GL error and returns false if parameters are invalid. 715 bool validateTexFuncParameters(const char* functionName, 716 TexFuncValidationFunctionType, 717 GC3Denum target, GC3Dint level, 718 GC3Denum internalformat, 719 GC3Dsizei width, GC3Dsizei height, GC3Dint border, 720 GC3Denum format, GC3Denum type); 721 722 enum NullDisposition { 723 NullAllowed, 724 NullNotAllowed 725 }; 726 727 // Helper function to validate that the given ArrayBufferView 728 // is of the correct type and contains enough data for the texImage call. 729 // Generates GL error and returns false if parameters are invalid. 730 bool validateTexFuncData(const char* functionName, GC3Dint level, 731 GC3Dsizei width, GC3Dsizei height, 732 GC3Denum format, GC3Denum type, 733 ArrayBufferView* pixels, 734 NullDisposition); 735 736 // Helper function to validate a given texture format is settable as in 737 // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and 738 // copyTexSubImage2D. 739 // Generates GL error and returns false if the format is not settable. 740 bool validateSettableTexFormat(const char* functionName, GC3Denum format); 741 742 // Helper function to validate compressed texture data is correct size 743 // for the given format and dimensions. 744 bool validateCompressedTexFuncData(const char* functionName, 745 GC3Dsizei width, GC3Dsizei height, 746 GC3Denum format, ArrayBufferView* pixels); 747 748 // Helper function for validating compressed texture formats. 749 bool validateCompressedTexFormat(GC3Denum format); 750 751 // Helper function to validate compressed texture dimensions are valid for 752 // the given format. 753 bool validateCompressedTexDimensions(const char* functionName, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format); 754 755 // Helper function to validate compressed texture dimensions are valid for 756 // the given format. 757 bool validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 758 GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*); 759 760 // Helper function to validate mode for draw{Arrays/Elements}. 761 bool validateDrawMode(const char* functionName, GC3Denum); 762 763 // Helper function to validate if front/back stencilMask and stencilFunc settings are the same. 764 bool validateStencilSettings(const char* functionName); 765 766 // Helper function to validate stencil or depth func. 767 bool validateStencilOrDepthFunc(const char* functionName, GC3Denum); 768 769 // Helper function for texParameterf and texParameteri. 770 void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat); 771 772 // Helper function to print GL errors to console. 773 void printGLErrorToConsole(const String&); 774 775 // Helper function to print warnings to console. Currently 776 // used only to warn about use of obsolete functions. 777 void printWarningToConsole(const String&); 778 779 // Helper function to validate input parameters for framebuffer functions. 780 // Generate GL error if parameters are illegal. 781 bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment); 782 783 // Helper function to validate blend equation mode. 784 bool validateBlendEquation(const char* functionName, GC3Denum); 785 786 // Helper function to validate blend func factors. 787 bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst); 788 789 // Helper function to validate a GL capability. 790 bool validateCapability(const char* functionName, GC3Denum); 791 792 // Helper function to validate input parameters for uniform functions. 793 bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod); 794 bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod); 795 bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod); 796 bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod); 797 bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod); 798 799 // Helper function to validate parameters for bufferData. 800 // Return the current bound buffer to target, or 0 if parameters are invalid. 801 WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage); 802 803 // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin. 804 bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionState&); 805 806 // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin. 807 bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionState&); 808 809 // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin. 810 bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionState&); 811 812 // Helper function to validate drawArrays(Instanced) calls 813 bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count); 814 815 // Helper function to validate drawElements(Instanced) calls 816 bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset); 817 818 // Helper function to validate draw*Instanced calls 819 bool validateDrawInstanced(const char* functionName, GC3Dsizei primcount); 820 821 // Helper functions for vertexAttribNf{v}. 822 void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat); 823 void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array*, GC3Dsizei expectedSize); 824 void vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat*, GC3Dsizei, GC3Dsizei expectedSize); 825 826 // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions. 827 // Return false if caller should return without further processing. 828 bool deleteObject(WebGLObject*); 829 830 // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram. 831 // If the object has already been deleted, set deleted to true upon return. 832 // Return false if caller should return without further processing. 833 bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted); 834 835 void dispatchContextLostEvent(Timer<WebGLRenderingContext>*); 836 // Helper for restoration after context lost. 837 void maybeRestoreContext(Timer<WebGLRenderingContext>*); 838 839 // Determine if we are running privileged code in the browser, for example, 840 // a Safari or Chrome extension. 841 bool allowPrivilegedExtensions() const; 842 843 enum ConsoleDisplayPreference { 844 DisplayInConsole, 845 DontDisplayInConsole 846 }; 847 848 // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message 849 // to the JavaScript console. 850 void synthesizeGLError(GC3Denum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole); 851 void emitGLWarning(const char* function, const char* reason); 852 853 String ensureNotNull(const String&) const; 854 855 // Enable or disable stencil test based on user setting and 856 // whether the current FBO has a stencil buffer. 857 void applyStencilTest(); 858 859 // Helper for enabling or disabling a capability. 860 void enableOrDisable(GC3Denum capability, bool enable); 861 862 // Clamp the width and height to GL_MAX_VIEWPORT_DIMS. 863 IntSize clampedCanvasSize(); 864 865 // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0. 866 // Later, return the cached value. 867 GC3Dint getMaxDrawBuffers(); 868 GC3Dint getMaxColorAttachments(); 869 870 void setBackDrawBuffer(GC3Denum); 871 872 void restoreCurrentFramebuffer(); 873 void restoreCurrentTexture2D(); 874 875 virtual void multisamplingChanged(bool); 876 bool m_multisamplingAllowed; 877 bool m_multisamplingObserverRegistered; 878 879 friend class WebGLStateRestorer; 880 friend class WebGLRenderingContextEvictionManager; 881 882 static Vector<WebGLRenderingContext*>& activeContexts(); 883 static Vector<WebGLRenderingContext*>& forciblyEvictedContexts(); 884 885 static void activateContext(WebGLRenderingContext*); 886 static void deactivateContext(WebGLRenderingContext*, bool addToInactiveList); 887 static void willDestroyContext(WebGLRenderingContext*); 888 static void forciblyLoseOldestContext(const String& reason); 889 static IntSize oldestContextSize(); 890 }; 891 892 } // namespace WebCore 893 894 #endif 895