| 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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 | 425 |
| 426 bool listenerNeedsNewFrameCapture = false; | 426 bool listenerNeedsNewFrameCapture = false; |
| 427 for (const CanvasDrawListener* listener : m_listeners) { | 427 for (const CanvasDrawListener* listener : m_listeners) { |
| 428 if (listener->needsNewFrame()) { | 428 if (listener->needsNewFrame()) { |
| 429 listenerNeedsNewFrameCapture = true; | 429 listenerNeedsNewFrameCapture = true; |
| 430 } | 430 } |
| 431 } | 431 } |
| 432 | 432 |
| 433 if (listenerNeedsNewFrameCapture) { | 433 if (listenerNeedsNewFrameCapture) { |
| 434 SourceImageStatus status; | 434 SourceImageStatus status; |
| 435 RefPtr<Image> sourceImage = getSourceImageForCanvas(&status, PreferNoAcc
eleration); | 435 RefPtr<Image> sourceImage = getSourceImageForCanvas(&status, PreferNoAcc
eleration, SnapshotReasonCanvasListenerCapture); |
| 436 if (status != NormalSourceImageStatus) | 436 if (status != NormalSourceImageStatus) |
| 437 return; | 437 return; |
| 438 RefPtr<SkImage> image = sourceImage->imageForCurrentFrame(); | 438 RefPtr<SkImage> image = sourceImage->imageForCurrentFrame(); |
| 439 for (CanvasDrawListener* listener : m_listeners) { | 439 for (CanvasDrawListener* listener : m_listeners) { |
| 440 if (listener->needsNewFrame()) { | 440 if (listener->needsNewFrame()) { |
| 441 listener->sendNewFrame(image); | 441 listener->sendNewFrame(image); |
| 442 } | 442 } |
| 443 } | 443 } |
| 444 } | 444 } |
| 445 | 445 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 return AtomicString(toDataURLInternal(DefaultMimeType, 0, FrontBuffer)); | 506 return AtomicString(toDataURLInternal(DefaultMimeType, 0, FrontBuffer)); |
| 507 } | 507 } |
| 508 | 508 |
| 509 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const | 509 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const |
| 510 { | 510 { |
| 511 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d
context | 511 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d
context |
| 512 if (buffer()) | 512 if (buffer()) |
| 513 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); | 513 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); |
| 514 } | 514 } |
| 515 | 515 |
| 516 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) cons
t | 516 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer, Snap
shotReason reason) const |
| 517 { | 517 { |
| 518 ImageData* imageData; | 518 ImageData* imageData; |
| 519 if (is3D()) { | 519 if (is3D()) { |
| 520 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). | 520 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). |
| 521 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); | 521 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); |
| 522 if (imageData) | 522 if (imageData) |
| 523 return imageData; | 523 return imageData; |
| 524 | 524 |
| 525 m_context->paintRenderingResultsToCanvas(sourceBuffer); | 525 m_context->paintRenderingResultsToCanvas(sourceBuffer); |
| 526 imageData = ImageData::create(m_size); | 526 imageData = ImageData::create(m_size); |
| 527 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelera
tion); | 527 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelera
tion, reason); |
| 528 if (snapshot) { | 528 if (snapshot) { |
| 529 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8
888_SkColorType, kUnpremul_SkAlphaType); | 529 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8
888_SkColorType, kUnpremul_SkAlphaType); |
| 530 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo
.minRowBytes(), 0, 0); | 530 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo
.minRowBytes(), 0, 0); |
| 531 } | 531 } |
| 532 return imageData; | 532 return imageData; |
| 533 } | 533 } |
| 534 | 534 |
| 535 imageData = ImageData::create(m_size); | 535 imageData = ImageData::create(m_size); |
| 536 | 536 |
| 537 if (!m_context) | 537 if (!m_context) |
| 538 return imageData; | 538 return imageData; |
| 539 | 539 |
| 540 ASSERT(m_context->is2d()); | 540 ASSERT(m_context->is2d()); |
| 541 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration
); | 541 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration
, reason); |
| 542 if (snapshot) { | 542 if (snapshot) { |
| 543 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_
SkColorType, kUnpremul_SkAlphaType); | 543 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_
SkColorType, kUnpremul_SkAlphaType); |
| 544 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min
RowBytes(), 0, 0); | 544 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min
RowBytes(), 0, 0); |
| 545 } | 545 } |
| 546 | 546 |
| 547 return imageData; | 547 return imageData; |
| 548 } | 548 } |
| 549 | 549 |
| 550 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
& quality, SourceDrawingBuffer sourceBuffer) const | 550 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
& quality, SourceDrawingBuffer sourceBuffer) const |
| 551 { | 551 { |
| 552 if (!isPaintable()) | 552 if (!isPaintable()) |
| 553 return String("data:,"); | 553 return String("data:,"); |
| 554 | 554 |
| 555 String encodingMimeType = toEncodingMimeType(mimeType); | 555 String encodingMimeType = toEncodingMimeType(mimeType); |
| 556 | 556 |
| 557 ImageData* imageData = toImageData(sourceBuffer); | 557 ImageData* imageData = toImageData(sourceBuffer, SnapshotReasonToDataURL); |
| 558 ScopedDisposal<ImageData> disposer(imageData); | 558 ScopedDisposal<ImageData> disposer(imageData); |
| 559 | 559 |
| 560 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU
RL(encodingMimeType, quality); | 560 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU
RL(encodingMimeType, quality); |
| 561 } | 561 } |
| 562 | 562 |
| 563 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q
ualityArgument, ExceptionState& exceptionState) const | 563 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q
ualityArgument, ExceptionState& exceptionState) const |
| 564 { | 564 { |
| 565 if (!originClean()) { | 565 if (!originClean()) { |
| 566 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); | 566 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); |
| 567 return String(); | 567 return String(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 592 double quality = UndefinedQualityValue; | 592 double quality = UndefinedQualityValue; |
| 593 if (!qualityArgument.isEmpty()) { | 593 if (!qualityArgument.isEmpty()) { |
| 594 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); | 594 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); |
| 595 if (v8Value->IsNumber()) { | 595 if (v8Value->IsNumber()) { |
| 596 quality = v8Value.As<v8::Number>()->Value(); | 596 quality = v8Value.As<v8::Number>()->Value(); |
| 597 } | 597 } |
| 598 } | 598 } |
| 599 | 599 |
| 600 String encodingMimeType = toEncodingMimeType(mimeType); | 600 String encodingMimeType = toEncodingMimeType(mimeType); |
| 601 | 601 |
| 602 ImageData* imageData = toImageData(BackBuffer); | 602 ImageData* imageData = toImageData(BackBuffer, SnapshotReasonToBlob); |
| 603 // imageData unref its data, which we still keep alive for the async toBlob
thread | 603 // imageData unref its data, which we still keep alive for the async toBlob
thread |
| 604 ScopedDisposal<ImageData> disposer(imageData); | 604 ScopedDisposal<ImageData> disposer(imageData); |
| 605 // Add a ref to keep image data alive until completion of encoding | 605 // Add a ref to keep image data alive until completion of encoding |
| 606 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); | 606 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); |
| 607 | 607 |
| 608 RefPtr<CanvasAsyncBlobCreator> asyncCreatorRef = CanvasAsyncBlobCreator::cre
ate(imageDataRef.release(), encodingMimeType, imageData->size(), callback); | 608 RefPtr<CanvasAsyncBlobCreator> asyncCreatorRef = CanvasAsyncBlobCreator::cre
ate(imageDataRef.release(), encodingMimeType, imageData->size(), callback); |
| 609 | 609 |
| 610 // TODO(xlai): Remove idle-periods version of implementation completely, htt
p://crbug.com/564218 | 610 // TODO(xlai): Remove idle-periods version of implementation completely, htt
p://crbug.com/564218 |
| 611 asyncCreatorRef->scheduleAsyncBlobCreation(false, quality); | 611 asyncCreatorRef->scheduleAsyncBlobCreation(false, quality); |
| 612 } | 612 } |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 // Subtracting two intptr_t that are known to be positive will never underfl
ow. | 839 // Subtracting two intptr_t that are known to be positive will never underfl
ow. |
| 840 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyA
llocatedMemory - m_externallyAllocatedMemory); | 840 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyA
llocatedMemory - m_externallyAllocatedMemory); |
| 841 m_externallyAllocatedMemory = externallyAllocatedMemory; | 841 m_externallyAllocatedMemory = externallyAllocatedMemory; |
| 842 } | 842 } |
| 843 | 843 |
| 844 SkCanvas* HTMLCanvasElement::drawingCanvas() const | 844 SkCanvas* HTMLCanvasElement::drawingCanvas() const |
| 845 { | 845 { |
| 846 return buffer() ? m_imageBuffer->canvas() : nullptr; | 846 return buffer() ? m_imageBuffer->canvas() : nullptr; |
| 847 } | 847 } |
| 848 | 848 |
| 849 void HTMLCanvasElement::disableDeferral() const | 849 void HTMLCanvasElement::disableDeferral(DisableDeferralReason reason) const |
| 850 { | 850 { |
| 851 if (buffer()) | 851 if (buffer()) |
| 852 m_imageBuffer->disableDeferral(); | 852 m_imageBuffer->disableDeferral(reason); |
| 853 } | 853 } |
| 854 | 854 |
| 855 SkCanvas* HTMLCanvasElement::existingDrawingCanvas() const | 855 SkCanvas* HTMLCanvasElement::existingDrawingCanvas() const |
| 856 { | 856 { |
| 857 if (!hasImageBuffer()) | 857 if (!hasImageBuffer()) |
| 858 return nullptr; | 858 return nullptr; |
| 859 | 859 |
| 860 return m_imageBuffer->canvas(); | 860 return m_imageBuffer->canvas(); |
| 861 } | 861 } |
| 862 | 862 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 } | 947 } |
| 948 | 948 |
| 949 void HTMLCanvasElement::didMoveToNewDocument(Document& oldDocument) | 949 void HTMLCanvasElement::didMoveToNewDocument(Document& oldDocument) |
| 950 { | 950 { |
| 951 setObservedDocument(document()); | 951 setObservedDocument(document()); |
| 952 if (m_context) | 952 if (m_context) |
| 953 m_context->didMoveToNewDocument(&document()); | 953 m_context->didMoveToNewDocument(&document()); |
| 954 HTMLElement::didMoveToNewDocument(oldDocument); | 954 HTMLElement::didMoveToNewDocument(oldDocument); |
| 955 } | 955 } |
| 956 | 956 |
| 957 PassRefPtr<Image> HTMLCanvasElement::getSourceImageForCanvas(SourceImageStatus*
status, AccelerationHint hint) const | 957 PassRefPtr<Image> HTMLCanvasElement::getSourceImageForCanvas(SourceImageStatus*
status, AccelerationHint hint, SnapshotReason reason) const |
| 958 { | 958 { |
| 959 if (!width() || !height()) { | 959 if (!width() || !height()) { |
| 960 *status = ZeroSizeCanvasSourceImageStatus; | 960 *status = ZeroSizeCanvasSourceImageStatus; |
| 961 return nullptr; | 961 return nullptr; |
| 962 } | 962 } |
| 963 | 963 |
| 964 if (!isPaintable()) { | 964 if (!isPaintable()) { |
| 965 *status = InvalidSourceImageStatus; | 965 *status = InvalidSourceImageStatus; |
| 966 return nullptr; | 966 return nullptr; |
| 967 } | 967 } |
| 968 | 968 |
| 969 if (!m_context) { | 969 if (!m_context) { |
| 970 *status = NormalSourceImageStatus; | 970 *status = NormalSourceImageStatus; |
| 971 return createTransparentImage(size()); | 971 return createTransparentImage(size()); |
| 972 } | 972 } |
| 973 | 973 |
| 974 if (m_context->is3d()) { | 974 if (m_context->is3d()) { |
| 975 m_context->paintRenderingResultsToCanvas(BackBuffer); | 975 m_context->paintRenderingResultsToCanvas(BackBuffer); |
| 976 } | 976 } |
| 977 | 977 |
| 978 RefPtr<SkImage> image = buffer()->newSkImageSnapshot(hint); | 978 RefPtr<SkImage> image = buffer()->newSkImageSnapshot(hint, reason); |
| 979 if (image) { | 979 if (image) { |
| 980 *status = NormalSourceImageStatus; | 980 *status = NormalSourceImageStatus; |
| 981 return StaticBitmapImage::create(image.release()); | 981 return StaticBitmapImage::create(image.release()); |
| 982 } | 982 } |
| 983 | 983 |
| 984 *status = InvalidSourceImageStatus; | 984 *status = InvalidSourceImageStatus; |
| 985 return nullptr; | 985 return nullptr; |
| 986 } | 986 } |
| 987 | 987 |
| 988 bool HTMLCanvasElement::wouldTaintOrigin(SecurityOrigin*) const | 988 bool HTMLCanvasElement::wouldTaintOrigin(SecurityOrigin*) const |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1009 } | 1009 } |
| 1010 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im
ageBitmap::create(this, IntRect(sx, sy, sw, sh)) : nullptr); | 1010 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im
ageBitmap::create(this, IntRect(sx, sy, sw, sh)) : nullptr); |
| 1011 } | 1011 } |
| 1012 | 1012 |
| 1013 bool HTMLCanvasElement::isOpaque() const | 1013 bool HTMLCanvasElement::isOpaque() const |
| 1014 { | 1014 { |
| 1015 return m_context && !m_context->hasAlpha(); | 1015 return m_context && !m_context->hasAlpha(); |
| 1016 } | 1016 } |
| 1017 | 1017 |
| 1018 } // blink | 1018 } // blink |
| OLD | NEW |