void FilterNodeD2D1::SetAttribute(uint32_t aIndex, const IntRect &aValue) { if (mType == FilterType::TURBULENCE) { MOZ_ASSERT(aIndex == ATT_TURBULENCE_RECT); mEffect->SetValue(D2D1_TURBULENCE_PROP_OFFSET, D2D1::Vector2F(Float(aValue.X()), Float(aValue.Y()))); mEffect->SetValue(D2D1_TURBULENCE_PROP_SIZE, D2D1::Vector2F(Float(aValue.Width()), Float(aValue.Height()))); return; } UINT32 input = GetD2D1PropForAttribute(mType, aIndex); MOZ_ASSERT(input < mEffect->GetPropertyCount()); mEffect->SetValue(input, D2D1::RectF(Float(aValue.X()), Float(aValue.Y()), Float(aValue.XMost()), Float(aValue.YMost()))); }
already_AddRefed<SourceSurface> ImageBitmap::PrepareForDrawTarget(gfx::DrawTarget* aTarget) { MOZ_ASSERT(aTarget); if (!mData) { return nullptr; } if (!mSurface) { mSurface = mData->GetAsSourceSurface(); } if (!mSurface) { return nullptr; } RefPtr<DrawTarget> target = aTarget; IntRect surfRect(0, 0, mSurface->GetSize().width, mSurface->GetSize().height); // Check if we still need to crop our surface if (!mPictureRect.IsEqualEdges(surfRect)) { IntRect surfPortion = surfRect.Intersect(mPictureRect); // the crop lies entirely outside the surface area, nothing to draw if (surfPortion.IsEmpty()) { mSurface = nullptr; RefPtr<gfx::SourceSurface> surface(mSurface); return surface.forget(); } IntPoint dest(std::max(0, surfPortion.X() - mPictureRect.X()), std::max(0, surfPortion.Y() - mPictureRect.Y())); // We must initialize this target with mPictureRect.Size() because the // specification states that if the cropping area is given, then return an // ImageBitmap with the size equals to the cropping area. target = target->CreateSimilarDrawTarget(mPictureRect.Size(), target->GetFormat()); if (!target) { mSurface = nullptr; RefPtr<gfx::SourceSurface> surface(mSurface); return surface.forget(); } // We need to fall back to generic copying and cropping for the Windows8.1, // D2D1 backend. // In the Windows8.1 D2D1 backend, it might trigger "partial upload" from a // non-SourceSurfaceD2D1 surface to a D2D1Image in the following // CopySurface() step. However, the "partial upload" only supports uploading // a rectangle starts from the upper-left point, which means it cannot // upload an arbitrary part of the source surface and this causes problems // if the mPictureRect is not starts from the upper-left point. if (target->GetBackendType() == BackendType::DIRECT2D1_1 && mSurface->GetType() != SurfaceType::D2D1_1_IMAGE) { RefPtr<DataSourceSurface> dataSurface = mSurface->GetDataSurface(); if (NS_WARN_IF(!dataSurface)) { mSurface = nullptr; RefPtr<gfx::SourceSurface> surface(mSurface); return surface.forget(); } mSurface = CropAndCopyDataSourceSurface(dataSurface, mPictureRect); } else { target->CopySurface(mSurface, surfPortion, dest); mSurface = target->Snapshot(); } // Make mCropRect match new surface we've cropped to mPictureRect.MoveTo(0, 0); } // Replace our surface with one optimized for the target we're about to draw // to, under the assumption it'll likely be drawn again to that target. // This call should be a no-op for already-optimized surfaces mSurface = target->OptimizeSourceSurface(mSurface); RefPtr<gfx::SourceSurface> surface(mSurface); return surface.forget(); }
already_AddRefed<SourceSurface> ImageBitmap::PrepareForDrawTarget(gfx::DrawTarget* aTarget) { MOZ_ASSERT(aTarget); if (!mSurface) { mSurface = mData->GetAsSourceSurface(); } if (!mSurface) { return nullptr; } RefPtr<DrawTarget> target = aTarget; IntRect surfRect(0, 0, mSurface->GetSize().width, mSurface->GetSize().height); // Check if we still need to crop our surface if (!mPictureRect.IsEqualEdges(surfRect)) { IntRect surfPortion = surfRect.Intersect(mPictureRect); // the crop lies entirely outside the surface area, nothing to draw if (surfPortion.IsEmpty()) { mSurface = nullptr; RefPtr<gfx::SourceSurface> surface(mSurface); return surface.forget(); } IntPoint dest(std::max(0, surfPortion.X() - mPictureRect.X()), std::max(0, surfPortion.Y() - mPictureRect.Y())); // Do not initialize this target with mPictureRect.Size(). // In the Windows8 D2D1 backend, it might trigger "partial upload" from a // non-SourceSurfaceD2D1 surface to a D2D1Image in the following // CopySurface() step. However, the "partial upload" only supports uploading // a rectangle starts from the upper-left point, which means it cannot // upload an arbitrary part of the source surface and this causes problems // if the mPictureRect is not starts from the upper-left point. target = target->CreateSimilarDrawTarget(mSurface->GetSize(), target->GetFormat()); if (!target) { mSurface = nullptr; RefPtr<gfx::SourceSurface> surface(mSurface); return surface.forget(); } // Make mCropRect match new surface we've cropped to mPictureRect.MoveTo(0, 0); target->CopySurface(mSurface, surfPortion, dest); mSurface = target->Snapshot(); } // Replace our surface with one optimized for the target we're about to draw // to, under the assumption it'll likely be drawn again to that target. // This call should be a no-op for already-optimized surfaces mSurface = target->OptimizeSourceSurface(mSurface); RefPtr<gfx::SourceSurface> surface(mSurface); return surface.forget(); }