예제 #1
0
already_AddRefed<gfxContext>
nsDeviceContext::CreateRenderingContext()
{
    MOZ_ASSERT(mWidth > 0 && mHeight > 0);

    RefPtr<gfxASurface> printingSurface = mPrintingSurface;
#ifdef XP_MACOSX
    // CreateRenderingContext() can be called (on reflow) after EndPage()
    // but before BeginPage().  On OS X (and only there) mPrintingSurface
    // will in this case be null, because OS X printing surfaces are
    // per-page, and therefore only truly valid between calls to BeginPage()
    // and EndPage().  But we can get away with fudging things here, if need
    // be, by using a cached copy.
    if (!printingSurface) {
      printingSurface = mCachedPrintingSurface;
    }
#endif

    RefPtr<gfx::DrawTarget> dt =
      gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(printingSurface,
                                                             gfx::IntSize(mWidth, mHeight));

    // This can legitimately happen - CreateDrawTargetForSurface will fail
    // to create a draw target if the size is too large, for instance.
    if (!dt) {
        gfxCriticalNote << "Failed to create draw target in device context sized " << mWidth << "x" << mHeight << " and pointers " << hexa(mPrintingSurface) << " and " << hexa(printingSurface);
        return nullptr;
    }

    RefPtr<DrawEventRecorder> recorder;
    nsresult rv = mDeviceContextSpec->GetDrawEventRecorder(getter_AddRefs(recorder));
    if (NS_SUCCEEDED(rv) && recorder) {
      dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dt);
    }

#ifdef XP_MACOSX
    dt->AddUserData(&gfxContext::sDontUseAsSourceKey, dt, nullptr);
