Maybe<wr::WrImageMask> WebRenderImageLayer::RenderMaskLayer(const StackingContextHelper& aSc, const gfx::Matrix4x4& aTransform) { if (!mContainer) { return Nothing(); } CompositableType type = GetImageClientType(); if (type == CompositableType::UNKNOWN) { return Nothing(); } MOZ_ASSERT(GetImageClientType() == CompositableType::IMAGE); if (GetImageClientType() != CompositableType::IMAGE) { return Nothing(); } if (!mImageClient) { mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE, WrBridge(), TextureFlags::DEFAULT); if (!mImageClient) { return Nothing(); } mImageClient->Connect(); } if (mExternalImageId.isNothing()) { mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient)); } AutoLockImage autoLock(mContainer); Image* image = autoLock.GetImage(); if (!image) { return Nothing(); } MOZ_ASSERT(mImageClient->AsImageClientSingle()); mKey = UpdateImageKey(mImageClient->AsImageClientSingle(), mContainer, mKey, mExternalImageId.ref()); if (mKey.isNothing()) { return Nothing(); } gfx::IntSize size = image->GetSize(); wr::WrImageMask imageMask; imageMask.image = mKey.value(); Rect maskRect = aTransform.TransformBounds(Rect(0, 0, size.width, size.height)); imageMask.rect = aSc.ToRelativeLayoutRect(ViewAs<LayerPixel>(maskRect)); imageMask.repeat = false; return Some(imageMask); }
void CompositorOGL::DrawVRDistortion(const gfx::Rect& aRect, const gfx::Rect& aClipRect, const EffectChain& aEffectChain, gfx::Float aOpacity, const gfx::Matrix4x4& aTransform) { MOZ_ASSERT(aEffectChain.mPrimaryEffect->mType == EffectTypes::VR_DISTORTION); MOZ_ASSERT(mVR.mInitialized); if (aEffectChain.mSecondaryEffects[EffectTypes::MASK] || aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE]) { NS_WARNING("DrawVRDistortion: ignoring secondary effect!"); } EffectVRDistortion* vrEffect = static_cast<EffectVRDistortion*>(aEffectChain.mPrimaryEffect.get()); GLenum textureTarget = LOCAL_GL_TEXTURE_2D; if (vrEffect->mRenderTarget) textureTarget = mFBOTextureTarget; RefPtr<CompositingRenderTargetOGL> surface = static_cast<CompositingRenderTargetOGL*>(vrEffect->mRenderTarget.get()); VRHMDInfo* hmdInfo = vrEffect->mHMD; VRDistortionConstants shaderConstants; if (hmdInfo->GetConfiguration() != mVR.mConfiguration) { for (uint32_t eye = 0; eye < 2; eye++) { const gfx::VRDistortionMesh& mesh = hmdInfo->GetDistortionMesh(eye); gl()->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mVR.mDistortionVertices[eye]); gl()->fBufferData(LOCAL_GL_ARRAY_BUFFER, mesh.mVertices.Length() * sizeof(gfx::VRDistortionVertex), mesh.mVertices.Elements(), LOCAL_GL_STATIC_DRAW); gl()->fBindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, mVR.mDistortionIndices[eye]); gl()->fBufferData(LOCAL_GL_ELEMENT_ARRAY_BUFFER, mesh.mIndices.Length() * sizeof(uint16_t), mesh.mIndices.Elements(), LOCAL_GL_STATIC_DRAW); mVR.mDistortionIndexCount[eye] = mesh.mIndices.Length(); } mVR.mConfiguration = hmdInfo->GetConfiguration(); } int programIndex = textureTarget == LOCAL_GL_TEXTURE_2D ? 0 : 1; gl()->fScissor(aClipRect.x, FlipY(aClipRect.y + aClipRect.height), aClipRect.width, aClipRect.height); // Clear out the entire area that we want to render; this ensures that // the layer will be opaque, even though the mesh geometry we'll be // drawing below won't cover the full rectangle. gl()->fClearColor(0.0, 0.0, 0.0, 1.0); gl()->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT); // Make sure that the cached current program is reset for the // rest of the compositor, since we're using a custom program here ResetProgram(); gl()->fUseProgram(mVR.mDistortionProgram[programIndex]); gl()->fEnableVertexAttribArray(mVR.mAPosition); gl()->fEnableVertexAttribArray(mVR.mATexCoord0); gl()->fEnableVertexAttribArray(mVR.mATexCoord1); gl()->fEnableVertexAttribArray(mVR.mATexCoord2); gl()->fEnableVertexAttribArray(mVR.mAGenericAttribs); surface->BindTexture(LOCAL_GL_TEXTURE0, mFBOTextureTarget); gl()->fUniform1i(mVR.mUTexture[programIndex], 0); Rect destRect = aTransform.TransformBounds(aRect); gfx::IntSize preDistortionSize = surface->GetInitSize(); // XXX source->GetSize() gfx::Size vpSize = destRect.Size(); for (uint32_t eye = 0; eye < 2; eye++) { gfx::IntRect eyeViewport; eyeViewport.x = eye * preDistortionSize.width / 2; eyeViewport.y = 0; eyeViewport.width = preDistortionSize.width / 2; eyeViewport.height = preDistortionSize.height; hmdInfo->FillDistortionConstants(eye, preDistortionSize, eyeViewport, vpSize, destRect, shaderConstants); float height = 1.0f; float texScaleAndOffset[4] = { shaderConstants.eyeToSourceScaleAndOffset[0], shaderConstants.eyeToSourceScaleAndOffset[1], shaderConstants.eyeToSourceScaleAndOffset[2], shaderConstants.eyeToSourceScaleAndOffset[3] }; if (textureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) { texScaleAndOffset[0] *= preDistortionSize.width; texScaleAndOffset[1] *= preDistortionSize.height; texScaleAndOffset[2] *= preDistortionSize.width; texScaleAndOffset[3] *= preDistortionSize.height; height = preDistortionSize.height; } gl()->fUniform4fv(mVR.mUVRDestionatinScaleAndOffset[programIndex], 1, shaderConstants.destinationScaleAndOffset); gl()->fUniform4fv(mVR.mUVREyeToSource[programIndex], 1, texScaleAndOffset); gl()->fUniform1f(mVR.mUHeight[programIndex], height); gl()->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mVR.mDistortionVertices[eye]); /* This is for Oculus DistortionVertex */ gl()->fVertexAttribPointer(mVR.mAPosition, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), (void*) (sizeof(float) * 0)); gl()->fVertexAttribPointer(mVR.mATexCoord0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), (void*) (sizeof(float) * 2)); gl()->fVertexAttribPointer(mVR.mATexCoord1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), (void*) (sizeof(float) * 4)); gl()->fVertexAttribPointer(mVR.mATexCoord2, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), (void*) (sizeof(float) * 6)); gl()->fVertexAttribPointer(mVR.mAGenericAttribs, 4, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), (void*) (sizeof(float) * 8)); gl()->fBindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, mVR.mDistortionIndices[eye]); gl()->fDrawElements(LOCAL_GL_TRIANGLES, mVR.mDistortionIndexCount[eye], LOCAL_GL_UNSIGNED_SHORT, 0); } // Not clear if I should disable all of this; but going to do it and hope that // any later code will enable what it needs. gl()->fDisableVertexAttribArray(mVR.mAPosition); gl()->fDisableVertexAttribArray(mVR.mATexCoord0); gl()->fDisableVertexAttribArray(mVR.mATexCoord1); gl()->fDisableVertexAttribArray(mVR.mATexCoord2); gl()->fDisableVertexAttribArray(mVR.mAGenericAttribs); }