Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1395 void WebGLRenderingContextBase::attachShader(ScriptState* scriptState, WebGLProg ram* program, WebGLShader* shader) | 1395 void WebGLRenderingContextBase::attachShader(ScriptState* scriptState, WebGLProg ram* program, WebGLShader* shader) |
| 1396 { | 1396 { |
| 1397 if (isContextLost() || !validateWebGLObject("attachShader", program) || !val idateWebGLObject("attachShader", shader)) | 1397 if (isContextLost() || !validateWebGLObject("attachShader", program) || !val idateWebGLObject("attachShader", shader)) |
| 1398 return; | 1398 return; |
| 1399 if (!program->attachShader(shader)) { | 1399 if (!program->attachShader(shader)) { |
| 1400 synthesizeGLError(GL_INVALID_OPERATION, "attachShader", "shader attachme nt already has shader"); | 1400 synthesizeGLError(GL_INVALID_OPERATION, "attachShader", "shader attachme nt already has shader"); |
| 1401 return; | 1401 return; |
| 1402 } | 1402 } |
| 1403 contextGL()->AttachShader(objectOrZero(program), objectOrZero(shader)); | 1403 contextGL()->AttachShader(objectOrZero(program), objectOrZero(shader)); |
| 1404 shader->onAttached(); | 1404 shader->onAttached(); |
| 1405 preserveObjectWrapper(scriptState, program, "shader", shader->type(), shader ); | 1405 preserveObjectWrapper(scriptState, program, V8HiddenValue::webglShaders(scri ptState->isolate()), program->getPersistentCache(), static_cast<uint32_t>(shader ->type()), shader); |
| 1406 } | 1406 } |
| 1407 | 1407 |
| 1408 void WebGLRenderingContextBase::bindAttribLocation(WebGLProgram* program, GLuint index, const String& name) | 1408 void WebGLRenderingContextBase::bindAttribLocation(WebGLProgram* program, GLuint index, const String& name) |
| 1409 { | 1409 { |
| 1410 if (isContextLost() || !validateWebGLObject("bindAttribLocation", program)) | 1410 if (isContextLost() || !validateWebGLObject("bindAttribLocation", program)) |
| 1411 return; | 1411 return; |
| 1412 if (!validateLocationLength("bindAttribLocation", name)) | 1412 if (!validateLocationLength("bindAttribLocation", name)) |
| 1413 return; | 1413 return; |
| 1414 if (isPrefixReserved(name)) { | 1414 if (isPrefixReserved(name)) { |
| 1415 synthesizeGLError(GL_INVALID_OPERATION, "bindAttribLocation", "reserved prefix"); | 1415 synthesizeGLError(GL_INVALID_OPERATION, "bindAttribLocation", "reserved prefix"); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1464 { | 1464 { |
| 1465 bool deleted; | 1465 bool deleted; |
| 1466 if (!checkObjectToBeBound("bindBuffer", buffer, deleted)) | 1466 if (!checkObjectToBeBound("bindBuffer", buffer, deleted)) |
| 1467 return; | 1467 return; |
| 1468 if (deleted) | 1468 if (deleted) |
| 1469 buffer = 0; | 1469 buffer = 0; |
| 1470 if (!validateAndUpdateBufferBindTarget("bindBuffer", target, buffer)) | 1470 if (!validateAndUpdateBufferBindTarget("bindBuffer", target, buffer)) |
| 1471 return; | 1471 return; |
| 1472 | 1472 |
| 1473 contextGL()->BindBuffer(target, objectOrZero(buffer)); | 1473 contextGL()->BindBuffer(target, objectOrZero(buffer)); |
| 1474 preserveObjectWrapper(scriptState, this, "buffer", target, buffer); | 1474 PreservedWrapperIndex idx; |
| 1475 switch (target) { | |
| 1476 case GL_ARRAY_BUFFER: | |
| 1477 idx = PreservedArrayBuffer; | |
| 1478 break; | |
| 1479 case GL_ELEMENT_ARRAY_BUFFER: | |
| 1480 idx = PreservedElementArrayBuffer; | |
| 1481 break; | |
| 1482 } | |
| 1483 | |
| 1484 preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(scriptStat e->isolate()), &m_miscWrappers, static_cast<uint32_t>(idx), buffer); | |
| 1475 maybePreserveDefaultVAOObjectWrapper(scriptState); | 1485 maybePreserveDefaultVAOObjectWrapper(scriptState); |
| 1476 } | 1486 } |
| 1477 | 1487 |
| 1478 void WebGLRenderingContextBase::bindFramebuffer(ScriptState* scriptState, GLenum target, WebGLFramebuffer* buffer) | 1488 void WebGLRenderingContextBase::bindFramebuffer(ScriptState* scriptState, GLenum target, WebGLFramebuffer* buffer) |
| 1479 { | 1489 { |
| 1480 bool deleted; | 1490 bool deleted; |
| 1481 if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted)) | 1491 if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted)) |
| 1482 return; | 1492 return; |
| 1483 | 1493 |
| 1484 if (deleted) | 1494 if (deleted) |
| 1485 buffer = 0; | 1495 buffer = 0; |
| 1486 | 1496 |
| 1487 if (target != GL_FRAMEBUFFER) { | 1497 if (target != GL_FRAMEBUFFER) { |
| 1488 synthesizeGLError(GL_INVALID_ENUM, "bindFramebuffer", "invalid target"); | 1498 synthesizeGLError(GL_INVALID_ENUM, "bindFramebuffer", "invalid target"); |
| 1489 return; | 1499 return; |
| 1490 } | 1500 } |
| 1491 | 1501 |
| 1492 setFramebuffer(target, buffer); | 1502 setFramebuffer(target, buffer); |
| 1493 // This is called both internally and externally (from JavaScript). We only update which wrapper | 1503 // This is called both internally and externally (from JavaScript). We only update which wrapper |
| 1494 // is preserved when it's called from JavaScript. | 1504 // is preserved when it's called from JavaScript. |
| 1495 if (scriptState) | 1505 if (scriptState) { |
| 1496 preserveObjectWrapper(scriptState, this, "framebuffer", 0, buffer); | 1506 preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(script State->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedFramebuffer), buffer); |
| 1507 } | |
| 1497 } | 1508 } |
| 1498 | 1509 |
| 1499 void WebGLRenderingContextBase::bindRenderbuffer(ScriptState* scriptState, GLenu m target, WebGLRenderbuffer* renderBuffer) | 1510 void WebGLRenderingContextBase::bindRenderbuffer(ScriptState* scriptState, GLenu m target, WebGLRenderbuffer* renderBuffer) |
| 1500 { | 1511 { |
| 1501 bool deleted; | 1512 bool deleted; |
| 1502 if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted)) | 1513 if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted)) |
| 1503 return; | 1514 return; |
| 1504 if (deleted) | 1515 if (deleted) |
| 1505 renderBuffer = 0; | 1516 renderBuffer = 0; |
| 1506 if (target != GL_RENDERBUFFER) { | 1517 if (target != GL_RENDERBUFFER) { |
| 1507 synthesizeGLError(GL_INVALID_ENUM, "bindRenderbuffer", "invalid target") ; | 1518 synthesizeGLError(GL_INVALID_ENUM, "bindRenderbuffer", "invalid target") ; |
| 1508 return; | 1519 return; |
| 1509 } | 1520 } |
| 1510 m_renderbufferBinding = renderBuffer; | 1521 m_renderbufferBinding = renderBuffer; |
| 1511 contextGL()->BindRenderbuffer(target, objectOrZero(renderBuffer)); | 1522 contextGL()->BindRenderbuffer(target, objectOrZero(renderBuffer)); |
| 1512 preserveObjectWrapper(scriptState, this, "renderbuffer", 0, renderBuffer); | 1523 preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(scriptStat e->isolate()), &m_miscWrappers, PreservedRenderbuffer, renderBuffer); |
| 1513 | 1524 |
| 1514 drawingBuffer()->setRenderbufferBinding(objectOrZero(renderBuffer)); | 1525 drawingBuffer()->setRenderbufferBinding(objectOrZero(renderBuffer)); |
| 1515 | 1526 |
| 1516 if (renderBuffer) | 1527 if (renderBuffer) |
| 1517 renderBuffer->setHasEverBeenBound(); | 1528 renderBuffer->setHasEverBeenBound(); |
| 1518 } | 1529 } |
| 1519 | 1530 |
| 1520 void WebGLRenderingContextBase::bindTexture(ScriptState* scriptState, GLenum tar get, WebGLTexture* texture) | 1531 void WebGLRenderingContextBase::bindTexture(ScriptState* scriptState, GLenum tar get, WebGLTexture* texture) |
| 1521 { | 1532 { |
| 1522 bool deleted; | 1533 bool deleted; |
| 1523 if (!checkObjectToBeBound("bindTexture", texture, deleted)) | 1534 if (!checkObjectToBeBound("bindTexture", texture, deleted)) |
| 1524 return; | 1535 return; |
| 1525 if (deleted) | 1536 if (deleted) |
| 1526 texture = 0; | 1537 texture = 0; |
| 1527 if (texture && texture->getTarget() && texture->getTarget() != target) { | 1538 if (texture && texture->getTarget() && texture->getTarget() != target) { |
| 1528 synthesizeGLError(GL_INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets"); | 1539 synthesizeGLError(GL_INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets"); |
| 1529 return; | 1540 return; |
| 1530 } | 1541 } |
| 1531 | 1542 |
| 1532 const char* bindingPointName = nullptr; | 1543 // ScriptState may be null if this method is called internally |
| 1544 // during restoration of texture unit bindings. Skip the | |
| 1545 // preserveObjectWrapper work in this case. | |
| 1546 v8::Local<v8::String> hiddenValueName; | |
| 1547 v8::Persistent<v8::Array>* persistentCache; | |
| 1533 if (target == GL_TEXTURE_2D) { | 1548 if (target == GL_TEXTURE_2D) { |
| 1534 m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture; | 1549 m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture; |
| 1535 | 1550 |
| 1536 if (!m_activeTextureUnit) | 1551 if (!m_activeTextureUnit) |
| 1537 drawingBuffer()->setTexture2DBinding(objectOrZero(texture)); | 1552 drawingBuffer()->setTexture2DBinding(objectOrZero(texture)); |
| 1538 bindingPointName = "texture_2d"; | 1553 if (scriptState) { |
| 1554 hiddenValueName = V8HiddenValue::webgl2DTextures(scriptState->isolat e()); | |
| 1555 persistentCache = &m_2DTextureWrappers; | |
| 1556 } | |
| 1539 } else if (target == GL_TEXTURE_CUBE_MAP) { | 1557 } else if (target == GL_TEXTURE_CUBE_MAP) { |
| 1540 m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture; | 1558 m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture; |
| 1541 bindingPointName = "texture_cube_map"; | 1559 if (scriptState) { |
| 1560 hiddenValueName = V8HiddenValue::webglCubeMapTextures(scriptState->i solate()); | |
| 1561 persistentCache = &m_cubeMapTextureWrappers; | |
| 1562 } | |
| 1542 } else if (isWebGL2OrHigher() && target == GL_TEXTURE_2D_ARRAY) { | 1563 } else if (isWebGL2OrHigher() && target == GL_TEXTURE_2D_ARRAY) { |
| 1543 m_textureUnits[m_activeTextureUnit].m_texture2DArrayBinding = texture; | 1564 m_textureUnits[m_activeTextureUnit].m_texture2DArrayBinding = texture; |
| 1544 bindingPointName = "texture_2d_array"; | 1565 if (scriptState) { |
| 1566 hiddenValueName = V8HiddenValue::webgl2DArrayTextures(scriptState->i solate()); | |
| 1567 persistentCache = &m_2DArrayTextureWrappers; | |
| 1568 } | |
| 1545 } else if (isWebGL2OrHigher() && target == GL_TEXTURE_3D) { | 1569 } else if (isWebGL2OrHigher() && target == GL_TEXTURE_3D) { |
| 1546 m_textureUnits[m_activeTextureUnit].m_texture3DBinding = texture; | 1570 m_textureUnits[m_activeTextureUnit].m_texture3DBinding = texture; |
| 1547 bindingPointName = "texture_3d"; | 1571 if (scriptState) { |
| 1572 hiddenValueName = V8HiddenValue::webgl3DTextures(scriptState->isolat e()); | |
| 1573 persistentCache = &m_3DTextureWrappers; | |
| 1574 } | |
| 1548 } else { | 1575 } else { |
| 1549 synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target"); | 1576 synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target"); |
| 1550 return; | 1577 return; |
| 1551 } | 1578 } |
| 1552 | 1579 |
| 1553 contextGL()->BindTexture(target, objectOrZero(texture)); | 1580 contextGL()->BindTexture(target, objectOrZero(texture)); |
| 1554 // This is called both internally and externally (from JavaScript). We only update which wrapper | 1581 // This is called both internally and externally (from JavaScript). We only update which wrapper |
| 1555 // is preserved when it's called from JavaScript. | 1582 // is preserved when it's called from JavaScript. |
| 1556 if (scriptState) { | 1583 if (scriptState) { |
| 1557 preserveObjectWrapper(scriptState, this, bindingPointName, m_activeTextu reUnit, texture); | 1584 preserveObjectWrapper(scriptState, this, hiddenValueName, persistentCach e, m_activeTextureUnit, texture); |
| 1558 } | 1585 } |
| 1559 if (texture) { | 1586 if (texture) { |
| 1560 texture->setTarget(target); | 1587 texture->setTarget(target); |
| 1561 m_onePlusMaxNonDefaultTextureUnit = max(m_activeTextureUnit + 1, m_onePl usMaxNonDefaultTextureUnit); | 1588 m_onePlusMaxNonDefaultTextureUnit = max(m_activeTextureUnit + 1, m_onePl usMaxNonDefaultTextureUnit); |
| 1562 } else { | 1589 } else { |
| 1563 // If the disabled index is the current maximum, trace backwards to find the new max enabled texture index | 1590 // If the disabled index is the current maximum, trace backwards to find the new max enabled texture index |
| 1564 if (m_onePlusMaxNonDefaultTextureUnit == m_activeTextureUnit + 1) { | 1591 if (m_onePlusMaxNonDefaultTextureUnit == m_activeTextureUnit + 1) { |
| 1565 findNewMaxNonDefaultTextureUnit(); | 1592 findNewMaxNonDefaultTextureUnit(); |
| 1566 } | 1593 } |
| 1567 } | 1594 } |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1950 return o; | 1977 return o; |
| 1951 } | 1978 } |
| 1952 | 1979 |
| 1953 void WebGLRenderingContextBase::setBoundVertexArrayObject(ScriptState* scriptSta te, WebGLVertexArrayObjectBase* arrayObject) | 1980 void WebGLRenderingContextBase::setBoundVertexArrayObject(ScriptState* scriptSta te, WebGLVertexArrayObjectBase* arrayObject) |
| 1954 { | 1981 { |
| 1955 if (arrayObject) | 1982 if (arrayObject) |
| 1956 m_boundVertexArrayObject = arrayObject; | 1983 m_boundVertexArrayObject = arrayObject; |
| 1957 else | 1984 else |
| 1958 m_boundVertexArrayObject = m_defaultVertexArrayObject; | 1985 m_boundVertexArrayObject = m_defaultVertexArrayObject; |
| 1959 | 1986 |
| 1960 preserveObjectWrapper(scriptState, this, "boundvao", 0, arrayObject); | 1987 preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(scriptStat e->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedVAO), arrayObject ); |
| 1961 } | 1988 } |
| 1962 | 1989 |
| 1963 WebGLShader* WebGLRenderingContextBase::createShader(GLenum type) | 1990 WebGLShader* WebGLRenderingContextBase::createShader(GLenum type) |
| 1964 { | 1991 { |
| 1965 if (isContextLost()) | 1992 if (isContextLost()) |
| 1966 return nullptr; | 1993 return nullptr; |
| 1967 if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) { | 1994 if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) { |
| 1968 synthesizeGLError(GL_INVALID_ENUM, "createShader", "invalid shader type" ); | 1995 synthesizeGLError(GL_INVALID_ENUM, "createShader", "invalid shader type" ); |
| 1969 return nullptr; | 1996 return nullptr; |
| 1970 } | 1997 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2111 void WebGLRenderingContextBase::detachShader(ScriptState* scriptState, WebGLProg ram* program, WebGLShader* shader) | 2138 void WebGLRenderingContextBase::detachShader(ScriptState* scriptState, WebGLProg ram* program, WebGLShader* shader) |
| 2112 { | 2139 { |
| 2113 if (isContextLost() || !validateWebGLObject("detachShader", program) || !val idateWebGLObject("detachShader", shader)) | 2140 if (isContextLost() || !validateWebGLObject("detachShader", program) || !val idateWebGLObject("detachShader", shader)) |
| 2114 return; | 2141 return; |
| 2115 if (!program->detachShader(shader)) { | 2142 if (!program->detachShader(shader)) { |
| 2116 synthesizeGLError(GL_INVALID_OPERATION, "detachShader", "shader not atta ched"); | 2143 synthesizeGLError(GL_INVALID_OPERATION, "detachShader", "shader not atta ched"); |
| 2117 return; | 2144 return; |
| 2118 } | 2145 } |
| 2119 contextGL()->DetachShader(objectOrZero(program), objectOrZero(shader)); | 2146 contextGL()->DetachShader(objectOrZero(program), objectOrZero(shader)); |
| 2120 shader->onDetached(contextGL()); | 2147 shader->onDetached(contextGL()); |
| 2121 preserveObjectWrapper(scriptState, program, "shader", shader->type(), nullpt r); | 2148 preserveObjectWrapper(scriptState, program, V8HiddenValue::webglShaders(scri ptState->isolate()), program->getPersistentCache(), static_cast<uint32_t>(shader ->type()), nullptr); |
| 2122 } | 2149 } |
| 2123 | 2150 |
| 2124 void WebGLRenderingContextBase::disable(GLenum cap) | 2151 void WebGLRenderingContextBase::disable(GLenum cap) |
| 2125 { | 2152 { |
| 2126 if (isContextLost() || !validateCapability("disable", cap)) | 2153 if (isContextLost() || !validateCapability("disable", cap)) |
| 2127 return; | 2154 return; |
| 2128 if (cap == GL_STENCIL_TEST) { | 2155 if (cap == GL_STENCIL_TEST) { |
| 2129 m_stencilEnabled = false; | 2156 m_stencilEnabled = false; |
| 2130 applyStencilTest(); | 2157 applyStencilTest(); |
| 2131 return; | 2158 return; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2285 return; | 2312 return; |
| 2286 } | 2313 } |
| 2287 GLuint bufferObject = objectOrZero(buffer); | 2314 GLuint bufferObject = objectOrZero(buffer); |
| 2288 if (isWebGL2OrHigher() && attachment == GL_DEPTH_STENCIL_ATTACHMENT) { | 2315 if (isWebGL2OrHigher() && attachment == GL_DEPTH_STENCIL_ATTACHMENT) { |
| 2289 // On ES3, DEPTH_STENCIL_ATTACHMENT is like an alias for DEPTH_ATTACHMEN T + STENCIL_ATTACHMENT. | 2316 // On ES3, DEPTH_STENCIL_ATTACHMENT is like an alias for DEPTH_ATTACHMEN T + STENCIL_ATTACHMENT. |
| 2290 // We divide it here so in WebGLFramebuffer, we don't have to handle DEP TH_STENCIL_ATTACHMENT in WebGL 2. | 2317 // We divide it here so in WebGLFramebuffer, we don't have to handle DEP TH_STENCIL_ATTACHMENT in WebGL 2. |
| 2291 contextGL()->FramebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, render buffertarget, bufferObject); | 2318 contextGL()->FramebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, render buffertarget, bufferObject); |
| 2292 contextGL()->FramebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, rend erbuffertarget, bufferObject); | 2319 contextGL()->FramebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, rend erbuffertarget, bufferObject); |
| 2293 framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_DEPTH_AT TACHMENT, buffer); | 2320 framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_DEPTH_AT TACHMENT, buffer); |
| 2294 framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_STENCIL_ ATTACHMENT, buffer); | 2321 framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_STENCIL_ ATTACHMENT, buffer); |
| 2295 preserveObjectWrapper(scriptState, framebufferBinding, "attachment", GL_ DEPTH_ATTACHMENT, buffer); | 2322 preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::we bglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache() , GL_DEPTH_ATTACHMENT, buffer); |
| 2296 preserveObjectWrapper(scriptState, framebufferBinding, "attachment", GL_ STENCIL_ATTACHMENT, buffer); | 2323 preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::we bglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache() , GL_STENCIL_ATTACHMENT, buffer); |
| 2297 } else { | 2324 } else { |
| 2298 contextGL()->FramebufferRenderbuffer(target, attachment, renderbuffertar get, bufferObject); | 2325 contextGL()->FramebufferRenderbuffer(target, attachment, renderbuffertar get, bufferObject); |
| 2299 framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, buffer); | 2326 framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, buffer); |
| 2300 preserveObjectWrapper(scriptState, framebufferBinding, "attachment", att achment, buffer); | 2327 preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::we bglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache() , attachment, buffer); |
| 2301 } | 2328 } |
| 2302 applyStencilTest(); | 2329 applyStencilTest(); |
| 2303 } | 2330 } |
| 2304 | 2331 |
| 2305 void WebGLRenderingContextBase::framebufferTexture2D(ScriptState* scriptState, G Lenum target, GLenum attachment, GLenum textarget, WebGLTexture* texture, GLint level) | 2332 void WebGLRenderingContextBase::framebufferTexture2D(ScriptState* scriptState, G Lenum target, GLenum attachment, GLenum textarget, WebGLTexture* texture, GLint level) |
| 2306 { | 2333 { |
| 2307 if (isContextLost() || !validateFramebufferFuncParameters("framebufferTextur e2D", target, attachment)) | 2334 if (isContextLost() || !validateFramebufferFuncParameters("framebufferTextur e2D", target, attachment)) |
| 2308 return; | 2335 return; |
| 2309 if (texture && !texture->validate(contextGroup(), this)) { | 2336 if (texture && !texture->validate(contextGroup(), this)) { |
| 2310 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no text ure or texture not from this context"); | 2337 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no text ure or texture not from this context"); |
| 2311 return; | 2338 return; |
| 2312 } | 2339 } |
| 2313 // Don't allow the default framebuffer to be mutated; all current | 2340 // Don't allow the default framebuffer to be mutated; all current |
| 2314 // implementations use an FBO internally in place of the default | 2341 // implementations use an FBO internally in place of the default |
| 2315 // FBO. | 2342 // FBO. |
| 2316 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target); | 2343 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target); |
| 2317 if (!framebufferBinding || !framebufferBinding->object()) { | 2344 if (!framebufferBinding || !framebufferBinding->object()) { |
| 2318 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no fram ebuffer bound"); | 2345 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no fram ebuffer bound"); |
| 2319 return; | 2346 return; |
| 2320 } | 2347 } |
| 2321 GLuint textureObject = objectOrZero(texture); | 2348 GLuint textureObject = objectOrZero(texture); |
| 2322 if (isWebGL2OrHigher() && attachment == GL_DEPTH_STENCIL_ATTACHMENT) { | 2349 if (isWebGL2OrHigher() && attachment == GL_DEPTH_STENCIL_ATTACHMENT) { |
| 2323 // On ES3, DEPTH_STENCIL_ATTACHMENT is like an alias for DEPTH_ATTACHMEN T + STENCIL_ATTACHMENT. | 2350 // On ES3, DEPTH_STENCIL_ATTACHMENT is like an alias for DEPTH_ATTACHMEN T + STENCIL_ATTACHMENT. |
| 2324 // We divide it here so in WebGLFramebuffer, we don't have to handle DEP TH_STENCIL_ATTACHMENT in WebGL 2. | 2351 // We divide it here so in WebGLFramebuffer, we don't have to handle DEP TH_STENCIL_ATTACHMENT in WebGL 2. |
| 2325 contextGL()->FramebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarget , textureObject, level); | 2352 contextGL()->FramebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarget , textureObject, level); |
| 2326 contextGL()->FramebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarg et, textureObject, level); | 2353 contextGL()->FramebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarg et, textureObject, level); |
| 2327 framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_DEPTH_AT TACHMENT, textarget, texture, level, 0); | 2354 framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_DEPTH_AT TACHMENT, textarget, texture, level, 0); |
| 2328 framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_STENCIL_ ATTACHMENT, textarget, texture, level, 0); | 2355 framebufferBinding->setAttachmentForBoundFramebuffer(target, GL_STENCIL_ ATTACHMENT, textarget, texture, level, 0); |
| 2329 preserveObjectWrapper(scriptState, framebufferBinding, "attachment", GL_ DEPTH_ATTACHMENT, texture); | 2356 preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::we bglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache() , GL_DEPTH_ATTACHMENT, texture); |
| 2330 preserveObjectWrapper(scriptState, framebufferBinding, "attachment", GL_ STENCIL_ATTACHMENT, texture); | 2357 preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::we bglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache() , GL_STENCIL_ATTACHMENT, texture); |
| 2331 } else { | 2358 } else { |
| 2332 contextGL()->FramebufferTexture2D(target, attachment, textarget, texture Object, level); | 2359 contextGL()->FramebufferTexture2D(target, attachment, textarget, texture Object, level); |
| 2333 framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, textarget, texture, level, 0); | 2360 framebufferBinding->setAttachmentForBoundFramebuffer(target, attachment, textarget, texture, level, 0); |
| 2334 preserveObjectWrapper(scriptState, framebufferBinding, "attachment", att achment, texture); | 2361 preserveObjectWrapper(scriptState, framebufferBinding, V8HiddenValue::we bglAttachments(scriptState->isolate()), framebufferBinding->getPersistentCache() , attachment, texture); |
| 2335 } | 2362 } |
| 2336 applyStencilTest(); | 2363 applyStencilTest(); |
| 2337 } | 2364 } |
| 2338 | 2365 |
| 2339 void WebGLRenderingContextBase::frontFace(GLenum mode) | 2366 void WebGLRenderingContextBase::frontFace(GLenum mode) |
| 2340 { | 2367 { |
| 2341 if (isContextLost()) | 2368 if (isContextLost()) |
| 2342 return; | 2369 return; |
| 2343 contextGL()->FrontFace(mode); | 2370 contextGL()->FrontFace(mode); |
| 2344 } | 2371 } |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2555 break; | 2582 break; |
| 2556 } | 2583 } |
| 2557 } | 2584 } |
| 2558 } | 2585 } |
| 2559 | 2586 |
| 2560 v8::Local<v8::Value> wrappedExtension = toV8(extension, scriptState->context ()->Global(), scriptState->isolate()); | 2587 v8::Local<v8::Value> wrappedExtension = toV8(extension, scriptState->context ()->Global(), scriptState->isolate()); |
| 2561 | 2588 |
| 2562 if (linkContextToExtension) { | 2589 if (linkContextToExtension) { |
| 2563 // Keep the extension's JavaScript wrapper alive as long as the context is alive, so that | 2590 // Keep the extension's JavaScript wrapper alive as long as the context is alive, so that |
| 2564 // expando properties that are added to the extension persist. | 2591 // expando properties that are added to the extension persist. |
| 2565 preserveObjectWrapper(scriptState, this, "extension", static_cast<unsign ed long>(extension->name()), extension); | 2592 preserveObjectWrapper(scriptState, this, V8HiddenValue::webglExtensions( scriptState->isolate()), &m_extensionWrappers, static_cast<uint32_t>(extension-> name()), extension); |
| 2566 } | 2593 } |
| 2567 | 2594 |
| 2568 return ScriptValue(scriptState, wrappedExtension); | 2595 return ScriptValue(scriptState, wrappedExtension); |
| 2569 } | 2596 } |
| 2570 | 2597 |
| 2571 ScriptValue WebGLRenderingContextBase::getFramebufferAttachmentParameter(ScriptS tate* scriptState, GLenum target, GLenum attachment, GLenum pname) | 2598 ScriptValue WebGLRenderingContextBase::getFramebufferAttachmentParameter(ScriptS tate* scriptState, GLenum target, GLenum attachment, GLenum pname) |
| 2572 { | 2599 { |
| 2573 if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAtt achmentParameter", target, attachment)) | 2600 if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAtt achmentParameter", target, attachment)) |
| 2574 return ScriptValue::createNull(scriptState); | 2601 return ScriptValue::createNull(scriptState); |
| 2575 | 2602 |
| (...skipping 2274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4850 return; | 4877 return; |
| 4851 } | 4878 } |
| 4852 | 4879 |
| 4853 if (m_currentProgram != program) { | 4880 if (m_currentProgram != program) { |
| 4854 if (m_currentProgram) | 4881 if (m_currentProgram) |
| 4855 m_currentProgram->onDetached(contextGL()); | 4882 m_currentProgram->onDetached(contextGL()); |
| 4856 m_currentProgram = program; | 4883 m_currentProgram = program; |
| 4857 contextGL()->UseProgram(objectOrZero(program)); | 4884 contextGL()->UseProgram(objectOrZero(program)); |
| 4858 if (program) | 4885 if (program) |
| 4859 program->onAttached(); | 4886 program->onAttached(); |
| 4860 preserveObjectWrapper(scriptState, this, "program", 0, program); | 4887 preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(script State->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedProgram), pro gram); |
| 4861 } | 4888 } |
| 4862 } | 4889 } |
| 4863 | 4890 |
| 4864 void WebGLRenderingContextBase::validateProgram(WebGLProgram* program) | 4891 void WebGLRenderingContextBase::validateProgram(WebGLProgram* program) |
| 4865 { | 4892 { |
| 4866 if (isContextLost() || !validateWebGLObject("validateProgram", program)) | 4893 if (isContextLost() || !validateWebGLObject("validateProgram", program)) |
| 4867 return; | 4894 return; |
| 4868 contextGL()->ValidateProgram(objectOrZero(program)); | 4895 contextGL()->ValidateProgram(objectOrZero(program)); |
| 4869 } | 4896 } |
| 4870 | 4897 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5013 if (!validateValueFitNonNegInt32("vertexAttribPointer", "offset", offset)) | 5040 if (!validateValueFitNonNegInt32("vertexAttribPointer", "offset", offset)) |
| 5014 return; | 5041 return; |
| 5015 if (!m_boundArrayBuffer) { | 5042 if (!m_boundArrayBuffer) { |
| 5016 synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER"); | 5043 synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER"); |
| 5017 return; | 5044 return; |
| 5018 } | 5045 } |
| 5019 | 5046 |
| 5020 m_boundVertexArrayObject->setArrayBufferForAttrib(index, m_boundArrayBuffer. get()); | 5047 m_boundVertexArrayObject->setArrayBufferForAttrib(index, m_boundArrayBuffer. get()); |
| 5021 contextGL()->VertexAttribPointer(index, size, type, normalized, stride, rein terpret_cast<void*>(static_cast<intptr_t>(offset))); | 5048 contextGL()->VertexAttribPointer(index, size, type, normalized, stride, rein terpret_cast<void*>(static_cast<intptr_t>(offset))); |
| 5022 maybePreserveDefaultVAOObjectWrapper(scriptState); | 5049 maybePreserveDefaultVAOObjectWrapper(scriptState); |
| 5023 preserveObjectWrapper(scriptState, m_boundVertexArrayObject, "arraybuffer", index, m_boundArrayBuffer); | 5050 preserveObjectWrapper(scriptState, m_boundVertexArrayObject, V8HiddenValue:: webglBuffers(scriptState->isolate()), m_boundVertexArrayObject->getPersistentCac he(), index, m_boundArrayBuffer); |
| 5024 } | 5051 } |
| 5025 | 5052 |
| 5026 void WebGLRenderingContextBase::vertexAttribDivisorANGLE(GLuint index, GLuint di visor) | 5053 void WebGLRenderingContextBase::vertexAttribDivisorANGLE(GLuint index, GLuint di visor) |
| 5027 { | 5054 { |
| 5028 if (isContextLost()) | 5055 if (isContextLost()) |
| 5029 return; | 5056 return; |
| 5030 | 5057 |
| 5031 if (index >= m_maxVertexAttribs) { | 5058 if (index >= m_maxVertexAttribs) { |
| 5032 synthesizeGLError(GL_INVALID_VALUE, "vertexAttribDivisorANGLE", "index o ut of range"); | 5059 synthesizeGLError(GL_INVALID_VALUE, "vertexAttribDivisorANGLE", "index o ut of range"); |
| 5033 return; | 5060 return; |
| (...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6249 for (int i = startIndex; i >= 0; --i) { | 6276 for (int i = startIndex; i >= 0; --i) { |
| 6250 if (m_textureUnits[i].m_texture2DBinding | 6277 if (m_textureUnits[i].m_texture2DBinding |
| 6251 || m_textureUnits[i].m_textureCubeMapBinding) { | 6278 || m_textureUnits[i].m_textureCubeMapBinding) { |
| 6252 m_onePlusMaxNonDefaultTextureUnit = i + 1; | 6279 m_onePlusMaxNonDefaultTextureUnit = i + 1; |
| 6253 return; | 6280 return; |
| 6254 } | 6281 } |
| 6255 } | 6282 } |
| 6256 m_onePlusMaxNonDefaultTextureUnit = 0; | 6283 m_onePlusMaxNonDefaultTextureUnit = 0; |
| 6257 } | 6284 } |
| 6258 | 6285 |
| 6259 void WebGLRenderingContextBase::preserveObjectWrapper(ScriptState* scriptState, ScriptWrappable* sourceObject, const char* baseName, unsigned long index, Script Wrappable* targetObject) | 6286 // We don't need a callback when the weak persistent caches are cleared. |
| 6287 static void NoopWeakCallback(const v8::WeakCallbackInfo<int>& data) | |
|
haraken
2016/05/13 02:12:20
You can use a phantom handle instead (see https://
Ken Russell (switch to Gerrit)
2016/05/13 02:24:30
Thanks for the suggestion; didn't know how to do t
| |
| 6260 { | 6288 { |
| 6261 ASSERT(scriptState); | 6289 } |
| 6290 static int constZero = 0; | |
| 6262 | 6291 |
| 6263 v8::Local<v8::Value> value; | 6292 |
| 6293 void WebGLRenderingContextBase::preserveObjectWrapper(ScriptState* scriptState, ScriptWrappable* sourceObject, v8::Local<v8::String> hiddenValueName, v8::Persis tent<v8::Array>* persistentCache, uint32_t index, ScriptWrappable* targetObject) | |
| 6294 { | |
| 6264 v8::Isolate* isolate = scriptState->isolate(); | 6295 v8::Isolate* isolate = scriptState->isolate(); |
| 6265 | 6296 if (persistentCache->IsEmpty()) { |
| 6266 // TODO (kbr): move this logic to V8HiddenValue. The difficulty in doing so is that the index | 6297 persistentCache->Reset(isolate, v8::Array::New(isolate)); |
| 6267 // may vary, so it'd be necessary to lazily instantiate the V8 internalized strings, and have | |
| 6268 // efficient lookup for already-created ones. | |
| 6269 StringBuilder builder; | |
| 6270 builder.append(baseName); | |
| 6271 builder.appendNumber(static_cast<unsigned>(index)); | |
| 6272 CString name = builder.toString().utf8(); | |
| 6273 v8::Local<v8::String> jsName = v8::String::NewFromUtf8( | |
| 6274 isolate, | |
| 6275 name.data(), | |
| 6276 v8::NewStringType::kNormal, | |
| 6277 name.length()).ToLocalChecked(); | |
| 6278 if (targetObject) { | |
| 6279 V8HiddenValue::setHiddenValue( | 6298 V8HiddenValue::setHiddenValue( |
| 6280 scriptState, | 6299 scriptState, |
| 6281 sourceObject->newLocalWrapper(isolate), | 6300 sourceObject->newLocalWrapper(isolate), |
| 6282 jsName, | 6301 hiddenValueName, |
| 6283 targetObject->newLocalWrapper(isolate)); | 6302 persistentCache->Get(isolate)); |
|
haraken
2016/05/13 02:12:20
So you're adding a strong reference from the JS wr
Ken Russell (switch to Gerrit)
2016/05/13 02:24:30
Correct.
haraken
2016/05/13 04:27:39
How slow was it?
It's nasty that you have to manu
| |
| 6303 // It seems important to mark the persistent cache as weak. | |
| 6304 // Otherwise there will be a reference cycle between it and | |
| 6305 // its JavaScript wrapper, and currently there are problems | |
| 6306 // collecting such cycles. | |
| 6307 persistentCache->SetWeak(&constZero, NoopWeakCallback, v8::WeakCallbackT ype::kParameter); | |
| 6308 } | |
| 6309 | |
| 6310 if (targetObject) { | |
| 6311 v8::Maybe<bool> result = persistentCache->Get(isolate)->Set( | |
|
haraken
2016/05/13 01:32:41
Avoid using Maybe APIs -- you can use macros in V8
Ken Russell (switch to Gerrit)
2016/05/13 01:45:35
Thanks, will revise.
Ken Russell (switch to Gerrit)
2016/05/13 02:10:14
Done.
| |
| 6312 scriptState->context(), index, targetObject->newLocalWrapper(isolate )); | |
| 6313 ASSERT_UNUSED(result, result.FromMaybe(true)); | |
| 6284 } else { | 6314 } else { |
| 6285 V8HiddenValue::deleteHiddenValue( | 6315 v8::Maybe<bool> result = persistentCache->Get(isolate)->Set( |
| 6286 scriptState, | 6316 scriptState->context(), index, v8::Null(isolate)); |
| 6287 sourceObject->newLocalWrapper(isolate), | 6317 ASSERT_UNUSED(result, result.FromMaybe(true)); |
| 6288 jsName); | |
| 6289 } | 6318 } |
| 6290 } | 6319 } |
| 6291 | 6320 |
| 6321 | |
| 6292 void WebGLRenderingContextBase::maybePreserveDefaultVAOObjectWrapper(ScriptState * scriptState) | 6322 void WebGLRenderingContextBase::maybePreserveDefaultVAOObjectWrapper(ScriptState * scriptState) |
| 6293 { | 6323 { |
| 6294 ASSERT(scriptState); | 6324 ASSERT(scriptState); |
| 6295 | 6325 |
| 6296 if (!m_preservedDefaultVAOObjectWrapper) { | 6326 if (!m_preservedDefaultVAOObjectWrapper) { |
| 6297 // The default VAO does not have a JavaScript wrapper created for it, bu t one is needed to | 6327 // The default VAO does not have a JavaScript wrapper created for it, bu t one is needed to |
| 6298 // link up the WebGLBuffers associated with the vertex attributes. | 6328 // link up the WebGLBuffers associated with the vertex attributes. |
| 6299 toV8(m_defaultVertexArrayObject, scriptState->context()->Global(), scrip tState->isolate()); | 6329 toV8(m_defaultVertexArrayObject, scriptState->context()->Global(), scrip tState->isolate()); |
| 6300 preserveObjectWrapper(scriptState, this, "defaultvao", 0, m_defaultVerte xArrayObject); | 6330 preserveObjectWrapper(scriptState, this, V8HiddenValue::webglMisc(script State->isolate()), &m_miscWrappers, static_cast<uint32_t>(PreservedDefaultVAO), m_defaultVertexArrayObject); |
| 6301 m_preservedDefaultVAOObjectWrapper = true; | 6331 m_preservedDefaultVAOObjectWrapper = true; |
| 6302 } | 6332 } |
| 6303 } | 6333 } |
| 6304 | 6334 |
| 6305 DEFINE_TRACE(WebGLRenderingContextBase::TextureUnitState) | 6335 DEFINE_TRACE(WebGLRenderingContextBase::TextureUnitState) |
| 6306 { | 6336 { |
| 6307 visitor->trace(m_texture2DBinding); | 6337 visitor->trace(m_texture2DBinding); |
| 6308 visitor->trace(m_textureCubeMapBinding); | 6338 visitor->trace(m_textureCubeMapBinding); |
| 6309 visitor->trace(m_texture3DBinding); | 6339 visitor->trace(m_texture3DBinding); |
| 6310 visitor->trace(m_texture2DArrayBinding); | 6340 visitor->trace(m_texture2DArrayBinding); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6361 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); | 6391 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| 6362 } | 6392 } |
| 6363 | 6393 |
| 6364 void WebGLRenderingContextBase::restoreUnpackParameters() | 6394 void WebGLRenderingContextBase::restoreUnpackParameters() |
| 6365 { | 6395 { |
| 6366 if (m_unpackAlignment != 1) | 6396 if (m_unpackAlignment != 1) |
| 6367 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); | 6397 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); |
| 6368 } | 6398 } |
| 6369 | 6399 |
| 6370 } // namespace blink | 6400 } // namespace blink |
| OLD | NEW |