Changeset 133935 in webkit
- Timestamp:
- Nov 8, 2012, 12:47:34 PM (12 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r133890 r133935 1 2012-11-08 Tim Horton <timothy_horton@apple.com> 2 3 [WK2] Print preview should vend images to the UIProcess instead of PDFs 4 https://bugs.webkit.org/show_bug.cgi?id=101382 5 <rdar://problem/9866766> 6 7 Reviewed by Alexey Proskuryakov. 8 9 In the interests of keeping PDF processing inside the WebProcess, we should 10 remove print preview's reliance on PDFs, by handing bitmaps back instead. 11 12 * Shared/ShareableBitmap.cpp: 13 (WebKit::ShareableBitmap::create): Add an optional SharedMemory::Protection argument, so we can make 14 ShareableBitmaps from read-only handles if desired. Defaults to read-write as previously. 15 (WebKit::ShareableBitmap::createHandle): Add an optional SharedMemory::Protection argument, so we can make 16 read-only handles if desired. Defaults to read-write as previously. 17 * Shared/ShareableBitmap.h: 18 * UIProcess/API/mac/WKPrintingView.h: 19 (WebImage): Store WebImages instead of raw PDF data for previews. 20 * UIProcess/API/mac/WKPrintingView.mm: 21 (pageDidDrawToImage): Add a callback for when a preview we've requested is done rendering into an image. 22 Cache the image in _pagePreviews if appropriate. 23 (pageDidDrawToPDF): Do not handle PDF data unless we are expecting a real print callback (not a preview). 24 (-[WKPrintingView _drawPreview:]): Request an image instead of PDF data when doing a print preview. 25 * UIProcess/GenericCallback.h: 26 (ImageCallback): Add a callback type with one argument: a ShareableBitmap::Handle. 27 I can't use the GenericCallback template because ShareableBitmap::Handle doesn't have a corresponding WK type. 28 * UIProcess/WebPageProxy.cpp: 29 (WebKit::WebPageProxy::close): Add support for ImageCallback. 30 (WebKit::WebPageProxy::imageCallback): Add support for ImageCallback. 31 (WebKit::WebPageProxy::drawRectToImage): Rename drawRectToPDF to drawRectToImage. 32 * UIProcess/WebPageProxy.h: 33 (WebPageProxy): Rename drawRectToPDF to drawRectToImage, add support for ImageCallback. 34 * UIProcess/WebPageProxy.messages.in: Add support for ImageCallback. 35 * WebProcess/WebPage/WebPage.cpp: 36 (WebKit::WebPage::drawRectToImage): Rename drawRectToPDF to drawRectToImage. 37 Make drawRectToImage create a bitmap snapshot of the page (using the normal snapshotting code), 38 or, if the page is backed by a *PDFPlugin, draw the PDF document into a bitmap and use that. 39 * WebProcess/WebPage/WebPage.h: 40 (WebPage): Rename drawRectToPDF to drawRectToImage. 41 * WebProcess/WebPage/WebPage.messages.in: Rename drawRectToPDF to drawRectToImage. 42 * WebProcess/WebPage/mac/WebPageMac.mm: 43 (WebKit::WebPage::drawPDFDocument): Rename drawRectToPDFFromPDFDocument to drawPDFDocument, 44 because it's more like drawImage than anything else. 45 1 46 2012-11-08 Simon Hausmann <simon.hausmann@digia.com> 2 47 -
trunk/Source/WebKit2/Shared/ShareableBitmap.cpp
r132926 r133935 90 90 } 91 91 92 PassRefPtr<ShareableBitmap> ShareableBitmap::create(const Handle& handle )92 PassRefPtr<ShareableBitmap> ShareableBitmap::create(const Handle& handle, SharedMemory::Protection protection) 93 93 { 94 94 // Create the shared memory. 95 RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle.m_handle, SharedMemory::ReadWrite);95 RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle.m_handle, protection); 96 96 if (!sharedMemory) 97 97 return 0; … … 100 100 } 101 101 102 bool ShareableBitmap::createHandle(Handle& handle )102 bool ShareableBitmap::createHandle(Handle& handle, SharedMemory::Protection protection) 103 103 { 104 104 ASSERT(isBackedBySharedMemory()); 105 105 106 if (!m_sharedMemory->createHandle(handle.m_handle, SharedMemory::ReadWrite))106 if (!m_sharedMemory->createHandle(handle.m_handle, protection)) 107 107 return false; 108 108 handle.m_size = m_size; -
trunk/Source/WebKit2/Shared/ShareableBitmap.h
r132361 r133935 94 94 95 95 // Create a shareable bitmap from a handle. 96 static PassRefPtr<ShareableBitmap> create(const Handle& );96 static PassRefPtr<ShareableBitmap> create(const Handle&, SharedMemory::Protection = SharedMemory::ReadWrite); 97 97 98 98 // Create a handle. 99 bool createHandle(Handle& );99 bool createHandle(Handle&, SharedMemory::Protection = SharedMemory::ReadWrite); 100 100 101 101 ~ShareableBitmap(); -
trunk/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h
r104377 r133935 31 31 32 32 namespace WebKit { 33 class ShareableBitmap; 33 34 class WebFrameProxy; 34 35 } … … 42 43 Vector<WebCore::IntRect> _printingPageRects; 43 44 double _totalScaleFactorForPrinting; 44 HashMap<WebCore::IntRect, Vector<uint8_t> > _pagePreviews;45 HashMap<WebCore::IntRect, RefPtr<WebKit::ShareableBitmap> > _pagePreviews; 45 46 46 47 Vector<uint8_t> _printedPagesData; -
trunk/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm
r130612 r133935 30 30 #import "PDFKitImports.h" 31 31 #import "PrintInfo.h" 32 #import "ShareableBitmap.h" 32 33 #import "WebData.h" 33 34 #import "WebPageProxy.h" 34 35 #import <PDFKit/PDFKit.h> 36 #import <WebCore/GraphicsContext.h> 35 37 #import <WebCore/WebCoreObjCExtras.h> 36 38 #import <wtf/MainThread.h> … … 206 208 }; 207 209 210 static void pageDidDrawToImage(const ShareableBitmap::Handle& imageHandle, WKErrorRef, void* untypedContext) 211 { 212 ASSERT(isMainThread()); 213 214 OwnPtr<IPCCallbackContext> context = adoptPtr(static_cast<IPCCallbackContext*>(untypedContext)); 215 WKPrintingView *view = context->view.get(); 216 217 // If the user has already changed print setup, then this response is obsolete. And if this callback is not in response to the latest request, 218 // then the user has already moved to another page - we'll cache the response, but won't draw it. 219 HashMap<uint64_t, WebCore::IntRect>::iterator iter = view->_expectedPreviewCallbacks.find(context->callbackID); 220 if (iter != view->_expectedPreviewCallbacks.end()) { 221 ASSERT([view _isPrintingPreview]); 222 223 if (!imageHandle.isNull()) { 224 RefPtr<ShareableBitmap> image = ShareableBitmap::create(imageHandle, SharedMemory::ReadOnly); 225 226 if (image) 227 view->_pagePreviews.add(iter->value, image); 228 } 229 230 view->_expectedPreviewCallbacks.remove(context->callbackID); 231 bool receivedResponseToLatestRequest = view->_latestExpectedPreviewCallback == context->callbackID; 232 if (receivedResponseToLatestRequest) { 233 view->_latestExpectedPreviewCallback = 0; 234 [view _updatePreview]; 235 } 236 } 237 } 238 208 239 static void pageDidDrawToPDF(WKDataRef dataRef, WKErrorRef, void* untypedContext) 209 240 { … … 222 253 view->_expectedPrintCallback = 0; 223 254 view->_printingCallbackCondition.signal(); 224 } else {225 // If the user has already changed print setup, then this response is obsolete. And this callback is not in response to the latest request,226 // then the user has already moved to another page - we'll cache the response, but won't draw it.227 HashMap<uint64_t, WebCore::IntRect>::iterator iter = view->_expectedPreviewCallbacks.find(context->callbackID);228 if (iter != view->_expectedPreviewCallbacks.end()) {229 ASSERT([view _isPrintingPreview]);230 231 if (data) {232 HashMap<WebCore::IntRect, Vector<uint8_t> >::AddResult entry = view->_pagePreviews.add(iter->value, Vector<uint8_t>());233 entry.iterator->value.append(data->bytes(), data->size());234 }235 view->_expectedPreviewCallbacks.remove(context->callbackID);236 bool receivedResponseToLatestRequest = view->_latestExpectedPreviewCallback == context->callbackID;237 if (receivedResponseToLatestRequest) {238 view->_latestExpectedPreviewCallback = 0;239 [view _updatePreview];240 }241 }242 255 } 243 256 } … … 462 475 IntRect rect(nsRect); 463 476 rect.scale(1 / _totalScaleFactorForPrinting); 464 HashMap<WebCore::IntRect, Vector<uint8_t> >::iterator pagePreviewIterator = _pagePreviews.find(rect);477 HashMap<WebCore::IntRect, RefPtr<ShareableBitmap> >::iterator pagePreviewIterator = _pagePreviews.find(rect); 465 478 if (pagePreviewIterator == _pagePreviews.end()) { 466 479 // It's too early to ask for page preview if we don't even know page size and scale. … … 479 492 480 493 IPCCallbackContext* context = new IPCCallbackContext; 481 RefPtr< DataCallback> callback = DataCallback::create(context, pageDidDrawToPDF);494 RefPtr<ImageCallback> callback = ImageCallback::create(context, pageDidDrawToImage); 482 495 _latestExpectedPreviewCallback = callback->callbackID(); 483 496 _expectedPreviewCallbacks.add(_latestExpectedPreviewCallback, rect); … … 486 499 context->callbackID = callback->callbackID(); 487 500 488 _webFrame->page()->drawRectTo PDF(_webFrame.get(), PrintInfo([_printOperation printInfo]), rect, callback.get());501 _webFrame->page()->drawRectToImage(_webFrame.get(), PrintInfo([_printOperation printInfo]), rect, callback.get()); 489 502 return; 490 503 } … … 495 508 } 496 509 497 const Vector<uint8_t>& pdfDataBytes = pagePreviewIterator->value; 498 RetainPtr<NSData> pdfData(AdoptNS, [[NSData alloc] initWithBytes:pdfDataBytes.data() length:pdfDataBytes.size()]); 499 RetainPtr<PDFDocument> pdfDocument(AdoptNS, [[pdfDocumentClass() alloc] initWithData:pdfData.get()]); 500 501 [self _drawPDFDocument:pdfDocument.get() page:0 atPoint:NSMakePoint(nsRect.origin.x, nsRect.origin.y)]; 510 RefPtr<ShareableBitmap> bitmap = pagePreviewIterator->value; 511 CGContextRef cgContext = static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]); 512 513 GraphicsContext context(cgContext); 514 GraphicsContextStateSaver stateSaver(context); 515 516 context.translate(nsRect.origin.x, nsRect.origin.y); 517 context.scale(FloatSize(_totalScaleFactorForPrinting, _totalScaleFactorForPrinting)); 518 519 // FIXME: Should we get the WebPage's deviceScaleFactor from here instead? 520 const IntRect& imageBounds = bitmap->bounds(); 521 float imageScaleFactor = imageBounds.width() / rect.width(); 522 523 bitmap->paint(context, imageScaleFactor, IntPoint(), imageBounds); 502 524 } 503 525 -
trunk/Source/WebKit2/UIProcess/GenericCallback.h
r128683 r133935 27 27 #define GenericCallback_h 28 28 29 #include "ShareableBitmap.h" 29 30 #include "WKAPICast.h" 30 31 31 #include "WebError.h" 32 32 #include <wtf/HashMap.h> … … 193 193 } 194 194 195 CallbackFunction m_callback; 196 }; 197 198 class ImageCallback : public CallbackBase { 199 public: 200 typedef void (*CallbackFunction)(const ShareableBitmap::Handle&, WKErrorRef, void*); 201 202 static PassRefPtr<ImageCallback> create(void* context, CallbackFunction callback) 203 { 204 return adoptRef(new ImageCallback(context, callback)); 205 } 206 207 virtual ~ImageCallback() 208 { 209 ASSERT(!m_callback); 210 } 211 212 void performCallbackWithReturnValue(const ShareableBitmap::Handle& returnValue1) 213 { 214 ASSERT(m_callback); 215 216 m_callback(returnValue1, 0, context()); 217 218 m_callback = 0; 219 } 220 221 void invalidate() 222 { 223 ASSERT(m_callback); 224 225 RefPtr<WebError> error = WebError::create(); 226 ShareableBitmap::Handle handle; 227 m_callback(handle, toAPI(error.get()), context()); 228 229 m_callback = 0; 230 } 231 232 private: 233 234 ImageCallback(void* context, CallbackFunction callback) 235 : CallbackBase(context) 236 , m_callback(callback) 237 { 238 } 239 195 240 CallbackFunction m_callback; 196 241 }; -
trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp
r133828 r133935 497 497 invalidateCallbackMap(m_voidCallbacks); 498 498 invalidateCallbackMap(m_dataCallbacks); 499 invalidateCallbackMap(m_imageCallbacks); 499 500 invalidateCallbackMap(m_stringCallbacks); 500 501 m_loadDependentStringCallbackIDs.clear(); … … 3474 3475 3475 3476 callback->performCallbackWithReturnValue(WebData::create(dataReference.data(), dataReference.size()).get()); 3477 } 3478 3479 void WebPageProxy::imageCallback(const ShareableBitmap::Handle& bitmapHandle, uint64_t callbackID) 3480 { 3481 RefPtr<ImageCallback> callback = m_imageCallbacks.take(callbackID); 3482 if (!callback) { 3483 // FIXME: Log error or assert. 3484 return; 3485 } 3486 3487 callback->performCallbackWithReturnValue(bitmapHandle); 3476 3488 } 3477 3489 … … 4010 4022 4011 4023 #if PLATFORM(MAC) || PLATFORM(WIN) 4012 void WebPageProxy::drawRectTo PDF(WebFrameProxy* frame, const PrintInfo& printInfo, const IntRect& rect, PassRefPtr<DataCallback> prpCallback)4013 { 4014 RefPtr< DataCallback> callback = prpCallback;4024 void WebPageProxy::drawRectToImage(WebFrameProxy* frame, const PrintInfo& printInfo, const IntRect& rect, PassRefPtr<ImageCallback> prpCallback) 4025 { 4026 RefPtr<ImageCallback> callback = prpCallback; 4015 4027 if (!isValid()) { 4016 4028 callback->invalidate(); … … 4019 4031 4020 4032 uint64_t callbackID = callback->callbackID(); 4021 m_ dataCallbacks.set(callbackID, callback.get());4022 m_process->send(Messages::WebPage::DrawRectTo PDF(frame->frameID(), printInfo, rect, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);4033 m_imageCallbacks.set(callbackID, callback.get()); 4034 m_process->send(Messages::WebPage::DrawRectToImage(frame->frameID(), printInfo, rect, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); 4023 4035 } 4024 4036 -
trunk/Source/WebKit2/UIProcess/WebPageProxy.h
r133828 r133935 698 698 void computePagesForPrinting(WebFrameProxy*, const PrintInfo&, PassRefPtr<ComputedPagesCallback>); 699 699 #if PLATFORM(MAC) || PLATFORM(WIN) 700 void drawRectTo PDF(WebFrameProxy*, const PrintInfo&, const WebCore::IntRect&, PassRefPtr<DataCallback>);700 void drawRectToImage(WebFrameProxy*, const PrintInfo&, const WebCore::IntRect&, PassRefPtr<ImageCallback>); 701 701 void drawPagesToPDF(WebFrameProxy*, const PrintInfo&, uint32_t first, uint32_t count, PassRefPtr<DataCallback>); 702 702 #elif PLATFORM(GTK) … … 974 974 void voidCallback(uint64_t); 975 975 void dataCallback(const CoreIPC::DataReference&, uint64_t); 976 void imageCallback(const ShareableBitmap::Handle&, uint64_t); 976 977 void stringCallback(const String&, uint64_t); 977 978 void scriptValueCallback(const CoreIPC::DataReference&, uint64_t); … … 1078 1079 HashMap<uint64_t, RefPtr<VoidCallback> > m_voidCallbacks; 1079 1080 HashMap<uint64_t, RefPtr<DataCallback> > m_dataCallbacks; 1081 HashMap<uint64_t, RefPtr<ImageCallback> > m_imageCallbacks; 1080 1082 HashMap<uint64_t, RefPtr<StringCallback> > m_stringCallbacks; 1081 1083 HashSet<uint64_t> m_loadDependentStringCallbackIDs; -
trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in
r132228 r133935 166 166 VoidCallback(uint64_t callbackID) 167 167 DataCallback(CoreIPC::DataReference resultData, uint64_t callbackID) 168 ImageCallback(WebKit::ShareableBitmap::Handle bitmapHandle, uint64_t callbackID) 168 169 StringCallback(WTF::String resultString, uint64_t callbackID) 169 170 ScriptValueCallback(CoreIPC::DataReference resultData, uint64_t callbackID) -
trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
r133871 r133935 3176 3176 3177 3177 #if PLATFORM(MAC) || PLATFORM(WIN) 3178 void WebPage::drawRectTo PDF(uint64_t frameID, const PrintInfo& printInfo, const WebCore::IntRect& rect, uint64_t callbackID)3178 void WebPage::drawRectToImage(uint64_t frameID, const PrintInfo& printInfo, const WebCore::IntRect& rect, uint64_t callbackID) 3179 3179 { 3180 3180 WebFrame* frame = WebProcess::shared().webFrame(frameID); 3181 3181 Frame* coreFrame = frame ? frame->coreFrame() : 0; 3182 3182 3183 Re tainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));3183 RefPtr<WebImage> image; 3184 3184 3185 3185 #if USE(CG) … … 3190 3190 ASSERT(coreFrame->document()->printing()); 3191 3191 #endif 3192 3193 // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.3194 RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));3195 3196 CGRect mediaBox = CGRectMake(0, 0, rect.width(), rect.height());3197 RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));3198 RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));3199 CGPDFContextBeginPage(context.get(), pageInfo.get());3200 3201 3192 #if PLATFORM(MAC) 3202 3193 if (RetainPtr<PDFDocument> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) { 3203 3194 ASSERT(!m_printContext); 3204 drawRectToPDFFromPDFDocument(context.get(), pdfDocument.get(), printInfo, rect); 3195 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(rect.size(), ShareableBitmap::SupportsAlpha); 3196 OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); 3197 graphicsContext->scale(FloatSize(1, -1)); 3198 graphicsContext->translate(0, -rect.height()); 3199 drawPDFDocument(graphicsContext->platformContext(), pdfDocument.get(), printInfo, rect); 3200 image = WebImage::create(bitmap.release()); 3205 3201 } else 3206 3202 #endif 3207 3203 { 3208 GraphicsContext ctx(context.get()); 3209 ctx.scale(FloatSize(1, -1)); 3210 ctx.translate(0, -rect.height()); 3211 m_printContext->spoolRect(ctx, rect); 3204 image = scaledSnapshotWithOptions(rect, 1, SnapshotOptionsShareable | SnapshotOptionsExcludeSelectionHighlighting); 3212 3205 } 3213 3214 CGPDFContextEndPage(context.get()); 3215 CGPDFContextClose(context.get()); 3216 } 3217 #endif 3218 3219 send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID)); 3206 } 3207 #endif 3208 3209 ShareableBitmap::Handle handle; 3210 3211 if (image) 3212 image->bitmap()->createHandle(handle, SharedMemory::ReadOnly); 3213 3214 send(Messages::WebPageProxy::ImageCallback(handle, callbackID)); 3220 3215 } 3221 3216 -
trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h
r132780 r133935 519 519 void computePagesForPrinting(uint64_t frameID, const PrintInfo&, uint64_t callbackID); 520 520 #if PLATFORM(MAC) || PLATFORM(WIN) 521 void drawRectTo PDF(uint64_t frameID, const PrintInfo&, const WebCore::IntRect&, uint64_t callbackID);521 void drawRectToImage(uint64_t frameID, const PrintInfo&, const WebCore::IntRect&, uint64_t callbackID); 522 522 void drawPagesToPDF(uint64_t frameID, const PrintInfo&, uint32_t first, uint32_t count, uint64_t callbackID); 523 523 #elif PLATFORM(GTK) … … 725 725 RetainPtr<PDFDocument> pdfDocumentForPrintingFrame(WebCore::Frame*); 726 726 void computePagesForPrintingPDFDocument(uint64_t frameID, const PrintInfo&, Vector<WebCore::IntRect>& resultPageRects); 727 void draw RectToPDFFromPDFDocument(CGContextRef, PDFDocument *, const PrintInfo&, const WebCore::IntRect&);727 void drawPDFDocument(CGContextRef, PDFDocument *, const PrintInfo&, const WebCore::IntRect&); 728 728 void drawPagesToPDFFromPDFDocument(CGContextRef, PDFDocument *, const PrintInfo&, uint32_t first, uint32_t count); 729 729 #endif -
trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
r132210 r133935 218 218 ComputePagesForPrinting(uint64_t frameID, WebKit::PrintInfo printInfo, uint64_t callbackID) 219 219 #if PLATFORM(MAC) || PLATFORM(WIN) 220 DrawRectTo PDF(uint64_t frameID, WebKit::PrintInfo printInfo, WebCore::IntRect rect, uint64_t callbackID)220 DrawRectToImage(uint64_t frameID, WebKit::PrintInfo printInfo, WebCore::IntRect rect, uint64_t callbackID) 221 221 DrawPagesToPDF(uint64_t frameID, WebKit::PrintInfo printInfo, uint32_t first, uint32_t count, uint64_t callbackID) 222 222 #endif -
trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm
r133410 r133935 838 838 } 839 839 840 void WebPage::draw RectToPDFFromPDFDocument(CGContextRef context, PDFDocument *pdfDocument, const PrintInfo& printInfo, const WebCore::IntRect& rect)840 void WebPage::drawPDFDocument(CGContextRef context, PDFDocument *pdfDocument, const PrintInfo& printInfo, const WebCore::IntRect& rect) 841 841 { 842 842 NSUInteger pageCount = [pdfDocument pageCount];
Note:
See TracChangeset
for help on using the changeset viewer.