Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: Source/core/html/canvas/WebGLRenderingContext.cpp

Issue 14840015: Lose/restore WebGL contexts if multisampling blackist status changes at runtime. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Missed one of kbr's suggestions in previous patch Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/html/canvas/WebGLRenderingContext.h ('k') | Source/core/page/Page.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 advance(); 443 advance();
444 break; 444 break;
445 } 445 }
446 446
447 // Swallow all other characters. Unclear whether we may 447 // Swallow all other characters. Unclear whether we may
448 // want or need to just emit a space per character to try 448 // want or need to just emit a space per character to try
449 // to preserve column numbers for debugging purposes. 449 // to preserve column numbers for debugging purposes.
450 break; 450 break;
451 } 451 }
452 } 452 }
453
454 GraphicsContext3D::Attributes adjustAttributes(const GraphicsContext3D::Attr ibutes attributes, Settings* settings)
455 {
456 GraphicsContext3D::Attributes adjustedAttributes = attributes;
457 if (adjustedAttributes.antialias) {
458 if (settings && !settings->openGLMultisamplingEnabled())
459 adjustedAttributes.antialias = false;
460 }
461
462 return adjustedAttributes;
463 }
453 } // namespace anonymous 464 } // namespace anonymous
454 465
455 class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostC allback { 466 class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostC allback {
456 WTF_MAKE_FAST_ALLOCATED; 467 WTF_MAKE_FAST_ALLOCATED;
457 public: 468 public:
458 explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_co ntext(cb) { } 469 explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_co ntext(cb) { }
459 virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingCon text::RealLostContext); } 470 virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingCon text::RealLostContext); }
460 virtual ~WebGLRenderingContextLostCallback() {} 471 virtual ~WebGLRenderingContextLostCallback() {}
461 private: 472 private:
462 WebGLRenderingContext* m_context; 473 WebGLRenderingContext* m_context;
(...skipping 21 matching lines...) Expand all
484 return nullptr; 495 return nullptr;
485 Settings* settings = frame->settings(); 496 Settings* settings = frame->settings();
486 497
487 // The FrameLoaderClient might block creation of a new WebGL context despite the page settings; in 498 // The FrameLoaderClient might block creation of a new WebGL context despite the page settings; in
488 // particular, if WebGL contexts were lost one or more times via the GL_ARB_ robustness extension. 499 // particular, if WebGL contexts were lost one or more times via the GL_ARB_ robustness extension.
489 if (!frame->loader()->client()->allowWebGL(settings && settings->webGLEnable d())) { 500 if (!frame->loader()->client()->allowWebGL(settings && settings->webGLEnable d())) {
490 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Web page was not allowed to create a WebGL co ntext.")); 501 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Web page was not allowed to create a WebGL co ntext."));
491 return nullptr; 502 return nullptr;
492 } 503 }
493 504
494 GraphicsContext3D::Attributes attributes = attrs ? attrs->attributes() : Gra phicsContext3D::Attributes(); 505 GraphicsContext3D::Attributes requestedAttributes = attrs ? attrs->attribute s() : GraphicsContext3D::Attributes();
495 506 GraphicsContext3D::Attributes attributes = adjustAttributes(requestedAttribu tes, settings);
496 if (attributes.antialias) {
497 if (settings && !settings->openGLMultisamplingEnabled())
498 attributes.antialias = false;
499 }
500
501 attributes.noExtensions = true;
502 attributes.shareResources = true;
503 attributes.preferDiscreteGPU = true;
504 attributes.topDocumentURL = document->topDocument()->url();
505 507
506 RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes)); 508 RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes));
507 509
508 if (!context || !context->makeContextCurrent()) { 510 if (!context || !context->makeContextCurrent()) {
509 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Could not create a WebGL context.")); 511 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Could not create a WebGL context."));
510 return nullptr; 512 return nullptr;
511 } 513 }
512 514
513 Extensions3D* extensions = context->getExtensions(); 515 Extensions3D* extensions = context->getExtensions();
514 if (extensions->supports("GL_EXT_debug_marker")) 516 if (extensions->supports("GL_EXT_debug_marker"))
515 extensions->pushGroupMarkerEXT("WebGLRenderingContext"); 517 extensions->pushGroupMarkerEXT("WebGLRenderingContext");
516 518
517 OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRendering Context(canvas, context, attributes)); 519 OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRendering Context(canvas, context, attributes, requestedAttributes));
518 renderingContext->suspendIfNeeded(); 520 renderingContext->suspendIfNeeded();
519 521
520 if (renderingContext->m_drawingBuffer->isZeroSized()) { 522 if (renderingContext->m_drawingBuffer->isZeroSized()) {
521 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Could not create a WebGL context.")); 523 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Could not create a WebGL context."));
522 return nullptr; 524 return nullptr;
523 } 525 }
524 526
525 return renderingContext.release(); 527 return renderingContext.release();
526 } 528 }
527 529
528 WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa ssRefPtr<GraphicsContext3D> context, 530 WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa ssRefPtr<GraphicsContext3D> context, GraphicsContext3D::Attributes attributes, G raphicsContext3D::Attributes requestedAttributes)
529 GraphicsContext3D::Attributes attri butes)
530 : CanvasRenderingContext(passedCanvas) 531 : CanvasRenderingContext(passedCanvas)
531 , ActiveDOMObject(passedCanvas->document()) 532 , ActiveDOMObject(passedCanvas->document())
532 , m_context(context) 533 , m_context(context)
533 , m_drawingBuffer(0) 534 , m_drawingBuffer(0)
534 , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchCont extLostEvent) 535 , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchCont extLostEvent)
535 , m_restoreAllowed(false) 536 , m_restoreAllowed(false)
536 , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext) 537 , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext)
537 , m_videoCache(4) 538 , m_videoCache(4)
538 , m_contextLost(false) 539 , m_contextLost(false)
539 , m_contextLostMode(SyntheticLostContext) 540 , m_contextLostMode(SyntheticLostContext)
540 , m_attributes(attributes) 541 , m_attributes(attributes)
542 , m_requestedAttributes(requestedAttributes)
541 , m_synthesizedErrorsToConsole(true) 543 , m_synthesizedErrorsToConsole(true)
542 , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole) 544 , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
545 , m_multisamplingAllowed(false)
546 , m_multisamplingObserverHost(0)
543 { 547 {
544 ASSERT(m_context); 548 ASSERT(m_context);
545 ScriptWrappable::init(this); 549 ScriptWrappable::init(this);
546 550
547 m_contextGroup = WebGLContextGroup::create(); 551 m_contextGroup = WebGLContextGroup::create();
548 m_contextGroup->addContext(this); 552 m_contextGroup->addContext(this);
549 553
550 m_maxViewportDims[0] = m_maxViewportDims[1] = 0; 554 m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
551 m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDi ms); 555 m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDi ms);
552 556
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMe ssageCallback(this))); 642 m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMe ssageCallback(this)));
639 643
640 activateContext(this); 644 activateContext(this);
641 } 645 }
642 646
643 void WebGLRenderingContext::setupFlags() 647 void WebGLRenderingContext::setupFlags()
644 { 648 {
645 ASSERT(m_context); 649 ASSERT(m_context);
646 650
647 Page* p = canvas()->document()->page(); 651 Page* p = canvas()->document()->page();
648 if (p) 652 if (p) {
649 m_synthesizedErrorsToConsole = p->settings()->webGLErrorsToConsoleEnable d(); 653 m_synthesizedErrorsToConsole = p->settings()->webGLErrorsToConsoleEnable d();
650 654
655 if (!m_multisamplingObserverHost && m_requestedAttributes.antialias) {
656 m_multisamplingAllowed = m_drawingBuffer->multisample();
657 m_multisamplingObserverHost = p;
Ken Russell (switch to Gerrit) 2013/05/09 00:17:13 Is it necessary to cache the Page like this? Would
658 m_multisamplingObserverHost->addMultisamplingChangedObserver(this);
659 }
660 }
661
651 m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_OES_texture _npot"); 662 m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_OES_texture _npot");
652 m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_OES_pa cked_depth_stencil"); 663 m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_OES_pa cked_depth_stencil");
653 m_isRobustnessEXTSupported = m_context->getExtensions()->isEnabled("GL_EXT_r obustness"); 664 m_isRobustnessEXTSupported = m_context->getExtensions()->isEnabled("GL_EXT_r obustness");
654 } 665 }
655 666
656 bool WebGLRenderingContext::allowPrivilegedExtensions() const 667 bool WebGLRenderingContext::allowPrivilegedExtensions() const
657 { 668 {
658 Page* p = canvas()->document()->page(); 669 Page* p = canvas()->document()->page();
659 if (p && p->settings()) 670 if (p && p->settings())
660 return p->settings()->privilegedWebGLExtensionsEnabled(); 671 return p->settings()->privilegedWebGLExtensionsEnabled();
(...skipping 23 matching lines...) Expand all
684 m_textureUnits[i].m_textureCubeMapBinding = 0; 695 m_textureUnits[i].m_textureCubeMapBinding = 0;
685 } 696 }
686 697
687 m_blackTexture2D = 0; 698 m_blackTexture2D = 0;
688 m_blackTextureCubeMap = 0; 699 m_blackTextureCubeMap = 0;
689 700
690 detachAndRemoveAllObjects(); 701 detachAndRemoveAllObjects();
691 destroyGraphicsContext3D(); 702 destroyGraphicsContext3D();
692 m_contextGroup->removeContext(this); 703 m_contextGroup->removeContext(this);
693 704
705 if (m_multisamplingObserverHost)
706 m_multisamplingObserverHost->removeMultisamplingChangedObserver(this);
707
694 willDestroyContext(this); 708 willDestroyContext(this);
695 } 709 }
696 710
697 void WebGLRenderingContext::destroyGraphicsContext3D() 711 void WebGLRenderingContext::destroyGraphicsContext3D()
698 { 712 {
699 m_contextLost = true; 713 m_contextLost = true;
700 714
701 // The drawing buffer holds a context reference. It must also be destroyed 715 // The drawing buffer holds a context reference. It must also be destroyed
702 // in order for the context to be released. 716 // in order for the context to be released.
703 m_drawingBuffer->releaseResources(); 717 m_drawingBuffer->releaseResources();
(...skipping 4522 matching lines...) Expand 10 before | Expand all | Expand 10 after
5226 for (int ii = 0; ii < expectedSize; ++ii) 5240 for (int ii = 0; ii < expectedSize; ++ii)
5227 attribValue.value[ii] = v[ii]; 5241 attribValue.value[ii] = v[ii];
5228 } 5242 }
5229 5243
5230 void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext >*) 5244 void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext >*)
5231 { 5245 {
5232 RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().web glcontextlostEvent, false, true, ""); 5246 RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().web glcontextlostEvent, false, true, "");
5233 canvas()->dispatchEvent(event); 5247 canvas()->dispatchEvent(event);
5234 m_restoreAllowed = event->defaultPrevented(); 5248 m_restoreAllowed = event->defaultPrevented();
5235 deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAll owed); 5249 deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAll owed);
5236 if (m_contextLostMode == RealLostContext && m_restoreAllowed) 5250 if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecove rSyntheticLostContext) && m_restoreAllowed)
5237 m_restoreTimer.startOneShot(0); 5251 m_restoreTimer.startOneShot(0);
5238 } 5252 }
5239 5253
5240 void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*) 5254 void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*)
5241 { 5255 {
5242 ASSERT(isContextLost()); 5256 ASSERT(isContextLost());
5243 5257
5244 // The rendering context is not restored unless the default behavior of the 5258 // The rendering context is not restored unless the default behavior of the
5245 // webglcontextlost event was prevented earlier. 5259 // webglcontextlost event was prevented earlier.
5246 // 5260 //
5247 // Because of the way m_restoreTimer is set up for real vs. synthetic lost 5261 // Because of the way m_restoreTimer is set up for real vs. synthetic lost
5248 // context events, we don't have to worry about this test short-circuiting 5262 // context events, we don't have to worry about this test short-circuiting
5249 // the retry loop for real context lost events. 5263 // the retry loop for real context lost events.
5250 if (!m_restoreAllowed) 5264 if (!m_restoreAllowed)
5251 return; 5265 return;
5252 5266
5253 Document* document = canvas()->document(); 5267 Document* document = canvas()->document();
5254 if (!document) 5268 if (!document)
5255 return; 5269 return;
5256 Frame* frame = document->frame(); 5270 Frame* frame = document->frame();
5257 if (!frame) 5271 if (!frame)
5258 return; 5272 return;
5259 5273
5260 if (!frame->loader()->client()->allowWebGL(frame->settings() && frame->setti ngs()->webGLEnabled())) 5274 Settings* settings = frame->settings();
5275
5276 if (!frame->loader()->client()->allowWebGL(settings && settings->webGLEnable d()))
5261 return; 5277 return;
5262 5278
5279 // Reset the context attributes back to the requested attributes and re-appl y restrictions
5280 m_attributes = adjustAttributes(m_requestedAttributes, settings);
5281
5263 RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes)); 5282 RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes));
5283
5264 if (!context) { 5284 if (!context) {
5265 if (m_contextLostMode == RealLostContext) 5285 if (m_contextLostMode == RealLostContext)
5266 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts); 5286 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
5267 else 5287 else
5268 // This likely shouldn't happen but is the best way to report it to the WebGL app. 5288 // This likely shouldn't happen but is the best way to report it to the WebGL app.
5269 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error r estoring context"); 5289 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error r estoring context");
5270 return; 5290 return;
5271 } 5291 }
5272 5292
5273 RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptR ef(new WebGLRenderingContextEvictionManager()); 5293 RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptR ef(new WebGLRenderingContextEvictionManager());
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
5443 ExceptionCode ec; 5463 ExceptionCode ec;
5444 bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebufferBinding.get(), ec); 5464 bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebufferBinding.get(), ec);
5445 } 5465 }
5446 5466
5447 void WebGLRenderingContext::restoreCurrentTexture2D() 5467 void WebGLRenderingContext::restoreCurrentTexture2D()
5448 { 5468 {
5449 ExceptionCode ec; 5469 ExceptionCode ec;
5450 bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureUnits[m_activeTextureUni t].m_texture2DBinding.get(), ec); 5470 bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureUnits[m_activeTextureUni t].m_texture2DBinding.get(), ec);
5451 } 5471 }
5452 5472
5473 void WebGLRenderingContext::multisamplingChanged(bool enabled)
5474 {
5475 if (m_multisamplingAllowed != enabled) {
5476 m_multisamplingAllowed = enabled;
5477 forceLostContext(WebGLRenderingContext::AutoRecoverSyntheticLostContext) ;
5478 }
5479 }
5480
5453 } // namespace WebCore 5481 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/html/canvas/WebGLRenderingContext.h ('k') | Source/core/page/Page.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698