예제 #1
0
/**
 * Recover the z component from a 2d transformed point by finding the intersection
 * of a line through the point in the z direction and the transformed plane.
 *
 * We want to solve:
 *
 * point = normal . (p0 - l0) / normal . l
 */
static gfxFloat RecoverZDepth(const gfx3DMatrix& aTransform, const gfxPoint& aPoint)
{
    const gfxPoint3D l(0, 0, 1);
    gfxPoint3D l0 = gfxPoint3D(aPoint.x, aPoint.y, 0);
    gfxPoint3D p0 = aTransform.Transform3D(gfxPoint3D(0, 0, 0));
    gfxPoint3D normal = aTransform.GetNormalVector();

    gfxFloat n = normal.DotProduct(p0 - l0); 
    gfxFloat d = normal.DotProduct(l);

    if (!d) {
        return 0;
    }

    return n/d;
}
static void
SampleValue(float aPortion, Animation& aAnimation, nsStyleAnimation::Value& aStart,
            nsStyleAnimation::Value& aEnd, Animatable* aValue)
{
  nsStyleAnimation::Value interpolatedValue;
  NS_ASSERTION(aStart.GetUnit() == aEnd.GetUnit() ||
               aStart.GetUnit() == nsStyleAnimation::eUnit_None ||
               aEnd.GetUnit() == nsStyleAnimation::eUnit_None, "Must have same unit");
  nsStyleAnimation::Interpolate(aAnimation.property(), aStart, aEnd,
                                aPortion, interpolatedValue);
  if (aAnimation.property() == eCSSProperty_opacity) {
    *aValue = interpolatedValue.GetFloatValue();
    return;
  }

  nsCSSValueList* interpolatedList = interpolatedValue.GetCSSValueListValue();

  TransformData& data = aAnimation.data().get_TransformData();
  nsPoint origin = data.origin();
  // we expect all our transform data to arrive in css pixels, so here we must
  // adjust to dev pixels.
  double cssPerDev = double(nsDeviceContext::AppUnitsPerCSSPixel())
                     / double(data.appUnitsPerDevPixel());
  gfxPoint3D mozOrigin = data.mozOrigin();
  mozOrigin.x = mozOrigin.x * cssPerDev;
  mozOrigin.y = mozOrigin.y * cssPerDev;
  gfxPoint3D perspectiveOrigin = data.perspectiveOrigin();
  perspectiveOrigin.x = perspectiveOrigin.x * cssPerDev;
  perspectiveOrigin.y = perspectiveOrigin.y * cssPerDev;
  nsDisplayTransform::FrameTransformProperties props(interpolatedList,
                                                     mozOrigin,
                                                     perspectiveOrigin,
                                                     data.perspective());
  gfx3DMatrix transform =
    nsDisplayTransform::GetResultingTransformMatrix(props, origin,
                                                    data.appUnitsPerDevPixel(),
                                                    &data.bounds());
  gfxPoint3D scaledOrigin =
    gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(origin.x, data.appUnitsPerDevPixel())),
               NS_round(NSAppUnitsToFloatPixels(origin.y, data.appUnitsPerDevPixel())),
               0.0f);

  transform.Translate(scaledOrigin);

  InfallibleTArray<TransformFunction> functions;
  functions.AppendElement(TransformMatrix(transform));
  *aValue = functions;
}
bool
LayerTransactionParent::RecvGetTransform(PLayerParent* aParent,
                                         gfx3DMatrix* aTransform)
{
  if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
    return false;
  }

  // The following code recovers the untranslated transform
  // from the shadow transform by undoing the translations in
  // AsyncCompositionManager::SampleValue.
  Layer* layer = cast(aParent)->AsLayer();
  if (!layer) {
    return false;
  }
  gfx::To3DMatrix(layer->AsLayerComposite()->GetShadowTransform(), *aTransform);
  if (ContainerLayer* c = layer->AsContainerLayer()) {
    aTransform->ScalePost(1.0f/c->GetInheritedXScale(),
                          1.0f/c->GetInheritedYScale(),
                          1.0f);
  }
  float scale = 1;
  gfxPoint3D scaledOrigin;
  gfxPoint3D transformOrigin;
  for (uint32_t i=0; i < layer->GetAnimations().Length(); i++) {
    if (layer->GetAnimations()[i].data().type() == AnimationData::TTransformData) {
      const TransformData& data = layer->GetAnimations()[i].data().get_TransformData();
      scale = data.appUnitsPerDevPixel();
      scaledOrigin =
        gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(data.origin().x, scale)),
                   NS_round(NSAppUnitsToFloatPixels(data.origin().y, scale)),
                   0.0f);
      transformOrigin = data.transformOrigin();
      break;
    }
  }

  aTransform->Translate(-scaledOrigin);
  *aTransform = nsLayoutUtils::ChangeMatrixBasis(-scaledOrigin - transformOrigin, *aTransform);
  return true;
}
예제 #4
0
bool
LayerTransactionParent::RecvGetAnimationTransform(PLayerParent* aParent,
                                                  MaybeTransform* aTransform)
{
  if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
    return false;
  }

  Layer* layer = cast(aParent)->AsLayer();
  if (!layer) {
    return false;
  }

  // This method is specific to transforms applied by animation.
  // This is because this method uses the information stored with an animation
  // such as the origin of the reference frame corresponding to the layer, to
  // recover the untranslated transform from the shadow transform. For
  // transforms that are not set by animation we don't have this information
  // available.
  if (!layer->AsLayerComposite()->GetShadowTransformSetByAnimation()) {
    *aTransform = mozilla::void_t();
    return true;
  }

  // The following code recovers the untranslated transform
  // from the shadow transform by undoing the translations in
  // AsyncCompositionManager::SampleValue.

  Matrix4x4 transform = layer->AsLayerComposite()->GetShadowTransform();
  if (ContainerLayer* c = layer->AsContainerLayer()) {
    // Undo the scale transform applied by AsyncCompositionManager::SampleValue
    transform.ScalePost(1.0f/c->GetInheritedXScale(),
                        1.0f/c->GetInheritedYScale(),
                        1.0f);
  }
  float scale = 1;
  gfxPoint3D scaledOrigin;
  gfxPoint3D transformOrigin;
  for (uint32_t i=0; i < layer->GetAnimations().Length(); i++) {
    if (layer->GetAnimations()[i].data().type() == AnimationData::TTransformData) {
      const TransformData& data = layer->GetAnimations()[i].data().get_TransformData();
      scale = data.appUnitsPerDevPixel();
      scaledOrigin =
        gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(data.origin().x, scale)),
                   NS_round(NSAppUnitsToFloatPixels(data.origin().y, scale)),
                   0.0f);
      double cssPerDev =
        double(nsDeviceContext::AppUnitsPerCSSPixel()) / double(scale);
      transformOrigin = data.transformOrigin() * cssPerDev;
      break;
    }
  }

  // Undo the translation to the origin of the reference frame applied by
  // AsyncCompositionManager::SampleValue
  transform.Translate(-scaledOrigin.x, -scaledOrigin.y, -scaledOrigin.z);

  // Undo the rebasing applied by
  // nsDisplayTransform::GetResultingTransformMatrixInternal
  gfxPoint3D basis = -scaledOrigin - transformOrigin;
  transform.ChangeBasis(basis.x, basis.y, basis.z);

  // Convert to CSS pixels (this undoes the operations performed by
  // nsStyleTransformMatrix::ProcessTranslatePart which is called from
  // nsDisplayTransform::GetResultingTransformMatrix)
  double devPerCss =
    double(scale) / double(nsDeviceContext::AppUnitsPerCSSPixel());
  transform._41 *= devPerCss;
  transform._42 *= devPerCss;
  transform._43 *= devPerCss;

  *aTransform = transform;
  return true;
}
void 
LayerPropertiesBase::MoveBy(const nsIntPoint& aOffset)
{
  mTransform.TranslatePost(gfxPoint3D(aOffset.x, aOffset.y, 0)); 
}
예제 #6
0
void
ThebesLayerD3D10::FillTexturesBlackWhite(const nsIntRegion& aRegion, const nsIntPoint& aOffset)
{
  if (mTexture && mTextureOnWhite) {
    // It would be more optimal to draw the actual geometry, but more code
    // and probably not worth the win here as this will often be a single
    // rect.
    nsRefPtr<ID3D10RenderTargetView> oldRT;
    device()->OMGetRenderTargets(1, getter_AddRefs(oldRT), NULL);

    nsRefPtr<ID3D10RenderTargetView> viewBlack;
    nsRefPtr<ID3D10RenderTargetView> viewWhite;
    device()->CreateRenderTargetView(mTexture, NULL, getter_AddRefs(viewBlack));
    device()->CreateRenderTargetView(mTextureOnWhite, NULL, getter_AddRefs(viewWhite));

    D3D10_RECT oldScissor;
    UINT numRects = 1;
    device()->RSGetScissorRects(&numRects, &oldScissor);

    D3D10_TEXTURE2D_DESC desc;
    mTexture->GetDesc(&desc);

    D3D10_RECT scissor = { 0, 0, desc.Width, desc.Height };
    device()->RSSetScissorRects(1, &scissor);

    mD3DManager->SetupInputAssembler();
    nsIntSize oldVP = mD3DManager->GetViewport();

    mD3DManager->SetViewport(nsIntSize(desc.Width, desc.Height));

    ID3D10RenderTargetView *views[2] = { viewBlack, viewWhite };
    device()->OMSetRenderTargets(2, views, NULL);

    gfx3DMatrix transform;
    transform.Translate(gfxPoint3D(-aOffset.x, -aOffset.y, 0));
    void* raw = &const_cast<gfx3DMatrix&>(transform)._11;
    effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64);

    ID3D10EffectTechnique *technique =
      effect()->GetTechniqueByName("PrepareAlphaExtractionTextures");

    nsIntRegionRectIterator iter(aRegion);

    const nsIntRect *iterRect;
    while ((iterRect = iter.Next())) {
      effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
        ShaderConstantRectD3D10(
          (float)iterRect->x,
          (float)iterRect->y,
          (float)iterRect->width,
          (float)iterRect->height)
        );

      technique->GetPassByIndex(0)->Apply(0);
      device()->Draw(4, 0);
    }

    views[0] = oldRT;
    device()->OMSetRenderTargets(1, views, NULL);
    mD3DManager->SetViewport(oldVP);
    device()->RSSetScissorRects(1, &oldScissor);
  }
}