OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. |
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> | 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 clearCopiedImage(); | 275 clearCopiedImage(); |
276 if (layoutObject()) | 276 if (layoutObject()) |
277 layoutObject()->setMayNeedPaintInvalidation(); | 277 layoutObject()->setMayNeedPaintInvalidation(); |
278 m_dirtyRect.unite(rect); | 278 m_dirtyRect.unite(rect); |
279 if (m_context && m_context->is2d() && hasImageBuffer()) | 279 if (m_context && m_context->is2d() && hasImageBuffer()) |
280 buffer()->didDraw(rect); | 280 buffer()->didDraw(rect); |
281 } | 281 } |
282 | 282 |
283 void HTMLCanvasElement::didFinalizeFrame() | 283 void HTMLCanvasElement::didFinalizeFrame() |
284 { | 284 { |
| 285 notifyListenersCanvasChanged(); |
| 286 |
285 if (m_dirtyRect.isEmpty()) | 287 if (m_dirtyRect.isEmpty()) |
286 return; | 288 return; |
287 | 289 |
288 // Propagate the m_dirtyRect accumulated so far to the compositor | 290 // Propagate the m_dirtyRect accumulated so far to the compositor |
289 // before restarting with a blank dirty rect. | 291 // before restarting with a blank dirty rect. |
290 FloatRect srcRect(0, 0, size().width(), size().height()); | 292 FloatRect srcRect(0, 0, size().width(), size().height()); |
291 m_dirtyRect.intersect(srcRect); | 293 m_dirtyRect.intersect(srcRect); |
292 LayoutBox* ro = layoutBox(); | 294 LayoutBox* ro = layoutBox(); |
293 // Canvas content updates do not need to be propagated as | 295 // Canvas content updates do not need to be propagated as |
294 // paint invalidations if the canvas is accelerated, since | 296 // paint invalidations if the canvas is accelerated, since |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 } | 387 } |
386 } | 388 } |
387 } | 389 } |
388 | 390 |
389 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const | 391 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const |
390 { | 392 { |
391 ASSERT(m_context); | 393 ASSERT(m_context); |
392 | 394 |
393 if (!m_context->isAccelerated()) | 395 if (!m_context->isAccelerated()) |
394 return true; | 396 return true; |
395 | |
396 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) | 397 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) |
397 return false; | 398 return false; |
398 | 399 |
399 return true; | 400 return true; |
400 } | 401 } |
401 | 402 |
| 403 void HTMLCanvasElement::notifyListenersCanvasChanged() |
| 404 { |
| 405 if (!originClean()) { |
| 406 m_listeners.clear(); |
| 407 return; |
| 408 } |
| 409 |
| 410 for (CanvasDrawListener* listener : m_listeners) { |
| 411 if (listener->needsNewFrameCapture()) { |
| 412 SourceImageStatus status; |
| 413 RefPtr<Image> sourceImage = getSourceImageForCanvas(&status, PreferN
oAcceleration); |
| 414 if (status != NormalSourceImageStatus) |
| 415 return; |
| 416 listener->setNewFrameCapture(sourceImage->imageForCurrentFrame()); |
| 417 } |
| 418 } |
| 419 } |
| 420 |
402 void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r) | 421 void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r) |
403 { | 422 { |
404 // FIXME: crbug.com/438240; there is a bug with the new CSS blending and com
positing feature. | 423 // FIXME: crbug.com/438240; there is a bug with the new CSS blending and com
positing feature. |
405 if (!m_context) | 424 if (!m_context) |
406 return; | 425 return; |
407 if (!paintsIntoCanvasBuffer() && !document().printing()) | 426 if (!paintsIntoCanvasBuffer() && !document().printing()) |
408 return; | 427 return; |
409 | 428 |
410 m_context->paintRenderingResultsToCanvas(FrontBuffer); | 429 m_context->paintRenderingResultsToCanvas(FrontBuffer); |
411 if (hasImageBuffer()) { | 430 if (hasImageBuffer()) { |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); | 579 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); |
561 | 580 |
562 RefPtr<CanvasAsyncBlobCreator> asyncCreatorRef = CanvasAsyncBlobCreator::cre
ate(imageDataRef.release(), encodingMimeType, imageData->size(), callback); | 581 RefPtr<CanvasAsyncBlobCreator> asyncCreatorRef = CanvasAsyncBlobCreator::cre
ate(imageDataRef.release(), encodingMimeType, imageData->size(), callback); |
563 if (Platform::current()->isThreadedCompositingEnabled() && (encodingMimeType
== DefaultMimeType)) { | 582 if (Platform::current()->isThreadedCompositingEnabled() && (encodingMimeType
== DefaultMimeType)) { |
564 asyncCreatorRef->scheduleAsyncBlobCreation(true); | 583 asyncCreatorRef->scheduleAsyncBlobCreation(true); |
565 } else { | 584 } else { |
566 asyncCreatorRef->scheduleAsyncBlobCreation(false, quality); | 585 asyncCreatorRef->scheduleAsyncBlobCreation(false, quality); |
567 } | 586 } |
568 } | 587 } |
569 | 588 |
| 589 void HTMLCanvasElement::addListener(CanvasDrawListener* listener) |
| 590 { |
| 591 m_listeners.add(listener); |
| 592 notifyListenersCanvasChanged(); |
| 593 } |
| 594 |
| 595 void HTMLCanvasElement::removeListener(CanvasDrawListener* listener) |
| 596 { |
| 597 m_listeners.remove(listener); |
| 598 } |
| 599 |
570 SecurityOrigin* HTMLCanvasElement::securityOrigin() const | 600 SecurityOrigin* HTMLCanvasElement::securityOrigin() const |
571 { | 601 { |
572 return document().securityOrigin(); | 602 return document().securityOrigin(); |
573 } | 603 } |
574 | 604 |
575 bool HTMLCanvasElement::originClean() const | 605 bool HTMLCanvasElement::originClean() const |
576 { | 606 { |
577 if (document().settings() && document().settings()->disableReadingFromCanvas
()) | 607 if (document().settings() && document().settings()->disableReadingFromCanvas
()) |
578 return false; | 608 return false; |
579 return m_originClean; | 609 return m_originClean; |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 } | 765 } |
736 | 766 |
737 void HTMLCanvasElement::notifySurfaceInvalid() | 767 void HTMLCanvasElement::notifySurfaceInvalid() |
738 { | 768 { |
739 if (m_context && m_context->is2d()) | 769 if (m_context && m_context->is2d()) |
740 m_context->loseContext(CanvasRenderingContext::RealLostContext); | 770 m_context->loseContext(CanvasRenderingContext::RealLostContext); |
741 } | 771 } |
742 | 772 |
743 DEFINE_TRACE(HTMLCanvasElement) | 773 DEFINE_TRACE(HTMLCanvasElement) |
744 { | 774 { |
| 775 visitor->trace(m_listeners); |
745 visitor->trace(m_context); | 776 visitor->trace(m_context); |
746 DocumentVisibilityObserver::trace(visitor); | 777 DocumentVisibilityObserver::trace(visitor); |
747 HTMLElement::trace(visitor); | 778 HTMLElement::trace(visitor); |
748 } | 779 } |
749 | 780 |
750 void HTMLCanvasElement::updateExternallyAllocatedMemory() const | 781 void HTMLCanvasElement::updateExternallyAllocatedMemory() const |
751 { | 782 { |
752 int bufferCount = 0; | 783 int bufferCount = 0; |
753 if (m_imageBuffer) { | 784 if (m_imageBuffer) { |
754 bufferCount++; | 785 bufferCount++; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 { | 963 { |
933 return FloatSize(width(), height()); | 964 return FloatSize(width(), height()); |
934 } | 965 } |
935 | 966 |
936 bool HTMLCanvasElement::isOpaque() const | 967 bool HTMLCanvasElement::isOpaque() const |
937 { | 968 { |
938 return m_context && !m_context->hasAlpha(); | 969 return m_context && !m_context->hasAlpha(); |
939 } | 970 } |
940 | 971 |
941 } // blink | 972 } // blink |
OLD | NEW |