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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 55 #include "platform/graphics/gpu/WebGLImageBufferSurface.h" | 55 #include "platform/graphics/gpu/WebGLImageBufferSurface.h" |
| 56 #include "platform/transforms/AffineTransform.h" | 56 #include "platform/transforms/AffineTransform.h" |
| 57 #include "public/platform/Platform.h" | 57 #include "public/platform/Platform.h" |
| 58 #include <math.h> | 58 #include <math.h> |
| 59 #include <v8.h> | 59 #include <v8.h> |
| 60 | 60 |
| 61 namespace blink { | 61 namespace blink { |
| 62 | 62 |
| 63 using namespace HTMLNames; | 63 using namespace HTMLNames; |
| 64 | 64 |
| 65 namespace { | |
| 66 | |
| 65 // These values come from the WhatWG spec. | 67 // These values come from the WhatWG spec. |
| 66 static const int DefaultWidth = 300; | 68 const int DefaultWidth = 300; |
| 67 static const int DefaultHeight = 150; | 69 const int DefaultHeight = 150; |
| 68 | 70 |
| 69 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo re it | 71 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo re it |
| 70 // reaches that limit. We limit by area instead, giving us larger maximum dimens ions, | 72 // reaches that limit. We limit by area instead, giving us larger maximum dimens ions, |
| 71 // in exchange for a smaller maximum canvas size. | 73 // in exchange for a smaller maximum canvas size. |
| 72 static const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pix els | 74 const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels |
| 73 | 75 |
| 74 //In Skia, we will also limit width/height to 32767. | 76 //In Skia, we will also limit width/height to 32767. |
| 75 static const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. | 77 const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. |
| 78 | |
| 79 CanvasRenderingContext::SourceBuffer convertSourceBuffer(HTMLCanvasElement::Sour ceBuffer sourceBuffer) | |
| 80 { | |
| 81 return static_cast<CanvasRenderingContext::SourceBuffer>(sourceBuffer); | |
| 82 } | |
| 83 | |
| 84 } // namespace | |
| 76 | 85 |
| 77 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver); | 86 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver); |
| 78 | 87 |
| 79 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) | 88 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) |
| 80 : HTMLElement(canvasTag, document) | 89 : HTMLElement(canvasTag, document) |
| 81 , DocumentVisibilityObserver(document) | 90 , DocumentVisibilityObserver(document) |
| 82 , m_size(DefaultWidth, DefaultHeight) | 91 , m_size(DefaultWidth, DefaultHeight) |
| 83 , m_ignoreReset(false) | 92 , m_ignoreReset(false) |
| 84 , m_accelerationDisabled(false) | 93 , m_accelerationDisabled(false) |
| 85 , m_externallyAllocatedMemory(0) | 94 , m_externallyAllocatedMemory(0) |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 | 389 |
| 381 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread). | 390 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread). |
| 382 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod ing(lowercaseMimeType)) | 391 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod ing(lowercaseMimeType)) |
| 383 lowercaseMimeType = "image/png"; | 392 lowercaseMimeType = "image/png"; |
| 384 | 393 |
| 385 return lowercaseMimeType; | 394 return lowercaseMimeType; |
| 386 } | 395 } |
| 387 | 396 |
| 388 const AtomicString HTMLCanvasElement::imageSourceURL() const | 397 const AtomicString HTMLCanvasElement::imageSourceURL() const |
| 389 { | 398 { |
| 390 return AtomicString(toDataURLInternal("image/png", 0, true)); | 399 return AtomicString(toDataURLInternal("image/png", 0, Front)); |
| 391 } | 400 } |
| 392 | 401 |
| 393 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double * quality, bool isSaving) const | 402 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double * quality, SourceBuffer sourceBuffer) const |
| 394 { | 403 { |
| 395 if (m_size.isEmpty() || !buffer()) | 404 if (m_size.isEmpty() || !buffer() || !m_context) |
|
dshwang
2014/11/22 19:32:18
I changed a behavior of toDataURL without context.
| |
| 396 return String("data:,"); | 405 return String("data:,"); |
| 397 | 406 |
| 398 String encodingMimeType = toEncodingMimeType(mimeType); | 407 String encodingMimeType = toEncodingMimeType(mimeType); |
| 399 | 408 |
| 400 // Try to get ImageData first, as that may avoid lossy conversions. | 409 if (m_context->is3d()) { |
| 401 RefPtrWillBeRawPtr<ImageData> imageData = getImageData(); | 410 // Get pure non-premultiplied data because of inaccurate premultiplied a lpha conversion of buffer()->toDataURL(). |
|
dshwang
2014/11/21 09:05:40
getImageData() is implemented by only webgl, so I
| |
| 402 | 411 RefPtrWillBeRawPtr<ImageData> imageData = |
| 403 if (imageData) | 412 toWebGLRenderingContext(m_context.get())->paintRenderingResultsToIma geData(convertSourceBuffer(sourceBuffer)); |
| 404 return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData-> data()), encodingMimeType, quality); | 413 // |imageData| is null when premultipliedAlpha == true. |
| 405 | 414 if (imageData) |
| 406 if (m_context && m_context->is3d()) { | 415 return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageDa ta->data()), encodingMimeType, quality); |
| 407 m_context->paintRenderingResultsToCanvas(isSaving ? CanvasRenderingConte xt::Front : CanvasRenderingContext::Back); | 416 m_context->paintRenderingResultsToCanvas(convertSourceBuffer(sourceBuffe r)); |
| 408 } | 417 } |
| 409 | 418 |
| 410 return buffer()->toDataURL(encodingMimeType, quality); | 419 return buffer()->toDataURL(encodingMimeType, quality); |
| 411 } | 420 } |
| 412 | 421 |
| 413 String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit y, ExceptionState& exceptionState) const | 422 String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit y, ExceptionState& exceptionState) const |
| 414 { | 423 { |
| 415 if (!m_originClean) { | 424 if (!m_originClean) { |
| 416 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); | 425 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); |
| 417 return String(); | 426 return String(); |
| 418 } | 427 } |
| 419 | 428 |
| 420 return toDataURLInternal(mimeType, quality); | 429 return toDataURLInternal(mimeType, quality, Back); |
| 421 } | |
| 422 | |
| 423 PassRefPtrWillBeRawPtr<ImageData> HTMLCanvasElement::getImageData() const | |
| 424 { | |
| 425 if (!m_context || !m_context->is3d()) | |
| 426 return nullptr; | |
| 427 return toWebGLRenderingContext(m_context.get())->paintRenderingResultsToImag eData(); | |
| 428 } | 430 } |
| 429 | 431 |
| 430 SecurityOrigin* HTMLCanvasElement::securityOrigin() const | 432 SecurityOrigin* HTMLCanvasElement::securityOrigin() const |
| 431 { | 433 { |
| 432 return document().securityOrigin(); | 434 return document().securityOrigin(); |
| 433 } | 435 } |
| 434 | 436 |
| 435 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const | 437 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const |
| 436 { | 438 { |
| 437 if (m_context && !m_context->is2d()) | 439 if (m_context && !m_context->is2d()) |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 665 void HTMLCanvasElement::ensureUnacceleratedImageBuffer() | 667 void HTMLCanvasElement::ensureUnacceleratedImageBuffer() |
| 666 { | 668 { |
| 667 if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCrea teImageBuffer) | 669 if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCrea teImageBuffer) |
| 668 return; | 670 return; |
| 669 discardImageBuffer(); | 671 discardImageBuffer(); |
| 670 OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque : Opaque; | 672 OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque : Opaque; |
| 671 m_imageBuffer = ImageBuffer::create(size(), opacityMode); | 673 m_imageBuffer = ImageBuffer::create(size(), opacityMode); |
| 672 m_didFailToCreateImageBuffer = !m_imageBuffer; | 674 m_didFailToCreateImageBuffer = !m_imageBuffer; |
| 673 } | 675 } |
| 674 | 676 |
| 675 Image* HTMLCanvasElement::copiedImage() const | 677 Image* HTMLCanvasElement::copiedImage(SourceBuffer sourceBuffer) const |
| 676 { | 678 { |
| 677 if (!m_copiedImage && buffer()) { | 679 if (!m_copiedImage && buffer()) { |
| 678 if (m_context && m_context->is3d()) { | 680 if (m_context && m_context->is3d()) |
| 679 m_context->paintRenderingResultsToCanvas(CanvasRenderingContext::Fro nt); | 681 m_context->paintRenderingResultsToCanvas(convertSourceBuffer(sourceB uffer)); |
| 680 } | |
| 681 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); | 682 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); |
| 682 updateExternallyAllocatedMemory(); | 683 updateExternallyAllocatedMemory(); |
| 683 } | 684 } |
| 684 return m_copiedImage.get(); | 685 return m_copiedImage.get(); |
| 685 } | 686 } |
| 686 | 687 |
| 687 void HTMLCanvasElement::clearImageBuffer() | 688 void HTMLCanvasElement::clearImageBuffer() |
| 688 { | 689 { |
| 689 ASSERT(hasImageBuffer() && !m_didFailToCreateImageBuffer); | 690 ASSERT(hasImageBuffer() && !m_didFailToCreateImageBuffer); |
| 690 ASSERT(!m_didClearImageBuffer); | 691 ASSERT(!m_didClearImageBuffer); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 784 { | 785 { |
| 785 return !originClean(); | 786 return !originClean(); |
| 786 } | 787 } |
| 787 | 788 |
| 788 FloatSize HTMLCanvasElement::sourceSize() const | 789 FloatSize HTMLCanvasElement::sourceSize() const |
| 789 { | 790 { |
| 790 return FloatSize(width(), height()); | 791 return FloatSize(width(), height()); |
| 791 } | 792 } |
| 792 | 793 |
| 793 } | 794 } |
| OLD | NEW |