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

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: Changed to a more generic SettingsChangedObserver 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
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(GraphicsContext3D::Attributes attributes, Settings* settings) {
455 if (attributes.antialias) {
456 if (settings && !settings->openGLMultisamplingEnabled())
457 attributes.antialias = false;
458 }
459
460 return attributes;
461 }
453 } // namespace anonymous 462 } // namespace anonymous
454 463
455 class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostC allback { 464 class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostC allback {
456 WTF_MAKE_FAST_ALLOCATED; 465 WTF_MAKE_FAST_ALLOCATED;
457 public: 466 public:
458 explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_co ntext(cb) { } 467 explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_co ntext(cb) { }
459 virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingCon text::RealLostContext); } 468 virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingCon text::RealLostContext); }
460 virtual ~WebGLRenderingContextLostCallback() {} 469 virtual ~WebGLRenderingContextLostCallback() {}
461 private: 470 private:
462 WebGLRenderingContext* m_context; 471 WebGLRenderingContext* m_context;
(...skipping 22 matching lines...) Expand all
485 Settings* settings = frame->settings(); 494 Settings* settings = frame->settings();
486 495
487 // The FrameLoaderClient might block creation of a new WebGL context despite the page settings; in 496 // 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. 497 // 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())) { 498 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.")); 499 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Web page was not allowed to create a WebGL co ntext."));
491 return nullptr; 500 return nullptr;
492 } 501 }
493 502
494 HostWindow* hostWindow = document->view()->root()->hostWindow(); 503 HostWindow* hostWindow = document->view()->root()->hostWindow();
495 GraphicsContext3D::Attributes attributes = attrs ? attrs->attributes() : Gra phicsContext3D::Attributes(); 504 GraphicsContext3D::Attributes requestedAttributes = attrs ? attrs->attribute s() : GraphicsContext3D::Attributes();
505 requestedAttributes.noExtensions = true;
506 requestedAttributes.shareResources = true;
507 requestedAttributes.preferDiscreteGPU = true;
508 requestedAttributes.topDocumentURL = document->topDocument()->url();
496 509
497 if (attributes.antialias) { 510 GraphicsContext3D::Attributes attributes = adjustAttributes(requestedAttribu tes, settings);
498 if (settings && !settings->openGLMultisamplingEnabled())
499 attributes.antialias = false;
500 }
501
502 attributes.noExtensions = true;
503 attributes.shareResources = true;
504 attributes.preferDiscreteGPU = true;
505 attributes.topDocumentURL = document->topDocument()->url();
506 511
507 RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes, host Window)); 512 RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes, host Window));
508 513
509 if (!context || !context->makeContextCurrent()) { 514 if (!context || !context->makeContextCurrent()) {
510 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Could not create a WebGL context.")); 515 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Could not create a WebGL context."));
511 return nullptr; 516 return nullptr;
512 } 517 }
513 518
514 Extensions3D* extensions = context->getExtensions(); 519 Extensions3D* extensions = context->getExtensions();
515 if (extensions->supports("GL_EXT_debug_marker")) 520 if (extensions->supports("GL_EXT_debug_marker"))
516 extensions->pushGroupMarkerEXT("WebGLRenderingContext"); 521 extensions->pushGroupMarkerEXT("WebGLRenderingContext");
517 522
518 OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRendering Context(canvas, context, attributes)); 523 OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRendering Context(canvas, context, attributes, requestedAttributes));
519 renderingContext->suspendIfNeeded(); 524 renderingContext->suspendIfNeeded();
520 525
521 if (renderingContext->m_drawingBuffer->isZeroSized()) { 526 if (renderingContext->m_drawingBuffer->isZeroSized()) {
522 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Could not create a WebGL context.")); 527 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Could not create a WebGL context."));
523 return nullptr; 528 return nullptr;
524 } 529 }
525 530
526 return renderingContext.release(); 531 return renderingContext.release();
527 } 532 }
528 533
529 WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa ssRefPtr<GraphicsContext3D> context, 534 WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa ssRefPtr<GraphicsContext3D> context,
530 GraphicsContext3D::Attributes attri butes) 535 GraphicsContext3D::Attributes attri butes,
536 GraphicsContext3D::Attributes reque stedAttributes)
531 : CanvasRenderingContext(passedCanvas) 537 : CanvasRenderingContext(passedCanvas)
532 , ActiveDOMObject(passedCanvas->document()) 538 , ActiveDOMObject(passedCanvas->document())
533 , m_context(context) 539 , m_context(context)
534 , m_drawingBuffer(0) 540 , m_drawingBuffer(0)
535 , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchCont extLostEvent) 541 , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchCont extLostEvent)
536 , m_restoreAllowed(false) 542 , m_restoreAllowed(false)
537 , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext) 543 , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext)
538 , m_videoCache(4) 544 , m_videoCache(4)
539 , m_contextLost(false) 545 , m_contextLost(false)
540 , m_contextLostMode(SyntheticLostContext) 546 , m_contextLostMode(SyntheticLostContext)
541 , m_attributes(attributes) 547 , m_attributes(attributes)
548 , m_requestedAttributes(requestedAttributes)
542 , m_synthesizedErrorsToConsole(true) 549 , m_synthesizedErrorsToConsole(true)
543 , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole) 550 , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
544 { 551 {
545 ASSERT(m_context); 552 ASSERT(m_context);
546 ScriptWrappable::init(this); 553 ScriptWrappable::init(this);
547 554
548 m_contextGroup = WebGLContextGroup::create(); 555 m_contextGroup = WebGLContextGroup::create();
549 m_contextGroup->addContext(this); 556 m_contextGroup->addContext(this);
550 557
551 m_maxViewportDims[0] = m_maxViewportDims[1] = 0; 558 m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMe ssageCallback(this))); 646 m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMe ssageCallback(this)));
640 647
641 activateContext(this); 648 activateContext(this);
642 } 649 }
643 650
644 void WebGLRenderingContext::setupFlags() 651 void WebGLRenderingContext::setupFlags()
645 { 652 {
646 ASSERT(m_context); 653 ASSERT(m_context);
647 654
648 Page* p = canvas()->document()->page(); 655 Page* p = canvas()->document()->page();
649 if (p) 656 if (p) {
650 m_synthesizedErrorsToConsole = p->settings()->webGLErrorsToConsoleEnable d(); 657 m_synthesizedErrorsToConsole = p->settings()->webGLErrorsToConsoleEnable d();
651 658
659 if (m_settingsChangedObserver == 0) {
660 m_settingsChangedObserver = adoptRef(new WebGLSettingsChangedObserve r(this, p));
661 p->addSettingsChangedObserver(m_settingsChangedObserver.get());
662 }
663 }
664
652 m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_OES_texture _npot"); 665 m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_OES_texture _npot");
653 m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_OES_pa cked_depth_stencil"); 666 m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_OES_pa cked_depth_stencil");
654 m_isRobustnessEXTSupported = m_context->getExtensions()->isEnabled("GL_EXT_r obustness"); 667 m_isRobustnessEXTSupported = m_context->getExtensions()->isEnabled("GL_EXT_r obustness");
655 } 668 }
656 669
657 bool WebGLRenderingContext::allowPrivilegedExtensions() const 670 bool WebGLRenderingContext::allowPrivilegedExtensions() const
658 { 671 {
659 Page* p = canvas()->document()->page(); 672 Page* p = canvas()->document()->page();
660 if (p && p->settings()) 673 if (p && p->settings())
661 return p->settings()->privilegedWebGLExtensionsEnabled(); 674 return p->settings()->privilegedWebGLExtensionsEnabled();
(...skipping 4575 matching lines...) Expand 10 before | Expand all | Expand 10 after
5237 for (int ii = 0; ii < expectedSize; ++ii) 5250 for (int ii = 0; ii < expectedSize; ++ii)
5238 attribValue.value[ii] = v[ii]; 5251 attribValue.value[ii] = v[ii];
5239 } 5252 }
5240 5253
5241 void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext >*) 5254 void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext >*)
5242 { 5255 {
5243 RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().web glcontextlostEvent, false, true, ""); 5256 RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().web glcontextlostEvent, false, true, "");
5244 canvas()->dispatchEvent(event); 5257 canvas()->dispatchEvent(event);
5245 m_restoreAllowed = event->defaultPrevented(); 5258 m_restoreAllowed = event->defaultPrevented();
5246 deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAll owed); 5259 deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAll owed);
5247 if (m_contextLostMode == RealLostContext && m_restoreAllowed) 5260 if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecove rSyntheticLostContext) && m_restoreAllowed)
5248 m_restoreTimer.startOneShot(0); 5261 m_restoreTimer.startOneShot(0);
5249 } 5262 }
5250 5263
5251 void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*) 5264 void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*)
5252 { 5265 {
5253 ASSERT(isContextLost()); 5266 ASSERT(isContextLost());
5254 5267
5255 // The rendering context is not restored unless the default behavior of the 5268 // The rendering context is not restored unless the default behavior of the
5256 // webglcontextlost event was prevented earlier. 5269 // webglcontextlost event was prevented earlier.
5257 // 5270 //
5258 // Because of the way m_restoreTimer is set up for real vs. synthetic lost 5271 // Because of the way m_restoreTimer is set up for real vs. synthetic lost
5259 // context events, we don't have to worry about this test short-circuiting 5272 // context events, we don't have to worry about this test short-circuiting
5260 // the retry loop for real context lost events. 5273 // the retry loop for real context lost events.
5261 if (!m_restoreAllowed) 5274 if (!m_restoreAllowed)
5262 return; 5275 return;
5263 5276
5264 Document* document = canvas()->document(); 5277 Document* document = canvas()->document();
5265 if (!document) 5278 if (!document)
5266 return; 5279 return;
5267 Frame* frame = document->frame(); 5280 Frame* frame = document->frame();
5268 if (!frame) 5281 if (!frame)
5269 return; 5282 return;
5270 5283
5271 if (!frame->loader()->client()->allowWebGL(frame->settings() && frame->setti ngs()->webGLEnabled())) 5284 Settings* settings = frame->settings();
5285
5286 if (!frame->loader()->client()->allowWebGL(settings && settings->webGLEnable d()))
5272 return; 5287 return;
5273 5288
5274 FrameView* view = frame->view(); 5289 FrameView* view = frame->view();
5275 if (!view) 5290 if (!view)
5276 return; 5291 return;
5277 ScrollView* root = view->root(); 5292 ScrollView* root = view->root();
5278 if (!root) 5293 if (!root)
5279 return; 5294 return;
5280 HostWindow* hostWindow = root->hostWindow(); 5295 HostWindow* hostWindow = root->hostWindow();
5281 if (!hostWindow) 5296 if (!hostWindow)
5282 return; 5297 return;
5283 5298
5299 // Reset the context attributes back to the requested attributes and re-appl y restrictions
5300 m_attributes = adjustAttributes(m_requestedAttributes, settings);
5301
5284 RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, ho stWindow)); 5302 RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, ho stWindow));
5285 if (!context) { 5303 if (!context) {
5286 if (m_contextLostMode == RealLostContext) 5304 if (m_contextLostMode == RealLostContext)
5287 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts); 5305 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
5288 else 5306 else
5289 // This likely shouldn't happen but is the best way to report it to the WebGL app. 5307 // This likely shouldn't happen but is the best way to report it to the WebGL app.
5290 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error r estoring context"); 5308 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error r estoring context");
5291 return; 5309 return;
5292 } 5310 }
5293 5311
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
5464 ExceptionCode ec; 5482 ExceptionCode ec;
5465 bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebufferBinding.get(), ec); 5483 bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebufferBinding.get(), ec);
5466 } 5484 }
5467 5485
5468 void WebGLRenderingContext::restoreCurrentTexture2D() 5486 void WebGLRenderingContext::restoreCurrentTexture2D()
5469 { 5487 {
5470 ExceptionCode ec; 5488 ExceptionCode ec;
5471 bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureUnits[m_activeTextureUni t].m_texture2DBinding.get(), ec); 5489 bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureUnits[m_activeTextureUni t].m_texture2DBinding.get(), ec);
5472 } 5490 }
5473 5491
5492 WebGLRenderingContext::WebGLSettingsChangedObserver::WebGLSettingsChangedObserve r(WebGLRenderingContext* context, Page* page)
5493 : m_context(context)
5494 , m_page(page)
5495 {
5496 m_multisamplingAllowed = m_context->getContextAttributes()->antialias();
5497 }
5498
5499 void WebGLRenderingContext::WebGLSettingsChangedObserver::settingsChanged(Settin gs* settings)
5500 {
5501 bool enabled = settings->openGLMultisamplingEnabled();
5502 if(m_multisamplingAllowed != enabled) {
abarth-chromium 2013/05/06 21:58:30 nit: missing a space after "if"
Ken Russell (switch to Gerrit) 2013/05/06 22:12:22 The logic here doesn't seem right. If the app didn
bajones 2013/05/06 22:44:14 Good point. I should be able to do that without to
5503 m_multisamplingAllowed = enabled;
5504 m_context->forceLostContext(WebGLRenderingContext::AutoRecoverSyntheticL ostContext);
5505 }
5506 }
5507
5508 WebGLRenderingContext::WebGLSettingsChangedObserver::~WebGLSettingsChangedObserv er()
5509 {
5510 m_page->removeSettingsChangedObserver(this);
5511 }
5512
5474 } // namespace WebCore 5513 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698