Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp

Issue 2493673002: Synchronize OffscreenCanvas content with the placeholder canvas (Closed)
Patch Set: fix obsolete test Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 } 138 }
139 139
140 DEFINE_NODE_FACTORY(HTMLCanvasElement) 140 DEFINE_NODE_FACTORY(HTMLCanvasElement)
141 141
142 HTMLCanvasElement::~HTMLCanvasElement() { 142 HTMLCanvasElement::~HTMLCanvasElement() {
143 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( 143 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
144 -m_externallyAllocatedMemory); 144 -m_externallyAllocatedMemory);
145 } 145 }
146 146
147 void HTMLCanvasElement::dispose() { 147 void HTMLCanvasElement::dispose() {
148 releasePlaceholderFrame();
149
148 if (m_context) { 150 if (m_context) {
149 m_context->detachCanvas(); 151 m_context->detachCanvas();
150 m_context = nullptr; 152 m_context = nullptr;
151 } 153 }
152 m_imageBuffer = nullptr; 154 m_imageBuffer = nullptr;
153 } 155 }
154 156
155 void HTMLCanvasElement::parseAttribute(const QualifiedName& name, 157 void HTMLCanvasElement::parseAttribute(const QualifiedName& name,
156 const AtomicString& oldValue, 158 const AtomicString& oldValue,
157 const AtomicString& value) { 159 const AtomicString& value) {
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) 465 if (layoutBox() && layoutBox()->hasAcceleratedCompositing())
464 layoutBox()->contentChanged(CanvasChanged); 466 layoutBox()->contentChanged(CanvasChanged);
465 } 467 }
466 if (hadImageBuffer) 468 if (hadImageBuffer)
467 layoutObject->setShouldDoFullPaintInvalidation(); 469 layoutObject->setShouldDoFullPaintInvalidation();
468 } 470 }
469 } 471 }
470 } 472 }
471 473
472 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const { 474 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const {
475 if (placeholderFrame())
476 return false;
473 DCHECK(m_context); 477 DCHECK(m_context);
474
475 if (!m_context->isAccelerated()) 478 if (!m_context->isAccelerated())
476 return true; 479 return true;
477 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) 480 if (layoutBox() && layoutBox()->hasAcceleratedCompositing())
478 return false; 481 return false;
479 482
480 return true; 483 return true;
481 } 484 }
482 485
483 void HTMLCanvasElement::notifyListenersCanvasChanged() { 486 void HTMLCanvasElement::notifyListenersCanvasChanged() {
484 if (m_listeners.size() == 0) 487 if (m_listeners.size() == 0)
(...skipping 23 matching lines...) Expand all
508 if (listener->needsNewFrame()) { 511 if (listener->needsNewFrame()) {
509 listener->sendNewFrame(image); 512 listener->sendNewFrame(image);
510 } 513 }
511 } 514 }
512 } 515 }
513 } 516 }
514 517
515 void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r) { 518 void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r) {
516 // FIXME: crbug.com/438240; there is a bug with the new CSS blending and 519 // FIXME: crbug.com/438240; there is a bug with the new CSS blending and
517 // compositing feature. 520 // compositing feature.
518 if (!m_context) 521 if (!m_context && !placeholderFrame())
519 return; 522 return;
520 523
521 const ComputedStyle* style = ensureComputedStyle(); 524 const ComputedStyle* style = ensureComputedStyle();
522 SkFilterQuality filterQuality = 525 SkFilterQuality filterQuality =
523 (style && style->imageRendering() == ImageRenderingPixelated) 526 (style && style->imageRendering() == ImageRenderingPixelated)
524 ? kNone_SkFilterQuality 527 ? kNone_SkFilterQuality
525 : kLow_SkFilterQuality; 528 : kLow_SkFilterQuality;
526 529
527 if (is3D()) { 530 if (is3D()) {
528 m_context->setFilterQuality(filterQuality); 531 m_context->setFilterQuality(filterQuality);
529 } else if (hasImageBuffer()) { 532 } else if (hasImageBuffer()) {
530 m_imageBuffer->setFilterQuality(filterQuality); 533 m_imageBuffer->setFilterQuality(filterQuality);
531 } 534 }
532 535
533 if (hasImageBuffer() && !m_imageBufferIsClear) 536 if (hasImageBuffer() && !m_imageBufferIsClear)
534 PaintTiming::from(document()).markFirstContentfulPaint(); 537 PaintTiming::from(document()).markFirstContentfulPaint();
535 538
536 if (!paintsIntoCanvasBuffer() && !document().printing()) 539 if (!paintsIntoCanvasBuffer() && !document().printing())
537 return; 540 return;
538 541
542 if (placeholderFrame()) {
543 DCHECK(document().printing());
544 context.drawImage(placeholderFrame().get(), pixelSnappedIntRect(r));
545 return;
546 }
547
539 // TODO(junov): Paint is currently only implemented by ImageBitmap contexts. 548 // TODO(junov): Paint is currently only implemented by ImageBitmap contexts.
540 // We could improve the abstraction by making all context types paint 549 // We could improve the abstraction by making all context types paint
541 // themselves (implement paint()). 550 // themselves (implement paint()).
542 if (m_context->paint(context, pixelSnappedIntRect(r))) 551 if (m_context->paint(context, pixelSnappedIntRect(r)))
543 return; 552 return;
544 553
545 m_context->paintRenderingResultsToCanvas(FrontBuffer); 554 m_context->paintRenderingResultsToCanvas(FrontBuffer);
546 if (hasImageBuffer()) { 555 if (hasImageBuffer()) {
547 if (!context.contextDisabled()) { 556 if (!context.contextDisabled()) {
548 SkBlendMode compositeOperator = 557 SkBlendMode compositeOperator =
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 width(), height(), kRGBA_8888_SkColorType, kUnpremul_SkAlphaType); 621 width(), height(), kRGBA_8888_SkColorType, kUnpremul_SkAlphaType);
613 snapshot->readPixels(imageInfo, imageData->data()->data(), 622 snapshot->readPixels(imageInfo, imageData->data()->data(),
614 imageInfo.minRowBytes(), 0, 0); 623 imageInfo.minRowBytes(), 0, 0);
615 } 624 }
616 } 625 }
617 return imageData; 626 return imageData;
618 } 627 }
619 628
620 imageData = ImageData::create(m_size); 629 imageData = ImageData::create(m_size);
621 630
622 if (!m_context || !imageData) 631 if ((!m_context || !imageData) && !placeholderFrame())
623 return imageData; 632 return imageData;
624 633
625 DCHECK(m_context->is2d()); 634 DCHECK((m_context && m_context->is2d()) || placeholderFrame());
635 sk_sp<SkImage> snapshot;
626 if (hasImageBuffer()) { 636 if (hasImageBuffer()) {
627 sk_sp<SkImage> snapshot = 637 snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration, reason);
628 buffer()->newSkImageSnapshot(PreferNoAcceleration, reason); 638 } else if (placeholderFrame()) {
629 if (snapshot) { 639 snapshot = placeholderFrame()->imageForCurrentFrame();
630 SkImageInfo imageInfo = SkImageInfo::Make( 640 }
631 width(), height(), kRGBA_8888_SkColorType, kUnpremul_SkAlphaType); 641
632 snapshot->readPixels(imageInfo, imageData->data()->data(), 642 if (snapshot) {
633 imageInfo.minRowBytes(), 0, 0); 643 SkImageInfo imageInfo = SkImageInfo::Make(
634 } 644 width(), height(), kRGBA_8888_SkColorType, kUnpremul_SkAlphaType);
645 snapshot->readPixels(imageInfo, imageData->data()->data(),
646 imageInfo.minRowBytes(), 0, 0);
635 } 647 }
636 648
637 return imageData; 649 return imageData;
638 } 650 }
639 651
640 String HTMLCanvasElement::toDataURLInternal( 652 String HTMLCanvasElement::toDataURLInternal(
641 const String& mimeType, 653 const String& mimeType,
642 const double& quality, 654 const double& quality,
643 SourceDrawingBuffer sourceBuffer) const { 655 SourceDrawingBuffer sourceBuffer) const {
644 if (!isPaintable()) 656 if (!isPaintable())
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 if (!imageData) // allocation failure 688 if (!imageData) // allocation failure
677 return String("data:,"); 689 return String("data:,");
678 690
679 return ImageDataBuffer(imageData->size(), imageData->data()->data()) 691 return ImageDataBuffer(imageData->size(), imageData->data()->data())
680 .toDataURL(encodingMimeType, quality); 692 .toDataURL(encodingMimeType, quality);
681 } 693 }
682 694
683 String HTMLCanvasElement::toDataURL(const String& mimeType, 695 String HTMLCanvasElement::toDataURL(const String& mimeType,
684 const ScriptValue& qualityArgument, 696 const ScriptValue& qualityArgument,
685 ExceptionState& exceptionState) const { 697 ExceptionState& exceptionState) const {
686 if (surfaceLayerBridge()) {
687 exceptionState.throwDOMException(InvalidStateError,
688 "canvas.toDataURL is not allowed for a "
689 "canvas that has transferred its control "
690 "to offscreen.");
691 return String();
692 }
693 if (!originClean()) { 698 if (!originClean()) {
694 exceptionState.throwSecurityError("Tainted canvases may not be exported."); 699 exceptionState.throwSecurityError("Tainted canvases may not be exported.");
695 return String(); 700 return String();
696 } 701 }
697 702
698 double quality = UndefinedQualityValue; 703 double quality = UndefinedQualityValue;
699 if (!qualityArgument.isEmpty()) { 704 if (!qualityArgument.isEmpty()) {
700 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); 705 v8::Local<v8::Value> v8Value = qualityArgument.v8Value();
701 if (v8Value->IsNumber()) { 706 if (v8Value->IsNumber()) {
702 quality = v8Value.As<v8::Number>()->Value(); 707 quality = v8Value.As<v8::Number>()->Value();
703 } 708 }
704 } 709 }
705 return toDataURLInternal(mimeType, quality, BackBuffer); 710 return toDataURLInternal(mimeType, quality, BackBuffer);
706 } 711 }
707 712
708 void HTMLCanvasElement::toBlob(BlobCallback* callback, 713 void HTMLCanvasElement::toBlob(BlobCallback* callback,
709 const String& mimeType, 714 const String& mimeType,
710 const ScriptValue& qualityArgument, 715 const ScriptValue& qualityArgument,
711 ExceptionState& exceptionState) { 716 ExceptionState& exceptionState) {
712 if (surfaceLayerBridge()) {
713 exceptionState.throwDOMException(InvalidStateError,
714 "canvas.toBlob is not allowed for a "
715 "canvas that has transferred its control "
716 "to offscreen.");
717 return;
718 }
719
720 if (!originClean()) { 717 if (!originClean()) {
721 exceptionState.throwSecurityError("Tainted canvases may not be exported."); 718 exceptionState.throwSecurityError("Tainted canvases may not be exported.");
722 return; 719 return;
723 } 720 }
724 721
725 if (!isPaintable()) { 722 if (!isPaintable()) {
726 // If the canvas element's bitmap has no pixels 723 // If the canvas element's bitmap has no pixels
727 TaskRunnerHelper::get(TaskType::CanvasBlobSerialization, &document()) 724 TaskRunnerHelper::get(TaskType::CanvasBlobSerialization, &document())
728 ->postTask(BLINK_FROM_HERE, 725 ->postTask(BLINK_FROM_HERE,
729 WTF::bind(&BlobCallback::handleEvent, 726 WTF::bind(&BlobCallback::handleEvent,
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 if (!width() || !height()) { 1190 if (!width() || !height()) {
1194 *status = ZeroSizeCanvasSourceImageStatus; 1191 *status = ZeroSizeCanvasSourceImageStatus;
1195 return nullptr; 1192 return nullptr;
1196 } 1193 }
1197 1194
1198 if (!isPaintable()) { 1195 if (!isPaintable()) {
1199 *status = InvalidSourceImageStatus; 1196 *status = InvalidSourceImageStatus;
1200 return nullptr; 1197 return nullptr;
1201 } 1198 }
1202 1199
1200 if (placeholderFrame()) {
1201 *status = NormalSourceImageStatus;
1202 return placeholderFrame();
1203 }
1204
1203 if (!m_context) { 1205 if (!m_context) {
1204 *status = NormalSourceImageStatus; 1206 *status = NormalSourceImageStatus;
1205 return createTransparentImage(size()); 1207 return createTransparentImage(size());
1206 } 1208 }
1207 1209
1208 sk_sp<SkImage> skImage; 1210 sk_sp<SkImage> skImage;
1209 if (m_context->is3d()) { 1211 if (m_context->is3d()) {
1210 // Because WebGL sources always require making a copy of the back buffer, we 1212 // Because WebGL sources always require making a copy of the back buffer, we
1211 // use paintRenderingResultsToCanvas instead of getImage in order to keep a 1213 // use paintRenderingResultsToCanvas instead of getImage in order to keep a
1212 // cached copy of the backing in the canvas's ImageBuffer. 1214 // cached copy of the backing in the canvas's ImageBuffer.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 mojom::blink::OffscreenCanvasSurfacePtr service; 1359 mojom::blink::OffscreenCanvasSurfacePtr service;
1358 Platform::current()->interfaceProvider()->getInterface( 1360 Platform::current()->interfaceProvider()->getInterface(
1359 mojo::GetProxy(&service)); 1361 mojo::GetProxy(&service));
1360 m_surfaceLayerBridge = 1362 m_surfaceLayerBridge =
1361 wrapUnique(new CanvasSurfaceLayerBridge(std::move(service))); 1363 wrapUnique(new CanvasSurfaceLayerBridge(std::move(service)));
1362 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), 1364 return m_surfaceLayerBridge->createSurfaceLayer(this->width(),
1363 this->height()); 1365 this->height());
1364 } 1366 }
1365 1367
1366 } // namespace blink 1368 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698