Commit e13ea649 authored by Wei Li's avatar Wei Li Committed by Commit Bot

Revert "Revert "Add support for OOPIF printing in renderer""

This reverts commit 39d52aa5.

Reason: The original CL was reverted just to revert
https://chromium-review.googlesource.com/c/chromium/src/+/924245 cleanly.
Context is in https://bugs.chromium.org/p/chromium/issues/detail?id=813246

TBR=thestig@chromium.org, alexmos@chromium.org

Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.android:android_optional_gpu_tests_rel
Change-Id: Ibfdb1571cd7fd4d78f9b8ff6c710c587e3cf3464
Reviewed-on: https://chromium-review.googlesource.com/924566
Commit-Queue: Wei Li <weili@chromium.org>
Reviewed-by: default avatarWei Li <weili@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537540}
parent 98260cd1
......@@ -344,15 +344,7 @@ void SkiaPaintCanvas::drawTextBlob(scoped_refptr<PaintTextBlob> blob,
}
void SkiaPaintCanvas::drawPicture(sk_sp<const PaintRecord> record) {
auto did_draw_op_cb =
context_flushes_.enable
? base::BindRepeating(&SkiaPaintCanvas::FlushAfterDrawIfNeeded,
base::Unretained(this))
: PlaybackParams::DidDrawOpCallback();
PlaybackParams params(image_provider_, canvas_->getTotalMatrix(),
PlaybackParams::CustomDataRasterCallback(),
did_draw_op_cb);
record->Playback(canvas_, params);
drawPicture(record, PlaybackParams::CustomDataRasterCallback());
}
bool SkiaPaintCanvas::isClipEmpty() const {
......@@ -385,6 +377,19 @@ void SkiaPaintCanvas::Annotate(AnnotationType type,
}
}
void SkiaPaintCanvas::drawPicture(
sk_sp<const PaintRecord> record,
PlaybackParams::CustomDataRasterCallback custom_raster_callback) {
auto did_draw_op_cb =
context_flushes_.enable
? base::BindRepeating(&SkiaPaintCanvas::FlushAfterDrawIfNeeded,
base::Unretained(this))
: PlaybackParams::DidDrawOpCallback();
PlaybackParams params(image_provider_, canvas_->getTotalMatrix(),
custom_raster_callback, did_draw_op_cb);
record->Playback(canvas_, params);
}
void SkiaPaintCanvas::FlushAfterDrawIfNeeded() {
if (!context_flushes_.enable)
return;
......
......@@ -135,6 +135,12 @@ class CC_PAINT_EXPORT SkiaPaintCanvas final : public PaintCanvas {
using PaintCanvas::drawImage;
using PaintCanvas::drawPicture;
// Same as the above drawPicture() except using the given custom data
// raster callback.
void drawPicture(
sk_sp<const PaintRecord> record,
PlaybackParams::CustomDataRasterCallback custom_raster_callback);
private:
// We always need skia shaders since the ops will be played on an SkCanvas.
static const bool kCreateSkiaShaders;
......
......@@ -227,15 +227,12 @@ IN_PROC_BROWSER_TEST_F(PrintBrowserTest, PrintSubframeContent) {
WaitUntilMessagesReceived();
}
// TODO(weili): Enabled the following tests when the render side change is
// completed.
// Printing frame content with a cross-site iframe which also has a cross-site
// iframe. The site reference chain is a.com --> b.com --> c.com.
// This test passes when both cross-site frames are printed and their
// responses which are checked in
// TestPrintFrameContentMsgFilter::CheckMessage().
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DISABLED_PrintSubframeChain) {
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, PrintSubframeChain) {
ASSERT_TRUE(embedded_test_server()->Started());
GURL url(embedded_test_server()->GetURL(
"/printing/content_with_iframe_chain.html"));
......@@ -282,7 +279,7 @@ IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DISABLED_PrintSubframeChain) {
// This test passes when both cross-site frames are printed and send back
// responses which are checked in
// TestPrintFrameContentMsgFilter::CheckMessage().
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DISABLED_PrintSubframeABA) {
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, PrintSubframeABA) {
ASSERT_TRUE(embedded_test_server()->Started());
GURL url(embedded_test_server()->GetURL(
"a.com", "/printing/content_with_iframe_loop.html"));
......
......@@ -193,7 +193,7 @@ void PrintViewManagerBase::PrintDocument(
}
#else
std::unique_ptr<PdfMetafileSkia> metafile =
std::make_unique<PdfMetafileSkia>(SkiaDocumentType::PDF);
std::make_unique<PdfMetafileSkia>();
CHECK(metafile->InitFromData(print_data->front(), print_data->size()));
// Update the rendered document. It will send notifications to the listener.
......
......@@ -30,9 +30,7 @@ uint64_t GenerateFrameGuid(int process_id, int frame_id) {
namespace printing {
PrintCompositeClient::PrintCompositeClient(content::WebContents* web_contents)
: for_preview_(false) {
DCHECK(web_contents);
}
: content::WebContentsObserver(web_contents), for_preview_(false) {}
PrintCompositeClient::~PrintCompositeClient() {}
......@@ -91,7 +89,6 @@ void PrintCompositeClient::DoCompositePageToPdf(
const ContentToProxyIdMap& subframe_content_info,
mojom::PdfCompositor::CompositePageToPdfCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
auto& compositor = GetCompositeRequest(document_cookie);
DCHECK(data_size);
......
......@@ -1221,7 +1221,8 @@ bool PrintRenderFrameHelper::CreatePreviewDocument() {
const std::vector<int>& pages = print_pages_params_->pages;
if (!print_preview_context_.CreatePreviewDocument(
std::move(prep_frame_view_), pages, print_params.printed_doc_type)) {
std::move(prep_frame_view_), pages, print_params.printed_doc_type,
print_params.document_cookie)) {
return false;
}
......@@ -1431,7 +1432,7 @@ void PrintRenderFrameHelper::OnPrintFrameContent(
if (!weak_this)
return;
PdfMetafileSkia metafile(SkiaDocumentType::MSKP);
PdfMetafileSkia metafile(SkiaDocumentType::MSKP, params.document_cookie);
gfx::Rect area(params.printable_area.width(), params.printable_area.height());
// Since GetVectorCanvasForNewPage() starts a new recording, it will return
// a valid canvas.
......@@ -1469,6 +1470,7 @@ void PrintRenderFrameHelper::OnPrintFrameContent(
DLOG(ERROR) << "CopyMetafileDataToSharedMem failed";
return;
}
Send(new PrintHostMsg_DidPrintFrameContent(
routing_id(), params.document_cookie, printed_frame_params));
......@@ -1668,7 +1670,8 @@ bool PrintRenderFrameHelper::PrintPagesNative(blink::WebLocalFrame* frame,
if (printed_pages.empty())
return false;
PdfMetafileSkia metafile(print_params.printed_doc_type);
PdfMetafileSkia metafile(print_params.printed_doc_type,
print_params.document_cookie);
CHECK(metafile.Init());
PrintHostMsg_DidPrintDocument_Params page_params;
......@@ -2028,6 +2031,7 @@ bool PrintRenderFrameHelper::CopyMetafileDataToReadOnlySharedMem(
&params->metafile_data_handle, nullptr, nullptr);
DCHECK_EQ(MOJO_RESULT_OK, result);
params->data_size = metafile.GetDataSize();
params->subframe_content_info = metafile.GetSubframeContentInfo();
return true;
}
......@@ -2195,7 +2199,8 @@ void PrintRenderFrameHelper::PrintPreviewContext::OnPrintPreview() {
bool PrintRenderFrameHelper::PrintPreviewContext::CreatePreviewDocument(
std::unique_ptr<PrepareFrameAndViewForPrint> prepared_frame,
const std::vector<int>& pages,
SkiaDocumentType doc_type) {
SkiaDocumentType doc_type,
int document_cookie) {
DCHECK_EQ(INITIALIZED, state_);
state_ = RENDERING;
......@@ -2210,7 +2215,7 @@ bool PrintRenderFrameHelper::PrintPreviewContext::CreatePreviewDocument(
return false;
}
metafile_ = std::make_unique<PdfMetafileSkia>(doc_type);
metafile_ = std::make_unique<PdfMetafileSkia>(doc_type, document_cookie);
CHECK(metafile_->Init());
current_page_index_ = 0;
......
......@@ -409,7 +409,8 @@ class PrintRenderFrameHelper
bool CreatePreviewDocument(
std::unique_ptr<PrepareFrameAndViewForPrint> prepared_frame,
const std::vector<int>& pages,
SkiaDocumentType doc_type);
SkiaDocumentType doc_type,
int document_cookie);
// Called after a page gets rendered. |page_time| is how long the
// rendering took.
......
......@@ -53,7 +53,8 @@ bool PrintRenderFrameHelper::PrintPagesNative(blink::WebLocalFrame* frame,
if (printed_pages.empty())
return false;
PdfMetafileSkia metafile(print_params.printed_doc_type);
PdfMetafileSkia metafile(print_params.printed_doc_type,
print_params.document_cookie);
CHECK(metafile.Init());
for (int page_number : printed_pages) {
......
......@@ -179,8 +179,7 @@ mojom::PdfCompositor::Status PdfCompositorImpl::CompositeToPdf(
}
std::vector<SkDocumentPage> pages(page_count);
// TODO(weili): Change the default functions to actual implementation.
SkDeserialProcs procs;
SkDeserialProcs procs = DeserializationProcs(&subframes);
if (!SkMultiPictureDocumentRead(&stream, pages.data(), page_count, &procs)) {
DLOG(ERROR) << "CompositeToPdf: Page reading failed.";
return mojom::PdfCompositor::Status::CONTENT_FORMAT_ERROR;
......@@ -211,6 +210,7 @@ sk_sp<SkPicture> PdfCompositorImpl::CompositeSubframe(uint64_t frame_guid) {
// The content of this frame should be available.
auto iter = frame_info_map_.find(frame_guid);
DCHECK(iter != frame_info_map_.end());
std::unique_ptr<FrameInfo>& frame_info = iter->second;
frame_info->composited = true;
......@@ -221,8 +221,7 @@ sk_sp<SkPicture> PdfCompositorImpl::CompositeSubframe(uint64_t frame_guid) {
// Composite the entire frame.
SkMemoryStream stream(iter->second->serialized_content->memory(),
iter->second->serialized_content->mapped_size());
// TODO(weili): Change the default functions to actual implementation.
SkDeserialProcs procs;
SkDeserialProcs procs = DeserializationProcs(&subframes);
iter->second->content = SkPicture::MakeFromStream(&stream, &procs);
return iter->second->content;
}
......
......@@ -213,7 +213,7 @@ void MockPrinter::PrintPage(
#if defined(OS_MACOSX)
printing::PdfMetafileCg metafile;
#else
printing::PdfMetafileSkia metafile(printing::SkiaDocumentType::PDF);
printing::PdfMetafileSkia metafile;
#endif
metafile.InitFromData(metafile_data.memory(), content.data_size);
printing::Image image(metafile);
......
......@@ -33,6 +33,7 @@
#include "content/renderer/render_widget.h"
#include "content/renderer/resource_timing_info_conversions.h"
#include "ipc/ipc_message_macros.h"
#include "printing/features/features.h"
#include "third_party/WebKit/public/common/feature_policy/feature_policy.h"
#include "third_party/WebKit/public/common/frame/frame_policy.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
......@@ -50,6 +51,13 @@
#include "content/renderer/mus/renderer_window_tree_client.h"
#endif
#if BUILDFLAG(ENABLE_PRINTING)
// nogncheck because dependency on //printing is conditional upon
// enable_basic_printing or enable_print_preview flags.
#include "printing/metafile_skia_wrapper.h" // nogncheck
#include "printing/pdf_metafile_skia.h" // nogncheck
#endif
namespace content {
namespace {
......@@ -796,4 +804,25 @@ SkBitmap* RenderFrameProxy::GetSadPageBitmap() {
return GetContentClient()->renderer()->GetSadWebViewBitmap();
}
uint32_t RenderFrameProxy::Print(const blink::WebRect& rect,
blink::WebCanvas* canvas) {
#if BUILDFLAG(ENABLE_PRINTING)
printing::PdfMetafileSkia* metafile =
printing::MetafileSkiaWrapper::GetMetafileFromCanvas(canvas);
DCHECK(metafile);
// Create a place holder content for the remote frame so it can be replaced
// with actual content later.
uint32_t content_id =
metafile->CreateContentForRemoteFrame(rect, routing_id_);
// Inform browser to print the remote subframe.
Send(new FrameHostMsg_PrintCrossProcessSubframe(
routing_id_, rect, metafile->GetDocumentCookie()));
return content_id;
#else
return 0;
#endif
}
} // namespace content
......@@ -15,6 +15,7 @@
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
#include "third_party/WebKit/public/common/feature_policy/feature_policy.h"
#include "third_party/WebKit/public/platform/WebCanvas.h"
#include "third_party/WebKit/public/platform/WebFocusType.h"
#include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h"
#include "third_party/WebKit/public/web/WebRemoteFrame.h"
......@@ -193,6 +194,7 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
blink::WebLocalFrame* source) override;
void FrameFocused() override;
base::UnguessableToken GetDevToolsFrameToken() override;
uint32_t Print(const blink::WebRect& rect, blink::WebCanvas* canvas) override;
// IPC handlers
void OnDidStartLoading();
......
......@@ -5,6 +5,9 @@
#include "printing/common/pdf_metafile_utils.h"
#include "base/time/time.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkTime.h"
namespace {
......@@ -24,6 +27,15 @@ SkTime::DateTime TimeToSkTime(base::Time time) {
return skdate;
}
sk_sp<SkPicture> GetEmptyPicture() {
SkPictureRecorder rec;
SkCanvas* canvas = rec.beginRecording(100, 100);
// Add some ops whose net effects equal to a noop.
canvas->save();
canvas->restore();
return rec.finishRecordingAsPicture();
}
} // namespace
namespace printing {
......@@ -42,4 +54,50 @@ sk_sp<SkDocument> MakePdfDocument(const std::string& creator,
return SkDocument::MakePDF(stream, metadata);
}
sk_sp<SkData> SerializeOopPicture(SkPicture* pic, void* ctx) {
const ContentToProxyIdMap* context =
reinterpret_cast<const ContentToProxyIdMap*>(ctx);
uint32_t pic_id = pic->uniqueID();
auto iter = context->find(pic_id);
if (iter == context->end())
return nullptr;
return SkData::MakeWithCopy(&pic_id, sizeof(pic_id));
}
sk_sp<SkPicture> DeserializeOopPicture(const void* data,
size_t length,
void* ctx) {
uint32_t pic_id;
if (length < sizeof(pic_id)) {
NOTREACHED(); // Should not happen if the content is as written.
return GetEmptyPicture();
}
memcpy(&pic_id, data, sizeof(pic_id));
auto* context = reinterpret_cast<DeserializationContext*>(ctx);
auto iter = context->find(pic_id);
if (iter == context->end()) {
// When we don't have the out-of-process picture available, we return
// an empty picture. Returning a nullptr will cause the deserialization
// crash.
return GetEmptyPicture();
}
return iter->second;
}
SkSerialProcs SerializationProcs(SerializationContext* ctx) {
SkSerialProcs procs;
procs.fPictureProc = SerializeOopPicture;
procs.fPictureCtx = ctx;
return procs;
}
SkDeserialProcs DeserializationProcs(DeserializationContext* ctx) {
SkDeserialProcs procs;
procs.fPictureProc = DeserializeOopPicture;
procs.fPictureCtx = ctx;
return procs;
}
} // namespace printing
......@@ -8,9 +8,11 @@
#include <map>
#include <string>
#include "base/containers/flat_map.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkDocument.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSerialProcs.h"
#include "third_party/skia/include/core/SkStream.h"
namespace printing {
......@@ -24,9 +26,20 @@ enum class SkiaDocumentType {
MAX = MSKP
};
// Stores the mapping between a content's unique id and its actual content.
using DeserializationContext = base::flat_map<uint32_t, sk_sp<SkPicture>>;
// Stores the mapping between content's unique id and its corresponding frame
// proxy id.
using SerializationContext = ContentToProxyIdMap;
sk_sp<SkDocument> MakePdfDocument(const std::string& creator,
SkWStream* stream);
SkSerialProcs SerializationProcs(SerializationContext* ctx);
SkDeserialProcs DeserializationProcs(DeserializationContext* ctx);
} // namespace printing
#endif // PRINTING_COMMON_PDF_METAFILE_UTILS_H_
......@@ -9,12 +9,17 @@
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file.h"
#include "base/stl_util.h"
#include "base/time/time.h"
#include "cc/paint/paint_record.h"
#include "cc/paint/paint_recorder.h"
#include "cc/paint/skia_paint_canvas.h"
#include "printing/print_settings.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSerialProcs.h"
#include "third_party/skia/include/core/SkStream.h"
// Note that headers in third_party/skia/src are fragile. This is
......@@ -62,12 +67,16 @@ struct Page {
};
// TODO(weili): Remove pdf from struct name and field names since it is used for
// other formats as well.
// other formats as well. Also change member variable names to
// conform with our style guide.
struct PdfMetafileSkiaData {
cc::PaintRecorder recorder_; // Current recording
std::vector<Page> pages_;
std::unique_ptr<SkStreamAsset> pdf_data_;
ContentToProxyIdMap subframe_content_info_;
std::map<uint32_t, sk_sp<SkPicture>> subframe_pics_;
int document_cookie_ = 0;
// The scale factor is used because Blink occasionally calls
// PaintCanvas::getTotalMatrix() even though the total matrix is not as
......@@ -81,9 +90,15 @@ struct PdfMetafileSkiaData {
#endif
};
PdfMetafileSkia::PdfMetafileSkia(SkiaDocumentType type)
PdfMetafileSkia::PdfMetafileSkia()
: data_(std::make_unique<PdfMetafileSkiaData>()) {
data_->type_ = SkiaDocumentType::PDF;
}
PdfMetafileSkia::PdfMetafileSkia(SkiaDocumentType type, int document_cookie)
: data_(std::make_unique<PdfMetafileSkiaData>()) {
data_->type_ = type;
data_->document_cookie_ = document_cookie;
}
PdfMetafileSkia::~PdfMetafileSkia() = default;
......@@ -166,19 +181,27 @@ bool PdfMetafileSkia::FinishDocument() {
SkDynamicMemoryWStream stream;
sk_sp<SkDocument> doc;
cc::PlaybackParams::CustomDataRasterCallback custom_callback;
switch (data_->type_) {
case SkiaDocumentType::PDF:
doc = MakePdfDocument(printing::GetAgent(), &stream);
break;
case SkiaDocumentType::MSKP:
doc = SkMakeMultiPictureDocument(&stream);
SkSerialProcs procs = SerializationProcs(&data_->subframe_content_info_);
doc = SkMakeMultiPictureDocument(&stream, &procs);
// It is safe to use base::Unretained(this) because the callback
// is only used by |canvas| in the following loop which has shorter
// lifetime than |this|.
custom_callback =
base::BindRepeating(&PdfMetafileSkia::CustomDataToSkPictureCallback,
base::Unretained(this));
break;
}
for (const Page& page : data_->pages_) {
cc::SkiaPaintCanvas canvas(
doc->beginPage(page.size_.width(), page.size_.height()));
canvas.drawPicture(page.content_);
canvas.drawPicture(page.content_, custom_callback);
doc->endPage();
}
doc->close();
......@@ -198,7 +221,7 @@ void PdfMetafileSkia::FinishFrameContent() {
SkDynamicMemoryWStream stream;
sk_sp<SkPicture> pic = ToSkPicture(data_->pages_[0].content_,
SkRect::MakeSize(data_->pages_[0].size_));
SkSerialProcs procs;
SkSerialProcs procs = SerializationProcs(&data_->subframe_content_info_);
pic->serialize(&stream, &procs);
data_->pdf_data_ = stream.detachAsStream();
}
......@@ -300,7 +323,8 @@ std::unique_ptr<PdfMetafileSkia> PdfMetafileSkia::GetMetafileForCurrentPage(
SkiaDocumentType type) {
// If we only ever need the metafile for the last page, should we
// only keep a handle on one PaintRecord?
auto metafile = std::make_unique<PdfMetafileSkia>(type);
auto metafile =
std::make_unique<PdfMetafileSkia>(type, data_->document_cookie_);
if (data_->pages_.size() == 0)
return metafile;
......@@ -308,6 +332,8 @@ std::unique_ptr<PdfMetafileSkia> PdfMetafileSkia::GetMetafileForCurrentPage(
return metafile;
metafile->data_->pages_.push_back(data_->pages_.back());
metafile->data_->subframe_content_info_ = data_->subframe_content_info_;
metafile->data_->subframe_pics_ = data_->subframe_pics_;
if (!metafile->FinishDocument()) // Generate PDF.
metafile.reset();
......@@ -315,4 +341,44 @@ std::unique_ptr<PdfMetafileSkia> PdfMetafileSkia::GetMetafileForCurrentPage(
return metafile;
}
uint32_t PdfMetafileSkia::CreateContentForRemoteFrame(const gfx::Rect& rect,
int render_proxy_id) {
// Create a place holder picture.
sk_sp<SkPicture> pic = SkPicture::MakePlaceholder(
SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()));
// Store the map between content id and the proxy id.
uint32_t content_id = pic->uniqueID();
DCHECK(!base::ContainsKey(data_->subframe_content_info_, content_id));
data_->subframe_content_info_[content_id] = render_proxy_id;
// Store the picture content.
data_->subframe_pics_[content_id] = pic;
return content_id;
}
int PdfMetafileSkia::GetDocumentCookie() const {
return data_->document_cookie_;
}
const ContentToProxyIdMap& PdfMetafileSkia::GetSubframeContentInfo() const {
return data_->subframe_content_info_;
}
void PdfMetafileSkia::CustomDataToSkPictureCallback(SkCanvas* canvas,
uint32_t content_id) {
// Check whether this is the one we need to handle.
if (!base::ContainsKey(data_->subframe_content_info_, content_id))
return;
auto it = data_->subframe_pics_.find(content_id);
DCHECK(it != data_->subframe_pics_.end());
// Found the picture, draw it on canvas.
sk_sp<SkPicture> pic = it->second;
SkRect rect = pic->cullRect();
SkMatrix matrix = SkMatrix::MakeTrans(rect.x(), rect.y());
canvas->drawPicture(it->second, &matrix, nullptr);
}
} // namespace printing
......@@ -28,7 +28,11 @@ struct PdfMetafileSkiaData;
// TODO(thestig): Rename to MetafileSkia.
class PRINTING_EXPORT PdfMetafileSkia : public Metafile {
public:
explicit PdfMetafileSkia(SkiaDocumentType type);
// Default constructor, for SkiaDocumentType::PDF type only.
// TODO(weili): we should split up this use case into a different class, see
// comments before InitFromData()'s implementation.
PdfMetafileSkia();
PdfMetafileSkia(SkiaDocumentType type, int document_cookie);
~PdfMetafileSkia() override;
// Metafile methods.
......@@ -81,7 +85,21 @@ class PRINTING_EXPORT PdfMetafileSkia : public Metafile {
const gfx::Rect& content_area,
const float& scale_factor);
// This is used for painting content of out-of-process subframes.
// For such a subframe, since the content is in another process, we create a
// place holder picture now, and replace it with actual content by pdf
// compositor service later.
uint32_t CreateContentForRemoteFrame(const gfx::Rect& rect,
int render_proxy_id);
int GetDocumentCookie() const;
const ContentToProxyIdMap& GetSubframeContentInfo() const;
private:
// Callback function used during page content drawing to replace a custom
// data holder with corresponding place holder SkPicture.
void CustomDataToSkPictureCallback(SkCanvas* canvas, uint32_t content_id);
std::unique_ptr<PdfMetafileSkiaData> data_;
DISALLOW_COPY_AND_ASSIGN(PdfMetafileSkia);
......
......@@ -8,6 +8,7 @@
#include "core/frame/FrameClient.h"
#include "core/frame/FrameTypes.h"
#include "core/loader/FrameLoaderTypes.h"
#include "public/platform/WebCanvas.h"
#include "public/platform/WebFocusType.h"
namespace blink {
......@@ -50,6 +51,8 @@ class RemoteFrameClient : public FrameClient {
virtual void UpdateRenderThrottlingStatus(bool isThrottled,
bool subtreeThrottled) = 0;
virtual uint32_t Print(const IntRect&, WebCanvas*) const = 0;
};
} // namespace blink
......
......@@ -178,4 +178,9 @@ void RemoteFrameClientImpl::UpdateRenderThrottlingStatus(
subtree_throttled);
}
uint32_t RemoteFrameClientImpl::Print(const IntRect& rect,
WebCanvas* canvas) const {
return web_frame_->Client()->Print(rect, canvas);
}
} // namespace blink
......@@ -44,6 +44,7 @@ class RemoteFrameClientImpl final : public RemoteFrameClient {
void SetIsInert(bool) override;
void UpdateRenderThrottlingStatus(bool is_throttled,
bool subtree_throttled) override;
uint32_t Print(const IntRect&, WebCanvas*) const override;
WebRemoteFrameImpl* GetWebFrame() const { return web_frame_; }
......
......@@ -13,6 +13,10 @@
#include "core/intersection_observer/IntersectionObserverEntry.h"
#include "core/layout/LayoutEmbeddedContent.h"
#include "core/layout/LayoutView.h"
#include "platform/geometry/IntRect.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/paint/CullRect.h"
#include "platform/graphics/paint/DrawingRecorder.h"
namespace blink {
......@@ -155,6 +159,26 @@ void RemoteFrameView::FrameRectsChanged() {
remote_frame_->Client()->FrameRectsChanged(frame_rect, screen_space_rect);
}
void RemoteFrameView::Paint(GraphicsContext& context,
const GlobalPaintFlags flags,
const CullRect& rect) const {
// Painting remote frames is only for printing.
if (!context.Printing())
return;
if (!rect.IntersectsCullRect(FrameRect()))
return;
DrawingRecorder recorder(context, *GetFrame().OwnerLayoutObject(),
DisplayItem::kDocumentBackground);
DCHECK(context.Canvas());
// Inform the remote frame to print.
uint32_t content_id = Print(FrameRect(), context.Canvas());
// Record the place holder id on canvas.
context.Canvas()->recordCustomData(content_id);
}
void RemoteFrameView::UpdateGeometry() {
if (LayoutEmbeddedContent* layout = remote_frame_->OwnerLayoutObject())
layout->UpdateGeometry(*this);
......@@ -259,6 +283,10 @@ bool RemoteFrameView::HasIntrinsicSizingInfo() const {
return has_intrinsic_sizing_info_;
}
uint32_t RemoteFrameView::Print(const IntRect& rect, WebCanvas* canvas) const {
return remote_frame_->Client()->Print(rect, canvas);
}
void RemoteFrameView::Trace(blink::Visitor* visitor) {
visitor->Trace(remote_frame_);
visitor->Trace(visibility_observer_);
......
......@@ -10,6 +10,7 @@
#include "core/frame/LocalFrameView.h"
#include "platform/geometry/IntRect.h"
#include "platform/heap/Handle.h"
#include "public/platform/WebCanvas.h"
namespace blink {
......@@ -44,7 +45,7 @@ class RemoteFrameView final : public GarbageCollectedFinalized<RemoteFrameView>,
IntRect FrameRect() const override;
void Paint(GraphicsContext&,
const GlobalPaintFlags,
const CullRect&) const override {}
const CullRect&) const override;
void UpdateGeometry() override;
void Hide() override;
void Show() override;
......@@ -58,6 +59,8 @@ class RemoteFrameView final : public GarbageCollectedFinalized<RemoteFrameView>,
void SetIntrinsicSizeInfo(const IntrinsicSizingInfo& size_info);
bool HasIntrinsicSizingInfo() const override;
uint32_t Print(const IntRect&, WebCanvas*) const;
virtual void Trace(blink::Visitor*);
private:
......
......@@ -49,6 +49,7 @@
#include "platform/loader/fetch/ResourceError.h"
#include "platform/wtf/Forward.h"
#include "public/platform/Platform.h"
#include "public/platform/WebCanvas.h"
#include "public/platform/WebFocusType.h"
#include "public/platform/WebMenuSourceType.h"
#include "public/platform/WebScreenInfo.h"
......@@ -428,6 +429,9 @@ class CORE_EXPORT EmptyRemoteFrameClient : public RemoteFrameClient {
void SetIsInert(bool) override {}
void UpdateRenderThrottlingStatus(bool is_throttled,
bool subtree_throttled) override {}
uint32_t Print(const IntRect& rect, WebCanvas* canvas) const override {
return 0;
}
// FrameClient implementation.
bool InShadowTree() const override { return false; }
......
......@@ -5,6 +5,7 @@
#ifndef WebRemoteFrameClient_h
#define WebRemoteFrameClient_h
#include "public/platform/WebCanvas.h"
#include "public/platform/WebFocusType.h"
#include "public/platform/WebSecurityOrigin.h"
#include "public/web/WebDOMMessageEvent.h"
......@@ -69,6 +70,13 @@ class WebRemoteFrameClient {
return base::UnguessableToken::Create();
}
// Print out this frame.
// |rect| is the rectangular area where this frame resides in its parent
// frame.
// |canvas| is the canvas we are printing on.
// Returns the id of the placeholder content.
virtual uint32_t Print(const WebRect& rect, WebCanvas* canvas) { return 0; }
protected:
virtual ~WebRemoteFrameClient() = default;
};
......
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