/** * 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; }
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)); }
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); } }