| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "services/pdf_compositor/pdf_compositor_impl.h" |
| 6 |
| 7 #include <string.h> |
| 8 |
| 9 #include <utility> |
| 10 #include <vector> |
| 11 |
| 12 #include "base/logging.h" |
| 13 #include "base/memory/shared_memory_handle.h" |
| 14 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 15 #include "mojo/public/cpp/system/platform_handle.h" |
| 16 #include "printing/pdf_metafile_skia.h" |
| 17 #include "services/pdf_compositor/public/cpp/compositor_data.h" |
| 18 #include "skia/ext/SkFutureDrawable.h" |
| 19 #include "skia/ext/skia_utils_base.h" |
| 20 |
| 21 namespace pdf_compositor { |
| 22 |
| 23 PdfCompositorImpl::PdfCompositorImpl( |
| 24 std::unique_ptr<service_manager::ServiceContextRef> service_ref) |
| 25 : service_ref_(std::move(service_ref)) {} |
| 26 |
| 27 PdfCompositorImpl::~PdfCompositorImpl() = default; |
| 28 |
| 29 /* |
| 30 void PdfCompositorImpl::PrepareComposition(int frameId) { |
| 31 painted_subframes_.clear(); |
| 32 pages_with_subframe_.clear(); |
| 33 pending_subframes_in_page_.clear(); |
| 34 SkFutureDrawable::resetDrawableRef(); |
| 35 }*/ |
| 36 |
| 37 void PdfCompositorImpl::PrepareSubframe(int subframe_id, int page_num) { |
| 38 // Check whether this frame is already painted. |
| 39 if (painted_subframes_.find(subframe_id) != painted_subframes_.end()) |
| 40 return; |
| 41 |
| 42 // Need to wait for this subframe to finish painting. |
| 43 pages_with_subframe_[subframe_id].insert(page_num); |
| 44 pending_subframes_in_page_[page_num].insert(subframe_id); |
| 45 } |
| 46 |
| 47 void PdfCompositorImpl::AddSubFrameContent( |
| 48 int subframe_id, |
| 49 mojo::ScopedSharedBufferHandle sk_handle) { |
| 50 base::SharedMemoryHandle memory_handle; |
| 51 size_t memory_size = 0; |
| 52 bool read_only_flag = false; |
| 53 |
| 54 const MojoResult result = mojo::UnwrapSharedMemoryHandle( |
| 55 std::move(sk_handle), &memory_handle, &memory_size, &read_only_flag); |
| 56 DCHECK_EQ(MOJO_RESULT_OK, result); |
| 57 DCHECK_GT(memory_size, 0u); |
| 58 |
| 59 std::unique_ptr<base::SharedMemory> shm( |
| 60 new base::SharedMemory(memory_handle, true)); |
| 61 if (!shm->Map(memory_size)) { |
| 62 DLOG(ERROR) << "OnBufferCreated: Map failed."; |
| 63 return; |
| 64 } |
| 65 |
| 66 size_t size = *((size_t*)shm->memory()); |
| 67 size_t off = 2 * sizeof(SkScalar) + sizeof(size_t); |
| 68 std::unique_ptr<SkDrawable> d = |
| 69 skia::ReadDrawable((char*)shm->memory() + off, size); |
| 70 |
| 71 // Update the maps to remove dependecy on this subframe. |
| 72 auto pages_entry = pages_with_subframe_.find(subframe_id); |
| 73 if (pages_entry != pages_with_subframe_.end()) { |
| 74 auto pages = pages_entry->second; |
| 75 for (auto page : pages) { |
| 76 auto frames_entry = pending_subframes_in_page_.find(page); |
| 77 if (frames_entry != pending_subframes_in_page_.end()) { |
| 78 // Page no longer depends on this frame. |
| 79 if (frames_entry->second.size() == 1) |
| 80 pending_subframes_in_page_.erase(frames_entry); |
| 81 else |
| 82 frames_entry->second.erase(subframe_id); |
| 83 } |
| 84 } |
| 85 pages_with_subframe_.erase(pages_entry); |
| 86 } |
| 87 painted_subframes_.insert(subframe_id); |
| 88 |
| 89 SkFutureDrawable::addDrawableRef(subframe_id, std::move(d)); |
| 90 } |
| 91 |
| 92 void PdfCompositorImpl::IsReadyToComposite( |
| 93 int page_num, |
| 94 const mojom::PdfCompositor::IsReadyToCompositeCallback& callback) { |
| 95 if (page_num == kPageRangeAll) { |
| 96 // Need to check for all pages. |
| 97 callback.Run(pages_with_subframe_.empty()); |
| 98 } else { |
| 99 callback.Run(pending_subframes_in_page_.find(page_num) == |
| 100 pending_subframes_in_page_.end()); |
| 101 } |
| 102 } |
| 103 |
| 104 void PdfCompositorImpl::CompositePdf( |
| 105 mojo::ScopedSharedBufferHandle sk_handle, |
| 106 const mojom::PdfCompositor::CompositePdfCallback& callback) { |
| 107 DCHECK(sk_handle.is_valid()); |
| 108 |
| 109 // Check whether all the subframes are ready. |
| 110 if (!pages_with_subframe_.empty()) { |
| 111 // Should not happen. |
| 112 return; |
| 113 } |
| 114 |
| 115 base::SharedMemoryHandle memory_handle; |
| 116 size_t memory_size = 0; |
| 117 bool read_only_flag = false; |
| 118 |
| 119 const MojoResult result = mojo::UnwrapSharedMemoryHandle( |
| 120 std::move(sk_handle), &memory_handle, &memory_size, &read_only_flag); |
| 121 DCHECK_EQ(MOJO_RESULT_OK, result); |
| 122 DCHECK_GT(memory_size, 0u); |
| 123 |
| 124 std::unique_ptr<base::SharedMemory> shm( |
| 125 new base::SharedMemory(memory_handle, true)); |
| 126 if (!shm->Map(memory_size)) { |
| 127 DLOG(ERROR) << "OnBufferCreated: Map failed."; |
| 128 return; |
| 129 } |
| 130 |
| 131 std::vector<uint8_t> ret_buf; |
| 132 if (shm->mapped_size() == 0) { |
| 133 callback.Run(mojo::ScopedSharedBufferHandle()); |
| 134 return; |
| 135 } |
| 136 |
| 137 std::unique_ptr<printing::PdfMetafileSkia> metafile( |
| 138 new printing::PdfMetafileSkia(printing::PDF_SKIA_DOCUMENT_TYPE)); |
| 139 if (!metafile->InitFromPageDataBuffer((char*)shm->memory(), memory_size)) { |
| 140 NOTREACHED() << "Invalid metafile header"; |
| 141 callback.Run(mojo::ScopedSharedBufferHandle()); |
| 142 return; |
| 143 } |
| 144 |
| 145 metafile->ConvertPagesToPdf(); |
| 146 metafile->GetDataAsVector((std::vector<char>*)&ret_buf); |
| 147 |
| 148 mojo::ScopedSharedBufferHandle buffer = |
| 149 mojo::SharedBufferHandle::Create(ret_buf.size()); |
| 150 CHECK(buffer.is_valid()); |
| 151 |
| 152 mojo::ScopedSharedBufferMapping mapping = buffer->Map(ret_buf.size()); |
| 153 CHECK(mapping); |
| 154 std::copy(ret_buf.begin(), ret_buf.end(), |
| 155 reinterpret_cast<char*>(mapping.get())); |
| 156 |
| 157 callback.Run(std::move(buffer)); |
| 158 } |
| 159 } // namespace pdf_compositor |
| OLD | NEW |