| 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 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 formatWebGLStatusString("ErrorMessage", info.errorMessage.utf8().data(), | 540 formatWebGLStatusString("ErrorMessage", info.errorMessage.utf8().data(), |
| 541 builder); | 541 builder); |
| 542 builder.append('.'); | 542 builder.append('.'); |
| 543 return builder.toString(); | 543 return builder.toString(); |
| 544 } | 544 } |
| 545 | 545 |
| 546 struct ContextProviderCreationInfo { | 546 struct ContextProviderCreationInfo { |
| 547 // Inputs. | 547 // Inputs. |
| 548 Platform::ContextAttributes contextAttributes; | 548 Platform::ContextAttributes contextAttributes; |
| 549 Platform::GraphicsInfo* glInfo; | 549 Platform::GraphicsInfo* glInfo; |
| 550 ScriptState* scriptState; | 550 KURL url; |
| 551 // Outputs. | 551 // Outputs. |
| 552 std::unique_ptr<WebGraphicsContext3DProvider> createdContextProvider; | 552 std::unique_ptr<WebGraphicsContext3DProvider> createdContextProvider; |
| 553 }; | 553 }; |
| 554 | 554 |
| 555 static void createContextProviderOnMainThread( | 555 static void createContextProviderOnMainThread( |
| 556 ContextProviderCreationInfo* creationInfo, | 556 ContextProviderCreationInfo* creationInfo, |
| 557 WaitableEvent* waitableEvent) { | 557 WaitableEvent* waitableEvent) { |
| 558 ASSERT(isMainThread()); | 558 ASSERT(isMainThread()); |
| 559 creationInfo->createdContextProvider = | 559 creationInfo->createdContextProvider = |
| 560 wrapUnique(Platform::current()->createOffscreenGraphicsContext3DProvider( | 560 wrapUnique(Platform::current()->createOffscreenGraphicsContext3DProvider( |
| 561 creationInfo->contextAttributes, | 561 creationInfo->contextAttributes, creationInfo->url, 0, |
| 562 creationInfo->scriptState->getExecutionContext()->url(), 0, | |
| 563 creationInfo->glInfo)); | 562 creationInfo->glInfo)); |
| 564 waitableEvent->signal(); | 563 waitableEvent->signal(); |
| 565 } | 564 } |
| 566 | 565 |
| 567 static std::unique_ptr<WebGraphicsContext3DProvider> | 566 static std::unique_ptr<WebGraphicsContext3DProvider> |
| 568 createContextProviderOnWorkerThread( | 567 createContextProviderOnWorkerThread( |
| 569 Platform::ContextAttributes contextAttributes, | 568 Platform::ContextAttributes contextAttributes, |
| 570 Platform::GraphicsInfo* glInfo, | 569 Platform::GraphicsInfo* glInfo, |
| 571 ScriptState* scriptState) { | 570 const KURL& url) { |
| 572 WaitableEvent waitableEvent; | 571 WaitableEvent waitableEvent; |
| 573 ContextProviderCreationInfo creationInfo; | 572 ContextProviderCreationInfo creationInfo; |
| 574 creationInfo.contextAttributes = contextAttributes; | 573 creationInfo.contextAttributes = contextAttributes; |
| 575 creationInfo.glInfo = glInfo; | 574 creationInfo.glInfo = glInfo; |
| 576 creationInfo.scriptState = scriptState; | 575 creationInfo.url = url; |
| 577 WebTaskRunner* taskRunner = | 576 WebTaskRunner* taskRunner = |
| 578 Platform::current()->mainThread()->getWebTaskRunner(); | 577 Platform::current()->mainThread()->getWebTaskRunner(); |
| 579 taskRunner->postTask(BLINK_FROM_HERE, | 578 taskRunner->postTask(BLINK_FROM_HERE, |
| 580 crossThreadBind(&createContextProviderOnMainThread, | 579 crossThreadBind(&createContextProviderOnMainThread, |
| 581 crossThreadUnretained(&creationInfo), | 580 crossThreadUnretained(&creationInfo), |
| 582 crossThreadUnretained(&waitableEvent))); | 581 crossThreadUnretained(&waitableEvent))); |
| 583 waitableEvent.wait(); | 582 waitableEvent.wait(); |
| 584 return std::move(creationInfo.createdContextProvider); | 583 return std::move(creationInfo.createdContextProvider); |
| 585 } | 584 } |
| 586 | 585 |
| 587 std::unique_ptr<WebGraphicsContext3DProvider> | 586 std::unique_ptr<WebGraphicsContext3DProvider> |
| 588 WebGLRenderingContextBase::createContextProviderInternal( | 587 WebGLRenderingContextBase::createContextProviderInternal( |
| 589 HTMLCanvasElement* canvas, | 588 HTMLCanvasElement* canvas, |
| 590 ScriptState* scriptState, | 589 ScriptState* scriptState, |
| 591 const CanvasContextCreationAttributes& attributes, | 590 const CanvasContextCreationAttributes& attributes, |
| 592 unsigned webGLVersion) { | 591 unsigned webGLVersion) { |
| 593 // Exactly one of these must be provided. | 592 // Exactly one of these must be provided. |
| 594 DCHECK_EQ(!canvas, !!scriptState); | 593 DCHECK_EQ(!canvas, !!scriptState); |
| 595 // The canvas is only given on the main thread. | 594 // The canvas is only given on the main thread. |
| 596 DCHECK(!canvas || isMainThread()); | 595 DCHECK(!canvas || isMainThread()); |
| 597 | 596 |
| 598 Platform::ContextAttributes contextAttributes = | 597 Platform::ContextAttributes contextAttributes = |
| 599 toPlatformContextAttributes(attributes, webGLVersion); | 598 toPlatformContextAttributes(attributes, webGLVersion); |
| 600 Platform::GraphicsInfo glInfo; | 599 Platform::GraphicsInfo glInfo; |
| 601 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider; | 600 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider; |
| 601 const auto& url = canvas ? canvas->document().topDocument().url() |
| 602 : scriptState->getExecutionContext()->url(); |
| 602 if (isMainThread()) { | 603 if (isMainThread()) { |
| 603 const auto& url = canvas ? canvas->document().topDocument().url() | |
| 604 : scriptState->getExecutionContext()->url(); | |
| 605 contextProvider = wrapUnique( | 604 contextProvider = wrapUnique( |
| 606 Platform::current()->createOffscreenGraphicsContext3DProvider( | 605 Platform::current()->createOffscreenGraphicsContext3DProvider( |
| 607 contextAttributes, url, 0, &glInfo)); | 606 contextAttributes, url, 0, &glInfo)); |
| 608 } else { | 607 } else { |
| 609 contextProvider = createContextProviderOnWorkerThread(contextAttributes, | 608 contextProvider = |
| 610 &glInfo, scriptState); | 609 createContextProviderOnWorkerThread(contextAttributes, &glInfo, url); |
| 611 } | 610 } |
| 612 if (contextProvider && !contextProvider->bindToCurrentThread()) { | 611 if (contextProvider && !contextProvider->bindToCurrentThread()) { |
| 613 contextProvider = nullptr; | 612 contextProvider = nullptr; |
| 614 String errorString(glInfo.errorMessage.utf8().data()); | 613 String errorString(glInfo.errorMessage.utf8().data()); |
| 615 errorString.insert("bindToCurrentThread failed: ", 0); | 614 errorString.insert("bindToCurrentThread failed: ", 0); |
| 616 glInfo.errorMessage = errorString; | 615 glInfo.errorMessage = errorString; |
| 617 } | 616 } |
| 618 if (!contextProvider || shouldFailContextCreationForTesting) { | 617 if (!contextProvider || shouldFailContextCreationForTesting) { |
| 619 shouldFailContextCreationForTesting = false; | 618 shouldFailContextCreationForTesting = false; |
| 620 if (canvas) | 619 if (canvas) |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 ASSERT(contextProvider); | 1026 ASSERT(contextProvider); |
| 1028 | 1027 |
| 1029 m_contextGroup = WebGLContextGroup::create(); | 1028 m_contextGroup = WebGLContextGroup::create(); |
| 1030 m_contextGroup->addContext(this); | 1029 m_contextGroup->addContext(this); |
| 1031 | 1030 |
| 1032 m_maxViewportDims[0] = m_maxViewportDims[1] = 0; | 1031 m_maxViewportDims[0] = m_maxViewportDims[1] = 0; |
| 1033 contextProvider->contextGL()->GetIntegerv(GL_MAX_VIEWPORT_DIMS, | 1032 contextProvider->contextGL()->GetIntegerv(GL_MAX_VIEWPORT_DIMS, |
| 1034 m_maxViewportDims); | 1033 m_maxViewportDims); |
| 1035 | 1034 |
| 1036 RefPtr<DrawingBuffer> buffer; | 1035 RefPtr<DrawingBuffer> buffer; |
| 1036 // On Mac OS, DrawingBuffer is using an IOSurface as its backing storage, this |
| 1037 // allows WebGL-rendered canvases to be composited by the OS rather than |
| 1038 // Chrome. |
| 1039 // IOSurfaces are only compatible with the GL_TEXTURE_RECTANGLE_ARB binding |
| 1040 // target. So to avoid the knowledge of GL_TEXTURE_RECTANGLE_ARB type textures |
| 1041 // being introduced into more areas of the code, we use the code path of |
| 1042 // non-WebGLImageChromium for OffscreenCanvas. |
| 1043 // See detailed discussion in crbug.com/649668. |
| 1037 if (passedOffscreenCanvas) | 1044 if (passedOffscreenCanvas) |
| 1038 buffer = createDrawingBuffer(std::move(contextProvider), | 1045 buffer = createDrawingBuffer(std::move(contextProvider), |
| 1039 DrawingBuffer::DisallowChromiumImage); | 1046 DrawingBuffer::DisallowChromiumImage); |
| 1040 else | 1047 else |
| 1041 buffer = createDrawingBuffer(std::move(contextProvider), | 1048 buffer = createDrawingBuffer(std::move(contextProvider), |
| 1042 DrawingBuffer::AllowChromiumImage); | 1049 DrawingBuffer::AllowChromiumImage); |
| 1043 if (!buffer) { | 1050 if (!buffer) { |
| 1044 m_contextLostMode = SyntheticLostContext; | 1051 m_contextLostMode = SyntheticLostContext; |
| 1045 return; | 1052 return; |
| 1046 } | 1053 } |
| (...skipping 6235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7282 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason); | 7289 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason); |
| 7283 return false; | 7290 return false; |
| 7284 } | 7291 } |
| 7285 | 7292 |
| 7286 return true; | 7293 return true; |
| 7287 } | 7294 } |
| 7288 | 7295 |
| 7289 void WebGLRenderingContextBase::dispatchContextLostEvent(TimerBase*) { | 7296 void WebGLRenderingContextBase::dispatchContextLostEvent(TimerBase*) { |
| 7290 WebGLContextEvent* event = WebGLContextEvent::create( | 7297 WebGLContextEvent* event = WebGLContextEvent::create( |
| 7291 EventTypeNames::webglcontextlost, false, true, ""); | 7298 EventTypeNames::webglcontextlost, false, true, ""); |
| 7292 canvas()->dispatchEvent(event); | 7299 if (getOffscreenCanvas()) |
| 7300 getOffscreenCanvas()->dispatchEvent(event); |
| 7301 else |
| 7302 canvas()->dispatchEvent(event); |
| 7293 m_restoreAllowed = event->defaultPrevented(); | 7303 m_restoreAllowed = event->defaultPrevented(); |
| 7294 if (m_restoreAllowed && !m_isHidden) { | 7304 if (m_restoreAllowed && !m_isHidden) { |
| 7295 if (m_autoRecoveryMethod == Auto) | 7305 if (m_autoRecoveryMethod == Auto) |
| 7296 m_restoreTimer.startOneShot(0, BLINK_FROM_HERE); | 7306 m_restoreTimer.startOneShot(0, BLINK_FROM_HERE); |
| 7297 } | 7307 } |
| 7298 } | 7308 } |
| 7299 | 7309 |
| 7300 void WebGLRenderingContextBase::maybeRestoreContext(TimerBase*) { | 7310 void WebGLRenderingContextBase::maybeRestoreContext(TimerBase*) { |
| 7301 ASSERT(isContextLost()); | 7311 ASSERT(isContextLost()); |
| 7302 | 7312 |
| 7303 // The rendering context is not restored unless the default behavior of the | 7313 // The rendering context is not restored unless the default behavior of the |
| 7304 // webglcontextlost event was prevented earlier. | 7314 // webglcontextlost event was prevented earlier. |
| 7305 // | 7315 // |
| 7306 // Because of the way m_restoreTimer is set up for real vs. synthetic lost | 7316 // Because of the way m_restoreTimer is set up for real vs. synthetic lost |
| 7307 // context events, we don't have to worry about this test short-circuiting | 7317 // context events, we don't have to worry about this test short-circuiting |
| 7308 // the retry loop for real context lost events. | 7318 // the retry loop for real context lost events. |
| 7309 if (!m_restoreAllowed) | 7319 if (!m_restoreAllowed) |
| 7310 return; | 7320 return; |
| 7311 | 7321 |
| 7312 LocalFrame* frame = canvas()->document().frame(); | 7322 if (canvas()) { |
| 7313 if (!frame) | 7323 LocalFrame* frame = canvas()->document().frame(); |
| 7314 return; | 7324 if (!frame) |
| 7325 return; |
| 7315 | 7326 |
| 7316 Settings* settings = frame->settings(); | 7327 Settings* settings = frame->settings(); |
| 7317 | 7328 |
| 7318 if (!frame->loader().client()->allowWebGL(settings && | 7329 if (!frame->loader().client()->allowWebGL(settings && |
| 7319 settings->webGLEnabled())) | 7330 settings->webGLEnabled())) |
| 7320 return; | 7331 return; |
| 7332 } |
| 7321 | 7333 |
| 7322 // If the context was lost due to RealLostContext, we need to destroy the old | 7334 // If the context was lost due to RealLostContext, we need to destroy the old |
| 7323 // DrawingBuffer before creating new DrawingBuffer to ensure resource budget | 7335 // DrawingBuffer before creating new DrawingBuffer to ensure resource budget |
| 7324 // enough. | 7336 // enough. |
| 7325 if (drawingBuffer()) { | 7337 if (drawingBuffer()) { |
| 7326 m_drawingBuffer->beginDestruction(); | 7338 m_drawingBuffer->beginDestruction(); |
| 7327 m_drawingBuffer.clear(); | 7339 m_drawingBuffer.clear(); |
| 7328 } | 7340 } |
| 7329 | 7341 |
| 7330 Platform::ContextAttributes attributes = | 7342 Platform::ContextAttributes attributes = |
| 7331 toPlatformContextAttributes(creationAttributes(), version()); | 7343 toPlatformContextAttributes(creationAttributes(), version()); |
| 7332 Platform::GraphicsInfo glInfo; | 7344 Platform::GraphicsInfo glInfo; |
| 7333 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = | 7345 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider; |
| 7334 wrapUnique(Platform::current()->createOffscreenGraphicsContext3DProvider( | 7346 const auto& url = canvas() |
| 7335 attributes, canvas()->document().topDocument().url(), 0, &glInfo)); | 7347 ? canvas()->document().topDocument().url() |
| 7348 : getOffscreenCanvas()->getExecutionContext()->url(); |
| 7349 if (isMainThread()) { |
| 7350 contextProvider = wrapUnique( |
| 7351 Platform::current()->createOffscreenGraphicsContext3DProvider( |
| 7352 attributes, url, 0, &glInfo)); |
| 7353 } else { |
| 7354 contextProvider = |
| 7355 createContextProviderOnWorkerThread(attributes, &glInfo, url); |
| 7356 } |
| 7336 RefPtr<DrawingBuffer> buffer; | 7357 RefPtr<DrawingBuffer> buffer; |
| 7337 if (contextProvider && contextProvider->bindToCurrentThread()) { | 7358 if (contextProvider && contextProvider->bindToCurrentThread()) { |
| 7338 // Construct a new drawing buffer with the new GL context. | 7359 // Construct a new drawing buffer with the new GL context. |
| 7339 // TODO(xidachen): make sure that the second parameter is correct for | 7360 if (canvas()) { |
| 7340 // OffscreenCanvas. | 7361 buffer = createDrawingBuffer(std::move(contextProvider), |
| 7341 buffer = createDrawingBuffer(std::move(contextProvider), | 7362 DrawingBuffer::AllowChromiumImage); |
| 7342 DrawingBuffer::AllowChromiumImage); | 7363 } else { |
| 7364 // Please refer to comment at Line 1040 in this file. |
| 7365 buffer = createDrawingBuffer(std::move(contextProvider), |
| 7366 DrawingBuffer::DisallowChromiumImage); |
| 7367 } |
| 7343 // If DrawingBuffer::create() fails to allocate a fbo, |drawingBuffer| is | 7368 // If DrawingBuffer::create() fails to allocate a fbo, |drawingBuffer| is |
| 7344 // set to null. | 7369 // set to null. |
| 7345 } | 7370 } |
| 7346 if (!buffer) { | 7371 if (!buffer) { |
| 7347 if (m_contextLostMode == RealLostContext) { | 7372 if (m_contextLostMode == RealLostContext) { |
| 7348 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, | 7373 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, |
| 7349 BLINK_FROM_HERE); | 7374 BLINK_FROM_HERE); |
| 7350 } else { | 7375 } else { |
| 7351 // This likely shouldn't happen but is the best way to report it to the | 7376 // This likely shouldn't happen but is the best way to report it to the |
| 7352 // WebGL app. | 7377 // WebGL app. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 7363 drawingBuffer()->bind(GL_FRAMEBUFFER); | 7388 drawingBuffer()->bind(GL_FRAMEBUFFER); |
| 7364 m_lostContextErrors.clear(); | 7389 m_lostContextErrors.clear(); |
| 7365 m_contextLostMode = NotLostContext; | 7390 m_contextLostMode = NotLostContext; |
| 7366 m_autoRecoveryMethod = Manual; | 7391 m_autoRecoveryMethod = Manual; |
| 7367 m_restoreAllowed = false; | 7392 m_restoreAllowed = false; |
| 7368 removeFromEvictedList(this); | 7393 removeFromEvictedList(this); |
| 7369 | 7394 |
| 7370 setupFlags(); | 7395 setupFlags(); |
| 7371 initializeNewContext(); | 7396 initializeNewContext(); |
| 7372 markContextChanged(CanvasContextChanged); | 7397 markContextChanged(CanvasContextChanged); |
| 7373 canvas()->dispatchEvent(WebGLContextEvent::create( | 7398 WebGLContextEvent* event = WebGLContextEvent::create( |
| 7374 EventTypeNames::webglcontextrestored, false, true, "")); | 7399 EventTypeNames::webglcontextrestored, false, true, ""); |
| 7400 if (canvas()) |
| 7401 canvas()->dispatchEvent(event); |
| 7402 else |
| 7403 getOffscreenCanvas()->dispatchEvent(event); |
| 7375 } | 7404 } |
| 7376 | 7405 |
| 7377 String WebGLRenderingContextBase::ensureNotNull(const String& text) const { | 7406 String WebGLRenderingContextBase::ensureNotNull(const String& text) const { |
| 7378 if (text.isNull()) | 7407 if (text.isNull()) |
| 7379 return WTF::emptyString(); | 7408 return WTF::emptyString(); |
| 7380 return text; | 7409 return text; |
| 7381 } | 7410 } |
| 7382 | 7411 |
| 7383 WebGLRenderingContextBase::LRUImageBufferCache::LRUImageBufferCache( | 7412 WebGLRenderingContextBase::LRUImageBufferCache::LRUImageBufferCache( |
| 7384 int capacity) | 7413 int capacity) |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7660 | 7689 |
| 7661 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( | 7690 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( |
| 7662 HTMLCanvasElementOrOffscreenCanvas& result) const { | 7691 HTMLCanvasElementOrOffscreenCanvas& result) const { |
| 7663 if (canvas()) | 7692 if (canvas()) |
| 7664 result.setHTMLCanvasElement(canvas()); | 7693 result.setHTMLCanvasElement(canvas()); |
| 7665 else | 7694 else |
| 7666 result.setOffscreenCanvas(getOffscreenCanvas()); | 7695 result.setOffscreenCanvas(getOffscreenCanvas()); |
| 7667 } | 7696 } |
| 7668 | 7697 |
| 7669 } // namespace blink | 7698 } // namespace blink |
| OLD | NEW |