| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 namespace blink { | 79 namespace blink { |
| 80 | 80 |
| 81 using namespace HTMLNames; | 81 using namespace HTMLNames; |
| 82 | 82 |
| 83 namespace { | 83 namespace { |
| 84 | 84 |
| 85 // These values come from the WhatWG spec. | 85 // These values come from the WhatWG spec. |
| 86 const int DefaultWidth = 300; | 86 const int DefaultWidth = 300; |
| 87 const int DefaultHeight = 150; | 87 const int DefaultHeight = 150; |
| 88 | 88 |
| 89 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo
re it | |
| 90 // reaches that limit. We limit by area instead, giving us larger maximum dimens
ions, | |
| 91 // in exchange for a smaller maximum canvas size. | |
| 92 const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels | |
| 93 | |
| 94 // In Skia, we will also limit width/height to 32767. | |
| 95 const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. | |
| 96 | |
| 97 #if OS(ANDROID) | 89 #if OS(ANDROID) |
| 98 // We estimate that the max limit for android phones is a quarter of that for | 90 // We estimate that the max limit for android phones is a quarter of that for |
| 99 // desktops based on local experimental results on Android One. | 91 // desktops based on local experimental results on Android One. |
| 100 const int MaxGlobalAcceleratedImageBufferCount = 25; | 92 const int MaxGlobalAcceleratedImageBufferCount = 25; |
| 101 #else | 93 #else |
| 102 const int MaxGlobalAcceleratedImageBufferCount = 100; | 94 const int MaxGlobalAcceleratedImageBufferCount = 100; |
| 103 #endif | 95 #endif |
| 104 | 96 |
| 105 // We estimate the max limit of GPU allocated memory for canvases before Chrome | 97 // We estimate the max limit of GPU allocated memory for canvases before Chrome |
| 106 // becomes laggy by setting the total allocated memory for accelerated canvases | 98 // becomes laggy by setting the total allocated memory for accelerated canvases |
| 107 // to be equivalent to memory used by 100 accelerated canvases, each has a size | 99 // to be equivalent to memory used by 100 accelerated canvases, each has a size |
| 108 // of 1000*500 and 2d context. | 100 // of 1000*500 and 2d context. |
| 109 // Each such canvas occupies 4000000 = 1000 * 500 * 2 * 4 bytes, where 2 is the | 101 // Each such canvas occupies 4000000 = 1000 * 500 * 2 * 4 bytes, where 2 is the |
| 110 // gpuBufferCount in ImageBuffer::updateGPUMemoryUsage() and 4 means four bytes | 102 // gpuBufferCount in ImageBuffer::updateGPUMemoryUsage() and 4 means four bytes |
| 111 // per pixel per buffer. | 103 // per pixel per buffer. |
| 112 const int MaxGlobalGPUMemoryUsage = 4000000 * MaxGlobalAcceleratedImageBufferCou
nt; | 104 const int MaxGlobalGPUMemoryUsage = 4000000 * MaxGlobalAcceleratedImageBufferCou
nt; |
| 113 | 105 |
| 114 // A default value of quality argument for toDataURL and toBlob | 106 // A default value of quality argument for toDataURL and toBlob |
| 115 // It is in an invalid range (outside 0.0 - 1.0) so that it will not be | 107 // It is in an invalid range (outside 0.0 - 1.0) so that it will not be |
| 116 // misinterpreted as a user-input value | 108 // misinterpreted as a user-input value |
| 117 const int UndefinedQualityValue = -1.0; | 109 const int UndefinedQualityValue = -1.0; |
| 118 | 110 |
| 119 // Default image mime type for toDataURL and toBlob functions | 111 // Default image mime type for toDataURL and toBlob functions |
| 120 const char DefaultMimeType[] = "image/png"; | 112 const char DefaultMimeType[] = "image/png"; |
| 121 | 113 |
| 122 bool canCreateImageBuffer(const IntSize& size) | |
| 123 { | |
| 124 if (size.isEmpty()) | |
| 125 return false; | |
| 126 CheckedNumeric<int> area = size.width(); | |
| 127 area *= size.height(); | |
| 128 if (!area.IsValid() || area.ValueOrDie() > MaxCanvasArea) | |
| 129 return false; | |
| 130 if (size.width() > MaxSkiaDim || size.height() > MaxSkiaDim) | |
| 131 return false; | |
| 132 return true; | |
| 133 } | |
| 134 | |
| 135 PassRefPtr<Image> createTransparentImage(const IntSize& size) | 114 PassRefPtr<Image> createTransparentImage(const IntSize& size) |
| 136 { | 115 { |
| 137 DCHECK(canCreateImageBuffer(size)); | 116 DCHECK(ImageBuffer::canCreateImageBuffer(size)); |
| 138 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(size.width(), size
.height()); | 117 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(size.width(), size
.height()); |
| 139 return StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot())); | 118 return StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot())); |
| 140 } | 119 } |
| 141 | 120 |
| 142 } // namespace | 121 } // namespace |
| 143 | 122 |
| 144 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) | 123 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) |
| 145 : HTMLElement(canvasTag, document) | 124 : HTMLElement(canvasTag, document) |
| 146 , ContextLifecycleObserver(&document) | 125 , ContextLifecycleObserver(&document) |
| 147 , PageVisibilityObserver(document.page()) | 126 , PageVisibilityObserver(document.page()) |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 } | 248 } |
| 270 | 249 |
| 271 bool HTMLCanvasElement::shouldBeDirectComposited() const | 250 bool HTMLCanvasElement::shouldBeDirectComposited() const |
| 272 { | 251 { |
| 273 return (m_context && m_context->isAccelerated()) || (hasImageBuffer() && buf
fer()->isExpensiveToPaint()) || (!!m_surfaceLayerBridge); | 252 return (m_context && m_context->isAccelerated()) || (hasImageBuffer() && buf
fer()->isExpensiveToPaint()) || (!!m_surfaceLayerBridge); |
| 274 } | 253 } |
| 275 | 254 |
| 276 bool HTMLCanvasElement::isPaintable() const | 255 bool HTMLCanvasElement::isPaintable() const |
| 277 { | 256 { |
| 278 if (!m_context) | 257 if (!m_context) |
| 279 return canCreateImageBuffer(size()); | 258 return ImageBuffer::canCreateImageBuffer(size()); |
| 280 return buffer(); | 259 return buffer(); |
| 281 } | 260 } |
| 282 | 261 |
| 283 void HTMLCanvasElement::didDraw(const FloatRect& rect) | 262 void HTMLCanvasElement::didDraw(const FloatRect& rect) |
| 284 { | 263 { |
| 285 if (rect.isEmpty()) | 264 if (rect.isEmpty()) |
| 286 return; | 265 return; |
| 287 m_imageBufferIsClear = false; | 266 m_imageBufferIsClear = false; |
| 288 clearCopiedImage(); | 267 clearCopiedImage(); |
| 289 if (layoutObject()) | 268 if (layoutObject()) |
| (...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 m_context->loseContext(CanvasRenderingContext::SyntheticLostContext); | 867 m_context->loseContext(CanvasRenderingContext::SyntheticLostContext); |
| 889 } | 868 } |
| 890 | 869 |
| 891 void HTMLCanvasElement::createImageBufferInternal(std::unique_ptr<ImageBufferSur
face> externalSurface) | 870 void HTMLCanvasElement::createImageBufferInternal(std::unique_ptr<ImageBufferSur
face> externalSurface) |
| 892 { | 871 { |
| 893 DCHECK(!m_imageBuffer); | 872 DCHECK(!m_imageBuffer); |
| 894 | 873 |
| 895 m_didFailToCreateImageBuffer = true; | 874 m_didFailToCreateImageBuffer = true; |
| 896 m_imageBufferIsClear = true; | 875 m_imageBufferIsClear = true; |
| 897 | 876 |
| 898 if (!canCreateImageBuffer(size())) | 877 if (!ImageBuffer::canCreateImageBuffer(size())) |
| 899 return; | 878 return; |
| 900 | 879 |
| 901 int msaaSampleCount = 0; | 880 int msaaSampleCount = 0; |
| 902 std::unique_ptr<ImageBufferSurface> surface; | 881 std::unique_ptr<ImageBufferSurface> surface; |
| 903 if (externalSurface) { | 882 if (externalSurface) { |
| 904 surface = std::move(externalSurface); | 883 surface = std::move(externalSurface); |
| 905 } else { | 884 } else { |
| 906 surface = createImageBufferSurface(size(), &msaaSampleCount); | 885 surface = createImageBufferSurface(size(), &msaaSampleCount); |
| 907 } | 886 } |
| 908 m_imageBuffer = ImageBuffer::create(std::move(surface)); | 887 m_imageBuffer = ImageBuffer::create(std::move(surface)); |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1236 | 1215 |
| 1237 bool HTMLCanvasElement::createSurfaceLayer() | 1216 bool HTMLCanvasElement::createSurfaceLayer() |
| 1238 { | 1217 { |
| 1239 DCHECK(!m_surfaceLayerBridge); | 1218 DCHECK(!m_surfaceLayerBridge); |
| 1240 std::unique_ptr<CanvasSurfaceLayerBridgeClient> bridgeClient = wrapUnique(ne
w CanvasSurfaceLayerBridgeClientImpl()); | 1219 std::unique_ptr<CanvasSurfaceLayerBridgeClient> bridgeClient = wrapUnique(ne
w CanvasSurfaceLayerBridgeClientImpl()); |
| 1241 m_surfaceLayerBridge = wrapUnique(new CanvasSurfaceLayerBridge(std::move(bri
dgeClient))); | 1220 m_surfaceLayerBridge = wrapUnique(new CanvasSurfaceLayerBridge(std::move(bri
dgeClient))); |
| 1242 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), this->height(
)); | 1221 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), this->height(
)); |
| 1243 } | 1222 } |
| 1244 | 1223 |
| 1245 } // namespace blink | 1224 } // namespace blink |
| OLD | NEW |