Пример #1
0
bool RenderViewMLGPU::UpdateVisibleRegion(ItemInfo& aItem) {
  // If the item has some kind of complex transform, we perform a very
  // simple occlusion test and move on. We using a depth buffer we skip
  // CPU-based occlusion culling as well, since the GPU will do most of our
  // culling work for us.
  if (mUseDepthBuffer || !aItem.translation ||
      !gfxPrefs::AdvancedLayersEnableCPUOcclusion()) {
    // Update the render region even if we won't compute visibility, since some
    // layer types (like Canvas and Image) need to have the visible region
    // clamped.
    LayerIntRegion region = aItem.layer->GetShadowVisibleRegion();
    aItem.layer->SetRenderRegion(std::move(region));

    AL_LOG("RenderView %p simple occlusion test, bounds=%s, translation?=%d\n",
           this, Stringify(aItem.bounds).c_str(), aItem.translation ? 1 : 0);
    return mInvalidBounds.Intersects(aItem.bounds);
  }

  MOZ_ASSERT(aItem.rectilinear);

  AL_LOG("RenderView %p starting visibility tests:\n", this);
  AL_LOG("  occluded=%s\n", Stringify(mOccludedRegion).c_str());

  // Compute the translation into render target space.
  LayerIntPoint translation = LayerIntPoint::FromUnknownPoint(
      aItem.translation.value() - mTargetOffset);
  AL_LOG("  translation=%s\n", Stringify(translation).c_str());

  IntRect clip = aItem.layer->GetComputedClipRect().ToUnknownRect();
  AL_LOG("  clip=%s\n", Stringify(translation).c_str());

  LayerIntRegion region = aItem.layer->GetShadowVisibleRegion();
  region.MoveBy(translation);
  AL_LOG("  effective-visible=%s\n", Stringify(region).c_str());

  region.SubOut(mOccludedRegion);
  region.AndWith(LayerIntRect::FromUnknownRect(mInvalidBounds));
  region.AndWith(LayerIntRect::FromUnknownRect(clip));
  if (region.IsEmpty()) {
    return false;
  }

  // Move the visible region back into layer space.
  region.MoveBy(-translation);
  AL_LOG("  new-local-visible=%s\n", Stringify(region).c_str());

  aItem.layer->SetRenderRegion(std::move(region));

  // Apply the new occluded area. We do another dance with the translation to
  // avoid copying the region. We do this after the SetRegionToRender call to
  // accomodate the possiblity of a layer changing its visible region.
  if (aItem.opaque) {
    mOccludedRegion.MoveBy(-translation);
    mOccludedRegion.OrWith(aItem.layer->GetRenderRegion());
    mOccludedRegion.MoveBy(translation);
    AL_LOG("  new-occluded=%s\n", Stringify(mOccludedRegion).c_str());

    // If the occluded region gets too complicated, we reset it.
    if (mOccludedRegion.GetNumRects() >= 32) {
      mOccludedRegion.SetEmpty();
      AL_LOG("  clear-occluded, too many rects\n");
    }
  }
  return true;
}