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 |