예제 #1
0
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);
}
예제 #2
0
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);
}