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 |