Пример #1
0
void
nsShmImage::Put(Display* aDisplay, Drawable aWindow,
                const LayoutDeviceIntRegion& aRegion)
{
    GC gc = XCreateGC(aDisplay, aWindow, 0, nullptr);
    LayoutDeviceIntRegion bounded;
    bounded.And(aRegion,
                LayoutDeviceIntRect(0, 0, mImage->width, mImage->height));
    LayoutDeviceIntRegion::RectIterator iter(bounded);
    for (const LayoutDeviceIntRect *r = iter.Next(); r; r = iter.Next()) {
        XShmPutImage(aDisplay, aWindow, gc, mImage,
                     r->x, r->y,
                     r->x, r->y,
                     r->width, r->height,
                     False);
    }

    XFreeGC(aDisplay, gc);

    // FIXME/bug 597336: we need to ensure that the shm image isn't
    // scribbled over before all its pending XShmPutImage()s complete.
    // However, XSync() is an unnecessarily heavyweight
    // synchronization mechanism; other options are possible.  If this
    // XSync is shown to hurt responsiveness, we need to explore the
    // other options.
    XSync(aDisplay, False);
}
Пример #2
0
void
BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
                            const gfx::Rect *aClipRectIn,
                            const gfx::Rect& aRenderBounds,
                            gfx::Rect *aClipRectOut /* = nullptr */,
                            gfx::Rect *aRenderBoundsOut /* = nullptr */)
{
  LayoutDeviceIntRect intRect(LayoutDeviceIntPoint(), mWidget->GetClientSize());
  Rect rect = Rect(0, 0, intRect.width, intRect.height);

  LayoutDeviceIntRegion invalidRegionSafe;
  if (mDidExternalComposition) {
    // We do not know rendered region during external composition, just redraw
    // whole widget.
    invalidRegionSafe = intRect;
    mDidExternalComposition = false;
  } else {
    // Sometimes the invalid region is larger than we want to draw.
    invalidRegionSafe.And(
      LayoutDeviceIntRegion::FromUnknownRegion(aInvalidRegion), intRect);
  }

  mInvalidRegion = invalidRegionSafe;
  mInvalidRect = mInvalidRegion.GetBounds();

  if (aRenderBoundsOut) {
    *aRenderBoundsOut = Rect();
  }

  BufferMode bufferMode = BufferMode::BUFFERED;
  if (mTarget) {
    // If we have a copy target, then we don't have a widget-provided mDrawTarget (currently). Use a dummy
    // placeholder so that CreateRenderTarget() works.
    mDrawTarget = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
  } else {
    // StartRemoteDrawingInRegion can mutate mInvalidRegion.
    mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion, &bufferMode);
    if (!mDrawTarget) {
      return;
    }
    mInvalidRect = mInvalidRegion.GetBounds();
    if (mInvalidRect.IsEmpty()) {
      mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
      return;
    }
  }

  if (!mDrawTarget || mInvalidRect.IsEmpty()) {
    return;
  }

  // Setup an intermediate render target to buffer all compositing. We will
  // copy this into mDrawTarget (the widget), and/or mTarget in EndFrame()
  RefPtr<CompositingRenderTarget> target =
    CreateRenderTargetForWindow(mInvalidRect.ToUnknownRect(), INIT_MODE_CLEAR, bufferMode);
  if (!target) {
    if (!mTarget) {
      mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
    }
    return;
  }
  SetRenderTarget(target);

  // We only allocate a surface sized to the invalidated region, so we need to
  // translate future coordinates.
  mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-mRenderTarget->GetOrigin()));

  gfxUtils::ClipToRegion(mRenderTarget->mDrawTarget,
                         mInvalidRegion.ToUnknownRegion());

  if (aRenderBoundsOut) {
    *aRenderBoundsOut = rect;
  }

  if (aClipRectIn) {
    mRenderTarget->mDrawTarget->PushClipRect(*aClipRectIn);
  } else {
    mRenderTarget->mDrawTarget->PushClipRect(rect);
    if (aClipRectOut) {
      *aClipRectOut = rect;
    }
  }
}