void TexturedLayerMLGPU::AssignBigImage(FrameBuilder* aBuilder,
                                        RenderViewMLGPU* aView,
                                        BigImageIterator* aIter,
                                        const Maybe<Polygon>& aGeometry) {
  const Matrix4x4& transform = GetLayer()->GetEffectiveTransformForBuffer();

  // Note that we don't need to assign these in any particular order, since
  // they do not overlap.
  do {
    IntRect tileRect = aIter->GetTileRect();
    IntRect rect = tileRect.Intersect(mPictureRect);
    if (rect.IsEmpty()) {
      continue;
    }

    {
      Rect screenRect = transform.TransformBounds(Rect(rect));
      screenRect.MoveBy(-aView->GetTargetOffset());
      screenRect =
          screenRect.Intersect(Rect(mComputedClipRect.ToUnknownRect()));
      if (screenRect.IsEmpty()) {
        // This tile is not in the clip region, so skip it.
        continue;
      }
    }

    RefPtr<TextureSource> tile = mBigImageTexture->ExtractCurrentTile();
    if (!tile) {
      continue;
    }

    // Create a temporary item.
    RefPtr<TempImageLayerMLGPU> item =
        new TempImageLayerMLGPU(aBuilder->GetManager());
    item->Init(this, tile, rect);

    Maybe<Polygon> geometry = aGeometry;
    item->AddBoundsToView(aBuilder, aView, std::move(geometry));

    // Since the layer tree is not holding this alive, we have to ask the
    // FrameBuilder to do it for us.
    aBuilder->RetainTemporaryLayer(item);
  } while (aIter->NextTile());
}
Esempio n. 2
0
IntRect
nsSVGFilterInstance::ComputeFilterPrimitiveSubregion(nsSVGFE* aFilterElement,
                                                     const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
                                                     const nsTArray<int32_t>& aInputIndices)
{
  nsSVGFE* fE = aFilterElement;

  IntRect defaultFilterSubregion(0,0,0,0);
  if (fE->SubregionIsUnionOfRegions()) {
    for (uint32_t i = 0; i < aInputIndices.Length(); ++i) {
      int32_t inputIndex = aInputIndices[i];
      bool isStandardInput = inputIndex < 0 || inputIndex == mSourceGraphicIndex;
      IntRect inputSubregion = isStandardInput ?
        ToIntRect(mFilterSpaceBounds) :
        aPrimitiveDescrs[inputIndex].PrimitiveSubregion();

      defaultFilterSubregion = defaultFilterSubregion.Union(inputSubregion);
    }
  } else {
    defaultFilterSubregion = ToIntRect(mFilterSpaceBounds);
  }

  gfxRect feArea = nsSVGUtils::GetRelativeRect(mPrimitiveUnits,
    &fE->mLengthAttributes[nsSVGFE::ATTR_X], mTargetBBox, mTargetFrame);
  Rect region = ToRect(UserSpaceToFilterSpace(feArea));

  if (!fE->mLengthAttributes[nsSVGFE::ATTR_X].IsExplicitlySet())
    region.x = defaultFilterSubregion.X();
  if (!fE->mLengthAttributes[nsSVGFE::ATTR_Y].IsExplicitlySet())
    region.y = defaultFilterSubregion.Y();
  if (!fE->mLengthAttributes[nsSVGFE::ATTR_WIDTH].IsExplicitlySet())
    region.width = defaultFilterSubregion.Width();
  if (!fE->mLengthAttributes[nsSVGFE::ATTR_HEIGHT].IsExplicitlySet())
    region.height = defaultFilterSubregion.Height();

  // We currently require filter primitive subregions to be pixel-aligned.
  // Following the spec, any pixel partially in the region is included
  // in the region.
  region.RoundOut();
  IntRect regionInt = RoundedToInt(region);

  // Clip the primitive subregion to this filter's filter region.
  return regionInt.Intersect(ToIntRect(mFilterSpaceBounds));
}
Esempio n. 3
0
bool
RectIsSolidColor(SourceSurface* aSurface,
                 const IntRect& aRect,
                 BGRAColor aColor,
                 uint8_t aFuzz /* = 0 */)
{
  IntSize surfaceSize = aSurface->GetSize();
  IntRect rect =
    aRect.Intersect(IntRect(0, 0, surfaceSize.width, surfaceSize.height));

  RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
  ASSERT_TRUE_OR_RETURN(dataSurface != nullptr, false);

  ASSERT_EQ_OR_RETURN(dataSurface->Stride(), surfaceSize.width * 4, false);

  DataSourceSurface::ScopedMap mapping(dataSurface,
                                       DataSourceSurface::MapType::READ);
  ASSERT_TRUE_OR_RETURN(mapping.IsMapped(), false);

  uint8_t* data = dataSurface->GetData();
  ASSERT_TRUE_OR_RETURN(data != nullptr, false);

  int32_t rowLength = dataSurface->Stride();
  for (int32_t row = rect.y; row < rect.YMost(); ++row) {
    for (int32_t col = rect.x; col < rect.XMost(); ++col) {
      int32_t i = row * rowLength + col * 4;
      if (aFuzz != 0) {
        ASSERT_LE_OR_RETURN(abs(aColor.mBlue - data[i + 0]), aFuzz, false);
        ASSERT_LE_OR_RETURN(abs(aColor.mGreen - data[i + 1]), aFuzz, false);
        ASSERT_LE_OR_RETURN(abs(aColor.mRed - data[i + 2]), aFuzz, false);
        ASSERT_LE_OR_RETURN(abs(aColor.mAlpha - data[i + 3]), aFuzz, false);
      } else {
        ASSERT_EQ_OR_RETURN(aColor.mBlue,  data[i + 0], false);
        ASSERT_EQ_OR_RETURN(aColor.mGreen, data[i + 1], false);
        ASSERT_EQ_OR_RETURN(aColor.mRed,   data[i + 2], false);
        ASSERT_EQ_OR_RETURN(aColor.mAlpha, data[i + 3], false);
      }
    }
  }

  return true;
}
Esempio n. 4
0
//******************************************************************************
void
FrameAnimator::ClearFrame(uint8_t* aFrameData, const IntRect& aFrameRect,
                          const IntRect& aRectToClear)
{
  if (!aFrameData || aFrameRect.width <= 0 || aFrameRect.height <= 0 ||
      aRectToClear.width <= 0 || aRectToClear.height <= 0) {
    return;
  }

  IntRect toClear = aFrameRect.Intersect(aRectToClear);
  if (toClear.IsEmpty()) {
    return;
  }

  uint32_t bytesPerRow = aFrameRect.width * 4;
  for (int row = toClear.y; row < toClear.y + toClear.height; ++row) {
    memset(aFrameData + toClear.x * 4 + row * bytesPerRow, 0,
           toClear.width * 4);
  }
}
Esempio n. 5
0
bool
PalettedRectIsSolidColor(Decoder* aDecoder, const IntRect& aRect, uint8_t aColor)
{
  RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
  uint8_t* imageData;
  uint32_t imageLength;
  currentFrame->GetImageData(&imageData, &imageLength);
  ASSERT_TRUE_OR_RETURN(imageData, false);

  // Clamp to the frame rect. If any pixels outside the frame rect are included,
  // we immediately fail, because such pixels don't have any "color" in the
  // sense this function measures - they're transparent, and that doesn't
  // necessarily correspond to any color palette index at all.
  IntRect frameRect = currentFrame->GetRect();
  ASSERT_EQ_OR_RETURN(imageLength, uint32_t(frameRect.Area()), false);
  IntRect rect = aRect.Intersect(frameRect);
  ASSERT_EQ_OR_RETURN(rect.Area(), aRect.Area(), false);

  // Translate |rect| by |frameRect.TopLeft()| to reflect the fact that the
  // frame rect's offset doesn't actually mean anything in terms of the
  // in-memory representation of the surface. The image data starts at the upper
  // left corner of the frame rect, in other words.
  rect -= frameRect.TopLeft();

  // Walk through the image data and make sure that the entire rect has the
  // palette index |aColor|.
  int32_t rowLength = frameRect.width;
  for (int32_t row = rect.y; row < rect.YMost(); ++row) {
    for (int32_t col = rect.x; col < rect.XMost(); ++col) {
      int32_t i = row * rowLength + col;
      ASSERT_EQ_OR_RETURN(aColor, imageData[i], false);
    }
  }

  return true;
}
nsresult
nsSVGFilterInstance::BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
                                     nsTArray<RefPtr<SourceSurface>>& aInputImages,
                                     bool aInputIsTainted)
{
  mSourceGraphicIndex = GetLastResultIndex(aPrimitiveDescrs);

  // Clip previous filter's output to this filter's filter region.
  if (mSourceGraphicIndex >= 0) {
    FilterPrimitiveDescription& sourceDescr = aPrimitiveDescrs[mSourceGraphicIndex];
    sourceDescr.SetPrimitiveSubregion(sourceDescr.PrimitiveSubregion().Intersect(mFilterSpaceBounds));
  }

  // Get the filter primitive elements.
  nsTArray<RefPtr<nsSVGFE> > primitives;
  for (nsIContent* child = mFilterElement->nsINode::GetFirstChild();
       child;
       child = child->GetNextSibling()) {
    RefPtr<nsSVGFE> primitive;
    CallQueryInterface(child, (nsSVGFE**)getter_AddRefs(primitive));
    if (primitive) {
      primitives.AppendElement(primitive);
    }
  }

  // Maps source image name to source index.
  nsDataHashtable<nsStringHashKey, int32_t> imageTable(8);

  // The principal that we check principals of any loaded images against.
  nsCOMPtr<nsIPrincipal> principal = mTargetContent->NodePrincipal();

  for (uint32_t primitiveElementIndex = 0;
       primitiveElementIndex < primitives.Length();
       ++primitiveElementIndex) {
    nsSVGFE* filter = primitives[primitiveElementIndex];

    AutoTArray<int32_t,2> sourceIndices;
    nsresult rv = GetSourceIndices(filter, aPrimitiveDescrs, imageTable, sourceIndices);
    if (NS_FAILED(rv)) {
      return rv;
    }

    IntRect primitiveSubregion =
      ComputeFilterPrimitiveSubregion(filter, aPrimitiveDescrs, sourceIndices);

    nsTArray<bool> sourcesAreTainted;
    GetInputsAreTainted(aPrimitiveDescrs, sourceIndices, aInputIsTainted, sourcesAreTainted);

    FilterPrimitiveDescription descr =
      filter->GetPrimitiveDescription(this, primitiveSubregion, sourcesAreTainted, aInputImages);

    descr.SetIsTainted(filter->OutputIsTainted(sourcesAreTainted, principal));
    descr.SetFilterSpaceBounds(mFilterSpaceBounds);
    descr.SetPrimitiveSubregion(primitiveSubregion.Intersect(descr.FilterSpaceBounds()));

    for (uint32_t i = 0; i < sourceIndices.Length(); i++) {
      int32_t inputIndex = sourceIndices[i];
      descr.SetInputPrimitive(i, inputIndex);

      ColorSpace inputColorSpace = inputIndex >= 0
        ? aPrimitiveDescrs[inputIndex].OutputColorSpace()
        : ColorSpace(ColorSpace::SRGB);

      ColorSpace desiredInputColorSpace = filter->GetInputColorSpace(i, inputColorSpace);
      descr.SetInputColorSpace(i, desiredInputColorSpace);
      if (i == 0) {
        // the output color space is whatever in1 is if there is an in1
        descr.SetOutputColorSpace(desiredInputColorSpace);
      }
    }

    if (sourceIndices.Length() == 0) {
      descr.SetOutputColorSpace(filter->GetOutputColorSpace());
    }

    aPrimitiveDescrs.AppendElement(descr);
    uint32_t primitiveDescrIndex = aPrimitiveDescrs.Length() - 1;

    nsAutoString str;
    filter->GetResultImageName().GetAnimValue(str, filter);
    imageTable.Put(str, primitiveDescrIndex);
  }

  return NS_OK;
}