Esempio n. 1
0
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())));
}
Esempio n. 2
0
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();
}
Esempio n. 3
0
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();
}