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 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 | 429 |
430 bool listenerNeedsNewFrameCapture = false; | 430 bool listenerNeedsNewFrameCapture = false; |
431 for (const CanvasDrawListener* listener : m_listeners) { | 431 for (const CanvasDrawListener* listener : m_listeners) { |
432 if (listener->needsNewFrame()) { | 432 if (listener->needsNewFrame()) { |
433 listenerNeedsNewFrameCapture = true; | 433 listenerNeedsNewFrameCapture = true; |
434 } | 434 } |
435 } | 435 } |
436 | 436 |
437 if (listenerNeedsNewFrameCapture) { | 437 if (listenerNeedsNewFrameCapture) { |
438 SourceImageStatus status; | 438 SourceImageStatus status; |
439 RefPtr<Image> sourceImage = getSourceImageForCanvas(&status, PreferAccel
eration); | 439 RefPtr<Image> sourceImage = getSourceImageForCanvas(&status, PreferNoAcc
eleration, SnapshotReasonCanvasListenerCapture); |
440 if (status != NormalSourceImageStatus) | 440 if (status != NormalSourceImageStatus) |
441 return; | 441 return; |
442 RefPtr<SkImage> image = sourceImage->imageForCurrentFrame(); | 442 RefPtr<SkImage> image = sourceImage->imageForCurrentFrame(); |
443 for (CanvasDrawListener* listener : m_listeners) { | 443 for (CanvasDrawListener* listener : m_listeners) { |
444 if (listener->needsNewFrame()) { | 444 if (listener->needsNewFrame()) { |
445 listener->sendNewFrame(image); | 445 listener->sendNewFrame(image); |
446 } | 446 } |
447 } | 447 } |
448 } | 448 } |
449 | 449 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 return AtomicString(toDataURLInternal(DefaultMimeType, 0, FrontBuffer)); | 510 return AtomicString(toDataURLInternal(DefaultMimeType, 0, FrontBuffer)); |
511 } | 511 } |
512 | 512 |
513 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const | 513 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const |
514 { | 514 { |
515 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d
context | 515 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d
context |
516 if (buffer()) | 516 if (buffer()) |
517 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); | 517 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); |
518 } | 518 } |
519 | 519 |
520 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) cons
t | 520 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer, Snap
shotReason reason) const |
521 { | 521 { |
522 ImageData* imageData; | 522 ImageData* imageData; |
523 if (is3D()) { | 523 if (is3D()) { |
524 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). | 524 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). |
525 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); | 525 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); |
526 if (imageData) | 526 if (imageData) |
527 return imageData; | 527 return imageData; |
528 | 528 |
529 m_context->paintRenderingResultsToCanvas(sourceBuffer); | 529 m_context->paintRenderingResultsToCanvas(sourceBuffer); |
530 imageData = ImageData::create(m_size); | 530 imageData = ImageData::create(m_size); |
531 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelera
tion); | 531 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelera
tion, reason); |
532 if (snapshot) { | 532 if (snapshot) { |
533 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8
888_SkColorType, kUnpremul_SkAlphaType); | 533 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8
888_SkColorType, kUnpremul_SkAlphaType); |
534 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo
.minRowBytes(), 0, 0); | 534 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo
.minRowBytes(), 0, 0); |
535 } | 535 } |
536 return imageData; | 536 return imageData; |
537 } | 537 } |
538 | 538 |
539 imageData = ImageData::create(m_size); | 539 imageData = ImageData::create(m_size); |
540 | 540 |
541 if (!m_context) | 541 if (!m_context) |
542 return imageData; | 542 return imageData; |
543 | 543 |
544 ASSERT(m_context->is2d()); | 544 ASSERT(m_context->is2d()); |
545 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration
); | 545 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration
, reason); |
546 if (snapshot) { | 546 if (snapshot) { |
547 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_
SkColorType, kUnpremul_SkAlphaType); | 547 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_
SkColorType, kUnpremul_SkAlphaType); |
548 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min
RowBytes(), 0, 0); | 548 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min
RowBytes(), 0, 0); |
549 } | 549 } |
550 | 550 |
551 return imageData; | 551 return imageData; |
552 } | 552 } |
553 | 553 |
554 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
& quality, SourceDrawingBuffer sourceBuffer) const | 554 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
& quality, SourceDrawingBuffer sourceBuffer) const |
555 { | 555 { |
556 if (!isPaintable()) | 556 if (!isPaintable()) |
557 return String("data:,"); | 557 return String("data:,"); |
558 | 558 |
559 String encodingMimeType = toEncodingMimeType(mimeType); | 559 String encodingMimeType = toEncodingMimeType(mimeType); |
560 | 560 |
561 ImageData* imageData = toImageData(sourceBuffer); | 561 ImageData* imageData = toImageData(sourceBuffer, SnapshotReasonToDataURL); |
562 ScopedDisposal<ImageData> disposer(imageData); | 562 ScopedDisposal<ImageData> disposer(imageData); |
563 | 563 |
564 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU
RL(encodingMimeType, quality); | 564 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU
RL(encodingMimeType, quality); |
565 } | 565 } |
566 | 566 |
567 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q
ualityArgument, ExceptionState& exceptionState) const | 567 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q
ualityArgument, ExceptionState& exceptionState) const |
568 { | 568 { |
569 if (!originClean()) { | 569 if (!originClean()) { |
570 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); | 570 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); |
571 return String(); | 571 return String(); |
(...skipping 24 matching lines...) Expand all Loading... |
596 double quality = UndefinedQualityValue; | 596 double quality = UndefinedQualityValue; |
597 if (!qualityArgument.isEmpty()) { | 597 if (!qualityArgument.isEmpty()) { |
598 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); | 598 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); |
599 if (v8Value->IsNumber()) { | 599 if (v8Value->IsNumber()) { |
600 quality = v8Value.As<v8::Number>()->Value(); | 600 quality = v8Value.As<v8::Number>()->Value(); |
601 } | 601 } |
602 } | 602 } |
603 | 603 |
604 String encodingMimeType = toEncodingMimeType(mimeType); | 604 String encodingMimeType = toEncodingMimeType(mimeType); |
605 | 605 |
606 ImageData* imageData = toImageData(BackBuffer); | 606 ImageData* imageData = toImageData(BackBuffer, SnapshotReasonToBlob); |
607 // imageData unref its data, which we still keep alive for the async toBlob
thread | 607 // imageData unref its data, which we still keep alive for the async toBlob
thread |
608 ScopedDisposal<ImageData> disposer(imageData); | 608 ScopedDisposal<ImageData> disposer(imageData); |
609 // Add a ref to keep image data alive until completion of encoding | 609 // Add a ref to keep image data alive until completion of encoding |
610 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); | 610 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); |
611 | 611 |
612 RefPtr<CanvasAsyncBlobCreator> asyncCreatorRef = CanvasAsyncBlobCreator::cre
ate(imageDataRef.release(), encodingMimeType, imageData->size(), callback); | 612 RefPtr<CanvasAsyncBlobCreator> asyncCreatorRef = CanvasAsyncBlobCreator::cre
ate(imageDataRef.release(), encodingMimeType, imageData->size(), callback); |
613 | 613 |
614 if (encodingMimeType == DefaultMimeType) { | 614 if (encodingMimeType == DefaultMimeType) { |
615 asyncCreatorRef->scheduleAsyncBlobCreation(true); | 615 asyncCreatorRef->scheduleAsyncBlobCreation(true); |
616 } else { | 616 } else { |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
846 // Subtracting two intptr_t that are known to be positive will never underfl
ow. | 846 // Subtracting two intptr_t that are known to be positive will never underfl
ow. |
847 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyA
llocatedMemory - m_externallyAllocatedMemory); | 847 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyA
llocatedMemory - m_externallyAllocatedMemory); |
848 m_externallyAllocatedMemory = externallyAllocatedMemory; | 848 m_externallyAllocatedMemory = externallyAllocatedMemory; |
849 } | 849 } |
850 | 850 |
851 SkCanvas* HTMLCanvasElement::drawingCanvas() const | 851 SkCanvas* HTMLCanvasElement::drawingCanvas() const |
852 { | 852 { |
853 return buffer() ? m_imageBuffer->canvas() : nullptr; | 853 return buffer() ? m_imageBuffer->canvas() : nullptr; |
854 } | 854 } |
855 | 855 |
856 void HTMLCanvasElement::disableDeferral() const | 856 void HTMLCanvasElement::disableDeferral(DisableDeferralReason reason) const |
857 { | 857 { |
858 if (buffer()) | 858 if (buffer()) |
859 m_imageBuffer->disableDeferral(); | 859 m_imageBuffer->disableDeferral(reason); |
860 } | 860 } |
861 | 861 |
862 SkCanvas* HTMLCanvasElement::existingDrawingCanvas() const | 862 SkCanvas* HTMLCanvasElement::existingDrawingCanvas() const |
863 { | 863 { |
864 if (!hasImageBuffer()) | 864 if (!hasImageBuffer()) |
865 return nullptr; | 865 return nullptr; |
866 | 866 |
867 return m_imageBuffer->canvas(); | 867 return m_imageBuffer->canvas(); |
868 } | 868 } |
869 | 869 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 if (m_context) | 959 if (m_context) |
960 m_context->styleDidChange(oldStyle, newStyle); | 960 m_context->styleDidChange(oldStyle, newStyle); |
961 } | 961 } |
962 | 962 |
963 void HTMLCanvasElement::didMoveToNewDocument(Document& oldDocument) | 963 void HTMLCanvasElement::didMoveToNewDocument(Document& oldDocument) |
964 { | 964 { |
965 setObservedDocument(document()); | 965 setObservedDocument(document()); |
966 HTMLElement::didMoveToNewDocument(oldDocument); | 966 HTMLElement::didMoveToNewDocument(oldDocument); |
967 } | 967 } |
968 | 968 |
969 PassRefPtr<Image> HTMLCanvasElement::getSourceImageForCanvas(SourceImageStatus*
status, AccelerationHint hint) const | 969 PassRefPtr<Image> HTMLCanvasElement::getSourceImageForCanvas(SourceImageStatus*
status, AccelerationHint hint, SnapshotReason reason) const |
970 { | 970 { |
971 if (!width() || !height()) { | 971 if (!width() || !height()) { |
972 *status = ZeroSizeCanvasSourceImageStatus; | 972 *status = ZeroSizeCanvasSourceImageStatus; |
973 return nullptr; | 973 return nullptr; |
974 } | 974 } |
975 | 975 |
976 if (!isPaintable()) { | 976 if (!isPaintable()) { |
977 *status = InvalidSourceImageStatus; | 977 *status = InvalidSourceImageStatus; |
978 return nullptr; | 978 return nullptr; |
979 } | 979 } |
980 | 980 |
981 if (!m_context) { | 981 if (!m_context) { |
982 *status = NormalSourceImageStatus; | 982 *status = NormalSourceImageStatus; |
983 return createTransparentImage(size()); | 983 return createTransparentImage(size()); |
984 } | 984 } |
985 | 985 |
986 if (m_context->is3d()) { | 986 if (m_context->is3d()) { |
987 m_context->paintRenderingResultsToCanvas(BackBuffer); | 987 m_context->paintRenderingResultsToCanvas(BackBuffer); |
988 } | 988 } |
989 | 989 |
990 RefPtr<SkImage> image = buffer()->newSkImageSnapshot(hint); | 990 RefPtr<SkImage> image = buffer()->newSkImageSnapshot(hint, reason); |
991 if (image) { | 991 if (image) { |
992 *status = NormalSourceImageStatus; | 992 *status = NormalSourceImageStatus; |
993 return StaticBitmapImage::create(image.release()); | 993 return StaticBitmapImage::create(image.release()); |
994 } | 994 } |
995 | 995 |
996 *status = InvalidSourceImageStatus; | 996 *status = InvalidSourceImageStatus; |
997 return nullptr; | 997 return nullptr; |
998 } | 998 } |
999 | 999 |
1000 bool HTMLCanvasElement::wouldTaintOrigin(SecurityOrigin*) const | 1000 bool HTMLCanvasElement::wouldTaintOrigin(SecurityOrigin*) const |
(...skipping 20 matching lines...) Expand all Loading... |
1021 } | 1021 } |
1022 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im
ageBitmap::create(this, IntRect(sx, sy, sw, sh), options) : nullptr); | 1022 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im
ageBitmap::create(this, IntRect(sx, sy, sw, sh), options) : nullptr); |
1023 } | 1023 } |
1024 | 1024 |
1025 bool HTMLCanvasElement::isOpaque() const | 1025 bool HTMLCanvasElement::isOpaque() const |
1026 { | 1026 { |
1027 return m_context && !m_context->hasAlpha(); | 1027 return m_context && !m_context->hasAlpha(); |
1028 } | 1028 } |
1029 | 1029 |
1030 } // namespace blink | 1030 } // namespace blink |
OLD | NEW |