#endif
    dt->AddUserData(&sDisablePixelSnapping, (void*)0x1, nullptr);

    RefPtr<gfxContext> pContext = new gfxContext(dt);

    gfxMatrix transform;
    if (printingSurface->GetRotateForLandscape()) {
      // Rotate page 90 degrees to draw landscape page on portrait paper
      IntSize size = printingSurface->GetSize();
      transform.Translate(gfxPoint(0, size.width));
      gfxMatrix rotate(0, -1,
                       1,  0,
                       0,  0);
      transform = rotate * transform;
    }
    transform.Scale(mPrintingScale, mPrintingScale);

    pContext->SetMatrix(transform);
    return pContext.forget();
}
예제 #2
0
already_AddRefed<gfxContext>
nsDeviceContext::CreateRenderingContextCommon(bool aWantReferenceContext)
{
    MOZ_ASSERT(IsPrinterContext());
    MOZ_ASSERT(mWidth > 0 && mHeight > 0);

    RefPtr<gfx::DrawTarget> dt;
    if (aWantReferenceContext) {
      dt = mPrintTarget->GetReferenceDrawTarget();
    } else {
      // This will be null if e10s is disabled or print.print_via_parent=false.
      RefPtr<DrawEventRecorder> recorder;
      mDeviceContextSpec->GetDrawEventRecorder(getter_AddRefs(recorder));
      dt = mPrintTarget->MakeDrawTarget(gfx::IntSize(mWidth, mHeight), recorder);
    }

    if (!dt || !dt->IsValid()) {
      gfxCriticalNote
        << "Failed to create draw target in device context sized "
        << mWidth << "x" << mHeight << " and pointer "
        << hexa(mPrintTarget);
      return nullptr;
    }

#ifdef XP_MACOSX
    // The CGContextRef provided by PMSessionGetCGGraphicsContext is
    // write-only, so we need to prevent gfxContext::PushGroupAndCopyBackground
    // trying to read from it or else we'll crash.
    // XXXjwatt Consider adding a MakeDrawTarget override to PrintTargetCG and
    // moving this AddUserData call there.
    dt->AddUserData(&gfxContext::sDontUseAsSourceKey, dt, nullptr);
#endif
    dt->AddUserData(&sDisablePixelSnapping, (void*)0x1, nullptr);

    RefPtr<gfxContext> pContext = gfxContext::CreateOrNull(dt);
    MOZ_ASSERT(pContext); // already checked draw target above

    gfxMatrix transform;
    transform.PreTranslate(mPrintingTranslate);
    if (mPrintTarget->RotateNeededForLandscape()) {
      // Rotate page 90 degrees to draw landscape page on portrait paper
      IntSize size = mPrintTarget->GetSize();
      transform.PreTranslate(gfxPoint(0, size.width));
      gfxMatrix rotate(0, -1,
                       1,  0,
                       0,  0);
      transform = rotate * transform;
    }
    transform.PreScale(mPrintingScale, mPrintingScale);

    pContext->SetMatrixDouble(transform);
    return pContext.forget();
}
예제 #3
0
void
TextureHostFileMapping::UpdatedInternal(const nsIntRegion* aRegion)
{
  if (!mProvider) {
    // This can happen if we send textures to a compositable that isn't yet
    // attached to a layer.
    return;
  }

  if (!mTextureSource) {
    mTextureSource = mProvider->CreateDataTextureSource(mFlags);
  }

  uint8_t* data = nullptr;
  int32_t totalBytes = BufferSizeFromDimensions(mSize.width, mSize.height, BytesPerPixel(mFormat));
  if (totalBytes > 0) {
    data = (uint8_t*)::MapViewOfFile(mFileMapping, FILE_MAP_READ, 0, 0, totalBytes);
  }

  if (data) {
    RefPtr<DataSourceSurface> surf = Factory::CreateWrappingDataSourceSurface(data, mSize.width * BytesPerPixel(mFormat), mSize, mFormat);
    if (surf) {
        surf->AddUserData(&kFileMappingKey, data, UnmapFileData);
        if (!mTextureSource->Update(surf, const_cast<nsIntRegion*>(aRegion))) {
          mTextureSource = nullptr;
        }
    } else {
      mTextureSource = nullptr;
    }
  } else {
    mTextureSource = nullptr;
  }

  ReadUnlock();
}
예제 #4
0
already_AddRefed<gfxContext>
nsDeviceContext::CreateRenderingContext()
{
    MOZ_ASSERT(mWidth > 0 && mHeight > 0);

    nsRefPtr<gfxASurface> printingSurface = mPrintingSurface;
#ifdef XP_MACOSX
    // CreateRenderingContext() can be called (on reflow) after EndPage()
    // but before BeginPage().  On OS X (and only there) mPrintingSurface
    // will in this case be null, because OS X printing surfaces are
    // per-page, and therefore only truly valid between calls to BeginPage()
    // and EndPage().  But we can get away with fudging things here, if need
    // be, by using a cached copy.
    if (!printingSurface) {
      printingSurface = mCachedPrintingSurface;
    }
#endif

    RefPtr<gfx::DrawTarget> dt =
      gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(printingSurface,
                                                             gfx::IntSize(mWidth, mHeight));

    if (!dt) {
        gfxCriticalError() << "Failed to create draw target in device context sized " << mWidth << "x" << mHeight << " and pointers " << hexa(mPrintingSurface) << " and " << hexa(printingSurface);
        MOZ_CRASH("Cannot CreateDrawTargetForSurface");
    }

#ifdef XP_MACOSX
    dt->AddUserData(&gfxContext::sDontUseAsSourceKey, dt, nullptr);
#endif
    dt->AddUserData(&sDisablePixelSnapping, (void*)0x1, nullptr);

    nsRefPtr<gfxContext> pContext = new gfxContext(dt);
    pContext->SetMatrix(gfxMatrix::Scaling(mPrintingScale, mPrintingScale));
    return pContext.forget();
}
예제 #5
0
static TemporaryRef<DataSourceSurface>
CreateLockedSurface(VolatileBuffer *vbuf,
                    const IntSize& size,
                    SurfaceFormat format)
{
  VolatileBufferPtr<unsigned char> *vbufptr =
    new VolatileBufferPtr<unsigned char>(vbuf);
  MOZ_ASSERT(!vbufptr->WasBufferPurged(), "Expected image data!");

  int32_t stride = VolatileSurfaceStride(size, format);
  RefPtr<DataSourceSurface> surf =
    Factory::CreateWrappingDataSourceSurface(*vbufptr, stride, size, format);
  if (!surf) {
    delete vbufptr;
    return nullptr;
  }

  surf->AddUserData(&kVolatileBuffer, vbufptr, VolatileBufferRelease);
  return surf;
}
already_AddRefed<SourceSurface> VideoDecoderManagerChild::Readback(
    const SurfaceDescriptorGPUVideo& aSD) {
  // We can't use NS_DISPATCH_SYNC here since that can spin the event
  // loop while it waits. This function can be called from JS and we
  // don't want that to happen.
  SynchronousTask task("Readback sync");

  RefPtr<VideoDecoderManagerChild> ref = this;
  SurfaceDescriptor sd;
  if (NS_FAILED(sVideoDecoderChildThread->Dispatch(
          NS_NewRunnableFunction("VideoDecoderManagerChild::Readback",
                                 [&]() {
                                   AutoCompleteTask complete(&task);
                                   if (ref->CanSend()) {
                                     ref->SendReadback(aSD, &sd);
                                   }
                                 }),
          NS_DISPATCH_NORMAL))) {
    return nullptr;
  }

  task.Wait();

  if (!IsSurfaceDescriptorValid(sd)) {
    return nullptr;
  }

  RefPtr<DataSourceSurface> source = GetSurfaceForDescriptor(sd);
  if (!source) {
    DestroySurfaceDescriptor(this, &sd);
    NS_WARNING("Failed to map SurfaceDescriptor in Readback");
    return nullptr;
  }

  static UserDataKey sSurfaceDescriptor;
  source->AddUserData(&sSurfaceDescriptor,
                      new SurfaceDescriptorUserData(this, sd),
                      DeleteSurfaceDescriptorUserData);

  return source.forget();
}