| 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 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 Document& document = canvas->document(); | 642 Document& document = canvas->document(); |
| 643 LocalFrame* frame = document.frame(); | 643 LocalFrame* frame = document.frame(); |
| 644 if (!frame) { | 644 if (!frame) { |
| 645 canvas->dispatchEvent(WebGLContextEvent::create( | 645 canvas->dispatchEvent(WebGLContextEvent::create( |
| 646 EventTypeNames::webglcontextcreationerror, false, true, | 646 EventTypeNames::webglcontextcreationerror, false, true, |
| 647 "Web page was not allowed to create a WebGL context.")); | 647 "Web page was not allowed to create a WebGL context.")); |
| 648 return nullptr; | 648 return nullptr; |
| 649 } | 649 } |
| 650 Settings* settings = frame->settings(); | 650 Settings* settings = frame->settings(); |
| 651 | 651 |
| 652 // The FrameLoaderClient might block creation of a new WebGL context despite t
he page settings; in | 652 // The FrameLoaderClient might block creation of a new WebGL context despite |
| 653 // particular, if WebGL contexts were lost one or more times via the GL_ARB_ro
bustness extension. | 653 // the page settings; in particular, if WebGL contexts were lost one or more |
| 654 // times via the GL_ARB_robustness extension. |
| 654 if (!frame->loader().client()->allowWebGL(settings && | 655 if (!frame->loader().client()->allowWebGL(settings && |
| 655 settings->webGLEnabled())) { | 656 settings->webGLEnabled())) { |
| 656 canvas->dispatchEvent(WebGLContextEvent::create( | 657 canvas->dispatchEvent(WebGLContextEvent::create( |
| 657 EventTypeNames::webglcontextcreationerror, false, true, | 658 EventTypeNames::webglcontextcreationerror, false, true, |
| 658 "Web page was not allowed to create a WebGL context.")); | 659 "Web page was not allowed to create a WebGL context.")); |
| 659 return nullptr; | 660 return nullptr; |
| 660 } | 661 } |
| 661 | 662 |
| 662 return createContextProviderInternal(canvas, nullptr, attributes, | 663 return createContextProviderInternal(canvas, nullptr, attributes, |
| 663 webGLVersion); | 664 webGLVersion); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 693 // no HTMLCanvas associated, thrown InvalidStateError | 694 // no HTMLCanvas associated, thrown InvalidStateError |
| 694 if (getOffscreenCanvas()->getAssociatedCanvasId() == -1) { | 695 if (getOffscreenCanvas()->getAssociatedCanvasId() == -1) { |
| 695 exceptionState.throwDOMException(InvalidStateError, | 696 exceptionState.throwDOMException(InvalidStateError, |
| 696 "Commit() was called on a context whose " | 697 "Commit() was called on a context whose " |
| 697 "OffscreenCanvas is not associated with a " | 698 "OffscreenCanvas is not associated with a " |
| 698 "canvas element."); | 699 "canvas element."); |
| 699 return; | 700 return; |
| 700 } | 701 } |
| 701 if (!drawingBuffer()) | 702 if (!drawingBuffer()) |
| 702 return; | 703 return; |
| 703 // TODO(crbug.com/646864): Make commit() work correctly with { preserveDrawing
Buffer : true }. | 704 // TODO(crbug.com/646864): Make commit() work correctly with |
| 705 // { preserveDrawingBuffer : true }. |
| 704 getOffscreenCanvas()->getOrCreateFrameDispatcher()->dispatchFrame( | 706 getOffscreenCanvas()->getOrCreateFrameDispatcher()->dispatchFrame( |
| 705 std::move(drawingBuffer()->transferToStaticBitmapImage())); | 707 std::move(drawingBuffer()->transferToStaticBitmapImage())); |
| 706 } | 708 } |
| 707 | 709 |
| 708 PassRefPtr<Image> WebGLRenderingContextBase::getImage( | 710 PassRefPtr<Image> WebGLRenderingContextBase::getImage( |
| 709 AccelerationHint hint, | 711 AccelerationHint hint, |
| 710 SnapshotReason reason) const { | 712 SnapshotReason reason) const { |
| 711 if (!drawingBuffer()) | 713 if (!drawingBuffer()) |
| 712 return nullptr; | 714 return nullptr; |
| 713 | 715 |
| 714 drawingBuffer()->commit(); | 716 drawingBuffer()->commit(); |
| 715 IntSize size = clampedCanvasSize(); | 717 IntSize size = clampedCanvasSize(); |
| 716 OpacityMode opacityMode = | 718 OpacityMode opacityMode = |
| 717 creationAttributes().hasAlpha() ? NonOpaque : Opaque; | 719 creationAttributes().hasAlpha() ? NonOpaque : Opaque; |
| 718 std::unique_ptr<AcceleratedImageBufferSurface> surface = | 720 std::unique_ptr<AcceleratedImageBufferSurface> surface = |
| 719 wrapUnique(new AcceleratedImageBufferSurface(size, opacityMode)); | 721 wrapUnique(new AcceleratedImageBufferSurface(size, opacityMode)); |
| 720 if (!surface->isValid()) | 722 if (!surface->isValid()) |
| 721 return nullptr; | 723 return nullptr; |
| 722 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(std::move(surface)); | 724 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(std::move(surface)); |
| 723 if (!buffer->copyRenderingResultsFromDrawingBuffer(drawingBuffer(), | 725 if (!buffer->copyRenderingResultsFromDrawingBuffer(drawingBuffer(), |
| 724 BackBuffer)) { | 726 BackBuffer)) { |
| 725 // copyRenderingResultsFromDrawingBuffer is expected to always succeed becau
se we've | 727 // copyRenderingResultsFromDrawingBuffer is expected to always succeed |
| 726 // explicitly created an Accelerated surface and have already validated it. | 728 // because we've explicitly created an Accelerated surface and have already |
| 729 // validated it. |
| 727 NOTREACHED(); | 730 NOTREACHED(); |
| 728 return nullptr; | 731 return nullptr; |
| 729 } | 732 } |
| 730 return buffer->newImageSnapshot(hint, reason); | 733 return buffer->newImageSnapshot(hint, reason); |
| 731 } | 734 } |
| 732 | 735 |
| 733 namespace { | 736 namespace { |
| 734 | 737 |
| 735 // Exposed by GL_ANGLE_depth_texture | 738 // Exposed by GL_ANGLE_depth_texture |
| 736 static const GLenum kSupportedInternalFormatsOESDepthTex[] = { | 739 static const GLenum kSupportedInternalFormatsOESDepthTex[] = { |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 convertToBaseCallback( | 1150 convertToBaseCallback( |
| 1148 WTF::bind(&WebGLRenderingContextBase::onErrorMessage, | 1151 WTF::bind(&WebGLRenderingContextBase::onErrorMessage, |
| 1149 wrapWeakPersistent(this)))); | 1152 wrapWeakPersistent(this)))); |
| 1150 | 1153 |
| 1151 // If WebGL 2, the PRIMITIVE_RESTART_FIXED_INDEX should be always enabled. | 1154 // If WebGL 2, the PRIMITIVE_RESTART_FIXED_INDEX should be always enabled. |
| 1152 // See the section <Primitive Restart is Always Enabled> in WebGL 2 spec: | 1155 // See the section <Primitive Restart is Always Enabled> in WebGL 2 spec: |
| 1153 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.1.4 | 1156 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.1.4 |
| 1154 if (isWebGL2OrHigher()) | 1157 if (isWebGL2OrHigher()) |
| 1155 contextGL()->Enable(GL_PRIMITIVE_RESTART_FIXED_INDEX); | 1158 contextGL()->Enable(GL_PRIMITIVE_RESTART_FIXED_INDEX); |
| 1156 | 1159 |
| 1157 // This ensures that the context has a valid "lastFlushID" and won't be mistak
enly identified as the "least recently used" context. | 1160 // This ensures that the context has a valid "lastFlushID" and won't be |
| 1161 // mistakenly identified as the "least recently used" context. |
| 1158 contextGL()->Flush(); | 1162 contextGL()->Flush(); |
| 1159 | 1163 |
| 1160 for (int i = 0; i < WebGLExtensionNameCount; ++i) | 1164 for (int i = 0; i < WebGLExtensionNameCount; ++i) |
| 1161 m_extensionEnabled[i] = false; | 1165 m_extensionEnabled[i] = false; |
| 1162 | 1166 |
| 1163 m_isWebGL2FormatsTypesAdded = false; | 1167 m_isWebGL2FormatsTypesAdded = false; |
| 1164 m_isWebGL2TexImageSourceFormatsTypesAdded = false; | 1168 m_isWebGL2TexImageSourceFormatsTypesAdded = false; |
| 1165 m_isWebGL2InternalFormatsCopyTexImageAdded = false; | 1169 m_isWebGL2InternalFormatsCopyTexImageAdded = false; |
| 1166 m_isOESTextureFloatFormatsTypesAdded = false; | 1170 m_isOESTextureFloatFormatsTypesAdded = false; |
| 1167 m_isOESTextureHalfFloatFormatsTypesAdded = false; | 1171 m_isOESTextureHalfFloatFormatsTypesAdded = false; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 | 1207 |
| 1204 void WebGLRenderingContextBase::addCompressedTextureFormat(GLenum format) { | 1208 void WebGLRenderingContextBase::addCompressedTextureFormat(GLenum format) { |
| 1205 if (!m_compressedTextureFormats.contains(format)) | 1209 if (!m_compressedTextureFormats.contains(format)) |
| 1206 m_compressedTextureFormats.append(format); | 1210 m_compressedTextureFormats.append(format); |
| 1207 } | 1211 } |
| 1208 | 1212 |
| 1209 void WebGLRenderingContextBase::removeAllCompressedTextureFormats() { | 1213 void WebGLRenderingContextBase::removeAllCompressedTextureFormats() { |
| 1210 m_compressedTextureFormats.clear(); | 1214 m_compressedTextureFormats.clear(); |
| 1211 } | 1215 } |
| 1212 | 1216 |
| 1213 // Helper function for V8 bindings to identify what version of WebGL a CanvasRen
deringContext supports. | 1217 // Helper function for V8 bindings to identify what version of WebGL a |
| 1218 // CanvasRenderingContext supports. |
| 1214 unsigned WebGLRenderingContextBase::getWebGLVersion( | 1219 unsigned WebGLRenderingContextBase::getWebGLVersion( |
| 1215 const CanvasRenderingContext* context) { | 1220 const CanvasRenderingContext* context) { |
| 1216 if (!context->is3d()) | 1221 if (!context->is3d()) |
| 1217 return 0; | 1222 return 0; |
| 1218 return static_cast<const WebGLRenderingContextBase*>(context)->version(); | 1223 return static_cast<const WebGLRenderingContextBase*>(context)->version(); |
| 1219 } | 1224 } |
| 1220 | 1225 |
| 1221 WebGLRenderingContextBase::~WebGLRenderingContextBase() { | 1226 WebGLRenderingContextBase::~WebGLRenderingContextBase() { |
| 1222 // Remove all references to WebGLObjects so if they are the last reference | 1227 // Remove all references to WebGLObjects so if they are the last reference |
| 1223 // they will be freed before the last context is removed from the context grou
p. | 1228 // they will be freed before the last context is removed from the context |
| 1229 // group. |
| 1224 m_boundArrayBuffer = nullptr; | 1230 m_boundArrayBuffer = nullptr; |
| 1225 m_defaultVertexArrayObject = nullptr; | 1231 m_defaultVertexArrayObject = nullptr; |
| 1226 m_boundVertexArrayObject = nullptr; | 1232 m_boundVertexArrayObject = nullptr; |
| 1227 m_currentProgram = nullptr; | 1233 m_currentProgram = nullptr; |
| 1228 m_framebufferBinding = nullptr; | 1234 m_framebufferBinding = nullptr; |
| 1229 m_renderbufferBinding = nullptr; | 1235 m_renderbufferBinding = nullptr; |
| 1230 | 1236 |
| 1231 // WebGLTexture shared objects will be detached and deleted | 1237 // WebGLTexture shared objects will be detached and deleted |
| 1232 // m_contextGroup->removeContext(this), which will bring about deleteTexture()
calls. | 1238 // m_contextGroup->removeContext(this), which will bring about deleteTexture() |
| 1233 // We null these out to avoid accessing those members in deleteTexture(). | 1239 // calls. We null these out to avoid accessing those members in |
| 1240 // deleteTexture(). |
| 1234 for (size_t i = 0; i < m_textureUnits.size(); ++i) { | 1241 for (size_t i = 0; i < m_textureUnits.size(); ++i) { |
| 1235 m_textureUnits[i].m_texture2DBinding = nullptr; | 1242 m_textureUnits[i].m_texture2DBinding = nullptr; |
| 1236 m_textureUnits[i].m_textureCubeMapBinding = nullptr; | 1243 m_textureUnits[i].m_textureCubeMapBinding = nullptr; |
| 1237 m_textureUnits[i].m_texture3DBinding = nullptr; | 1244 m_textureUnits[i].m_texture3DBinding = nullptr; |
| 1238 m_textureUnits[i].m_texture2DArrayBinding = nullptr; | 1245 m_textureUnits[i].m_texture2DArrayBinding = nullptr; |
| 1239 } | 1246 } |
| 1240 | 1247 |
| 1241 detachAndRemoveAllObjects(); | 1248 detachAndRemoveAllObjects(); |
| 1242 | 1249 |
| 1243 // Release all extensions now. | 1250 // Release all extensions now. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 if (!drawingBuffer()->bufferClearNeeded() || (mask && m_framebufferBinding)) | 1327 if (!drawingBuffer()->bufferClearNeeded() || (mask && m_framebufferBinding)) |
| 1321 return Skipped; | 1328 return Skipped; |
| 1322 | 1329 |
| 1323 Nullable<WebGLContextAttributes> contextAttributes; | 1330 Nullable<WebGLContextAttributes> contextAttributes; |
| 1324 getContextAttributes(contextAttributes); | 1331 getContextAttributes(contextAttributes); |
| 1325 if (contextAttributes.isNull()) { | 1332 if (contextAttributes.isNull()) { |
| 1326 // Unlikely, but context was lost. | 1333 // Unlikely, but context was lost. |
| 1327 return Skipped; | 1334 return Skipped; |
| 1328 } | 1335 } |
| 1329 | 1336 |
| 1330 // Determine if it's possible to combine the clear the user asked for and this
clear. | 1337 // Determine if it's possible to combine the clear the user asked for and this |
| 1338 // clear. |
| 1331 bool combinedClear = mask && !m_scissorEnabled; | 1339 bool combinedClear = mask && !m_scissorEnabled; |
| 1332 | 1340 |
| 1333 contextGL()->Disable(GL_SCISSOR_TEST); | 1341 contextGL()->Disable(GL_SCISSOR_TEST); |
| 1334 if (combinedClear && (mask & GL_COLOR_BUFFER_BIT)) { | 1342 if (combinedClear && (mask & GL_COLOR_BUFFER_BIT)) { |
| 1335 contextGL()->ClearColor(m_colorMask[0] ? m_clearColor[0] : 0, | 1343 contextGL()->ClearColor(m_colorMask[0] ? m_clearColor[0] : 0, |
| 1336 m_colorMask[1] ? m_clearColor[1] : 0, | 1344 m_colorMask[1] ? m_clearColor[1] : 0, |
| 1337 m_colorMask[2] ? m_clearColor[2] : 0, | 1345 m_colorMask[2] ? m_clearColor[2] : 0, |
| 1338 m_colorMask[3] ? m_clearColor[3] : 0); | 1346 m_colorMask[3] ? m_clearColor[3] : 0); |
| 1339 } else { | 1347 } else { |
| 1340 contextGL()->ClearColor(0, 0, 0, 0); | 1348 contextGL()->ClearColor(0, 0, 0, 0); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1418 | 1426 |
| 1419 if (!canvas()->buffer()) | 1427 if (!canvas()->buffer()) |
| 1420 return false; | 1428 return false; |
| 1421 | 1429 |
| 1422 ScopedTexture2DRestorer restorer(this); | 1430 ScopedTexture2DRestorer restorer(this); |
| 1423 ScopedFramebufferRestorer fboRestorer(this); | 1431 ScopedFramebufferRestorer fboRestorer(this); |
| 1424 | 1432 |
| 1425 drawingBuffer()->commit(); | 1433 drawingBuffer()->commit(); |
| 1426 if (!canvas()->buffer()->copyRenderingResultsFromDrawingBuffer( | 1434 if (!canvas()->buffer()->copyRenderingResultsFromDrawingBuffer( |
| 1427 drawingBuffer(), sourceBuffer)) { | 1435 drawingBuffer(), sourceBuffer)) { |
| 1428 // Currently, copyRenderingResultsFromDrawingBuffer is expected to always su
cceed because cases | 1436 // Currently, copyRenderingResultsFromDrawingBuffer is expected to always |
| 1429 // where canvas()-buffer() is not accelerated are handle before reaching thi
s point. | 1437 // succeed because cases where canvas()-buffer() is not accelerated are |
| 1430 // If that assumption ever stops holding true, we may need to implement a fa
llback right here. | 1438 // handle before reaching this point. If that assumption ever stops holding |
| 1439 // true, we may need to implement a fallback right here. |
| 1431 ASSERT_NOT_REACHED(); | 1440 ASSERT_NOT_REACHED(); |
| 1432 return false; | 1441 return false; |
| 1433 } | 1442 } |
| 1434 | 1443 |
| 1435 return true; | 1444 return true; |
| 1436 } | 1445 } |
| 1437 | 1446 |
| 1438 ImageData* WebGLRenderingContextBase::paintRenderingResultsToImageData( | 1447 ImageData* WebGLRenderingContextBase::paintRenderingResultsToImageData( |
| 1439 SourceDrawingBuffer sourceBuffer) { | 1448 SourceDrawingBuffer sourceBuffer) { |
| 1440 if (isContextLost()) | 1449 if (isContextLost()) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1459 } | 1468 } |
| 1460 | 1469 |
| 1461 void WebGLRenderingContextBase::reshape(int width, int height) { | 1470 void WebGLRenderingContextBase::reshape(int width, int height) { |
| 1462 if (isContextLost()) | 1471 if (isContextLost()) |
| 1463 return; | 1472 return; |
| 1464 | 1473 |
| 1465 if (isWebGL2OrHigher()) { | 1474 if (isWebGL2OrHigher()) { |
| 1466 contextGL()->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 1475 contextGL()->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| 1467 } | 1476 } |
| 1468 | 1477 |
| 1469 // This is an approximation because at WebGLRenderingContextBase level we don'
t | 1478 // This is an approximation because at WebGLRenderingContextBase level we |
| 1470 // know if the underlying FBO uses textures or renderbuffers. | 1479 // don't know if the underlying FBO uses textures or renderbuffers. |
| 1471 GLint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize); | 1480 GLint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize); |
| 1472 GLint maxWidth = std::min(maxSize, m_maxViewportDims[0]); | 1481 GLint maxWidth = std::min(maxSize, m_maxViewportDims[0]); |
| 1473 GLint maxHeight = std::min(maxSize, m_maxViewportDims[1]); | 1482 GLint maxHeight = std::min(maxSize, m_maxViewportDims[1]); |
| 1474 width = clamp(width, 1, maxWidth); | 1483 width = clamp(width, 1, maxWidth); |
| 1475 height = clamp(height, 1, maxHeight); | 1484 height = clamp(height, 1, maxHeight); |
| 1476 | 1485 |
| 1477 // Limit drawing buffer area to 4k*4k to avoid memory exhaustion. Width or hei
ght may be larger than | 1486 // Limit drawing buffer area to 4k*4k to avoid memory exhaustion. Width or |
| 1478 // 4k as long as it's within the max viewport dimensions and total area remain
s within the limit. | 1487 // height may be larger than 4k as long as it's within the max viewport |
| 1488 // dimensions and total area remains within the limit. |
| 1479 // For example: 5120x2880 should be fine. | 1489 // For example: 5120x2880 should be fine. |
| 1480 const int maxArea = 4096 * 4096; | 1490 const int maxArea = 4096 * 4096; |
| 1481 int currentArea = width * height; | 1491 int currentArea = width * height; |
| 1482 if (currentArea > maxArea) { | 1492 if (currentArea > maxArea) { |
| 1483 // If we've exceeded the area limit scale the buffer down, preserving ascpec
t ratio, until it fits. | 1493 // If we've exceeded the area limit scale the buffer down, preserving |
| 1494 // ascpect ratio, until it fits. |
| 1484 float scaleFactor = | 1495 float scaleFactor = |
| 1485 sqrtf(static_cast<float>(maxArea) / static_cast<float>(currentArea)); | 1496 sqrtf(static_cast<float>(maxArea) / static_cast<float>(currentArea)); |
| 1486 width = std::max(1, static_cast<int>(width * scaleFactor)); | 1497 width = std::max(1, static_cast<int>(width * scaleFactor)); |
| 1487 height = std::max(1, static_cast<int>(height * scaleFactor)); | 1498 height = std::max(1, static_cast<int>(height * scaleFactor)); |
| 1488 } | 1499 } |
| 1489 | 1500 |
| 1490 // We don't have to mark the canvas as dirty, since the newly created image bu
ffer will also start off | 1501 // We don't have to mark the canvas as dirty, since the newly created image |
| 1491 // clear (and this matches what reshape will do). | 1502 // buffer will also start off clear (and this matches what reshape will do). |
| 1492 drawingBuffer()->reset(IntSize(width, height)); | 1503 drawingBuffer()->reset(IntSize(width, height)); |
| 1493 restoreStateAfterClear(); | 1504 restoreStateAfterClear(); |
| 1494 | 1505 |
| 1495 contextGL()->BindTexture( | 1506 contextGL()->BindTexture( |
| 1496 GL_TEXTURE_2D, | 1507 GL_TEXTURE_2D, |
| 1497 objectOrZero( | 1508 objectOrZero( |
| 1498 m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get())); | 1509 m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get())); |
| 1499 contextGL()->BindRenderbuffer(GL_RENDERBUFFER, | 1510 contextGL()->BindRenderbuffer(GL_RENDERBUFFER, |
| 1500 objectOrZero(m_renderbufferBinding.get())); | 1511 objectOrZero(m_renderbufferBinding.get())); |
| 1501 drawingBuffer()->restoreFramebufferBindings(); | 1512 drawingBuffer()->restoreFramebufferBindings(); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1694 synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target"); | 1705 synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target"); |
| 1695 return; | 1706 return; |
| 1696 } | 1707 } |
| 1697 | 1708 |
| 1698 contextGL()->BindTexture(target, objectOrZero(texture)); | 1709 contextGL()->BindTexture(target, objectOrZero(texture)); |
| 1699 if (texture) { | 1710 if (texture) { |
| 1700 texture->setTarget(target); | 1711 texture->setTarget(target); |
| 1701 m_onePlusMaxNonDefaultTextureUnit = | 1712 m_onePlusMaxNonDefaultTextureUnit = |
| 1702 max(m_activeTextureUnit + 1, m_onePlusMaxNonDefaultTextureUnit); | 1713 max(m_activeTextureUnit + 1, m_onePlusMaxNonDefaultTextureUnit); |
| 1703 } else { | 1714 } else { |
| 1704 // If the disabled index is the current maximum, trace backwards to find the
new max enabled texture index | 1715 // If the disabled index is the current maximum, trace backwards to find the |
| 1716 // new max enabled texture index |
| 1705 if (m_onePlusMaxNonDefaultTextureUnit == m_activeTextureUnit + 1) { | 1717 if (m_onePlusMaxNonDefaultTextureUnit == m_activeTextureUnit + 1) { |
| 1706 findNewMaxNonDefaultTextureUnit(); | 1718 findNewMaxNonDefaultTextureUnit(); |
| 1707 } | 1719 } |
| 1708 } | 1720 } |
| 1709 | 1721 |
| 1710 // Note: previously we used to automatically set the TEXTURE_WRAP_R | 1722 // Note: previously we used to automatically set the TEXTURE_WRAP_R |
| 1711 // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL | 1723 // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL |
| 1712 // ES 2.0 doesn't expose this flag (a bug in the specification) and | 1724 // ES 2.0 doesn't expose this flag (a bug in the specification) and |
| 1713 // otherwise the application has no control over the seams in this | 1725 // otherwise the application has no control over the seams in this |
| 1714 // dimension. However, it appears that supporting this properly on all | 1726 // dimension. However, it appears that supporting this properly on all |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1905 m_framebufferBinding->checkDepthStencilStatus(&reason) != | 1917 m_framebufferBinding->checkDepthStencilStatus(&reason) != |
| 1906 GL_FRAMEBUFFER_COMPLETE) { | 1918 GL_FRAMEBUFFER_COMPLETE) { |
| 1907 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason); | 1919 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason); |
| 1908 return; | 1920 return; |
| 1909 } | 1921 } |
| 1910 | 1922 |
| 1911 ScopedRGBEmulationColorMask emulationColorMask(contextGL(), m_colorMask, | 1923 ScopedRGBEmulationColorMask emulationColorMask(contextGL(), m_colorMask, |
| 1912 m_drawingBuffer.get()); | 1924 m_drawingBuffer.get()); |
| 1913 | 1925 |
| 1914 if (clearIfComposited(mask) != CombinedClear) { | 1926 if (clearIfComposited(mask) != CombinedClear) { |
| 1915 // If clearing the default back buffer's depth buffer, also clear the stenci
l buffer, if one | 1927 // If clearing the default back buffer's depth buffer, also clear the |
| 1916 // was allocated implicitly. This avoids performance problems on some GPUs. | 1928 // stencil buffer, if one was allocated implicitly. This avoids performance |
| 1929 // problems on some GPUs. |
| 1917 if (!m_framebufferBinding && drawingBuffer()->hasImplicitStencilBuffer() && | 1930 if (!m_framebufferBinding && drawingBuffer()->hasImplicitStencilBuffer() && |
| 1918 (mask & GL_DEPTH_BUFFER_BIT)) { | 1931 (mask & GL_DEPTH_BUFFER_BIT)) { |
| 1919 // It shouldn't matter what value it's cleared to, since in other queries
in the API, we | 1932 // It shouldn't matter what value it's cleared to, since in other queries |
| 1920 // claim that the stencil buffer doesn't exist. | 1933 // in the API, we claim that the stencil buffer doesn't exist. |
| 1921 mask |= GL_STENCIL_BUFFER_BIT; | 1934 mask |= GL_STENCIL_BUFFER_BIT; |
| 1922 } | 1935 } |
| 1923 contextGL()->Clear(mask); | 1936 contextGL()->Clear(mask); |
| 1924 } | 1937 } |
| 1925 markContextChanged(CanvasChanged); | 1938 markContextChanged(CanvasChanged); |
| 1926 } | 1939 } |
| 1927 | 1940 |
| 1928 void WebGLRenderingContextBase::clearColor(GLfloat r, | 1941 void WebGLRenderingContextBase::clearColor(GLfloat r, |
| 1929 GLfloat g, | 1942 GLfloat g, |
| 1930 GLfloat b, | 1943 GLfloat b, |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2255 } | 2268 } |
| 2256 } | 2269 } |
| 2257 } | 2270 } |
| 2258 if (m_framebufferBinding) | 2271 if (m_framebufferBinding) |
| 2259 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(GL_FRAMEBUFFER, | 2272 m_framebufferBinding->removeAttachmentFromBoundFramebuffer(GL_FRAMEBUFFER, |
| 2260 texture); | 2273 texture); |
| 2261 if (getFramebufferBinding(GL_READ_FRAMEBUFFER)) | 2274 if (getFramebufferBinding(GL_READ_FRAMEBUFFER)) |
| 2262 getFramebufferBinding(GL_READ_FRAMEBUFFER) | 2275 getFramebufferBinding(GL_READ_FRAMEBUFFER) |
| 2263 ->removeAttachmentFromBoundFramebuffer(GL_READ_FRAMEBUFFER, texture); | 2276 ->removeAttachmentFromBoundFramebuffer(GL_READ_FRAMEBUFFER, texture); |
| 2264 | 2277 |
| 2265 // If the deleted was bound to the the current maximum index, trace backwards
to find the new max texture index | 2278 // If the deleted was bound to the the current maximum index, trace backwards |
| 2279 // to find the new max texture index. |
| 2266 if (m_onePlusMaxNonDefaultTextureUnit == | 2280 if (m_onePlusMaxNonDefaultTextureUnit == |
| 2267 static_cast<unsigned long>(maxBoundTextureIndex + 1)) { | 2281 static_cast<unsigned long>(maxBoundTextureIndex + 1)) { |
| 2268 findNewMaxNonDefaultTextureUnit(); | 2282 findNewMaxNonDefaultTextureUnit(); |
| 2269 } | 2283 } |
| 2270 } | 2284 } |
| 2271 | 2285 |
| 2272 void WebGLRenderingContextBase::depthFunc(GLenum func) { | 2286 void WebGLRenderingContextBase::depthFunc(GLenum func) { |
| 2273 if (isContextLost()) | 2287 if (isContextLost()) |
| 2274 return; | 2288 return; |
| 2275 contextGL()->DepthFunc(func); | 2289 contextGL()->DepthFunc(func); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2509 // implementations use an FBO internally in place of the default | 2523 // implementations use an FBO internally in place of the default |
| 2510 // FBO. | 2524 // FBO. |
| 2511 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target); | 2525 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target); |
| 2512 if (!framebufferBinding || !framebufferBinding->object()) { | 2526 if (!framebufferBinding || !framebufferBinding->object()) { |
| 2513 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", | 2527 synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", |
| 2514 "no framebuffer bound"); | 2528 "no framebuffer bound"); |
| 2515 return; | 2529 return; |
| 2516 } | 2530 } |
| 2517 GLuint bufferObject = objectOrZero(buffer); | 2531 GLuint bufferObject = objectOrZero(buffer); |
| 2518 if (isWebGL2OrHigher() && attachment == GL_DEPTH_STENCIL_ATTACHMENT) { | 2532 if (isWebGL2OrHigher() && attachment == GL_DEPTH_STENCIL_ATTACHMENT) { |
| 2519 // On ES3, DEPTH_STENCIL_ATTACHMENT is like an alias for DEPTH_ATTACHMENT +
STENCIL_ATTACHMENT. | 2533 // On ES3, DEPTH_STENCIL_ATTACHMENT is like an alias for DEPTH_ATTACHMENT + |
| 2520 // We divide it here so in WebGLFramebuffer, we don't have to handle DEPTH_S
TENCIL_ATTACHMENT in WebGL 2. | 2534 // STENCIL_ATTACHMENT. We divide it here so in WebGLFramebuffer, we don't |
| 2535 // have to handle DEPTH_STENCIL_ATTACHMENT in WebGL 2. |
| 2521 contextGL()->FramebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, | 2536 contextGL()->FramebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, |
| 2522 renderbuffertarget, bufferObject); | 2537 renderbuffertarget, bufferObject); |
| 2523 contextGL()->FramebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, | 2538 contextGL()->FramebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, |
| 2524 renderbuffertarget, bufferObject); | 2539 renderbuffertarget, bufferObject); |
| 2525 framebufferBinding->setAttachmentForBoundFramebuffer( | 2540 framebufferBinding->setAttachmentForBoundFramebuffer( |
| 2526 target, GL_DEPTH_ATTACHMENT, buffer); | 2541 target, GL_DEPTH_ATTACHMENT, buffer); |
| 2527 framebufferBinding->setAttachmentForBoundFramebuffer( | 2542 framebufferBinding->setAttachmentForBoundFramebuffer( |
| 2528 target, GL_STENCIL_ATTACHMENT, buffer); | 2543 target, GL_STENCIL_ATTACHMENT, buffer); |
| 2529 } else { | 2544 } else { |
| 2530 contextGL()->FramebufferRenderbuffer(target, attachment, renderbuffertarget, | 2545 contextGL()->FramebufferRenderbuffer(target, attachment, renderbuffertarget, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2553 // implementations use an FBO internally in place of the default | 2568 // implementations use an FBO internally in place of the default |
| 2554 // FBO. | 2569 // FBO. |
| 2555 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target); | 2570 WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target); |
| 2556 if (!framebufferBinding || !framebufferBinding->object()) { | 2571 if (!framebufferBinding || !framebufferBinding->object()) { |
| 2557 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", | 2572 synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", |
| 2558 "no framebuffer bound"); | 2573 "no framebuffer bound"); |
| 2559 return; | 2574 return; |
| 2560 } | 2575 } |
| 2561 GLuint textureObject = objectOrZero(texture); | 2576 GLuint textureObject = objectOrZero(texture); |
| 2562 if (isWebGL2OrHigher() && attachment == GL_DEPTH_STENCIL_ATTACHMENT) { | 2577 if (isWebGL2OrHigher() && attachment == GL_DEPTH_STENCIL_ATTACHMENT) { |
| 2563 // On ES3, DEPTH_STENCIL_ATTACHMENT is like an alias for DEPTH_ATTACHMENT +
STENCIL_ATTACHMENT. | 2578 // On ES3, DEPTH_STENCIL_ATTACHMENT is like an alias for DEPTH_ATTACHMENT + |
| 2564 // We divide it here so in WebGLFramebuffer, we don't have to handle DEPTH_S
TENCIL_ATTACHMENT in WebGL 2. | 2579 // STENCIL_ATTACHMENT. We divide it here so in WebGLFramebuffer, we don't |
| 2580 // have to handle DEPTH_STENCIL_ATTACHMENT in WebGL 2. |
| 2565 contextGL()->FramebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarget, | 2581 contextGL()->FramebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarget, |
| 2566 textureObject, level); | 2582 textureObject, level); |
| 2567 contextGL()->FramebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarget, | 2583 contextGL()->FramebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarget, |
| 2568 textureObject, level); | 2584 textureObject, level); |
| 2569 framebufferBinding->setAttachmentForBoundFramebuffer( | 2585 framebufferBinding->setAttachmentForBoundFramebuffer( |
| 2570 target, GL_DEPTH_ATTACHMENT, textarget, texture, level, 0); | 2586 target, GL_DEPTH_ATTACHMENT, textarget, texture, level, 0); |
| 2571 framebufferBinding->setAttachmentForBoundFramebuffer( | 2587 framebufferBinding->setAttachmentForBoundFramebuffer( |
| 2572 target, GL_STENCIL_ATTACHMENT, textarget, texture, level, 0); | 2588 target, GL_STENCIL_ATTACHMENT, textarget, texture, level, 0); |
| 2573 } else { | 2589 } else { |
| 2574 contextGL()->FramebufferTexture2D(target, attachment, textarget, | 2590 contextGL()->FramebufferTexture2D(target, attachment, textarget, |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2722 "invalid parameter name"); | 2738 "invalid parameter name"); |
| 2723 return ScriptValue::createNull(scriptState); | 2739 return ScriptValue::createNull(scriptState); |
| 2724 } | 2740 } |
| 2725 } | 2741 } |
| 2726 | 2742 |
| 2727 void WebGLRenderingContextBase::getContextAttributes( | 2743 void WebGLRenderingContextBase::getContextAttributes( |
| 2728 Nullable<WebGLContextAttributes>& result) { | 2744 Nullable<WebGLContextAttributes>& result) { |
| 2729 if (isContextLost()) | 2745 if (isContextLost()) |
| 2730 return; | 2746 return; |
| 2731 result.set(toWebGLContextAttributes(creationAttributes())); | 2747 result.set(toWebGLContextAttributes(creationAttributes())); |
| 2732 // Some requested attributes may not be honored, so we need to query the under
lying | 2748 // Some requested attributes may not be honored, so we need to query the |
| 2733 // context/drawing buffer and adjust accordingly. | 2749 // underlying context/drawing buffer and adjust accordingly. |
| 2734 if (creationAttributes().depth() && !drawingBuffer()->hasDepthBuffer()) | 2750 if (creationAttributes().depth() && !drawingBuffer()->hasDepthBuffer()) |
| 2735 result.get().setDepth(false); | 2751 result.get().setDepth(false); |
| 2736 if (creationAttributes().stencil() && !drawingBuffer()->hasStencilBuffer()) | 2752 if (creationAttributes().stencil() && !drawingBuffer()->hasStencilBuffer()) |
| 2737 result.get().setStencil(false); | 2753 result.get().setStencil(false); |
| 2738 result.get().setAntialias(drawingBuffer()->multisample()); | 2754 result.get().setAntialias(drawingBuffer()->multisample()); |
| 2739 } | 2755 } |
| 2740 | 2756 |
| 2741 GLenum WebGLRenderingContextBase::getError() { | 2757 GLenum WebGLRenderingContextBase::getError() { |
| 2742 if (!m_lostContextErrors.isEmpty()) { | 2758 if (!m_lostContextErrors.isEmpty()) { |
| 2743 GLenum error = m_lostContextErrors.first(); | 2759 GLenum error = m_lostContextErrors.first(); |
| (...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3419 contextGL()->GetProgramiv(programId, GL_ACTIVE_UNIFORM_MAX_LENGTH, | 3435 contextGL()->GetProgramiv(programId, GL_ACTIVE_UNIFORM_MAX_LENGTH, |
| 3420 &maxNameLength); | 3436 &maxNameLength); |
| 3421 if (maxNameLength < 0) | 3437 if (maxNameLength < 0) |
| 3422 return ScriptValue::createNull(scriptState); | 3438 return ScriptValue::createNull(scriptState); |
| 3423 if (maxNameLength == 0) { | 3439 if (maxNameLength == 0) { |
| 3424 synthesizeGLError(GL_INVALID_VALUE, "getUniform", | 3440 synthesizeGLError(GL_INVALID_VALUE, "getUniform", |
| 3425 "no active uniforms exist"); | 3441 "no active uniforms exist"); |
| 3426 return ScriptValue::createNull(scriptState); | 3442 return ScriptValue::createNull(scriptState); |
| 3427 } | 3443 } |
| 3428 | 3444 |
| 3429 // FIXME: make this more efficient using WebGLUniformLocation and caching type
s in it | 3445 // FIXME: make this more efficient using WebGLUniformLocation and caching |
| 3446 // types in it. |
| 3430 GLint activeUniforms = 0; | 3447 GLint activeUniforms = 0; |
| 3431 contextGL()->GetProgramiv(programId, GL_ACTIVE_UNIFORMS, &activeUniforms); | 3448 contextGL()->GetProgramiv(programId, GL_ACTIVE_UNIFORMS, &activeUniforms); |
| 3432 for (GLint i = 0; i < activeUniforms; i++) { | 3449 for (GLint i = 0; i < activeUniforms; i++) { |
| 3433 LChar* namePtr; | 3450 LChar* namePtr; |
| 3434 RefPtr<StringImpl> nameImpl = | 3451 RefPtr<StringImpl> nameImpl = |
| 3435 StringImpl::createUninitialized(maxNameLength, namePtr); | 3452 StringImpl::createUninitialized(maxNameLength, namePtr); |
| 3436 GLsizei length = 0; | 3453 GLsizei length = 0; |
| 3437 GLint size = -1; | 3454 GLint size = -1; |
| 3438 GLenum type = 0; | 3455 GLenum type = 0; |
| 3439 contextGL()->GetActiveUniform(programId, i, maxNameLength, &length, &size, | 3456 contextGL()->GetActiveUniform(programId, i, maxNameLength, &length, &size, |
| 3440 &type, reinterpret_cast<GLchar*>(namePtr)); | 3457 &type, reinterpret_cast<GLchar*>(namePtr)); |
| 3441 if (size < 0) | 3458 if (size < 0) |
| 3442 return ScriptValue::createNull(scriptState); | 3459 return ScriptValue::createNull(scriptState); |
| 3443 String name(nameImpl->substring(0, length)); | 3460 String name(nameImpl->substring(0, length)); |
| 3444 StringBuilder nameBuilder; | 3461 StringBuilder nameBuilder; |
| 3445 // Strip "[0]" from the name if it's an array. | 3462 // Strip "[0]" from the name if it's an array. |
| 3446 if (size > 1 && name.endsWith("[0]")) | 3463 if (size > 1 && name.endsWith("[0]")) |
| 3447 name = name.left(name.length() - 3); | 3464 name = name.left(name.length() - 3); |
| 3448 // If it's an array, we need to iterate through each element, appending "[in
dex]" to the name. | 3465 // If it's an array, we need to iterate through each element, appending |
| 3466 // "[index]" to the name. |
| 3449 for (GLint index = 0; index < size; ++index) { | 3467 for (GLint index = 0; index < size; ++index) { |
| 3450 nameBuilder.clear(); | 3468 nameBuilder.clear(); |
| 3451 nameBuilder.append(name); | 3469 nameBuilder.append(name); |
| 3452 if (size > 1 && index >= 1) { | 3470 if (size > 1 && index >= 1) { |
| 3453 nameBuilder.append('['); | 3471 nameBuilder.append('['); |
| 3454 nameBuilder.appendNumber(index); | 3472 nameBuilder.appendNumber(index); |
| 3455 nameBuilder.append(']'); | 3473 nameBuilder.append(']'); |
| 3456 } | 3474 } |
| 3457 // Now need to look this up by name again to find its location | 3475 // Now need to look this up by name again to find its location |
| 3458 GLint loc = contextGL()->GetUniformLocation( | 3476 GLint loc = contextGL()->GetUniformLocation( |
| 3459 objectOrZero(program), nameBuilder.toString().utf8().data()); | 3477 objectOrZero(program), nameBuilder.toString().utf8().data()); |
| 3460 if (loc == location) { | 3478 if (loc == location) { |
| 3461 // Found it. Use the type in the ActiveInfo to determine the return type
. | 3479 // Found it. Use the type in the ActiveInfo to determine the return |
| 3480 // type. |
| 3462 GLenum baseType; | 3481 GLenum baseType; |
| 3463 unsigned length; | 3482 unsigned length; |
| 3464 switch (type) { | 3483 switch (type) { |
| 3465 case GL_BOOL: | 3484 case GL_BOOL: |
| 3466 baseType = GL_BOOL; | 3485 baseType = GL_BOOL; |
| 3467 length = 1; | 3486 length = 1; |
| 3468 break; | 3487 break; |
| 3469 case GL_BOOL_VEC2: | 3488 case GL_BOOL_VEC2: |
| 3470 baseType = GL_BOOL; | 3489 baseType = GL_BOOL; |
| 3471 length = 2; | 3490 length = 2; |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3621 return WebGLAny(scriptState, boolValue, length); | 3640 return WebGLAny(scriptState, boolValue, length); |
| 3622 } | 3641 } |
| 3623 return WebGLAny(scriptState, static_cast<bool>(value[0])); | 3642 return WebGLAny(scriptState, static_cast<bool>(value[0])); |
| 3624 } | 3643 } |
| 3625 default: | 3644 default: |
| 3626 NOTIMPLEMENTED(); | 3645 NOTIMPLEMENTED(); |
| 3627 } | 3646 } |
| 3628 } | 3647 } |
| 3629 } | 3648 } |
| 3630 } | 3649 } |
| 3631 // If we get here, something went wrong in our unfortunately complex logic abo
ve | 3650 // If we get here, something went wrong in our unfortunately complex logic |
| 3651 // above |
| 3632 synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unknown error"); | 3652 synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unknown error"); |
| 3633 return ScriptValue::createNull(scriptState); | 3653 return ScriptValue::createNull(scriptState); |
| 3634 } | 3654 } |
| 3635 | 3655 |
| 3636 WebGLUniformLocation* WebGLRenderingContextBase::getUniformLocation( | 3656 WebGLUniformLocation* WebGLRenderingContextBase::getUniformLocation( |
| 3637 WebGLProgram* program, | 3657 WebGLProgram* program, |
| 3638 const String& name) { | 3658 const String& name) { |
| 3639 if (isContextLost() || !validateWebGLObject("getUniformLocation", program)) | 3659 if (isContextLost() || !validateWebGLObject("getUniformLocation", program)) |
| 3640 return nullptr; | 3660 return nullptr; |
| 3641 if (!validateLocationLength("getUniformLocation", name)) | 3661 if (!validateLocationLength("getUniformLocation", name)) |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4077 } | 4097 } |
| 4078 } | 4098 } |
| 4079 | 4099 |
| 4080 void WebGLRenderingContextBase::renderbufferStorageImpl( | 4100 void WebGLRenderingContextBase::renderbufferStorageImpl( |
| 4081 GLenum target, | 4101 GLenum target, |
| 4082 GLsizei samples, | 4102 GLsizei samples, |
| 4083 GLenum internalformat, | 4103 GLenum internalformat, |
| 4084 GLsizei width, | 4104 GLsizei width, |
| 4085 GLsizei height, | 4105 GLsizei height, |
| 4086 const char* functionName) { | 4106 const char* functionName) { |
| 4087 ASSERT( | 4107 ASSERT(!samples); // |samples| > 0 is only valid in WebGL2's |
| 4088 !samples); // |samples| > 0 is only valid in WebGL2's renderbufferStorage
Multisample(). | 4108 // renderbufferStorageMultisample(). |
| 4089 ASSERT(!isWebGL2OrHigher()); // Make sure this is overridden in WebGL 2. | 4109 ASSERT(!isWebGL2OrHigher()); // Make sure this is overridden in WebGL 2. |
| 4090 switch (internalformat) { | 4110 switch (internalformat) { |
| 4091 case GL_DEPTH_COMPONENT16: | 4111 case GL_DEPTH_COMPONENT16: |
| 4092 case GL_RGBA4: | 4112 case GL_RGBA4: |
| 4093 case GL_RGB5_A1: | 4113 case GL_RGB5_A1: |
| 4094 case GL_RGB565: | 4114 case GL_RGB565: |
| 4095 case GL_STENCIL_INDEX8: | 4115 case GL_STENCIL_INDEX8: |
| 4096 contextGL()->RenderbufferStorage(target, internalformat, width, height); | 4116 contextGL()->RenderbufferStorage(target, internalformat, width, height); |
| 4097 m_renderbufferBinding->setInternalFormat(internalformat); | 4117 m_renderbufferBinding->setInternalFormat(internalformat); |
| 4098 m_renderbufferBinding->setSize(width, height); | 4118 m_renderbufferBinding->setSize(width, height); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4157 if (isContextLost()) | 4177 if (isContextLost()) |
| 4158 return; | 4178 return; |
| 4159 contextGL()->Scissor(x, y, width, height); | 4179 contextGL()->Scissor(x, y, width, height); |
| 4160 } | 4180 } |
| 4161 | 4181 |
| 4162 void WebGLRenderingContextBase::shaderSource(WebGLShader* shader, | 4182 void WebGLRenderingContextBase::shaderSource(WebGLShader* shader, |
| 4163 const String& string) { | 4183 const String& string) { |
| 4164 if (isContextLost() || !validateWebGLObject("shaderSource", shader)) | 4184 if (isContextLost() || !validateWebGLObject("shaderSource", shader)) |
| 4165 return; | 4185 return; |
| 4166 String stringWithoutComments = StripComments(string).result(); | 4186 String stringWithoutComments = StripComments(string).result(); |
| 4167 // TODO(danakj): Make validateShaderSource reject characters > 255 (or utf16 S
trings) | 4187 // TODO(danakj): Make validateShaderSource reject characters > 255 (or utf16 |
| 4168 // so we don't need to use StringUTF8Adaptor. | 4188 // Strings) so we don't need to use StringUTF8Adaptor. |
| 4169 if (!validateShaderSource(stringWithoutComments)) | 4189 if (!validateShaderSource(stringWithoutComments)) |
| 4170 return; | 4190 return; |
| 4171 shader->setSource(string); | 4191 shader->setSource(string); |
| 4172 WTF::StringUTF8Adaptor adaptor(stringWithoutComments); | 4192 WTF::StringUTF8Adaptor adaptor(stringWithoutComments); |
| 4173 const GLchar* shaderData = adaptor.data(); | 4193 const GLchar* shaderData = adaptor.data(); |
| 4174 // TODO(danakj): Use base::saturated_cast<GLint>. | 4194 // TODO(danakj): Use base::saturated_cast<GLint>. |
| 4175 const GLint shaderLength = adaptor.length(); | 4195 const GLint shaderLength = adaptor.length(); |
| 4176 contextGL()->ShaderSource(objectOrZero(shader), 1, &shaderData, | 4196 contextGL()->ShaderSource(objectOrZero(shader), 1, &shaderData, |
| 4177 &shaderLength); | 4197 &shaderLength); |
| 4178 } | 4198 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4263 GLenum zfail, | 4283 GLenum zfail, |
| 4264 GLenum zpass) { | 4284 GLenum zpass) { |
| 4265 if (isContextLost()) | 4285 if (isContextLost()) |
| 4266 return; | 4286 return; |
| 4267 contextGL()->StencilOpSeparate(face, fail, zfail, zpass); | 4287 contextGL()->StencilOpSeparate(face, fail, zfail, zpass); |
| 4268 } | 4288 } |
| 4269 | 4289 |
| 4270 GLenum WebGLRenderingContextBase::convertTexInternalFormat( | 4290 GLenum WebGLRenderingContextBase::convertTexInternalFormat( |
| 4271 GLenum internalformat, | 4291 GLenum internalformat, |
| 4272 GLenum type) { | 4292 GLenum type) { |
| 4273 // Convert to sized internal formats that are renderable with GL_CHROMIUM_colo
r_buffer_float_rgb(a). | 4293 // Convert to sized internal formats that are renderable with |
| 4294 // GL_CHROMIUM_color_buffer_float_rgb(a). |
| 4274 if (type == GL_FLOAT && internalformat == GL_RGBA && | 4295 if (type == GL_FLOAT && internalformat == GL_RGBA && |
| 4275 extensionsUtil()->isExtensionEnabled( | 4296 extensionsUtil()->isExtensionEnabled( |
| 4276 "GL_CHROMIUM_color_buffer_float_rgba")) | 4297 "GL_CHROMIUM_color_buffer_float_rgba")) |
| 4277 return GL_RGBA32F_EXT; | 4298 return GL_RGBA32F_EXT; |
| 4278 if (type == GL_FLOAT && internalformat == GL_RGB && | 4299 if (type == GL_FLOAT && internalformat == GL_RGB && |
| 4279 extensionsUtil()->isExtensionEnabled( | 4300 extensionsUtil()->isExtensionEnabled( |
| 4280 "GL_CHROMIUM_color_buffer_float_rgb")) | 4301 "GL_CHROMIUM_color_buffer_float_rgb")) |
| 4281 return GL_RGB32F_EXT; | 4302 return GL_RGB32F_EXT; |
| 4282 return internalformat; | 4303 return internalformat; |
| 4283 } | 4304 } |
| 4284 | 4305 |
| 4285 void WebGLRenderingContextBase::texImage2DBase(GLenum target, | 4306 void WebGLRenderingContextBase::texImage2DBase(GLenum target, |
| 4286 GLint level, | 4307 GLint level, |
| 4287 GLint internalformat, | 4308 GLint internalformat, |
| 4288 GLsizei width, | 4309 GLsizei width, |
| 4289 GLsizei height, | 4310 GLsizei height, |
| 4290 GLint border, | 4311 GLint border, |
| 4291 GLenum format, | 4312 GLenum format, |
| 4292 GLenum type, | 4313 GLenum type, |
| 4293 const void* pixels) { | 4314 const void* pixels) { |
| 4294 // All calling functions check isContextLost, so a duplicate check is not need
ed here. | 4315 // All calling functions check isContextLost, so a duplicate check is not |
| 4316 // needed here. |
| 4295 contextGL()->TexImage2D(target, level, | 4317 contextGL()->TexImage2D(target, level, |
| 4296 convertTexInternalFormat(internalformat, type), width, | 4318 convertTexInternalFormat(internalformat, type), width, |
| 4297 height, border, format, type, pixels); | 4319 height, border, format, type, pixels); |
| 4298 } | 4320 } |
| 4299 | 4321 |
| 4300 void WebGLRenderingContextBase::texImageImpl( | 4322 void WebGLRenderingContextBase::texImageImpl( |
| 4301 TexImageFunctionID functionID, | 4323 TexImageFunctionID functionID, |
| 4302 GLenum target, | 4324 GLenum target, |
| 4303 GLint level, | 4325 GLint level, |
| 4304 GLint internalformat, | 4326 GLint internalformat, |
| 4305 GLint xoffset, | 4327 GLint xoffset, |
| 4306 GLint yoffset, | 4328 GLint yoffset, |
| 4307 GLint zoffset, | 4329 GLint zoffset, |
| 4308 GLenum format, | 4330 GLenum format, |
| 4309 GLenum type, | 4331 GLenum type, |
| 4310 Image* image, | 4332 Image* image, |
| 4311 WebGLImageConversion::ImageHtmlDomSource domSource, | 4333 WebGLImageConversion::ImageHtmlDomSource domSource, |
| 4312 bool flipY, | 4334 bool flipY, |
| 4313 bool premultiplyAlpha) { | 4335 bool premultiplyAlpha) { |
| 4314 const char* funcName = getTexImageFunctionName(functionID); | 4336 const char* funcName = getTexImageFunctionName(functionID); |
| 4315 // All calling functions check isContextLost, so a duplicate check is not need
ed here. | 4337 // All calling functions check isContextLost, so a duplicate check is not |
| 4338 // needed here. |
| 4316 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { | 4339 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
| 4317 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. | 4340 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
| 4318 type = GL_FLOAT; | 4341 type = GL_FLOAT; |
| 4319 } | 4342 } |
| 4320 Vector<uint8_t> data; | 4343 Vector<uint8_t> data; |
| 4321 WebGLImageConversion::ImageExtractor imageExtractor( | 4344 WebGLImageConversion::ImageExtractor imageExtractor( |
| 4322 image, domSource, premultiplyAlpha, | 4345 image, domSource, premultiplyAlpha, |
| 4323 m_unpackColorspaceConversion == GL_NONE); | 4346 m_unpackColorspaceConversion == GL_NONE); |
| 4324 if (!imageExtractor.imagePixelData()) { | 4347 if (!imageExtractor.imagePixelData()) { |
| 4325 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); | 4348 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4390 level, internalformat, width, height, depth, | 4413 level, internalformat, width, height, depth, |
| 4391 border, format, type)) | 4414 border, format, type)) |
| 4392 return false; | 4415 return false; |
| 4393 | 4416 |
| 4394 if (functionType == TexSubImage) { | 4417 if (functionType == TexSubImage) { |
| 4395 if (!validateSettableTexFormat(functionName, format)) | 4418 if (!validateSettableTexFormat(functionName, format)) |
| 4396 return false; | 4419 return false; |
| 4397 if (!validateSize(functionName, xoffset, yoffset, zoffset)) | 4420 if (!validateSize(functionName, xoffset, yoffset, zoffset)) |
| 4398 return false; | 4421 return false; |
| 4399 } else { | 4422 } else { |
| 4400 // For SourceArrayBufferView, function validateTexFuncData() would handle wh
ether to validate the SettableTexFormat | 4423 // For SourceArrayBufferView, function validateTexFuncData() would handle |
| 4424 // whether to validate the SettableTexFormat |
| 4401 // by checking if the ArrayBufferView is null or not. | 4425 // by checking if the ArrayBufferView is null or not. |
| 4402 if (sourceType != SourceArrayBufferView) { | 4426 if (sourceType != SourceArrayBufferView) { |
| 4403 if (!validateSettableTexFormat(functionName, format)) | 4427 if (!validateSettableTexFormat(functionName, format)) |
| 4404 return false; | 4428 return false; |
| 4405 } | 4429 } |
| 4406 } | 4430 } |
| 4407 | 4431 |
| 4408 return true; | 4432 return true; |
| 4409 } | 4433 } |
| 4410 | 4434 |
| 4411 bool WebGLRenderingContextBase::validateValueFitNonNegInt32( | 4435 bool WebGLRenderingContextBase::validateValueFitNonNegInt32( |
| 4412 const char* functionName, | 4436 const char* functionName, |
| 4413 const char* paramName, | 4437 const char* paramName, |
| 4414 long long value) { | 4438 long long value) { |
| 4415 if (value < 0) { | 4439 if (value < 0) { |
| 4416 String errorMsg = String(paramName) + " < 0"; | 4440 String errorMsg = String(paramName) + " < 0"; |
| 4417 synthesizeGLError(GL_INVALID_VALUE, functionName, errorMsg.ascii().data()); | 4441 synthesizeGLError(GL_INVALID_VALUE, functionName, errorMsg.ascii().data()); |
| 4418 return false; | 4442 return false; |
| 4419 } | 4443 } |
| 4420 if (value > static_cast<long long>(std::numeric_limits<int>::max())) { | 4444 if (value > static_cast<long long>(std::numeric_limits<int>::max())) { |
| 4421 String errorMsg = String(paramName) + " more than 32-bit"; | 4445 String errorMsg = String(paramName) + " more than 32-bit"; |
| 4422 synthesizeGLError(GL_INVALID_OPERATION, functionName, | 4446 synthesizeGLError(GL_INVALID_OPERATION, functionName, |
| 4423 errorMsg.ascii().data()); | 4447 errorMsg.ascii().data()); |
| 4424 return false; | 4448 return false; |
| 4425 } | 4449 } |
| 4426 return true; | 4450 return true; |
| 4427 } | 4451 } |
| 4428 | 4452 |
| 4429 // TODO(fmalita): figure why WebGLImageConversion::ImageExtractor can't handle S
VG-backed images, | 4453 // TODO(fmalita): figure why WebGLImageConversion::ImageExtractor can't handle |
| 4430 // and get rid of this intermediate step. | 4454 // SVG-backed images, and get rid of this intermediate step. |
| 4431 PassRefPtr<Image> WebGLRenderingContextBase::drawImageIntoBuffer( | 4455 PassRefPtr<Image> WebGLRenderingContextBase::drawImageIntoBuffer( |
| 4432 PassRefPtr<Image> passImage, | 4456 PassRefPtr<Image> passImage, |
| 4433 int width, | 4457 int width, |
| 4434 int height, | 4458 int height, |
| 4435 const char* functionName) { | 4459 const char* functionName) { |
| 4436 RefPtr<Image> image(passImage); | 4460 RefPtr<Image> image(passImage); |
| 4437 ASSERT(image); | 4461 ASSERT(image); |
| 4438 | 4462 |
| 4439 IntSize size(width, height); | 4463 IntSize size(width, height); |
| 4440 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); | 4464 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4607 functionType = TexImage; | 4631 functionType = TexImage; |
| 4608 else | 4632 else |
| 4609 functionType = TexSubImage; | 4633 functionType = TexSubImage; |
| 4610 if (!validateTexFunc(funcName, functionType, SourceImageData, target, level, | 4634 if (!validateTexFunc(funcName, functionType, SourceImageData, target, level, |
| 4611 internalformat, pixels->width(), pixels->height(), depth, | 4635 internalformat, pixels->width(), pixels->height(), depth, |
| 4612 border, format, type, xoffset, yoffset, zoffset)) | 4636 border, format, type, xoffset, yoffset, zoffset)) |
| 4613 return; | 4637 return; |
| 4614 Vector<uint8_t> data; | 4638 Vector<uint8_t> data; |
| 4615 bool needConversion = true; | 4639 bool needConversion = true; |
| 4616 // The data from ImageData is always of format RGBA8. | 4640 // The data from ImageData is always of format RGBA8. |
| 4617 // No conversion is needed if destination format is RGBA and type is USIGNED_B
YTE and no Flip or Premultiply operation is required. | 4641 // No conversion is needed if destination format is RGBA and type is |
| 4642 // USIGNED_BYTE and no Flip or Premultiply operation is required. |
| 4618 if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && | 4643 if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && |
| 4619 type == GL_UNSIGNED_BYTE) { | 4644 type == GL_UNSIGNED_BYTE) { |
| 4620 needConversion = false; | 4645 needConversion = false; |
| 4621 } else { | 4646 } else { |
| 4622 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { | 4647 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
| 4623 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. | 4648 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
| 4624 type = GL_FLOAT; | 4649 type = GL_FLOAT; |
| 4625 } | 4650 } |
| 4626 if (!WebGLImageConversion::extractImageData( | 4651 if (!WebGLImageConversion::extractImageData( |
| 4627 pixels->data()->data(), | 4652 pixels->data()->data(), |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4715 } | 4740 } |
| 4716 | 4741 |
| 4717 bool WebGLRenderingContextBase::canUseTexImageByGPU( | 4742 bool WebGLRenderingContextBase::canUseTexImageByGPU( |
| 4718 TexImageFunctionID functionID, | 4743 TexImageFunctionID functionID, |
| 4719 GLint internalformat, | 4744 GLint internalformat, |
| 4720 GLenum type) { | 4745 GLenum type) { |
| 4721 if (functionID == TexImage2D && | 4746 if (functionID == TexImage2D && |
| 4722 (isFloatType(type) || isIntegerFormat(internalformat) || | 4747 (isFloatType(type) || isIntegerFormat(internalformat) || |
| 4723 isSRGBFormat(internalformat))) | 4748 isSRGBFormat(internalformat))) |
| 4724 return false; | 4749 return false; |
| 4725 // TODO(crbug.com/622958): Implement GPU-to-GPU path for WebGL 2 and more inte
rnal formats. | 4750 // TODO(crbug.com/622958): Implement GPU-to-GPU path for WebGL 2 and more |
| 4751 // internal formats. |
| 4726 if (functionID == TexSubImage2D && | 4752 if (functionID == TexSubImage2D && |
| 4727 (isWebGL2OrHigher() || extensionEnabled(OESTextureFloatName) || | 4753 (isWebGL2OrHigher() || extensionEnabled(OESTextureFloatName) || |
| 4728 extensionEnabled(OESTextureHalfFloatName) || | 4754 extensionEnabled(OESTextureHalfFloatName) || |
| 4729 extensionEnabled(EXTsRGBName))) | 4755 extensionEnabled(EXTsRGBName))) |
| 4730 return false; | 4756 return false; |
| 4731 return true; | 4757 return true; |
| 4732 } | 4758 } |
| 4733 | 4759 |
| 4734 void WebGLRenderingContextBase::texImageCanvasByGPU(HTMLCanvasElement* canvas, | 4760 void WebGLRenderingContextBase::texImageCanvasByGPU(HTMLCanvasElement* canvas, |
| 4735 GLuint targetTexture, | 4761 GLuint targetTexture, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4776 GLuint targetTexture = texture->object(); | 4802 GLuint targetTexture = texture->object(); |
| 4777 GLenum targetType = type; | 4803 GLenum targetType = type; |
| 4778 GLenum targetInternalformat = internalformat; | 4804 GLenum targetInternalformat = internalformat; |
| 4779 GLint targetLevel = level; | 4805 GLint targetLevel = level; |
| 4780 bool possibleDirectCopy = false; | 4806 bool possibleDirectCopy = false; |
| 4781 if (functionType == TexImage2DByGPU) { | 4807 if (functionType == TexImage2DByGPU) { |
| 4782 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM( | 4808 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM( |
| 4783 target, internalformat, type, level); | 4809 target, internalformat, type, level); |
| 4784 } | 4810 } |
| 4785 | 4811 |
| 4786 // if direct copy is not possible, create a temporary texture and then copy fr
om canvas to temporary texture to target texture. | 4812 // if direct copy is not possible, create a temporary texture and then copy |
| 4813 // from canvas to temporary texture to target texture. |
| 4787 if (!possibleDirectCopy) { | 4814 if (!possibleDirectCopy) { |
| 4788 targetLevel = 0; | 4815 targetLevel = 0; |
| 4789 targetInternalformat = GL_RGBA; | 4816 targetInternalformat = GL_RGBA; |
| 4790 targetType = GL_UNSIGNED_BYTE; | 4817 targetType = GL_UNSIGNED_BYTE; |
| 4791 contextGL()->GenTextures(1, &targetTexture); | 4818 contextGL()->GenTextures(1, &targetTexture); |
| 4792 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); | 4819 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); |
| 4793 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, | 4820 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, |
| 4794 GL_NEAREST); | 4821 GL_NEAREST); |
| 4795 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, | 4822 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, |
| 4796 GL_NEAREST); | 4823 GL_NEAREST); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4857 TexImageFunctionType functionType; | 4884 TexImageFunctionType functionType; |
| 4858 if (functionID == TexImage2D) | 4885 if (functionID == TexImage2D) |
| 4859 functionType = TexImage; | 4886 functionType = TexImage; |
| 4860 else | 4887 else |
| 4861 functionType = TexSubImage; | 4888 functionType = TexSubImage; |
| 4862 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target, | 4889 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target, |
| 4863 level, internalformat, canvas->width(), canvas->height(), | 4890 level, internalformat, canvas->width(), canvas->height(), |
| 4864 1, 0, format, type, xoffset, yoffset, zoffset)) | 4891 1, 0, format, type, xoffset, yoffset, zoffset)) |
| 4865 return; | 4892 return; |
| 4866 if (functionID == TexImage2D || functionID == TexSubImage2D) { | 4893 if (functionID == TexImage2D || functionID == TexSubImage2D) { |
| 4867 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support float/i
nteger/sRGB internal format. | 4894 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support |
| 4868 // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is up
graded to handle more formats. | 4895 // float/integer/sRGB internal format. |
| 4896 // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is |
| 4897 // upgraded to handle more formats. |
| 4869 if (!canvas->renderingContext() || | 4898 if (!canvas->renderingContext() || |
| 4870 !canvas->renderingContext()->isAccelerated() || | 4899 !canvas->renderingContext()->isAccelerated() || |
| 4871 !canUseTexImageByGPU(functionID, internalformat, type)) { | 4900 !canUseTexImageByGPU(functionID, internalformat, type)) { |
| 4872 // 2D canvas has only FrontBuffer. | 4901 // 2D canvas has only FrontBuffer. |
| 4873 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, | 4902 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, |
| 4874 zoffset, format, type, | 4903 zoffset, format, type, |
| 4875 canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), | 4904 canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), |
| 4876 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, | 4905 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, |
| 4877 m_unpackPremultiplyAlpha); | 4906 m_unpackPremultiplyAlpha); |
| 4878 return; | 4907 return; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4948 functionType = TexImage; | 4977 functionType = TexImage; |
| 4949 else | 4978 else |
| 4950 functionType = TexSubImage; | 4979 functionType = TexSubImage; |
| 4951 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, | 4980 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, |
| 4952 level, internalformat, video->videoWidth(), | 4981 level, internalformat, video->videoWidth(), |
| 4953 video->videoHeight(), 1, 0, format, type, xoffset, | 4982 video->videoHeight(), 1, 0, format, type, xoffset, |
| 4954 yoffset, zoffset)) | 4983 yoffset, zoffset)) |
| 4955 return; | 4984 return; |
| 4956 | 4985 |
| 4957 if (functionID == TexImage2D) { | 4986 if (functionID == TexImage2D) { |
| 4958 // Go through the fast path doing a GPU-GPU textures copy without a readback
to system memory if possible. | 4987 // Go through the fast path doing a GPU-GPU textures copy without a readback |
| 4959 // Otherwise, it will fall back to the normal SW path. | 4988 // to system memory if possible. Otherwise, it will fall back to the normal |
| 4989 // SW path. |
| 4960 if (GL_TEXTURE_2D == target) { | 4990 if (GL_TEXTURE_2D == target) { |
| 4961 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, | 4991 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, |
| 4962 type, level) && | 4992 type, level) && |
| 4963 video->copyVideoTextureToPlatformTexture( | 4993 video->copyVideoTextureToPlatformTexture( |
| 4964 contextGL(), texture->object(), internalformat, type, | 4994 contextGL(), texture->object(), internalformat, type, |
| 4965 m_unpackPremultiplyAlpha, m_unpackFlipY)) { | 4995 m_unpackPremultiplyAlpha, m_unpackFlipY)) { |
| 4966 return; | 4996 return; |
| 4967 } | 4997 } |
| 4968 | 4998 |
| 4969 // Try using an accelerated image buffer, this allows YUV conversion to be
done on the GPU. | 4999 // Try using an accelerated image buffer, this allows YUV conversion to be |
| 5000 // done on the GPU. |
| 4970 std::unique_ptr<ImageBufferSurface> surface = | 5001 std::unique_ptr<ImageBufferSurface> surface = |
| 4971 wrapUnique(new AcceleratedImageBufferSurface( | 5002 wrapUnique(new AcceleratedImageBufferSurface( |
| 4972 IntSize(video->videoWidth(), video->videoHeight()))); | 5003 IntSize(video->videoWidth(), video->videoHeight()))); |
| 4973 if (surface->isValid()) { | 5004 if (surface->isValid()) { |
| 4974 std::unique_ptr<ImageBuffer> imageBuffer( | 5005 std::unique_ptr<ImageBuffer> imageBuffer( |
| 4975 ImageBuffer::create(std::move(surface))); | 5006 ImageBuffer::create(std::move(surface))); |
| 4976 if (imageBuffer) { | 5007 if (imageBuffer) { |
| 4977 // The video element paints an RGBA frame into our surface here. By us
ing an AcceleratedImageBufferSurface, | 5008 // The video element paints an RGBA frame into our surface here. By |
| 4978 // we enable the WebMediaPlayer implementation to do any necessary col
or space conversion on the GPU (though it | 5009 // using an AcceleratedImageBufferSurface, we enable the |
| 5010 // WebMediaPlayer implementation to do any necessary color space |
| 5011 // conversion on the GPU (though it |
| 4979 // may still do a CPU conversion and upload the results). | 5012 // may still do a CPU conversion and upload the results). |
| 4980 video->paintCurrentFrame( | 5013 video->paintCurrentFrame( |
| 4981 imageBuffer->canvas(), | 5014 imageBuffer->canvas(), |
| 4982 IntRect(0, 0, video->videoWidth(), video->videoHeight()), | 5015 IntRect(0, 0, video->videoWidth(), video->videoHeight()), |
| 4983 nullptr); | 5016 nullptr); |
| 4984 | 5017 |
| 4985 // This is a straight GPU-GPU copy, any necessary color space conversi
on was handled in the paintCurrentFrameInContext() call. | 5018 // This is a straight GPU-GPU copy, any necessary color space |
| 5019 // conversion was handled in the paintCurrentFrameInContext() call. |
| 4986 if (imageBuffer->copyToPlatformTexture( | 5020 if (imageBuffer->copyToPlatformTexture( |
| 4987 contextGL(), texture->object(), internalformat, type, level, | 5021 contextGL(), texture->object(), internalformat, type, level, |
| 4988 m_unpackPremultiplyAlpha, m_unpackFlipY)) { | 5022 m_unpackPremultiplyAlpha, m_unpackFlipY)) { |
| 4989 return; | 5023 return; |
| 4990 } | 5024 } |
| 4991 } | 5025 } |
| 4992 } | 5026 } |
| 4993 } | 5027 } |
| 4994 } | 5028 } |
| 4995 | 5029 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5065 } else if (functionID == TexSubImage2D) { | 5099 } else if (functionID == TexSubImage2D) { |
| 5066 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, | 5100 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, |
| 5067 xoffset, yoffset, 0, bitmap); | 5101 xoffset, yoffset, 0, bitmap); |
| 5068 } | 5102 } |
| 5069 return; | 5103 return; |
| 5070 } | 5104 } |
| 5071 sk_sp<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); | 5105 sk_sp<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); |
| 5072 SkPixmap pixmap; | 5106 SkPixmap pixmap; |
| 5073 uint8_t* pixelDataPtr = nullptr; | 5107 uint8_t* pixelDataPtr = nullptr; |
| 5074 RefPtr<Uint8Array> pixelData; | 5108 RefPtr<Uint8Array> pixelData; |
| 5075 // In the case where an ImageBitmap is not texture backed, peekPixels() always
succeed. | 5109 // In the case where an ImageBitmap is not texture backed, peekPixels() always |
| 5076 // However, when it is texture backed and !canUseTexImageByGPU, we do a GPU re
ad back. | 5110 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we |
| 5111 // do a GPU read back. |
| 5077 bool peekSucceed = skImage->peekPixels(&pixmap); | 5112 bool peekSucceed = skImage->peekPixels(&pixmap); |
| 5078 if (peekSucceed) { | 5113 if (peekSucceed) { |
| 5079 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); | 5114 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); |
| 5080 } else { | 5115 } else { |
| 5081 pixelData = bitmap->copyBitmapData( | 5116 pixelData = bitmap->copyBitmapData( |
| 5082 bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha); | 5117 bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha); |
| 5083 pixelDataPtr = pixelData->data(); | 5118 pixelDataPtr = pixelData->data(); |
| 5084 } | 5119 } |
| 5085 Vector<uint8_t> data; | 5120 Vector<uint8_t> data; |
| 5086 bool needConversion = true; | 5121 bool needConversion = true; |
| 5087 bool havePeekableRGBA = | 5122 bool havePeekableRGBA = |
| 5088 (peekSucceed && | 5123 (peekSucceed && |
| 5089 pixmap.colorType() == SkColorType::kRGBA_8888_SkColorType); | 5124 pixmap.colorType() == SkColorType::kRGBA_8888_SkColorType); |
| 5090 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed); | 5125 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed); |
| 5091 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { | 5126 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { |
| 5092 needConversion = false; | 5127 needConversion = false; |
| 5093 } else { | 5128 } else { |
| 5094 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { | 5129 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
| 5095 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. | 5130 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
| 5096 type = GL_FLOAT; | 5131 type = GL_FLOAT; |
| 5097 } | 5132 } |
| 5098 // In the case of ImageBitmap, we do not need to apply flipY or premultiplyA
lpha. | 5133 // In the case of ImageBitmap, we do not need to apply flipY or |
| 5134 // premultiplyAlpha. |
| 5099 bool isPixelDataBGRA = | 5135 bool isPixelDataBGRA = |
| 5100 pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType; | 5136 pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType; |
| 5101 if ((isPixelDataBGRA && | 5137 if ((isPixelDataBGRA && |
| 5102 !WebGLImageConversion::extractImageData( | 5138 !WebGLImageConversion::extractImageData( |
| 5103 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, | 5139 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, |
| 5104 bitmap->size(), format, type, false, false, data)) || | 5140 bitmap->size(), format, type, false, false, data)) || |
| 5105 (isPixelDataRGBA && | 5141 (isPixelDataRGBA && |
| 5106 !WebGLImageConversion::extractImageData( | 5142 !WebGLImageConversion::extractImageData( |
| 5107 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, | 5143 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, |
| 5108 bitmap->size(), format, type, false, false, data))) { | 5144 bitmap->size(), format, type, false, false, data))) { |
| (...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5850 | 5886 |
| 5851 void WebGLRenderingContextBase::viewport(GLint x, | 5887 void WebGLRenderingContextBase::viewport(GLint x, |
| 5852 GLint y, | 5888 GLint y, |
| 5853 GLsizei width, | 5889 GLsizei width, |
| 5854 GLsizei height) { | 5890 GLsizei height) { |
| 5855 if (isContextLost()) | 5891 if (isContextLost()) |
| 5856 return; | 5892 return; |
| 5857 contextGL()->Viewport(x, y, width, height); | 5893 contextGL()->Viewport(x, y, width, height); |
| 5858 } | 5894 } |
| 5859 | 5895 |
| 5860 // Added to provide a unified interface with CanvasRenderingContext2D. Prefer ca
lling forceLostContext instead. | 5896 // Added to provide a unified interface with CanvasRenderingContext2D. Prefer |
| 5897 // calling forceLostContext instead. |
| 5861 void WebGLRenderingContextBase::loseContext(LostContextMode mode) { | 5898 void WebGLRenderingContextBase::loseContext(LostContextMode mode) { |
| 5862 forceLostContext(mode, Manual); | 5899 forceLostContext(mode, Manual); |
| 5863 } | 5900 } |
| 5864 | 5901 |
| 5865 void WebGLRenderingContextBase::forceLostContext( | 5902 void WebGLRenderingContextBase::forceLostContext( |
| 5866 LostContextMode mode, | 5903 LostContextMode mode, |
| 5867 AutoRecoveryMethod autoRecoveryMethod) { | 5904 AutoRecoveryMethod autoRecoveryMethod) { |
| 5868 if (isContextLost()) { | 5905 if (isContextLost()) { |
| 5869 synthesizeGLError(GL_INVALID_OPERATION, "loseContext", | 5906 synthesizeGLError(GL_INVALID_OPERATION, "loseContext", |
| 5870 "context already lost"); | 5907 "context already lost"); |
| 5871 return; | 5908 return; |
| 5872 } | 5909 } |
| 5873 | 5910 |
| 5874 m_contextGroup->loseContextGroup(mode, autoRecoveryMethod); | 5911 m_contextGroup->loseContextGroup(mode, autoRecoveryMethod); |
| 5875 } | 5912 } |
| 5876 | 5913 |
| 5877 void WebGLRenderingContextBase::loseContextImpl( | 5914 void WebGLRenderingContextBase::loseContextImpl( |
| 5878 WebGLRenderingContextBase::LostContextMode mode, | 5915 WebGLRenderingContextBase::LostContextMode mode, |
| 5879 AutoRecoveryMethod autoRecoveryMethod) { | 5916 AutoRecoveryMethod autoRecoveryMethod) { |
| 5880 if (isContextLost()) | 5917 if (isContextLost()) |
| 5881 return; | 5918 return; |
| 5882 | 5919 |
| 5883 m_contextLostMode = mode; | 5920 m_contextLostMode = mode; |
| 5884 ASSERT(m_contextLostMode != NotLostContext); | 5921 ASSERT(m_contextLostMode != NotLostContext); |
| 5885 m_autoRecoveryMethod = autoRecoveryMethod; | 5922 m_autoRecoveryMethod = autoRecoveryMethod; |
| 5886 | 5923 |
| 5887 // Make absolutely sure we do not refer to an already-deleted texture or frame
buffer. | 5924 // Make absolutely sure we do not refer to an already-deleted texture or |
| 5925 // framebuffer. |
| 5888 drawingBuffer()->setTexture2DBinding(0); | 5926 drawingBuffer()->setTexture2DBinding(0); |
| 5889 drawingBuffer()->setFramebufferBinding(GL_FRAMEBUFFER, 0); | 5927 drawingBuffer()->setFramebufferBinding(GL_FRAMEBUFFER, 0); |
| 5890 drawingBuffer()->setRenderbufferBinding(0); | 5928 drawingBuffer()->setRenderbufferBinding(0); |
| 5891 | 5929 |
| 5892 detachAndRemoveAllObjects(); | 5930 detachAndRemoveAllObjects(); |
| 5893 | 5931 |
| 5894 // Lose all the extensions. | 5932 // Lose all the extensions. |
| 5895 for (size_t i = 0; i < m_extensions.size(); ++i) { | 5933 for (size_t i = 0; i < m_extensions.size(); ++i) { |
| 5896 ExtensionTracker* tracker = m_extensions[i]; | 5934 ExtensionTracker* tracker = m_extensions[i]; |
| 5897 tracker->loseExtension(false); | 5935 tracker->loseExtension(false); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5948 SkFilterQuality filterQuality) { | 5986 SkFilterQuality filterQuality) { |
| 5949 if (!isContextLost() && drawingBuffer()) { | 5987 if (!isContextLost() && drawingBuffer()) { |
| 5950 drawingBuffer()->setFilterQuality(filterQuality); | 5988 drawingBuffer()->setFilterQuality(filterQuality); |
| 5951 } | 5989 } |
| 5952 } | 5990 } |
| 5953 | 5991 |
| 5954 Extensions3DUtil* WebGLRenderingContextBase::extensionsUtil() { | 5992 Extensions3DUtil* WebGLRenderingContextBase::extensionsUtil() { |
| 5955 if (!m_extensionsUtil) { | 5993 if (!m_extensionsUtil) { |
| 5956 gpu::gles2::GLES2Interface* gl = contextGL(); | 5994 gpu::gles2::GLES2Interface* gl = contextGL(); |
| 5957 m_extensionsUtil = Extensions3DUtil::create(gl); | 5995 m_extensionsUtil = Extensions3DUtil::create(gl); |
| 5958 // The only reason the ExtensionsUtil should be invalid is if the gl context
is lost. | 5996 // The only reason the ExtensionsUtil should be invalid is if the gl context |
| 5997 // is lost. |
| 5959 ASSERT(m_extensionsUtil->isValid() || | 5998 ASSERT(m_extensionsUtil->isValid() || |
| 5960 gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR); | 5999 gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR); |
| 5961 } | 6000 } |
| 5962 return m_extensionsUtil.get(); | 6001 return m_extensionsUtil.get(); |
| 5963 } | 6002 } |
| 5964 | 6003 |
| 5965 void WebGLRenderingContextBase::removeSharedObject(WebGLSharedObject* object) { | 6004 void WebGLRenderingContextBase::removeSharedObject(WebGLSharedObject* object) { |
| 5966 m_contextGroup->removeObject(object); | 6005 m_contextGroup->removeObject(object); |
| 5967 } | 6006 } |
| 5968 | 6007 |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6478 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: | 6517 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: |
| 6479 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: | 6518 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: |
| 6480 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: | 6519 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: |
| 6481 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: | 6520 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: |
| 6482 if (functionType != TexSubImage && width != height) { | 6521 if (functionType != TexSubImage && width != height) { |
| 6483 synthesizeGLError(GL_INVALID_VALUE, functionName, | 6522 synthesizeGLError(GL_INVALID_VALUE, functionName, |
| 6484 "width != height for cube map"); | 6523 "width != height for cube map"); |
| 6485 return false; | 6524 return false; |
| 6486 } | 6525 } |
| 6487 // No need to check height here. For texImage width == height. | 6526 // No need to check height here. For texImage width == height. |
| 6488 // For texSubImage that will be checked when checking yoffset + height is
in range. | 6527 // For texSubImage that will be checked when checking yoffset + height is |
| 6528 // in range. |
| 6489 if (width > (m_maxCubeMapTextureSize >> level)) { | 6529 if (width > (m_maxCubeMapTextureSize >> level)) { |
| 6490 synthesizeGLError(GL_INVALID_VALUE, functionName, | 6530 synthesizeGLError(GL_INVALID_VALUE, functionName, |
| 6491 "width or height out of range for cube map"); | 6531 "width or height out of range for cube map"); |
| 6492 return false; | 6532 return false; |
| 6493 } | 6533 } |
| 6494 break; | 6534 break; |
| 6495 case GL_TEXTURE_3D: | 6535 case GL_TEXTURE_3D: |
| 6496 if (isWebGL2OrHigher()) { | 6536 if (isWebGL2OrHigher()) { |
| 6497 if (width > (m_max3DTextureSize >> level) || | 6537 if (width > (m_max3DTextureSize >> level) || |
| 6498 height > (m_max3DTextureSize >> level) || | 6538 height > (m_max3DTextureSize >> level) || |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6569 TexImageDimension texDimension, | 6609 TexImageDimension texDimension, |
| 6570 GLint level, | 6610 GLint level, |
| 6571 GLsizei width, | 6611 GLsizei width, |
| 6572 GLsizei height, | 6612 GLsizei height, |
| 6573 GLsizei depth, | 6613 GLsizei depth, |
| 6574 GLenum format, | 6614 GLenum format, |
| 6575 GLenum type, | 6615 GLenum type, |
| 6576 DOMArrayBufferView* pixels, | 6616 DOMArrayBufferView* pixels, |
| 6577 NullDisposition disposition, | 6617 NullDisposition disposition, |
| 6578 GLuint srcOffset) { | 6618 GLuint srcOffset) { |
| 6579 // All calling functions check isContextLost, so a duplicate check is not need
ed here. | 6619 // All calling functions check isContextLost, so a duplicate check is not |
| 6620 // needed here. |
| 6580 if (!pixels) { | 6621 if (!pixels) { |
| 6581 DCHECK_NE(disposition, NullNotReachable); | 6622 DCHECK_NE(disposition, NullNotReachable); |
| 6582 if (disposition == NullAllowed) | 6623 if (disposition == NullAllowed) |
| 6583 return true; | 6624 return true; |
| 6584 synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels"); | 6625 synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels"); |
| 6585 return false; | 6626 return false; |
| 6586 } | 6627 } |
| 6587 | 6628 |
| 6588 if (!validateSettableTexFormat(functionName, format)) | 6629 if (!validateSettableTexFormat(functionName, format)) |
| 6589 return false; | 6630 return false; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6643 break; | 6684 break; |
| 6644 case GL_FLOAT: // OES_texture_float | 6685 case GL_FLOAT: // OES_texture_float |
| 6645 if (pixels->type() != DOMArrayBufferView::TypeFloat32) { | 6686 if (pixels->type() != DOMArrayBufferView::TypeFloat32) { |
| 6646 synthesizeGLError(GL_INVALID_OPERATION, functionName, | 6687 synthesizeGLError(GL_INVALID_OPERATION, functionName, |
| 6647 "type FLOAT but ArrayBufferView not Float32Array"); | 6688 "type FLOAT but ArrayBufferView not Float32Array"); |
| 6648 return false; | 6689 return false; |
| 6649 } | 6690 } |
| 6650 break; | 6691 break; |
| 6651 case GL_HALF_FLOAT: | 6692 case GL_HALF_FLOAT: |
| 6652 case GL_HALF_FLOAT_OES: // OES_texture_half_float | 6693 case GL_HALF_FLOAT_OES: // OES_texture_half_float |
| 6653 // As per the specification, ArrayBufferView should be null or a Uint16Arr
ay when | 6694 // As per the specification, ArrayBufferView should be null or a |
| 6654 // OES_texture_half_float is enabled. | 6695 // Uint16Array when OES_texture_half_float is enabled. |
| 6655 if (pixels->type() != DOMArrayBufferView::TypeUint16) { | 6696 if (pixels->type() != DOMArrayBufferView::TypeUint16) { |
| 6656 synthesizeGLError(GL_INVALID_OPERATION, functionName, | 6697 synthesizeGLError(GL_INVALID_OPERATION, functionName, |
| 6657 "type HALF_FLOAT_OES but ArrayBufferView is not NULL " | 6698 "type HALF_FLOAT_OES but ArrayBufferView is not NULL " |
| 6658 "and not Uint16Array"); | 6699 "and not Uint16Array"); |
| 6659 return false; | 6700 return false; |
| 6660 } | 6701 } |
| 6661 break; | 6702 break; |
| 6662 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: | 6703 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: |
| 6663 synthesizeGLError(GL_INVALID_OPERATION, functionName, | 6704 synthesizeGLError(GL_INVALID_OPERATION, functionName, |
| 6664 "type FLOAT_32_UNSIGNED_INT_24_8_REV but " | 6705 "type FLOAT_32_UNSIGNED_INT_24_8_REV but " |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7107 LocalFrame* frame = canvas()->document().frame(); | 7148 LocalFrame* frame = canvas()->document().frame(); |
| 7108 if (!frame) | 7149 if (!frame) |
| 7109 return; | 7150 return; |
| 7110 | 7151 |
| 7111 Settings* settings = frame->settings(); | 7152 Settings* settings = frame->settings(); |
| 7112 | 7153 |
| 7113 if (!frame->loader().client()->allowWebGL(settings && | 7154 if (!frame->loader().client()->allowWebGL(settings && |
| 7114 settings->webGLEnabled())) | 7155 settings->webGLEnabled())) |
| 7115 return; | 7156 return; |
| 7116 | 7157 |
| 7117 // If the context was lost due to RealLostContext, we need to destroy the old
DrawingBuffer before creating new DrawingBuffer to ensure resource budget enough
. | 7158 // If the context was lost due to RealLostContext, we need to destroy the old |
| 7159 // DrawingBuffer before creating new DrawingBuffer to ensure resource budget |
| 7160 // enough. |
| 7118 if (drawingBuffer()) { | 7161 if (drawingBuffer()) { |
| 7119 m_drawingBuffer->beginDestruction(); | 7162 m_drawingBuffer->beginDestruction(); |
| 7120 m_drawingBuffer.clear(); | 7163 m_drawingBuffer.clear(); |
| 7121 } | 7164 } |
| 7122 | 7165 |
| 7123 Platform::ContextAttributes attributes = | 7166 Platform::ContextAttributes attributes = |
| 7124 toPlatformContextAttributes(creationAttributes(), version()); | 7167 toPlatformContextAttributes(creationAttributes(), version()); |
| 7125 Platform::GraphicsInfo glInfo; | 7168 Platform::GraphicsInfo glInfo; |
| 7126 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = | 7169 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = |
| 7127 wrapUnique(Platform::current()->createOffscreenGraphicsContext3DProvider( | 7170 wrapUnique(Platform::current()->createOffscreenGraphicsContext3DProvider( |
| 7128 attributes, canvas()->document().topDocument().url(), 0, &glInfo)); | 7171 attributes, canvas()->document().topDocument().url(), 0, &glInfo)); |
| 7129 RefPtr<DrawingBuffer> buffer; | 7172 RefPtr<DrawingBuffer> buffer; |
| 7130 if (contextProvider && contextProvider->bindToCurrentThread()) { | 7173 if (contextProvider && contextProvider->bindToCurrentThread()) { |
| 7131 // Construct a new drawing buffer with the new GL context. | 7174 // Construct a new drawing buffer with the new GL context. |
| 7132 // TODO(xidachen): make sure that the second parameter is correct for Offscr
eenCanvas. | 7175 // TODO(xidachen): make sure that the second parameter is correct for |
| 7176 // OffscreenCanvas. |
| 7133 buffer = createDrawingBuffer(std::move(contextProvider), | 7177 buffer = createDrawingBuffer(std::move(contextProvider), |
| 7134 DrawingBuffer::AllowChromiumImage); | 7178 DrawingBuffer::AllowChromiumImage); |
| 7135 // If DrawingBuffer::create() fails to allocate a fbo, |drawingBuffer| is se
t to null. | 7179 // If DrawingBuffer::create() fails to allocate a fbo, |drawingBuffer| is |
| 7180 // set to null. |
| 7136 } | 7181 } |
| 7137 if (!buffer) { | 7182 if (!buffer) { |
| 7138 if (m_contextLostMode == RealLostContext) { | 7183 if (m_contextLostMode == RealLostContext) { |
| 7139 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, | 7184 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, |
| 7140 BLINK_FROM_HERE); | 7185 BLINK_FROM_HERE); |
| 7141 } else { | 7186 } else { |
| 7142 // This likely shouldn't happen but is the best way to report it to the We
bGL app. | 7187 // This likely shouldn't happen but is the best way to report it to the |
| 7188 // WebGL app. |
| 7143 synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context"); | 7189 synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context"); |
| 7144 } | 7190 } |
| 7145 return; | 7191 return; |
| 7146 } | 7192 } |
| 7147 | 7193 |
| 7148 m_drawingBuffer = buffer.release(); | 7194 m_drawingBuffer = buffer.release(); |
| 7149 m_drawingBuffer->addNewMailboxCallback( | 7195 m_drawingBuffer->addNewMailboxCallback( |
| 7150 WTF::bind(&WebGLRenderingContextBase::notifyCanvasContextChanged, | 7196 WTF::bind(&WebGLRenderingContextBase::notifyCanvasContextChanged, |
| 7151 wrapWeakPersistent(this))); | 7197 wrapWeakPersistent(this))); |
| 7152 | 7198 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7344 void WebGLRenderingContextBase::restoreCurrentFramebuffer() { | 7390 void WebGLRenderingContextBase::restoreCurrentFramebuffer() { |
| 7345 bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding.get()); | 7391 bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding.get()); |
| 7346 } | 7392 } |
| 7347 | 7393 |
| 7348 void WebGLRenderingContextBase::restoreCurrentTexture2D() { | 7394 void WebGLRenderingContextBase::restoreCurrentTexture2D() { |
| 7349 bindTexture(GL_TEXTURE_2D, | 7395 bindTexture(GL_TEXTURE_2D, |
| 7350 m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get()); | 7396 m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get()); |
| 7351 } | 7397 } |
| 7352 | 7398 |
| 7353 void WebGLRenderingContextBase::findNewMaxNonDefaultTextureUnit() { | 7399 void WebGLRenderingContextBase::findNewMaxNonDefaultTextureUnit() { |
| 7354 // Trace backwards from the current max to find the new max non-default textur
e unit | 7400 // Trace backwards from the current max to find the new max non-default |
| 7401 // texture unit |
| 7355 int startIndex = m_onePlusMaxNonDefaultTextureUnit - 1; | 7402 int startIndex = m_onePlusMaxNonDefaultTextureUnit - 1; |
| 7356 for (int i = startIndex; i >= 0; --i) { | 7403 for (int i = startIndex; i >= 0; --i) { |
| 7357 if (m_textureUnits[i].m_texture2DBinding || | 7404 if (m_textureUnits[i].m_texture2DBinding || |
| 7358 m_textureUnits[i].m_textureCubeMapBinding) { | 7405 m_textureUnits[i].m_textureCubeMapBinding) { |
| 7359 m_onePlusMaxNonDefaultTextureUnit = i + 1; | 7406 m_onePlusMaxNonDefaultTextureUnit = i + 1; |
| 7360 return; | 7407 return; |
| 7361 } | 7408 } |
| 7362 } | 7409 } |
| 7363 m_onePlusMaxNonDefaultTextureUnit = 0; | 7410 m_onePlusMaxNonDefaultTextureUnit = 0; |
| 7364 } | 7411 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7428 | 7475 |
| 7429 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( | 7476 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( |
| 7430 HTMLCanvasElementOrOffscreenCanvas& result) const { | 7477 HTMLCanvasElementOrOffscreenCanvas& result) const { |
| 7431 if (canvas()) | 7478 if (canvas()) |
| 7432 result.setHTMLCanvasElement(canvas()); | 7479 result.setHTMLCanvasElement(canvas()); |
| 7433 else | 7480 else |
| 7434 result.setOffscreenCanvas(getOffscreenCanvas()); | 7481 result.setOffscreenCanvas(getOffscreenCanvas()); |
| 7435 } | 7482 } |
| 7436 | 7483 |
| 7437 } // namespace blink | 7484 } // namespace blink |
| OLD | NEW |