author | Imanol Fernandez <mortimergoro@gmail.com> |
Fri, 28 Sep 2018 19:25:21 +0000 | |
changeset 438719 | 9dbf3ababbfe6293e7f046f0a0d0e8e38aa157cf |
parent 438718 | 2d322a75865c81bf97ec7bf58725ba3c0a9c95e6 |
child 438720 | 4c34c45253ef2eb49b8f5a726d9c6c4e8eb56de5 |
push id | 34735 |
push user | aiakab@mozilla.com |
push date | Sat, 29 Sep 2018 04:15:27 +0000 |
treeherder | mozilla-central@669ffcf8bc71 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kip, jgilbert |
bugs | 1492554 |
milestone | 64.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/canvas/WebGLContext.cpp | file | annotate | diff | comparison | revisions | |
dom/canvas/WebGLContext.h | file | annotate | diff | comparison | revisions |
--- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -45,16 +45,17 @@ #include "nsIVariant.h" #include "nsIWidget.h" #include "nsIXPConnect.h" #include "nsServiceManagerUtils.h" #include "SVGObserverUtils.h" #include "prenv.h" #include "ScopedGLHelpers.h" #include "VRManagerChild.h" +#include "mozilla/layers/ImageBridgeChild.h" #include "mozilla/layers/TextureClientSharedSurface.h" #include "mozilla/layers/WebRenderUserData.h" #include "mozilla/layers/WebRenderCanvasRenderer.h" // Local #include "CanvasUtils.h" #include "WebGL1Context.h" #include "WebGLActiveInfo.h" @@ -77,20 +78,16 @@ #ifdef MOZ_WIDGET_COCOA #include "nsCocoaFeatures.h" #endif #ifdef XP_WIN #include "WGLLibrary.h" #endif -#if defined(MOZ_WIDGET_ANDROID) -#include "mozilla/layers/ImageBridgeChild.h" -#endif - // Generated #include "mozilla/dom/WebGLRenderingContextBinding.h" namespace mozilla { using namespace mozilla::dom; using namespace mozilla::gfx; @@ -140,16 +137,17 @@ WebGLContext::WebGLContext() mShouldPresent = true; mResetLayer = true; mOptionsFrozen = false; mDisableExtensions = false; mIsMesa = false; mEmitContextLostErrorOnce = false; mWebGLError = 0; mUnderlyingGLError = 0; + mVRReady = false; mContextLostErrorSet = false; mViewportX = 0; mViewportY = 0; mViewportWidth = 0; mViewportHeight = 0; @@ -1264,16 +1262,17 @@ WebGLContext::InitializeCanvasRenderer(n data.mGLContext = gl; data.mSize = DrawingBufferSize(); data.mHasAlpha = mOptions.alpha; data.mIsGLAlphaPremult = IsPremultAlpha() || !data.mHasAlpha; aRenderer->Initialize(data); aRenderer->SetDirty(); + mVRReady = true; return true; } layers::LayersBackend WebGLContext::GetCompositorBackendType() const { if (mCanvasElement) { return mCanvasElement->GetCompositorBackendType(); @@ -2302,16 +2301,18 @@ WebGLContext::GetUnpackSize(bool isFunc3 #if defined(MOZ_WIDGET_ANDROID) already_AddRefed<layers::SharedSurfaceTextureClient> WebGLContext::GetVRFrame() { if (!gl) return nullptr; + EnsureVRReady(); + // Create a custom GLScreenBuffer for VR. if (!mVRScreen) { auto caps = gl->Screen()->mCaps; mVRScreen = GLScreenBuffer::Create(gl, gfx::IntSize(1, 1), caps); RefPtr<ImageBridgeChild> imageBridge = ImageBridgeChild::GetSingleton(); if (imageBridge) { TextureFlags flags = TextureFlags::ORIGIN_BOTTOM_LEFT; @@ -2338,16 +2339,17 @@ WebGLContext::GetVRFrame() sharedSurface->Surf()->ProducerRelease(); return sharedSurface.forget(); } #else already_AddRefed<layers::SharedSurfaceTextureClient> WebGLContext::GetVRFrame() { + EnsureVRReady(); /** * Swap buffers as though composition has occurred. * We will then share the resulting front buffer to be submitted to the VR * compositor. */ BeginComposition(); EndComposition(); @@ -2362,16 +2364,45 @@ WebGLContext::GetVRFrame() if (!sharedSurface) return nullptr; return sharedSurface.forget(); } #endif // ifdefined(MOZ_WIDGET_ANDROID) +void +WebGLContext::EnsureVRReady() +{ + if (mVRReady) { + return; + } + + // Make not composited canvases work with WebVR. See bug #1492554 + // WebGLContext::InitializeCanvasRenderer is only called when the 2D compositor renders a WebGL canvas + // for the first time. This causes canvases not added to the DOM not to work properly with WebVR. + // Here we mimic what InitializeCanvasRenderer does internally as a workaround. + const auto imageBridge = ImageBridgeChild::GetSingleton(); + if (imageBridge) { + const auto caps = gl->Screen()->mCaps; + auto flags = TextureFlags::ORIGIN_BOTTOM_LEFT; + if (!IsPremultAlpha() && mOptions.alpha) { + flags |= TextureFlags::NON_PREMULTIPLIED; + } + auto factory = gl::GLScreenBuffer::CreateFactory(gl, caps, imageBridge.get(), flags); + gl->Screen()->Morph(std::move(factory)); +#if defined(MOZ_WIDGET_ANDROID) + // On Android we are using a different GLScreenBuffer for WebVR, so we need a resize here because + // PresentScreenBuffer() may not be called for the gl->Screen() after we set the new factory. + gl->Screen()->Resize(DrawingBufferSize()); +#endif + mVRReady = true; + } +} + //////////////////////////////////////////////////////////////////////////////// static inline size_t SizeOfViewElem(const dom::ArrayBufferView& view) { const auto& elemType = view.Type(); if (elemType == js::Scalar::MaxTypedArrayViewType) // DataViews. return 1;
--- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -692,16 +692,17 @@ public: bool IsVertexArray(const WebGLVertexArray* obj); void LineWidth(GLfloat width); void LinkProgram(WebGLProgram& prog); void PixelStorei(GLenum pname, GLint param); void PolygonOffset(GLfloat factor, GLfloat units); already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame(); + void EnsureVRReady(); //// webgl::PackingInfo ValidImplementationColorReadPI(const webgl::FormatUsageInfo* usage) const; protected: bool ReadPixels_SharedPrecheck(dom::CallerType aCallerType, @@ -1483,16 +1484,17 @@ protected: bool mOptionsFrozen; bool mDisableExtensions; bool mIsMesa; bool mLoseContextOnMemoryPressure; bool mCanLoseContextInForeground; bool mRestoreWhenVisible; bool mShouldPresent; bool mDisableFragHighP; + bool mVRReady; template<typename WebGLObjectType> void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array); GLuint mActiveTexture = 0; GLenum mDefaultFB_DrawBuffer0 = 0; GLenum mDefaultFB_ReadBuffer = 0;