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