Closed Bug 1280324 Opened 4 years ago Closed 3 years ago

Provide a way to get a reference DrawTarget from PrintTargets, and fix various nsDeviceContext::CreateRenderingContext consumers to get a reference context

Categories

(Core :: Printing: Output, defect)

defect
Not set

Tracking

()

RESOLVED FIXED
mozilla52
Tracking Status
e10s - ---
firefox50 --- affected
firefox52 --- fixed

People

(Reporter: jwatt, Assigned: jwatt)

References

(Blocks 1 open bug)

Details

Attachments

(4 files)

When the nsDeviceContext is created it creates its mPrintTarget, which in the case of the child process for e10s will be a PrintTargetRecording.

On printing we will end up under this stack:

  nsDeviceContextSpecProxy::GetDrawEventRecorder
  nsDeviceContext::CreateRenderingContext
  PresShell::CreateReferenceRenderingContext
  PresShell::DoReflow
  PresShell::ProcessReflowCommands
  PresShell::FlushPendingNotifications
  PresShell::FlushPendingNotifications
  nsPrintEngine::ReflowPrintObject
  nsPrintEngine::ReflowDocList
  nsPrintEngine::InitPrintDocConstruction
  nsPrintEngine::DoCommonPrint
  nsPrintEngine::CommonPrint
  nsPrintEngine::Print
  nsDocumentViewer::Print

GetDrawEventRecorder at this point returns null because nsDeviceContextSpecProxy::BeginDocument hasn't yet been called and set mRecorder. Null is then passed to the printingTarget->MakeDrawTarget(...) call and so it returns a platform specific DrawTarget. This is important because nsDeviceContext::CreateRenderingContext should return something that can do actual measurements.

Eventually we will go on to call nsDeviceContextSpecProxy::BeginDocument and mRecorder will be set. As of that point when nsDeviceContext::CreateRenderingContext calls GetDrawEventRecorder it will get back a recorder object, and so when that is passed to the MakeDrawTarget call a DrawTarget wrapping a _recording_ cairo surface will be returned instead of a platform DrawTarget.

This would all be fine...-ish, if PresShell::CreateReferenceRenderingContext isn't called again...which at the very least will happen if a the page is printed a second time... If CreateReferenceRenderingContext is called again then nsDeviceContext::CreateRenderingContext will now return a recording target that is not capable of doing measurements.

Basically it is wrong that PresShell::CreateReferenceRenderingContext is calling  nsDeviceContext::CreateRenderingContext. Quite apart from the issue explained above, we should be returning a 1x1 px context for measuring purposes and not a full sized context.
See Also: → 1280181
Blocks: 1279654
confimed the backout fix the problem. 

Current nightly -> crash on the steps to reproduce

a tinderbox build with the fix like http://ftp.mozilla.org/pub/firefox/tinderbox-builds/mozilla-inbound-win32/1466098702/ and the steps to reproduce -->>>> no crash \o/
jwatt, how serious is this?
Flags: needinfo?(jwatt)
It just blocks me landing bug 1279654. You don't need to worry about this blocking e10s.
Flags: needinfo?(jwatt)
Taking, as discussed on IRC.
Assignee: edwin → jwatt
Summary: [e10s] PresShell::CreateReferenceRenderingContext should not call nsDeviceContext::CreateRenderingContext → Provide a way to get a reference DrawTarget from PrintTargets, and fix various nsDeviceContext::CreateRenderingContext consumers to get a reference context
It's not just PresShell::CreateReferenceRenderingContext that should be switched to use nsDeviceContext::CreateReferenceRendingContext.

Right now consumers can get away with asking for and using the DrawTarget that abstracts the printer itself outside of the BeforePage()/EndPage() calls, but I'm changing that elsewhere. Specifically in bug 1309272 PrintTargetSkPDF will only have a valid DrawTarget between BeforePage()/EndPage() calls. Also I'm working on patches to get rid of the hacks for PrintTargetCG where we replace the PrintTargetCG for each page and instead keep the PrintTargetCG for the entire document like we do for all other PrintTargets. So the DrawTarget obtained from PrintTargetCG will also only be valid between BeforePage()/EndPage() calls. For this to work there are two other places that need fixed up to switch from calling nsDeviceContext::CreateRendingContext to calling nsDeviceContext::CreateReferenceRendingContext.

nsSimplePageSequenceFrame::PrePrintNextPage: Obviously this is making its call outside the BeforePage()/EndPage() calls, which means the context returned may not be valid. As it turns out the only use it makes of the returned context is to call CreateSimilarDrawTarget() on it for each HTML <canvas>. We should switch to using the reference context.

PrintTranslator::PrintTranslator: The call here happens even before BeginPrinting() has been called. The returned context is only used by:

  PrintTranslator::GetDesiredFontType
  RecordedCreateSimilarDrawTarget
  RecordedPathCreation
  RecordedSourceSurfaceCreation
  RecordedFilterNodeCreation
  RecordedGradientStopsCreation

All of these would be served just as well by the reference context.
Attachment #8805516 - Flags: review?(edwin)
Pushed by jwatt@jwatt.org:
https://hg.mozilla.org/integration/mozilla-inbound/rev/bcb5f7b49427
part 1 - Add functionality to the PrintTarget sub-classes to return reference DrawTargets. r=edwin
https://hg.mozilla.org/integration/mozilla-inbound/rev/620893e272d6
part 2 - Add a CreateReferenceRenderingContext method to nsDeviceContext. r=edwin
https://hg.mozilla.org/integration/mozilla-inbound/rev/20f8aeb59ada
part 3 - Fix various nsDeviceContext::CreateRenderingContext to call CreateReferenceRenderingContext instead. r=edwin
https://hg.mozilla.org/integration/mozilla-inbound/rev/afb9ba10005e
part 4 - Assert that PrintTarget::MakeDrawTarget is only called while a print page is being processed. r=edwin
Depends on: 1316338
Depends on: 1316750
Depends on: 1326418
See Also: → 1347646
(In reply to Carsten Book [:Tomcat] from comment #1)
> Current nightly -> crash on the steps to reproduce
What are the steps to reproduce?
I'm trying to reproduce this in order to verify another fix.
Flags: needinfo?(cbook)
Hi Paul, i guess that relates to https://bugzilla.mozilla.org/show_bug.cgi?id=1280181#c16 and the steps to reproduce according to 

https://bugzilla.mozilla.org/show_bug.cgi?id=1280181#c4

or simply printing with e10s on
Flags: needinfo?(cbook)
Thank you, Carsten!
You need to log in before you can comment on or make changes to this bug.