| 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 const int DefaultHeight = 150; | 82 const int DefaultHeight = 150; |
| 83 | 83 |
| 84 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo
re it | 84 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo
re it |
| 85 // reaches that limit. We limit by area instead, giving us larger maximum dimens
ions, | 85 // reaches that limit. We limit by area instead, giving us larger maximum dimens
ions, |
| 86 // in exchange for a smaller maximum canvas size. | 86 // in exchange for a smaller maximum canvas size. |
| 87 const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels | 87 const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels |
| 88 | 88 |
| 89 // In Skia, we will also limit width/height to 32767. | 89 // In Skia, we will also limit width/height to 32767. |
| 90 const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. | 90 const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. |
| 91 | 91 |
| 92 #if OS(ANDROID) |
| 93 // We estimate that the max limit for android phones is a quarter of that for |
| 94 // desktops based on local experimental results on Android One. |
| 95 const int MaxGlobalAcceleratedImageBufferCount = 25; |
| 96 #else |
| 97 const int MaxGlobalAcceleratedImageBufferCount = 100; |
| 98 #endif |
| 99 |
| 92 // We estimate the max limit of GPU allocated memory for canvases before Chrome | 100 // We estimate the max limit of GPU allocated memory for canvases before Chrome |
| 93 // becomes laggy by setting the total allocated memory for accelerated canvases | 101 // becomes laggy by setting the total allocated memory for accelerated canvases |
| 94 // to be equivalent to memory used by 80 accelerated canvases, each has a size | 102 // to be equivalent to memory used by 100 accelerated canvases, each has a size |
| 95 // of 1000*500 and 2d context. | 103 // of 1000*500 and 2d context. |
| 96 // Each such canvas occupies 4000000 = 1000 * 500 * 2 * 4 bytes, where 2 is the | 104 // Each such canvas occupies 4000000 = 1000 * 500 * 2 * 4 bytes, where 2 is the |
| 97 // gpuBufferCount in ImageBuffer::updateGPUMemoryUsage() and 4 means four bytes | 105 // gpuBufferCount in ImageBuffer::updateGPUMemoryUsage() and 4 means four bytes |
| 98 // per pixel per buffer. | 106 // per pixel per buffer. |
| 99 #if !OS(ANDROID) | 107 const int MaxGlobalGPUMemoryUsage = 4000000 * MaxGlobalAcceleratedImageBufferCou
nt; |
| 100 const int MaxGlobalGPUMemoryUsage = 4000000 * 80; | |
| 101 #else | |
| 102 // We estimate that the max limit for android phones is a quarter of that for | |
| 103 // desktops based on local experimental results on Android One., | |
| 104 const int MaxGlobalGPUMemoryUsage = 4000000 * 20; | |
| 105 #endif | |
| 106 | 108 |
| 107 // A default value of quality argument for toDataURL and toBlob | 109 // A default value of quality argument for toDataURL and toBlob |
| 108 // It is in an invalid range (outside 0.0 - 1.0) so that it will not be | 110 // It is in an invalid range (outside 0.0 - 1.0) so that it will not be |
| 109 // misinterpreted as a user-input value | 111 // misinterpreted as a user-input value |
| 110 const int UndefinedQualityValue = -1.0; | 112 const int UndefinedQualityValue = -1.0; |
| 111 | 113 |
| 112 // Default image mime type for toDataURL and toBlob functions | 114 // Default image mime type for toDataURL and toBlob functions |
| 113 const char DefaultMimeType[] = "image/png"; | 115 const char DefaultMimeType[] = "image/png"; |
| 114 | 116 |
| 115 bool canCreateImageBuffer(const IntSize& size) | 117 bool canCreateImageBuffer(const IntSize& size) |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 return lowercaseMimeType; | 550 return lowercaseMimeType; |
| 549 } | 551 } |
| 550 | 552 |
| 551 const AtomicString HTMLCanvasElement::imageSourceURL() const | 553 const AtomicString HTMLCanvasElement::imageSourceURL() const |
| 552 { | 554 { |
| 553 return AtomicString(toDataURLInternal(DefaultMimeType, 0, FrontBuffer)); | 555 return AtomicString(toDataURLInternal(DefaultMimeType, 0, FrontBuffer)); |
| 554 } | 556 } |
| 555 | 557 |
| 556 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const | 558 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const |
| 557 { | 559 { |
| 558 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d
context | 560 DCHECK(m_context && m_context->is2d()); // This function is called by the 2d
context |
| 559 if (buffer()) | 561 if (buffer()) |
| 560 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); | 562 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); |
| 561 } | 563 } |
| 562 | 564 |
| 563 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer, Snap
shotReason reason) const | 565 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer, Snap
shotReason reason) const |
| 564 { | 566 { |
| 565 ImageData* imageData; | 567 ImageData* imageData; |
| 566 if (is3D()) { | 568 if (is3D()) { |
| 567 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). | 569 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). |
| 568 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); | 570 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 if (!Platform::current()->canAccelerate2dCanvas()) | 743 if (!Platform::current()->canAccelerate2dCanvas()) |
| 742 return false; | 744 return false; |
| 743 | 745 |
| 744 // When GPU allocated memory runs low (due to having created too many | 746 // When GPU allocated memory runs low (due to having created too many |
| 745 // accelerated canvases), the compositor starves and browser becomes laggy. | 747 // accelerated canvases), the compositor starves and browser becomes laggy. |
| 746 // Thus, we should stop allocating more GPU memory to new canvases created | 748 // Thus, we should stop allocating more GPU memory to new canvases created |
| 747 // when the current memory usage exceeds the threshold. | 749 // when the current memory usage exceeds the threshold. |
| 748 if (ImageBuffer::getGlobalGPUMemoryUsage() >= MaxGlobalGPUMemoryUsage) | 750 if (ImageBuffer::getGlobalGPUMemoryUsage() >= MaxGlobalGPUMemoryUsage) |
| 749 return false; | 751 return false; |
| 750 | 752 |
| 753 // Allocating too many GPU resources can makes us run into the driver's |
| 754 // resource limits. So we need to keep the number of texture resources |
| 755 // under tight control |
| 756 if (ImageBuffer::getGlobalAcceleratedImageBufferCount() >= MaxGlobalAccelera
tedImageBufferCount) |
| 757 return false; |
| 758 |
| 751 return true; | 759 return true; |
| 752 } | 760 } |
| 753 | 761 |
| 754 class UnacceleratedSurfaceFactory : public RecordingImageBufferFallbackSurfaceFa
ctory { | 762 class UnacceleratedSurfaceFactory : public RecordingImageBufferFallbackSurfaceFa
ctory { |
| 755 public: | 763 public: |
| 756 virtual PassOwnPtr<ImageBufferSurface> createSurface(const IntSize& size, Op
acityMode opacityMode) | 764 virtual PassOwnPtr<ImageBufferSurface> createSurface(const IntSize& size, Op
acityMode opacityMode) |
| 757 { | 765 { |
| 758 return adoptPtr(new UnacceleratedImageBufferSurface(size, opacityMode)); | 766 return adoptPtr(new UnacceleratedImageBufferSurface(size, opacityMode)); |
| 759 } | 767 } |
| 760 | 768 |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 return FloatSize(width(), height()); | 1082 return FloatSize(width(), height()); |
| 1075 } | 1083 } |
| 1076 | 1084 |
| 1077 IntSize HTMLCanvasElement::bitmapSourceSize() const | 1085 IntSize HTMLCanvasElement::bitmapSourceSize() const |
| 1078 { | 1086 { |
| 1079 return IntSize(width(), height()); | 1087 return IntSize(width(), height()); |
| 1080 } | 1088 } |
| 1081 | 1089 |
| 1082 ScriptPromise HTMLCanvasElement::createImageBitmap(ScriptState* scriptState, Eve
ntTarget& eventTarget, int sx, int sy, int sw, int sh, const ImageBitmapOptions&
options, ExceptionState& exceptionState) | 1090 ScriptPromise HTMLCanvasElement::createImageBitmap(ScriptState* scriptState, Eve
ntTarget& eventTarget, int sx, int sy, int sw, int sh, const ImageBitmapOptions&
options, ExceptionState& exceptionState) |
| 1083 { | 1091 { |
| 1084 ASSERT(eventTarget.toLocalDOMWindow()); | 1092 DCHECK(eventTarget.toLocalDOMWindow()); |
| 1085 if (!sw || !sh) { | 1093 if (!sw || !sh) { |
| 1086 exceptionState.throwDOMException(IndexSizeError, String::format("The sou
rce %s provided is 0.", sw ? "height" : "width")); | 1094 exceptionState.throwDOMException(IndexSizeError, String::format("The sou
rce %s provided is 0.", sw ? "height" : "width")); |
| 1087 return ScriptPromise(); | 1095 return ScriptPromise(); |
| 1088 } | 1096 } |
| 1089 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im
ageBitmap::create(this, IntRect(sx, sy, sw, sh), options) : nullptr); | 1097 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im
ageBitmap::create(this, IntRect(sx, sy, sw, sh), options) : nullptr); |
| 1090 } | 1098 } |
| 1091 | 1099 |
| 1092 bool HTMLCanvasElement::isOpaque() const | 1100 bool HTMLCanvasElement::isOpaque() const |
| 1093 { | 1101 { |
| 1094 return m_context && !m_context->hasAlpha(); | 1102 return m_context && !m_context->hasAlpha(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 return m_context->getIdFromControl(element); | 1173 return m_context->getIdFromControl(element); |
| 1166 return String(); | 1174 return String(); |
| 1167 } | 1175 } |
| 1168 | 1176 |
| 1169 void HTMLCanvasElement::createSurfaceLayerBridge() | 1177 void HTMLCanvasElement::createSurfaceLayerBridge() |
| 1170 { | 1178 { |
| 1171 m_surfaceLayerBridge = adoptPtr(new CanvasSurfaceLayerBridge()); | 1179 m_surfaceLayerBridge = adoptPtr(new CanvasSurfaceLayerBridge()); |
| 1172 } | 1180 } |
| 1173 | 1181 |
| 1174 } // namespace blink | 1182 } // namespace blink |
| OLD | NEW |