Ejemplo n.º 1
0
IntRect
LayerMLGPU::GetClippedBoundingBox(RenderViewMLGPU* aView,
                                  const Maybe<gfx::Polygon>& aGeometry)
{
  MOZ_ASSERT(IsPrepared());

  Layer* layer = GetLayer();
  const Matrix4x4& transform = layer->GetEffectiveTransform();

  Rect rect = aGeometry
              ? aGeometry->BoundingBox()
              : Rect(layer->GetLocalVisibleRegion().GetBounds().ToUnknownRect());
  rect = transform.TransformBounds(rect);
  rect.MoveBy(-aView->GetTargetOffset());
  rect = rect.Intersect(Rect(mComputedClipRect.ToUnknownRect()));

  IntRect bounds;
  rect.RoundOut();
  rect.ToIntRect(&bounds);
  return bounds;
}
Ejemplo n.º 2
0
bool
BasicContainerLayer::ChildrenPartitionVisibleRegion(const gfx::IntRect& aInRect)
{
  Matrix transform;
  if (!GetEffectiveTransform().CanDraw2D(&transform) ||
      ThebesMatrix(transform).HasNonIntegerTranslation())
    return false;

  nsIntPoint offset(int32_t(transform._31), int32_t(transform._32));
  gfx::IntRect rect = aInRect.Intersect(GetEffectiveVisibleRegion().GetBounds() + offset);
  nsIntRegion covered;

  for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) {
    if (ToData(l)->IsHidden())
      continue;

    Matrix childTransform;
    if (!l->GetEffectiveTransform().CanDraw2D(&childTransform) ||
        ThebesMatrix(childTransform).HasNonIntegerTranslation() ||
        l->GetEffectiveOpacity() != 1.0)
      return false;
    nsIntRegion childRegion = l->GetEffectiveVisibleRegion();
    childRegion.MoveBy(int32_t(childTransform._31), int32_t(childTransform._32));
    childRegion.And(childRegion, rect);
    if (l->GetClipRect()) {
      childRegion.And(childRegion, ParentLayerIntRect::ToUntyped(*l->GetClipRect()) + offset);
    }
    nsIntRegion intersection;
    intersection.And(covered, childRegion);
    if (!intersection.IsEmpty())
      return false;
    covered.Or(covered, childRegion);
  }

  return covered.Contains(rect);
}
Ejemplo n.º 3
0
bool
FrameBuilder::AddLayerToConstantBuffer(ItemInfo& aItem)
{
  LayerMLGPU* layer = aItem.layer;

  // If this layer could appear multiple times, cache it.
  if (aItem.geometry) {
    if (mLayerBufferMap.Get(layer, &aItem.layerIndex)) {
      return true;
    }
  }

  LayerConstants* info = AllocateLayerInfo(aItem);
  if (!info) {
    return false;
  }

  // Note we do not use GetEffectiveTransformForBuffer, since we calculate
  // the correct scaling when we build texture coordinates.
  Layer* baseLayer = layer->GetLayer();
  const gfx::Matrix4x4& transform = baseLayer->GetEffectiveTransform();

  memcpy(&info->transform, &transform._11, 64);
  info->clipRect = gfx::Rect(layer->GetComputedClipRect().ToUnknownRect());
  info->maskIndex = 0;
  if (MaskOperation* op = layer->GetMask()) {
    // Note: we use 0 as an invalid index, and so indices are offset by 1.
    gfx::Rect rect = op->ComputeMaskRect(baseLayer);
    AddMaskRect(rect, &info->maskIndex);
  }

  if (aItem.geometry) {
    mLayerBufferMap.Put(layer, aItem.layerIndex);
  }
  return true;
}
Ejemplo n.º 4
0
float
LayerManagerComposite::ComputeRenderIntegrity()
{
  // We only ever have incomplete rendering when progressive tiles are enabled.
  Layer* root = GetRoot();
  if (!gfxPlatform::GetPlatform()->UseProgressivePaint() || !root) {
    return 1.f;
  }

  FrameMetrics rootMetrics = LayerMetricsWrapper::TopmostScrollableMetrics(root);
  if (!rootMetrics.IsScrollable()) {
    // The root may not have any scrollable metrics, in which case rootMetrics
    // will just be an empty FrameMetrics. Instead use the actual metrics from
    // the root layer.
    rootMetrics = LayerMetricsWrapper(root).Metrics();
  }
  ParentLayerIntRect bounds = RoundedToInt(rootMetrics.GetCompositionBounds());
  IntRect screenRect(bounds.x,
                       bounds.y,
                       bounds.width,
                       bounds.height);

  float lowPrecisionMultiplier = 1.0f;
  float highPrecisionMultiplier = 1.0f;

#ifdef MOZ_WIDGET_ANDROID
  // Use the transform on the primary scrollable layer and its FrameMetrics
  // to find out how much of the viewport the current displayport covers
  nsTArray<Layer*> rootScrollableLayers;
  GetRootScrollableLayers(rootScrollableLayers);
  if (rootScrollableLayers.Length() > 0) {
    // This is derived from the code in
    // AsyncCompositionManager::TransformScrollableLayer
    Layer* rootScrollable = rootScrollableLayers[0];
    const FrameMetrics& metrics = LayerMetricsWrapper::TopmostScrollableMetrics(rootScrollable);
    Matrix4x4 transform = rootScrollable->GetEffectiveTransform();
    transform.PostScale(metrics.GetPresShellResolution(), metrics.GetPresShellResolution(), 1);

    // Clip the screen rect to the document bounds
    Rect documentBounds =
      transform.TransformBounds(Rect(metrics.GetScrollableRect().x - metrics.GetScrollOffset().x,
                                     metrics.GetScrollableRect().y - metrics.GetScrollOffset().y,
                                     metrics.GetScrollableRect().width,
                                     metrics.GetScrollableRect().height));
    documentBounds.RoundOut();
    screenRect = screenRect.Intersect(IntRect(documentBounds.x, documentBounds.y,
                                                documentBounds.width, documentBounds.height));

    // If the screen rect is empty, the user has scrolled entirely into
    // over-scroll and so we can be considered to have full integrity.
    if (screenRect.IsEmpty()) {
      return 1.0f;
    }

    // Work out how much of the critical display-port covers the screen
    bool hasLowPrecision = false;
    if (!metrics.GetCriticalDisplayPort().IsEmpty()) {
      hasLowPrecision = true;
      highPrecisionMultiplier =
        GetDisplayportCoverage(metrics.GetCriticalDisplayPort(), transform, screenRect);
    }

    // Work out how much of the display-port covers the screen
    if (!metrics.GetDisplayPort().IsEmpty()) {
      if (hasLowPrecision) {
        lowPrecisionMultiplier =
          GetDisplayportCoverage(metrics.GetDisplayPort(), transform, screenRect);
      } else {
        lowPrecisionMultiplier = highPrecisionMultiplier =
          GetDisplayportCoverage(metrics.GetDisplayPort(), transform, screenRect);
      }
    }
  }

  // If none of the screen is covered, we have zero integrity.
  if (highPrecisionMultiplier <= 0.0f && lowPrecisionMultiplier <= 0.0f) {
    return 0.0f;
  }
#endif // MOZ_WIDGET_ANDROID

  nsIntRegion screenRegion(screenRect);
  nsIntRegion lowPrecisionScreenRegion(screenRect);
  Matrix4x4 transform;
  ComputeRenderIntegrityInternal(root, screenRegion,
                                 lowPrecisionScreenRegion, transform);

  if (!screenRegion.IsEqual(screenRect)) {
    // Calculate the area of the region. All rects in an nsRegion are
    // non-overlapping.
    float screenArea = screenRect.width * screenRect.height;
    float highPrecisionIntegrity = screenRegion.Area() / screenArea;
    float lowPrecisionIntegrity = 1.f;
    if (!lowPrecisionScreenRegion.IsEqual(screenRect)) {
      lowPrecisionIntegrity = lowPrecisionScreenRegion.Area() / screenArea;
    }

    return ((highPrecisionIntegrity * highPrecisionMultiplier) +
            (lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2;
  }

  return 1.f;
}
Ejemplo n.º 5
0
float
LayerManagerComposite::ComputeRenderIntegrity()
{
  // We only ever have incomplete rendering when progressive tiles are enabled.
  Layer* root = GetRoot();
  if (!gfxPrefs::UseProgressiveTilePainting() || !root) {
    return 1.f;
  }

  const FrameMetrics& rootMetrics = root->GetFrameMetrics();
  ParentLayerIntRect bounds = RoundedToInt(rootMetrics.mCompositionBounds);
  nsIntRect screenRect(bounds.x,
                       bounds.y,
                       bounds.width,
                       bounds.height);

  float lowPrecisionMultiplier = 1.0f;
  float highPrecisionMultiplier = 1.0f;

#ifdef MOZ_ANDROID_OMTC
  // Use the transform on the primary scrollable layer and its FrameMetrics
  // to find out how much of the viewport the current displayport covers
  Layer* primaryScrollable = GetPrimaryScrollableLayer();
  if (primaryScrollable) {
    // This is derived from the code in
    // AsyncCompositionManager::TransformScrollableLayer
    const FrameMetrics& metrics = primaryScrollable->GetFrameMetrics();
    Matrix4x4 transform = primaryScrollable->GetEffectiveTransform();
    transform.ScalePost(metrics.mResolution.scale, metrics.mResolution.scale, 1);

    // Clip the screen rect to the document bounds
    Rect documentBounds =
      transform.TransformBounds(Rect(metrics.mScrollableRect.x - metrics.GetScrollOffset().x,
                                     metrics.mScrollableRect.y - metrics.GetScrollOffset().y,
                                     metrics.mScrollableRect.width,
                                     metrics.mScrollableRect.height));
    documentBounds.RoundOut();
    screenRect = screenRect.Intersect(nsIntRect(documentBounds.x, documentBounds.y,
                                                documentBounds.width, documentBounds.height));

    // If the screen rect is empty, the user has scrolled entirely into
    // over-scroll and so we can be considered to have full integrity.
    if (screenRect.IsEmpty()) {
      return 1.0f;
    }

    // Work out how much of the critical display-port covers the screen
    bool hasLowPrecision = false;
    if (!metrics.mCriticalDisplayPort.IsEmpty()) {
      hasLowPrecision = true;
      highPrecisionMultiplier =
        GetDisplayportCoverage(metrics.mCriticalDisplayPort, transform, screenRect);
    }

    // Work out how much of the display-port covers the screen
    if (!metrics.mDisplayPort.IsEmpty()) {
      if (hasLowPrecision) {
        lowPrecisionMultiplier =
          GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect);
      } else {
        lowPrecisionMultiplier = highPrecisionMultiplier =
          GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect);
      }
    }
  }

  // If none of the screen is covered, we have zero integrity.
  if (highPrecisionMultiplier <= 0.0f && lowPrecisionMultiplier <= 0.0f) {
    return 0.0f;
  }
#endif // MOZ_ANDROID_OMTC

  nsIntRegion screenRegion(screenRect);
  nsIntRegion lowPrecisionScreenRegion(screenRect);
  Matrix4x4 transform;
  ComputeRenderIntegrityInternal(root, screenRegion,
                                 lowPrecisionScreenRegion, transform);

  if (!screenRegion.IsEqual(screenRect)) {
    // Calculate the area of the region. All rects in an nsRegion are
    // non-overlapping.
    float screenArea = screenRect.width * screenRect.height;
    float highPrecisionIntegrity = screenRegion.Area() / screenArea;
    float lowPrecisionIntegrity = 1.f;
    if (!lowPrecisionScreenRegion.IsEqual(screenRect)) {
      lowPrecisionIntegrity = lowPrecisionScreenRegion.Area() / screenArea;
    }

    return ((highPrecisionIntegrity * highPrecisionMultiplier) +
            (lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2;
  }

  return 1.f;
}