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 "platform/Timer.h" 34 #include "platform/graphics/GraphicsContext3D.h" 35 #include "platform/graphics/ImageBuffer.h" 36 37 #include "wtf/Float32Array.h" 38 #include "wtf/Int32Array.h" 39 #include "wtf/OwnPtr.h" 40 #include "wtf/text/WTFString.h" 41 42 namespace blink { 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 blink::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 maxVertexAttribs() 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> drawImageIntoBuffer(Image*, int width, int height); 377 378 PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy); 379 380 WebGLRenderbuffer* ensureEmulatedStencilBuffer(GC3Denum target, WebGLRenderbuffer*); 381 382 RefPtr<GraphicsContext3D> m_context; 383 RefPtr<WebGLContextGroup> m_contextGroup; 384 385 // Structure for rendering to a DrawingBuffer, instead of directly 386 // to the back-buffer of m_context. 387 RefPtr<DrawingBuffer> m_drawingBuffer; 388 389 // Dispatches a context lost event once it is determined that one is needed. 390 // This is used both for synthetic and real context losses. For real ones, it's 391 // likely that there's no JavaScript on the stack, but that might be dependent 392 // on how exactly the platform discovers that the context was lost. For better 393 // portability we always defer the dispatch of the event. 394 Timer<WebGLRenderingContext> m_dispatchContextLostEventTimer; 395 bool m_restoreAllowed; 396 Timer<WebGLRenderingContext> m_restoreTimer; 397 398 bool m_needsUpdate; 399 bool m_markedCanvasDirty; 400 HashSet<WebGLContextObject*> m_contextObjects; 401 402 // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER 403 RefPtr<WebGLBuffer> m_boundArrayBuffer; 404 405 RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject; 406 RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject; 407 void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject) 408 { 409 if (arrayObject) 410 m_boundVertexArrayObject = arrayObject; 411 else 412 m_boundVertexArrayObject = m_defaultVertexArrayObject; 413 } 414 415 class VertexAttribValue { 416 public: 417 VertexAttribValue() 418 { 419 initValue(); 420 } 421 422 void initValue() 423 { 424 value[0] = 0.0f; 425 value[1] = 0.0f; 426 value[2] = 0.0f; 427 value[3] = 1.0f; 428 } 429 430 GC3Dfloat value[4]; 431 }; 432 Vector<VertexAttribValue> m_vertexAttribValue; 433 unsigned m_maxVertexAttribs; 434 RefPtr<WebGLBuffer> m_vertexAttrib0Buffer; 435 long m_vertexAttrib0BufferSize; 436 GC3Dfloat m_vertexAttrib0BufferValue[4]; 437 bool m_forceAttrib0BufferRefill; 438 bool m_vertexAttrib0UsedBefore; 439 440 RefPtr<WebGLProgram> m_currentProgram; 441 RefPtr<WebGLFramebuffer> m_framebufferBinding; 442 RefPtr<WebGLRenderbuffer> m_renderbufferBinding; 443 class TextureUnitState { 444 public: 445 RefPtr<WebGLTexture> m_texture2DBinding; 446 RefPtr<WebGLTexture> m_textureCubeMapBinding; 447 }; 448 Vector<TextureUnitState> m_textureUnits; 449 unsigned long m_activeTextureUnit; 450 451 RefPtr<WebGLTexture> m_blackTexture2D; 452 RefPtr<WebGLTexture> m_blackTextureCubeMap; 453 454 Vector<GC3Denum> m_compressedTextureFormats; 455 456 // Fixed-size cache of reusable image buffers for video texImage2D calls. 457 class LRUImageBufferCache { 458 public: 459 LRUImageBufferCache(int capacity); 460 // The pointer returned is owned by the image buffer map. 461 ImageBuffer* imageBuffer(const IntSize& size); 462 private: 463 void bubbleToFront(int idx); 464 OwnPtr<OwnPtr<ImageBuffer>[]> m_buffers; 465 int m_capacity; 466 }; 467 LRUImageBufferCache m_generatedImageCache; 468 469 GC3Dint m_maxTextureSize; 470 GC3Dint m_maxCubeMapTextureSize; 471 GC3Dint m_maxRenderbufferSize; 472 GC3Dint m_maxViewportDims[2]; 473 GC3Dint m_maxTextureLevel; 474 GC3Dint m_maxCubeMapTextureLevel; 475 476 GC3Dint m_maxDrawBuffers; 477 GC3Dint m_maxColorAttachments; 478 GC3Denum m_backDrawBuffer; 479 bool m_drawBuffersWebGLRequirementsChecked; 480 bool m_drawBuffersSupported; 481 482 GC3Dint m_packAlignment; 483 GC3Dint m_unpackAlignment; 484 bool m_unpackFlipY; 485 bool m_unpackPremultiplyAlpha; 486 GC3Denum m_unpackColorspaceConversion; 487 bool m_contextLost; 488 LostContextMode m_contextLostMode; 489 GraphicsContext3D::Attributes m_attributes; 490 GraphicsContext3D::Attributes m_requestedAttributes; 491 492 bool m_layerCleared; 493 GC3Dfloat m_clearColor[4]; 494 bool m_scissorEnabled; 495 GC3Dfloat m_clearDepth; 496 GC3Dint m_clearStencil; 497 GC3Dboolean m_colorMask[4]; 498 GC3Dboolean m_depthMask; 499 500 bool m_stencilEnabled; 501 GC3Duint m_stencilMask, m_stencilMaskBack; 502 GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value. 503 GC3Duint m_stencilFuncMask, m_stencilFuncMaskBack; 504 505 bool m_isGLES2NPOTStrict; 506 bool m_isDepthStencilSupported; 507 508 bool m_synthesizedErrorsToConsole; 509 int m_numGLErrorsToConsoleAllowed; 510 511 bool m_multisamplingAllowed; 512 bool m_multisamplingObserverRegistered; 513 514 GC3Duint m_onePlusMaxEnabledAttribIndex; 515 unsigned long m_onePlusMaxNonDefaultTextureUnit; 516 517 // Enabled extension objects. 518 RefPtr<ANGLEInstancedArrays> m_angleInstancedArrays; 519 RefPtr<EXTFragDepth> m_extFragDepth; 520 RefPtr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic; 521 RefPtr<OESTextureFloat> m_oesTextureFloat; 522 RefPtr<OESTextureFloatLinear> m_oesTextureFloatLinear; 523 RefPtr<OESTextureHalfFloat> m_oesTextureHalfFloat; 524 RefPtr<OESTextureHalfFloatLinear> m_oesTextureHalfFloatLinear; 525 RefPtr<OESStandardDerivatives> m_oesStandardDerivatives; 526 RefPtr<OESVertexArrayObject> m_oesVertexArrayObject; 527 RefPtr<OESElementIndexUint> m_oesElementIndexUint; 528 RefPtr<WebGLLoseContext> m_webglLoseContext; 529 RefPtr<WebGLDebugRendererInfo> m_webglDebugRendererInfo; 530 RefPtr<WebGLDebugShaders> m_webglDebugShaders; 531 RefPtr<WebGLDrawBuffers> m_webglDrawBuffers; 532 RefPtr<WebGLCompressedTextureATC> m_webglCompressedTextureATC; 533 RefPtr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC; 534 RefPtr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC; 535 RefPtr<WebGLDepthTexture> m_webglDepthTexture; 536 537 enum ExtensionFlags { 538 ApprovedExtension = 0x00, 539 DraftExtension = 0x01, 540 PrivilegedExtension = 0x02, 541 PrefixedExtension = 0x04, 542 WebGLDebugRendererInfoExtension = 0x08, 543 }; 544 545 class ExtensionTracker { 546 public: 547 ExtensionTracker(ExtensionFlags flags, const char* const* prefixes) 548 : m_privileged(flags & PrivilegedExtension) 549 , m_draft(flags & DraftExtension) 550 , m_prefixed(flags & PrefixedExtension) 551 , m_webglDebugRendererInfo(flags & WebGLDebugRendererInfoExtension) 552 , m_prefixes(prefixes) 553 { 554 } 555 556 virtual ~ExtensionTracker() 557 { 558 } 559 560 bool prefixed() const 561 { 562 return m_prefixed; 563 } 564 565 bool privileged() const 566 { 567 return m_privileged; 568 } 569 570 bool draft() const 571 { 572 return m_draft; 573 } 574 575 bool webglDebugRendererInfo() const 576 { 577 return m_webglDebugRendererInfo; 578 } 579 580 bool matchesNameWithPrefixes(const String&) const; 581 582 virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext*) const = 0; 583 virtual bool supported(WebGLRenderingContext*) const = 0; 584 virtual const char* extensionName() const = 0; 585 virtual void loseExtension() = 0; 586 587 private: 588 bool m_privileged; 589 bool m_draft; 590 bool m_prefixed; 591 bool m_webglDebugRendererInfo; 592 const char* const* m_prefixes; 593 }; 594 595 template <typename T> 596 class TypedExtensionTracker : public ExtensionTracker { 597 public: 598 TypedExtensionTracker(RefPtr<T>& extensionField, ExtensionFlags flags, const char* const* prefixes) 599 : ExtensionTracker(flags, prefixes) 600 , m_extensionField(extensionField) 601 { 602 } 603 604 ~TypedExtensionTracker() 605 { 606 if (m_extensionField) { 607 m_extensionField->lose(true); 608 m_extensionField = 0; 609 } 610 } 611 612 virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext* context) const 613 { 614 if (!m_extensionField) 615 m_extensionField = T::create(context); 616 617 return m_extensionField; 618 } 619 620 virtual bool supported(WebGLRenderingContext* context) const 621 { 622 return T::supported(context); 623 } 624 625 virtual const char* extensionName() const 626 { 627 return T::extensionName(); 628 } 629 630 virtual void loseExtension() 631 { 632 if (m_extensionField) { 633 m_extensionField->lose(false); 634 if (m_extensionField->isLost()) 635 m_extensionField = 0; 636 } 637 } 638 639 private: 640 RefPtr<T>& m_extensionField; 641 }; 642 643 Vector<ExtensionTracker*> m_extensions; 644 645 template <typename T> 646 void registerExtension(RefPtr<T>& extensionPtr, ExtensionFlags flags = ApprovedExtension, const char* const* prefixes = 0) 647 { 648 m_extensions.append(new TypedExtensionTracker<T>(extensionPtr, flags, prefixes)); 649 } 650 651 // Errors raised by synthesizeGLError() while the context is lost. 652 Vector<GC3Denum> lost_context_errors_; 653 654 // Helpers for getParameter and others 655 WebGLGetInfo getBooleanParameter(GC3Denum); 656 WebGLGetInfo getBooleanArrayParameter(GC3Denum); 657 WebGLGetInfo getFloatParameter(GC3Denum); 658 WebGLGetInfo getIntParameter(GC3Denum); 659 WebGLGetInfo getUnsignedIntParameter(GC3Denum); 660 WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum); 661 WebGLGetInfo getWebGLIntArrayParameter(GC3Denum); 662 663 // Clear the backbuffer if it was composited since the last operation. 664 // clearMask is set to the bitfield of any clear that would happen anyway at this time 665 // and the function returns true if that clear is now unnecessary. 666 bool clearIfComposited(GC3Dbitfield clearMask = 0); 667 668 // Helper to restore state that clearing the framebuffer may destroy. 669 void restoreStateAfterClear(); 670 671 void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState&); 672 void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&); 673 void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState&); 674 void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&); 675 676 void handleTextureCompleteness(const char*, bool); 677 void createFallbackBlackTextures1x1(); 678 679 // Helper function for copyTex{Sub}Image, check whether the internalformat 680 // and the color buffer format of the current bound framebuffer combination 681 // is valid. 682 bool isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat, 683 GC3Denum colorBufferFormat); 684 685 // Helper function to get the bound framebuffer's color buffer format. 686 GC3Denum boundFramebufferColorFormat(); 687 688 // Helper function to get the bound framebuffer's width. 689 int boundFramebufferWidth(); 690 691 // Helper function to get the bound framebuffer's height. 692 int boundFramebufferHeight(); 693 694 // Helper function to verify limits on the length of uniform and attribute locations. 695 bool validateLocationLength(const char* functionName, const String&); 696 697 // Helper function to check if size is non-negative. 698 // Generate GL error and return false for negative inputs; otherwise, return true. 699 bool validateSize(const char* functionName, GC3Dint x, GC3Dint y); 700 701 // Helper function to check if all characters in the string belong to the 702 // ASCII subset as defined in GLSL ES 1.0 spec section 3.1. 703 bool validateString(const char* functionName, const String&); 704 705 // Helper function to check target and texture bound to the target. 706 // Generate GL errors and return 0 if target is invalid or texture bound is 707 // null. Otherwise, return the texture bound to the target. 708 WebGLTexture* validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap); 709 710 // Helper function to check input format/type for functions {copy}Tex{Sub}Image. 711 // Generates GL error and returns false if parameters are invalid. 712 bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level); 713 714 // Helper function to check input level for functions {copy}Tex{Sub}Image. 715 // Generates GL error and returns false if level is invalid. 716 bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level); 717 718 enum TexFuncValidationFunctionType { 719 NotTexSubImage2D, 720 TexSubImage2D, 721 }; 722 723 enum TexFuncValidationSourceType { 724 SourceArrayBufferView, 725 SourceImageData, 726 SourceHTMLImageElement, 727 SourceHTMLCanvasElement, 728 SourceHTMLVideoElement, 729 }; 730 731 // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid. 732 // Otherwise, it would return quickly without doing other work. 733 bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, 734 GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset); 735 736 // Helper function to check input width and height for functions {copy, compressed}Tex{Sub}Image. 737 // Generates GL error and returns false if width or height is invalid. 738 bool validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType, 739 GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height); 740 741 // Helper function to check input parameters for functions {copy}Tex{Sub}Image. 742 // Generates GL error and returns false if parameters are invalid. 743 bool validateTexFuncParameters(const char* functionName, 744 TexFuncValidationFunctionType, 745 GC3Denum target, GC3Dint level, 746 GC3Denum internalformat, 747 GC3Dsizei width, GC3Dsizei height, GC3Dint border, 748 GC3Denum format, GC3Denum type); 749 750 enum NullDisposition { 751 NullAllowed, 752 NullNotAllowed 753 }; 754 755 // Helper function to validate that the given ArrayBufferView 756 // is of the correct type and contains enough data for the texImage call. 757 // Generates GL error and returns false if parameters are invalid. 758 bool validateTexFuncData(const char* functionName, GC3Dint level, 759 GC3Dsizei width, GC3Dsizei height, 760 GC3Denum format, GC3Denum type, 761 ArrayBufferView* pixels, 762 NullDisposition); 763 764 // Helper function to validate a given texture format is settable as in 765 // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and 766 // copyTexSubImage2D. 767 // Generates GL error and returns false if the format is not settable. 768 bool validateSettableTexFormat(const char* functionName, GC3Denum format); 769 770 // Helper function to validate compressed texture data is correct size 771 // for the given format and dimensions. 772 bool validateCompressedTexFuncData(const char* functionName, 773 GC3Dsizei width, GC3Dsizei height, 774 GC3Denum format, ArrayBufferView* pixels); 775 776 // Helper function for validating compressed texture formats. 777 bool validateCompressedTexFormat(GC3Denum format); 778 779 // Helper function to validate compressed texture dimensions are valid for 780 // the given format. 781 bool validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format); 782 783 // Helper function to validate compressed texture dimensions are valid for 784 // the given format. 785 bool validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 786 GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*); 787 788 // Helper function to validate mode for draw{Arrays/Elements}. 789 bool validateDrawMode(const char* functionName, GC3Denum); 790 791 // Helper function to validate if front/back stencilMask and stencilFunc settings are the same. 792 bool validateStencilSettings(const char* functionName); 793 794 // Helper function to validate stencil or depth func. 795 bool validateStencilOrDepthFunc(const char* functionName, GC3Denum); 796 797 // Helper function for texParameterf and texParameteri. 798 void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat); 799 800 // Helper function to print GL errors to console. 801 void printGLErrorToConsole(const String&); 802 803 // Helper function to print warnings to console. Currently 804 // used only to warn about use of obsolete functions. 805 void printWarningToConsole(const String&); 806 807 // Helper function to validate input parameters for framebuffer functions. 808 // Generate GL error if parameters are illegal. 809 bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment); 810 811 // Helper function to validate blend equation mode. 812 bool validateBlendEquation(const char* functionName, GC3Denum); 813 814 // Helper function to validate blend func factors. 815 bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst); 816 817 // Helper function to validate a GL capability. 818 bool validateCapability(const char* functionName, GC3Denum); 819 820 // Helper function to validate input parameters for uniform functions. 821 bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod); 822 bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod); 823 bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod); 824 bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod); 825 bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod); 826 827 // Helper function to validate parameters for bufferData. 828 // Return the current bound buffer to target, or 0 if parameters are invalid. 829 WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage); 830 831 // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin. 832 bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionState&); 833 834 // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin. 835 bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionState&); 836 837 // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin. 838 bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionState&); 839 840 // Helper function to validate drawArrays(Instanced) calls 841 bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count); 842 843 // Helper function to validate drawElements(Instanced) calls 844 bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset); 845 846 // Helper function to validate draw*Instanced calls 847 bool validateDrawInstanced(const char* functionName, GC3Dsizei primcount); 848 849 // Helper functions for vertexAttribNf{v}. 850 void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat); 851 void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array*, GC3Dsizei expectedSize); 852 void vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat*, GC3Dsizei, GC3Dsizei expectedSize); 853 854 // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions. 855 // Return false if caller should return without further processing. 856 bool deleteObject(WebGLObject*); 857 858 // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram. 859 // If the object has already been deleted, set deleted to true upon return. 860 // Return false if caller should return without further processing. 861 bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted); 862 863 void dispatchContextLostEvent(Timer<WebGLRenderingContext>*); 864 // Helper for restoration after context lost. 865 void maybeRestoreContext(Timer<WebGLRenderingContext>*); 866 867 // Determine if we are running privileged code in the browser, for example, 868 // a Safari or Chrome extension. 869 bool allowPrivilegedExtensions() const; 870 871 // Determine if WEBGL_debug_renderer_info extension is enabled. For the 872 // moment it can be enabled either through a chromium finch experiment 873 // or for privileged code in the browser. 874 bool allowWebGLDebugRendererInfo() const; 875 876 enum ConsoleDisplayPreference { 877 DisplayInConsole, 878 DontDisplayInConsole 879 }; 880 881 // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message 882 // to the JavaScript console. 883 void synthesizeGLError(GC3Denum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole); 884 void emitGLWarning(const char* function, const char* reason); 885 886 String ensureNotNull(const String&) const; 887 888 // Enable or disable stencil test based on user setting and 889 // whether the current FBO has a stencil buffer. 890 void applyStencilTest(); 891 892 // Helper for enabling or disabling a capability. 893 void enableOrDisable(GC3Denum capability, bool enable); 894 895 // Clamp the width and height to GL_MAX_VIEWPORT_DIMS. 896 IntSize clampedCanvasSize(); 897 898 // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0. 899 // Later, return the cached value. 900 GC3Dint maxDrawBuffers(); 901 GC3Dint maxColorAttachments(); 902 903 void setBackDrawBuffer(GC3Denum); 904 905 void restoreCurrentFramebuffer(); 906 void restoreCurrentTexture2D(); 907 908 virtual void multisamplingChanged(bool); 909 910 void findNewMaxEnabledAttribIndex(); 911 void findNewMaxNonDefaultTextureUnit(); 912 913 friend class WebGLStateRestorer; 914 friend class WebGLRenderingContextEvictionManager; 915 916 static Vector<WebGLRenderingContext*>& activeContexts(); 917 static Vector<WebGLRenderingContext*>& forciblyEvictedContexts(); 918 919 static void activateContext(WebGLRenderingContext*); 920 static void deactivateContext(WebGLRenderingContext*, bool addToInactiveList); 921 static void willDestroyContext(WebGLRenderingContext*); 922 static void forciblyLoseOldestContext(const String& reason); 923 // Return the least recently used context's position in the active context vector. 924 // If the vector is empty, return the maximum allowed active context number. 925 static size_t oldestContextIndex(); 926 static IntSize oldestContextSize(); 927 }; 928 929 DEFINE_TYPE_CASTS(WebGLRenderingContext, CanvasRenderingContext, context, context->is3d(), context.is3d()); 930 931 } // namespace WebCore 932 933 #endif 934