Commit 711f8a01 authored by Alan Screen's avatar Alan Screen Committed by Commit Bot

[Windows] Release page metafile after printing to GDI API

Printing on Windows involves a two-step process, first converting pages
to the Windows metafile format (EMF) and then later playing that
metafile to print to the destination device.

The PrintedPage objects which contain this metafile data are retained
in the PrintedDocument until the document completes.  This has caused
the extra metafile representation to stay in memory well after it's
required lifetime has passed.  For jobs with many pages that include
full page rasters this triggers a memory spike that subsides only once
the last page is sent and the document is destroyed.

Avoid such memory spikes by dropping the PrintedPage object from the
document as soon as the page has been rendered to the destination, so
that its destructor can run and release the associated |metafile_|
memory.

Bug: 1031438
Change-Id: If6ff81f63e11989bc7ef1b341ee37be0cd8d4af7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1975993Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Commit-Queue: Alan Screen <awscreen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726671}
parent 5546ab99
...@@ -475,6 +475,7 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) { ...@@ -475,6 +475,7 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) {
pdf_conversion_state_->OnPageProcessed( pdf_conversion_state_->OnPageProcessed(
base::BindRepeating(&PrintJob::OnPdfPageConverted, this)); base::BindRepeating(&PrintJob::OnPdfPageConverted, this));
} }
document_->DropPage(event_details.page());
break; break;
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
default: { default: {
......
...@@ -156,6 +156,14 @@ scoped_refptr<PrintedPage> PrintedDocument::GetPage(int page_number) { ...@@ -156,6 +156,14 @@ scoped_refptr<PrintedPage> PrintedDocument::GetPage(int page_number) {
} }
return page; return page;
} }
void PrintedDocument::DropPage(const PrintedPage* page) {
base::AutoLock lock(lock_);
PrintedPages::const_iterator it =
mutable_.pages_.find(page->page_number() - 1);
DCHECK_EQ(page, it->second.get());
mutable_.pages_.erase(it);
}
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
void PrintedDocument::SetDocument(std::unique_ptr<MetafilePlayer> metafile, void PrintedDocument::SetDocument(std::unique_ptr<MetafilePlayer> metafile,
......
...@@ -60,6 +60,10 @@ class PRINTING_EXPORT PrintedDocument ...@@ -60,6 +60,10 @@ class PRINTING_EXPORT PrintedDocument
// requests to have this page be rendered and returns NULL. // requests to have this page be rendered and returns NULL.
// Note: locks for a short amount of time. // Note: locks for a short amount of time.
scoped_refptr<PrintedPage> GetPage(int page_number); scoped_refptr<PrintedPage> GetPage(int page_number);
// Drop the specified page's reference for the particular page number.
// Note: locks for a short amount of time.
void DropPage(const PrintedPage* page);
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
// Sets the document data. Note: locks for a short amount of time. // Sets the document data. Note: locks for a short amount of time.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment