| Index: services/pdf_compositor/pdf_compositor_impl.cc
|
| diff --git a/services/pdf_compositor/pdf_compositor_impl.cc b/services/pdf_compositor/pdf_compositor_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..af92002602ed8f85c03717fc74e2178ca368beab
|
| --- /dev/null
|
| +++ b/services/pdf_compositor/pdf_compositor_impl.cc
|
| @@ -0,0 +1,159 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "services/pdf_compositor/pdf_compositor_impl.h"
|
| +
|
| +#include <string.h>
|
| +
|
| +#include <utility>
|
| +#include <vector>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/memory/shared_memory_handle.h"
|
| +#include "mojo/public/cpp/bindings/strong_binding.h"
|
| +#include "mojo/public/cpp/system/platform_handle.h"
|
| +#include "printing/pdf_metafile_skia.h"
|
| +#include "services/pdf_compositor/public/cpp/compositor_data.h"
|
| +#include "skia/ext/SkFutureDrawable.h"
|
| +#include "skia/ext/skia_utils_base.h"
|
| +
|
| +namespace pdf_compositor {
|
| +
|
| +PdfCompositorImpl::PdfCompositorImpl(
|
| + std::unique_ptr<service_manager::ServiceContextRef> service_ref)
|
| + : service_ref_(std::move(service_ref)) {}
|
| +
|
| +PdfCompositorImpl::~PdfCompositorImpl() = default;
|
| +
|
| +/*
|
| +void PdfCompositorImpl::PrepareComposition(int frameId) {
|
| + painted_subframes_.clear();
|
| + pages_with_subframe_.clear();
|
| + pending_subframes_in_page_.clear();
|
| + SkFutureDrawable::resetDrawableRef();
|
| +}*/
|
| +
|
| +void PdfCompositorImpl::PrepareSubframe(int subframe_id, int page_num) {
|
| + // Check whether this frame is already painted.
|
| + if (painted_subframes_.find(subframe_id) != painted_subframes_.end())
|
| + return;
|
| +
|
| + // Need to wait for this subframe to finish painting.
|
| + pages_with_subframe_[subframe_id].insert(page_num);
|
| + pending_subframes_in_page_[page_num].insert(subframe_id);
|
| +}
|
| +
|
| +void PdfCompositorImpl::AddSubFrameContent(
|
| + int subframe_id,
|
| + mojo::ScopedSharedBufferHandle sk_handle) {
|
| + base::SharedMemoryHandle memory_handle;
|
| + size_t memory_size = 0;
|
| + bool read_only_flag = false;
|
| +
|
| + const MojoResult result = mojo::UnwrapSharedMemoryHandle(
|
| + std::move(sk_handle), &memory_handle, &memory_size, &read_only_flag);
|
| + DCHECK_EQ(MOJO_RESULT_OK, result);
|
| + DCHECK_GT(memory_size, 0u);
|
| +
|
| + std::unique_ptr<base::SharedMemory> shm(
|
| + new base::SharedMemory(memory_handle, true));
|
| + if (!shm->Map(memory_size)) {
|
| + DLOG(ERROR) << "OnBufferCreated: Map failed.";
|
| + return;
|
| + }
|
| +
|
| + size_t size = *((size_t*)shm->memory());
|
| + size_t off = 2 * sizeof(SkScalar) + sizeof(size_t);
|
| + std::unique_ptr<SkDrawable> d =
|
| + skia::ReadDrawable((char*)shm->memory() + off, size);
|
| +
|
| + // Update the maps to remove dependecy on this subframe.
|
| + auto pages_entry = pages_with_subframe_.find(subframe_id);
|
| + if (pages_entry != pages_with_subframe_.end()) {
|
| + auto pages = pages_entry->second;
|
| + for (auto page : pages) {
|
| + auto frames_entry = pending_subframes_in_page_.find(page);
|
| + if (frames_entry != pending_subframes_in_page_.end()) {
|
| + // Page no longer depends on this frame.
|
| + if (frames_entry->second.size() == 1)
|
| + pending_subframes_in_page_.erase(frames_entry);
|
| + else
|
| + frames_entry->second.erase(subframe_id);
|
| + }
|
| + }
|
| + pages_with_subframe_.erase(pages_entry);
|
| + }
|
| + painted_subframes_.insert(subframe_id);
|
| +
|
| + SkFutureDrawable::addDrawableRef(subframe_id, std::move(d));
|
| +}
|
| +
|
| +void PdfCompositorImpl::IsReadyToComposite(
|
| + int page_num,
|
| + const mojom::PdfCompositor::IsReadyToCompositeCallback& callback) {
|
| + if (page_num == kPageRangeAll) {
|
| + // Need to check for all pages.
|
| + callback.Run(pages_with_subframe_.empty());
|
| + } else {
|
| + callback.Run(pending_subframes_in_page_.find(page_num) ==
|
| + pending_subframes_in_page_.end());
|
| + }
|
| +}
|
| +
|
| +void PdfCompositorImpl::CompositePdf(
|
| + mojo::ScopedSharedBufferHandle sk_handle,
|
| + const mojom::PdfCompositor::CompositePdfCallback& callback) {
|
| + DCHECK(sk_handle.is_valid());
|
| +
|
| + // Check whether all the subframes are ready.
|
| + if (!pages_with_subframe_.empty()) {
|
| + // Should not happen.
|
| + return;
|
| + }
|
| +
|
| + base::SharedMemoryHandle memory_handle;
|
| + size_t memory_size = 0;
|
| + bool read_only_flag = false;
|
| +
|
| + const MojoResult result = mojo::UnwrapSharedMemoryHandle(
|
| + std::move(sk_handle), &memory_handle, &memory_size, &read_only_flag);
|
| + DCHECK_EQ(MOJO_RESULT_OK, result);
|
| + DCHECK_GT(memory_size, 0u);
|
| +
|
| + std::unique_ptr<base::SharedMemory> shm(
|
| + new base::SharedMemory(memory_handle, true));
|
| + if (!shm->Map(memory_size)) {
|
| + DLOG(ERROR) << "OnBufferCreated: Map failed.";
|
| + return;
|
| + }
|
| +
|
| + std::vector<uint8_t> ret_buf;
|
| + if (shm->mapped_size() == 0) {
|
| + callback.Run(mojo::ScopedSharedBufferHandle());
|
| + return;
|
| + }
|
| +
|
| + std::unique_ptr<printing::PdfMetafileSkia> metafile(
|
| + new printing::PdfMetafileSkia(printing::PDF_SKIA_DOCUMENT_TYPE));
|
| + if (!metafile->InitFromPageDataBuffer((char*)shm->memory(), memory_size)) {
|
| + NOTREACHED() << "Invalid metafile header";
|
| + callback.Run(mojo::ScopedSharedBufferHandle());
|
| + return;
|
| + }
|
| +
|
| + metafile->ConvertPagesToPdf();
|
| + metafile->GetDataAsVector((std::vector<char>*)&ret_buf);
|
| +
|
| + mojo::ScopedSharedBufferHandle buffer =
|
| + mojo::SharedBufferHandle::Create(ret_buf.size());
|
| + CHECK(buffer.is_valid());
|
| +
|
| + mojo::ScopedSharedBufferMapping mapping = buffer->Map(ret_buf.size());
|
| + CHECK(mapping);
|
| + std::copy(ret_buf.begin(), ret_buf.end(),
|
| + reinterpret_cast<char*>(mapping.get()));
|
| +
|
| + callback.Run(std::move(buffer));
|
| +}
|
| +} // namespace pdf_compositor
|
|
|