Chromium Code Reviews| 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 75 | 75 |
| 76 //In Skia, we will also limit width/height to 32767. | 76 //In Skia, we will also limit width/height to 32767. |
| 77 const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. | 77 const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. |
| 78 | 78 |
| 79 bool canCreateImageBuffer(const IntSize& deviceSize) | 79 bool canCreateImageBuffer(const IntSize& deviceSize) |
| 80 { | 80 { |
| 81 if (deviceSize.width() * deviceSize.height() > MaxCanvasArea) | 81 if (deviceSize.width() * deviceSize.height() > MaxCanvasArea) |
| 82 return false; | 82 return false; |
| 83 if (deviceSize.width() > MaxSkiaDim || deviceSize.height() > MaxSkiaDim) | 83 if (deviceSize.width() > MaxSkiaDim || deviceSize.height() > MaxSkiaDim) |
| 84 return false; | 84 return false; |
| 85 if (!deviceSize.width() || !deviceSize.height()) | 85 if (deviceSize.isEmpty()) |
| 86 return false; | 86 return false; |
| 87 return true; | 87 return true; |
| 88 } | 88 } |
| 89 | 89 |
| 90 } // namespace | 90 } // namespace |
| 91 | 91 |
| 92 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver); | 92 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver); |
| 93 | 93 |
| 94 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) | 94 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) |
| 95 : HTMLElement(canvasTag, document) | 95 : HTMLElement(canvasTag, document) |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 return lowercaseMimeType; | 403 return lowercaseMimeType; |
| 404 } | 404 } |
| 405 | 405 |
| 406 const AtomicString HTMLCanvasElement::imageSourceURL() const | 406 const AtomicString HTMLCanvasElement::imageSourceURL() const |
| 407 { | 407 { |
| 408 return AtomicString(toDataURLInternal("image/png", 0, FrontBuffer)); | 408 return AtomicString(toDataURLInternal("image/png", 0, FrontBuffer)); |
| 409 } | 409 } |
| 410 | 410 |
| 411 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double * quality, SourceDrawingBuffer sourceBuffer) const | 411 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double * quality, SourceDrawingBuffer sourceBuffer) const |
| 412 { | 412 { |
| 413 if (m_size.isEmpty() || !canCreateImageBuffer(size())) | 413 if (!buffer()) |
| 414 return String("data:,"); | 414 return String("data:,"); |
| 415 | 415 |
| 416 String encodingMimeType = toEncodingMimeType(mimeType); | 416 String encodingMimeType = toEncodingMimeType(mimeType); |
| 417 if (!m_context) { | 417 if (m_context && m_context->is3d()) { |
| 418 RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(m_size); | |
| 419 return ImageEncoder::toDataURL(ImageEncoder::RawImageBytes(imageData->si ze(), imageData->data()->data()), encodingMimeType, quality); | |
| 420 } | |
| 421 | |
| 422 if (m_context->is3d()) { | |
| 423 // Get non-premultiplied data because of inaccurate premultiplied alpha conversion of buffer()->toDataURL(). | 418 // Get non-premultiplied data because of inaccurate premultiplied alpha conversion of buffer()->toDataURL(). |
| 424 RefPtrWillBeRawPtr<ImageData> imageData = | 419 RefPtrWillBeRawPtr<ImageData> imageData = |
| 425 toWebGLRenderingContext(m_context.get())->paintRenderingResultsToIma geData(sourceBuffer); | 420 toWebGLRenderingContext(m_context.get())->paintRenderingResultsToIma geData(sourceBuffer); |
| 426 if (imageData) | 421 if (imageData) |
| 427 return ImageEncoder::toDataURL(ImageEncoder::RawImageBytes(imageData ->size(), imageData->data()->data()), encodingMimeType, quality); | 422 return ImageEncoder::toDataURL(ImageEncoder::RawImageBytes(imageData ->size(), imageData->data()->data()), encodingMimeType, quality); |
| 428 m_context->paintRenderingResultsToCanvas(sourceBuffer); | 423 m_context->paintRenderingResultsToCanvas(sourceBuffer); |
| 429 } | 424 } |
| 430 | 425 |
| 431 return buffer()->toDataURL(encodingMimeType, quality); | 426 return buffer()->toDataURL(encodingMimeType, quality); |
| 432 } | 427 } |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 547 if (surface->isValid()) | 542 if (surface->isValid()) |
| 548 return surface.release(); | 543 return surface.release(); |
| 549 surfaceFactory = createSurfaceFactory(deviceSize, msaaSampleCount); // r ecreate because old previous one was released | 544 surfaceFactory = createSurfaceFactory(deviceSize, msaaSampleCount); // r ecreate because old previous one was released |
| 550 } | 545 } |
| 551 | 546 |
| 552 return surfaceFactory->createSurface(deviceSize, opacityMode); | 547 return surfaceFactory->createSurface(deviceSize, opacityMode); |
| 553 } | 548 } |
| 554 | 549 |
| 555 void HTMLCanvasElement::createImageBuffer() | 550 void HTMLCanvasElement::createImageBuffer() |
| 556 { | 551 { |
| 552 ASSERT(m_context); | |
| 557 createImageBufferInternal(); | 553 createImageBufferInternal(); |
| 558 if (m_didFailToCreateImageBuffer && m_context && m_context->is2d()) | 554 if (m_didFailToCreateImageBuffer && m_context->is2d()) |
| 559 toCanvasRenderingContext2D(m_context.get())->loseContext(); | 555 toCanvasRenderingContext2D(m_context.get())->loseContext(); |
| 560 } | 556 } |
| 561 | 557 |
| 562 void HTMLCanvasElement::createImageBufferInternal() | 558 void HTMLCanvasElement::createImageBufferInternal() |
| 563 { | 559 { |
| 564 ASSERT(!m_imageBuffer); | 560 ASSERT(!m_imageBuffer); |
| 565 ASSERT(!m_contextStateSaver); | 561 ASSERT(!m_contextStateSaver); |
| 566 | 562 |
| 567 m_didFailToCreateImageBuffer = true; | 563 m_didFailToCreateImageBuffer = true; |
| 568 m_imageBufferIsClear = true; | 564 m_imageBufferIsClear = true; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == C heckedState::DidOverflow) | 640 if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == C heckedState::DidOverflow) |
| 645 externallyAllocatedMemory = std::numeric_limits<intptr_t>::max(); | 641 externallyAllocatedMemory = std::numeric_limits<intptr_t>::max(); |
| 646 | 642 |
| 647 // Subtracting two intptr_t that are known to be positive will never underfl ow. | 643 // Subtracting two intptr_t that are known to be positive will never underfl ow. |
| 648 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyA llocatedMemory - m_externallyAllocatedMemory); | 644 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyA llocatedMemory - m_externallyAllocatedMemory); |
| 649 m_externallyAllocatedMemory = externallyAllocatedMemory; | 645 m_externallyAllocatedMemory = externallyAllocatedMemory; |
| 650 } | 646 } |
| 651 | 647 |
| 652 GraphicsContext* HTMLCanvasElement::drawingContext() const | 648 GraphicsContext* HTMLCanvasElement::drawingContext() const |
| 653 { | 649 { |
| 654 return buffer() ? m_imageBuffer->context() : 0; | 650 return buffer() && m_imageBuffer ? m_imageBuffer->context() : 0; |
| 655 } | 651 } |
| 656 | 652 |
| 657 GraphicsContext* HTMLCanvasElement::existingDrawingContext() const | 653 GraphicsContext* HTMLCanvasElement::existingDrawingContext() const |
| 658 { | 654 { |
| 659 if (!hasImageBuffer()) | 655 if (!hasImageBuffer()) |
| 660 return nullptr; | 656 return nullptr; |
| 661 | 657 |
| 662 return drawingContext(); | 658 return drawingContext(); |
| 663 } | 659 } |
| 664 | 660 |
| 665 ImageBuffer* HTMLCanvasElement::buffer() const | 661 ImageBuffer* HTMLCanvasElement::buffer() const |
| 666 { | 662 { |
| 663 if (!m_context) { | |
| 664 if (!canCreateImageBuffer(size())) | |
| 665 return nullptr; | |
| 666 m_noContextImageBuffer = ImageBuffer::create(size(), NonOpaque); | |
|
Justin Novosad
2014/11/27 18:58:35
Please explain how this code helps. It seems waste
Justin Novosad
2014/11/27 19:04:29
Ironically, the title of this change is "Don't mak
dshwang
2014/11/27 19:34:28
That's good question.
Two reason:
1. this method r
Justin Novosad
2014/11/27 20:18:15
That is a problem. We cannot guarantee that this m
dshwang
2014/11/27 20:42:17
That's true, but in that sense, most of layout tes
dshwang
2014/11/28 07:49:44
Let me explain more in the case of context.drawIma
| |
| 667 return m_noContextImageBuffer.get(); | |
| 668 } | |
| 669 if (m_noContextImageBuffer) { | |
| 670 m_noContextImageBuffer.clear(); | |
| 671 const_cast<HTMLCanvasElement*>(this)->clearCopiedImage(); | |
| 672 } | |
| 667 if (!hasImageBuffer() && !m_didFailToCreateImageBuffer) | 673 if (!hasImageBuffer() && !m_didFailToCreateImageBuffer) |
| 668 const_cast<HTMLCanvasElement*>(this)->createImageBuffer(); | 674 const_cast<HTMLCanvasElement*>(this)->createImageBuffer(); |
| 669 return m_imageBuffer.get(); | 675 return m_imageBuffer.get(); |
| 670 } | 676 } |
| 671 | 677 |
| 672 void HTMLCanvasElement::ensureUnacceleratedImageBuffer() | 678 void HTMLCanvasElement::ensureUnacceleratedImageBuffer() |
| 673 { | 679 { |
| 680 ASSERT(m_context); | |
| 674 if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCrea teImageBuffer) | 681 if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCrea teImageBuffer) |
| 675 return; | 682 return; |
| 676 discardImageBuffer(); | 683 discardImageBuffer(); |
| 677 OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque : Opaque; | 684 OpacityMode opacityMode = m_context->hasAlpha() ? NonOpaque : Opaque; |
| 678 m_imageBuffer = ImageBuffer::create(size(), opacityMode); | 685 m_imageBuffer = ImageBuffer::create(size(), opacityMode); |
| 679 m_didFailToCreateImageBuffer = !m_imageBuffer; | 686 m_didFailToCreateImageBuffer = !m_imageBuffer; |
| 680 } | 687 } |
| 681 | 688 |
| 682 Image* HTMLCanvasElement::copiedImage(SourceDrawingBuffer sourceBuffer) const | 689 Image* HTMLCanvasElement::copiedImage(SourceDrawingBuffer sourceBuffer) const |
| 683 { | 690 { |
| 684 if (!m_copiedImage && buffer()) { | 691 if (!m_copiedImage && buffer()) { |
|
Justin Novosad
2014/11/27 18:58:35
Not new in this patch, but there is something wron
dshwang
2014/11/27 19:34:28
Good point. I'll fix it in the separate CL. Thank
| |
| 685 if (m_context && m_context->is3d()) | 692 if (m_context && m_context->is3d()) |
| 686 m_context->paintRenderingResultsToCanvas(sourceBuffer); | 693 m_context->paintRenderingResultsToCanvas(sourceBuffer); |
| 687 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); | 694 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); |
| 688 updateExternallyAllocatedMemory(); | 695 updateExternallyAllocatedMemory(); |
| 689 } | 696 } |
| 690 return m_copiedImage.get(); | 697 return m_copiedImage.get(); |
| 691 } | 698 } |
| 692 | 699 |
| 693 void HTMLCanvasElement::discardImageBuffer() | 700 void HTMLCanvasElement::discardImageBuffer() |
| 694 { | 701 { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 747 if (!buffer()) { | 754 if (!buffer()) { |
| 748 *status = InvalidSourceImageStatus; | 755 *status = InvalidSourceImageStatus; |
| 749 return nullptr; | 756 return nullptr; |
| 750 } | 757 } |
| 751 | 758 |
| 752 if (m_context && m_context->is3d()) { | 759 if (m_context && m_context->is3d()) { |
| 753 m_context->paintRenderingResultsToCanvas(BackBuffer); | 760 m_context->paintRenderingResultsToCanvas(BackBuffer); |
| 754 *status = ExternalSourceImageStatus; | 761 *status = ExternalSourceImageStatus; |
| 755 | 762 |
| 756 // can't create SkImage from WebGLImageBufferSurface (contains only SkBi tmap) | 763 // can't create SkImage from WebGLImageBufferSurface (contains only SkBi tmap) |
| 757 return m_imageBuffer->copyImage(DontCopyBackingStore, Unscaled); | 764 return buffer()->copyImage(DontCopyBackingStore, Unscaled); |
|
Justin Novosad
2014/11/27 18:58:35
I think this CL is a good opportunity to fix somet
dshwang
2014/11/27 19:34:28
That's good idea, but many const methods call buff
Justin Novosad
2014/11/27 20:18:15
Acknowledged.
| |
| 758 } | 765 } |
| 759 | 766 |
| 760 RefPtr<SkImage> image = m_imageBuffer->newImageSnapshot(); | 767 RefPtr<SkImage> image = buffer()->newImageSnapshot(); |
| 761 if (image) { | 768 if (image) { |
| 762 *status = NormalSourceImageStatus; | 769 *status = NormalSourceImageStatus; |
| 763 | 770 |
| 764 return StaticBitmapImage::create(image.release()); | 771 return StaticBitmapImage::create(image.release()); |
| 765 } | 772 } |
| 766 | 773 |
| 767 | 774 |
| 768 *status = InvalidSourceImageStatus; | 775 *status = InvalidSourceImageStatus; |
| 769 | 776 |
| 770 return nullptr; | 777 return nullptr; |
| 771 } | 778 } |
| 772 | 779 |
| 773 bool HTMLCanvasElement::wouldTaintOrigin(SecurityOrigin*) const | 780 bool HTMLCanvasElement::wouldTaintOrigin(SecurityOrigin*) const |
| 774 { | 781 { |
| 775 return !originClean(); | 782 return !originClean(); |
| 776 } | 783 } |
| 777 | 784 |
| 778 FloatSize HTMLCanvasElement::sourceSize() const | 785 FloatSize HTMLCanvasElement::sourceSize() const |
| 779 { | 786 { |
| 780 return FloatSize(width(), height()); | 787 return FloatSize(width(), height()); |
| 781 } | 788 } |
| 782 | 789 |
| 783 } | 790 } |
| OLD | NEW |