| 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 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 | 491 |
| 492 // TODO(junov): Paint is currently only implemented by ImageBitmap contexts. | 492 // TODO(junov): Paint is currently only implemented by ImageBitmap contexts. |
| 493 // We could improve the abstraction by making all context types paint | 493 // We could improve the abstraction by making all context types paint |
| 494 // themselves (implement paint()). | 494 // themselves (implement paint()). |
| 495 if (m_context->paint(context, pixelSnappedIntRect(r))) | 495 if (m_context->paint(context, pixelSnappedIntRect(r))) |
| 496 return; | 496 return; |
| 497 | 497 |
| 498 m_context->paintRenderingResultsToCanvas(FrontBuffer); | 498 m_context->paintRenderingResultsToCanvas(FrontBuffer); |
| 499 if (hasImageBuffer()) { | 499 if (hasImageBuffer()) { |
| 500 if (!context.contextDisabled()) { | 500 if (!context.contextDisabled()) { |
| 501 SkXfermode::Mode compositeOperator = !m_context || m_context->hasAlp
ha() ? SkXfermode::kSrcOver_Mode : SkXfermode::kSrc_Mode; | 501 SkXfermode::Mode compositeOperator = !m_context || m_context->creati
onAttributes().alpha() ? SkXfermode::kSrcOver_Mode : SkXfermode::kSrc_Mode; |
| 502 buffer()->draw(context, pixelSnappedIntRect(r), 0, compositeOperator
); | 502 buffer()->draw(context, pixelSnappedIntRect(r), 0, compositeOperator
); |
| 503 } | 503 } |
| 504 } else { | 504 } else { |
| 505 // When alpha is false, we should draw to opaque black. | 505 // When alpha is false, we should draw to opaque black. |
| 506 if (!m_context->hasAlpha()) | 506 if (!m_context->creationAttributes().alpha()) |
| 507 context.fillRect(FloatRect(r), Color(0, 0, 0)); | 507 context.fillRect(FloatRect(r), Color(0, 0, 0)); |
| 508 } | 508 } |
| 509 | 509 |
| 510 if (is3D() && paintsIntoCanvasBuffer()) | 510 if (is3D() && paintsIntoCanvasBuffer()) |
| 511 m_context->markLayerComposited(); | 511 m_context->markLayerComposited(); |
| 512 } | 512 } |
| 513 | 513 |
| 514 bool HTMLCanvasElement::is3D() const | 514 bool HTMLCanvasElement::is3D() const |
| 515 { | 515 { |
| 516 return m_context && m_context->is3d(); | 516 return m_context && m_context->is3d(); |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 799 // resource limits. So we need to keep the number of texture resources | 799 // resource limits. So we need to keep the number of texture resources |
| 800 // under tight control | 800 // under tight control |
| 801 if (ImageBuffer::getGlobalAcceleratedImageBufferCount() >= MaxGlobalAccelera
tedImageBufferCount) | 801 if (ImageBuffer::getGlobalAcceleratedImageBufferCount() >= MaxGlobalAccelera
tedImageBufferCount) |
| 802 return false; | 802 return false; |
| 803 | 803 |
| 804 return true; | 804 return true; |
| 805 } | 805 } |
| 806 | 806 |
| 807 class UnacceleratedSurfaceFactory : public RecordingImageBufferFallbackSurfaceFa
ctory { | 807 class UnacceleratedSurfaceFactory : public RecordingImageBufferFallbackSurfaceFa
ctory { |
| 808 public: | 808 public: |
| 809 virtual std::unique_ptr<ImageBufferSurface> createSurface(const IntSize& siz
e, OpacityMode opacityMode) | 809 virtual std::unique_ptr<ImageBufferSurface> createSurface(const IntSize& siz
e, OpacityMode opacityMode, sk_sp<SkColorSpace> colorSpace) |
| 810 { | 810 { |
| 811 return wrapUnique(new UnacceleratedImageBufferSurface(size, opacityMode)
); | 811 return wrapUnique(new UnacceleratedImageBufferSurface(size, opacityMode,
InitializeImagePixels, colorSpace)); |
| 812 } | 812 } |
| 813 | 813 |
| 814 virtual ~UnacceleratedSurfaceFactory() { } | 814 virtual ~UnacceleratedSurfaceFactory() { } |
| 815 }; | 815 }; |
| 816 | 816 |
| 817 bool HTMLCanvasElement::shouldUseDisplayList(const IntSize& deviceSize) | 817 bool HTMLCanvasElement::shouldUseDisplayList(const IntSize& deviceSize) |
| 818 { | 818 { |
| 819 if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled()) | 819 if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled()) |
| 820 return true; | 820 return true; |
| 821 | 821 |
| 822 if (!RuntimeEnabledFeatures::displayList2dCanvasEnabled()) | 822 if (!RuntimeEnabledFeatures::displayList2dCanvasEnabled()) |
| 823 return false; | 823 return false; |
| 824 | 824 |
| 825 return true; | 825 return true; |
| 826 } | 826 } |
| 827 | 827 |
| 828 std::unique_ptr<ImageBufferSurface> HTMLCanvasElement::createImageBufferSurface(
const IntSize& deviceSize, int* msaaSampleCount) | 828 std::unique_ptr<ImageBufferSurface> HTMLCanvasElement::createImageBufferSurface(
const IntSize& deviceSize, int* msaaSampleCount, sk_sp<SkColorSpace> colorSpace) |
| 829 { | 829 { |
| 830 OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque :
Opaque; | 830 OpacityMode opacityMode = !m_context || m_context->creationAttributes().alph
a() ? NonOpaque : Opaque; |
| 831 | 831 |
| 832 *msaaSampleCount = 0; | 832 *msaaSampleCount = 0; |
| 833 if (is3D()) { | 833 if (is3D()) { |
| 834 // If 3d, but the use of the canvas will be for non-accelerated content | 834 // If 3d, but the use of the canvas will be for non-accelerated content |
| 835 // then make a non-accelerated ImageBuffer. This means copying the inter
nal | 835 // then make a non-accelerated ImageBuffer. This means copying the inter
nal |
| 836 // Image will require a pixel readback, but that is unavoidable in this
case. | 836 // Image will require a pixel readback, but that is unavoidable in this
case. |
| 837 return wrapUnique(new AcceleratedImageBufferSurface(deviceSize, opacityM
ode)); | 837 return wrapUnique(new AcceleratedImageBufferSurface(deviceSize, opacityM
ode, colorSpace)); |
| 838 } | 838 } |
| 839 | 839 |
| 840 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = wrapUnique(P
latform::current()->createSharedOffscreenGraphicsContext3DProvider()); | 840 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = wrapUnique(P
latform::current()->createSharedOffscreenGraphicsContext3DProvider()); |
| 841 if (!contextProvider) { | 841 if (!contextProvider) { |
| 842 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Accelerated2DCanva
sGPUContextLost); | 842 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Accelerated2DCanva
sGPUContextLost); |
| 843 } else if (shouldAccelerate(deviceSize, contextProvider.get())) { | 843 } else if (shouldAccelerate(deviceSize, contextProvider.get())) { |
| 844 if (document().settings()) | 844 if (document().settings()) |
| 845 *msaaSampleCount = document().settings()->accelerated2dCanvasMSAASam
pleCount(); | 845 *msaaSampleCount = document().settings()->accelerated2dCanvasMSAASam
pleCount(); |
| 846 std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new Canvas2DIma
geBufferSurface(std::move(contextProvider), deviceSize, *msaaSampleCount, opacit
yMode, Canvas2DLayerBridge::EnableAcceleration)); | 846 std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new Canvas2DIma
geBufferSurface(std::move(contextProvider), deviceSize, *msaaSampleCount, opacit
yMode, Canvas2DLayerBridge::EnableAcceleration, colorSpace)); |
| 847 if (surface->isValid()) { | 847 if (surface->isValid()) { |
| 848 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated
2DCanvasImageBufferCreated); | 848 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated
2DCanvasImageBufferCreated); |
| 849 return surface; | 849 return surface; |
| 850 } | 850 } |
| 851 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCa
nvasImageBufferCreationFailed); | 851 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCa
nvasImageBufferCreationFailed); |
| 852 } | 852 } |
| 853 | 853 |
| 854 std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> surfaceFactory =
wrapUnique(new UnacceleratedSurfaceFactory()); | 854 std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> surfaceFactory =
wrapUnique(new UnacceleratedSurfaceFactory()); |
| 855 | 855 |
| 856 if (shouldUseDisplayList(deviceSize)) { | 856 if (shouldUseDisplayList(deviceSize)) { |
| 857 std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new RecordingIm
ageBufferSurface(deviceSize, std::move(surfaceFactory), opacityMode)); | 857 std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new RecordingIm
ageBufferSurface(deviceSize, std::move(surfaceFactory), opacityMode, colorSpace)
); |
| 858 if (surface->isValid()) { | 858 if (surface->isValid()) { |
| 859 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::DisplayList2DC
anvasImageBufferCreated); | 859 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::DisplayList2DC
anvasImageBufferCreated); |
| 860 return surface; | 860 return surface; |
| 861 } | 861 } |
| 862 surfaceFactory = wrapUnique(new UnacceleratedSurfaceFactory()); // recre
ate because previous one was released | 862 surfaceFactory = wrapUnique(new UnacceleratedSurfaceFactory()); // recre
ate because previous one was released |
| 863 } | 863 } |
| 864 auto surface = surfaceFactory->createSurface(deviceSize, opacityMode); | 864 auto surface = surfaceFactory->createSurface(deviceSize, opacityMode, colorS
pace); |
| 865 if (!surface->isValid()) { | 865 if (!surface->isValid()) { |
| 866 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCan
vasImageBufferCreationFailed); | 866 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCan
vasImageBufferCreationFailed); |
| 867 } else { | 867 } else { |
| 868 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCan
vasImageBufferCreated); | 868 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCan
vasImageBufferCreated); |
| 869 } | 869 } |
| 870 return surface; | 870 return surface; |
| 871 } | 871 } |
| 872 | 872 |
| 873 void HTMLCanvasElement::createImageBuffer() | 873 void HTMLCanvasElement::createImageBuffer() |
| 874 { | 874 { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 885 m_imageBufferIsClear = true; | 885 m_imageBufferIsClear = true; |
| 886 | 886 |
| 887 if (!ImageBuffer::canCreateImageBuffer(size())) | 887 if (!ImageBuffer::canCreateImageBuffer(size())) |
| 888 return; | 888 return; |
| 889 | 889 |
| 890 int msaaSampleCount = 0; | 890 int msaaSampleCount = 0; |
| 891 std::unique_ptr<ImageBufferSurface> surface; | 891 std::unique_ptr<ImageBufferSurface> surface; |
| 892 if (externalSurface) { | 892 if (externalSurface) { |
| 893 surface = std::move(externalSurface); | 893 surface = std::move(externalSurface); |
| 894 } else { | 894 } else { |
| 895 surface = createImageBufferSurface(size(), &msaaSampleCount); | 895 surface = createImageBufferSurface(size(), &msaaSampleCount, m_context->
skColorSpace()); |
| 896 } | 896 } |
| 897 m_imageBuffer = ImageBuffer::create(std::move(surface)); | 897 m_imageBuffer = ImageBuffer::create(std::move(surface)); |
| 898 if (!m_imageBuffer) | 898 if (!m_imageBuffer) |
| 899 return; | 899 return; |
| 900 m_imageBuffer->setClient(this); | 900 m_imageBuffer->setClient(this); |
| 901 | 901 |
| 902 m_didFailToCreateImageBuffer = false; | 902 m_didFailToCreateImageBuffer = false; |
| 903 | 903 |
| 904 updateExternallyAllocatedMemory(); | 904 updateExternallyAllocatedMemory(); |
| 905 | 905 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 setHeight(surface->size().height()); | 1005 setHeight(surface->size().height()); |
| 1006 createImageBufferInternal(std::move(surface)); | 1006 createImageBufferInternal(std::move(surface)); |
| 1007 } | 1007 } |
| 1008 | 1008 |
| 1009 void HTMLCanvasElement::ensureUnacceleratedImageBuffer() | 1009 void HTMLCanvasElement::ensureUnacceleratedImageBuffer() |
| 1010 { | 1010 { |
| 1011 DCHECK(m_context); | 1011 DCHECK(m_context); |
| 1012 if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCrea
teImageBuffer) | 1012 if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCrea
teImageBuffer) |
| 1013 return; | 1013 return; |
| 1014 discardImageBuffer(); | 1014 discardImageBuffer(); |
| 1015 OpacityMode opacityMode = m_context->hasAlpha() ? NonOpaque : Opaque; | 1015 OpacityMode opacityMode = m_context->creationAttributes().alpha() ? NonOpaqu
e : Opaque; |
| 1016 m_imageBuffer = ImageBuffer::create(size(), opacityMode); | 1016 m_imageBuffer = ImageBuffer::create(size(), opacityMode); |
| 1017 m_didFailToCreateImageBuffer = !m_imageBuffer; | 1017 m_didFailToCreateImageBuffer = !m_imageBuffer; |
| 1018 } | 1018 } |
| 1019 | 1019 |
| 1020 PassRefPtr<Image> HTMLCanvasElement::copiedImage(SourceDrawingBuffer sourceBuffe
r, AccelerationHint hint) const | 1020 PassRefPtr<Image> HTMLCanvasElement::copiedImage(SourceDrawingBuffer sourceBuffe
r, AccelerationHint hint) const |
| 1021 { | 1021 { |
| 1022 if (!isPaintable()) | 1022 if (!isPaintable()) |
| 1023 return nullptr; | 1023 return nullptr; |
| 1024 if (!m_context) | 1024 if (!m_context) |
| 1025 return createTransparentImage(size()); | 1025 return createTransparentImage(size()); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1149 if ((cropRect && !ImageBitmap::isSourceSizeValid(cropRect->width(), cropRect
->height(), exceptionState)) | 1149 if ((cropRect && !ImageBitmap::isSourceSizeValid(cropRect->width(), cropRect
->height(), exceptionState)) |
| 1150 || !ImageBitmap::isSourceSizeValid(bitmapSourceSize().width(), bitmapSou
rceSize().height(), exceptionState)) | 1150 || !ImageBitmap::isSourceSizeValid(bitmapSourceSize().width(), bitmapSou
rceSize().height(), exceptionState)) |
| 1151 return ScriptPromise(); | 1151 return ScriptPromise(); |
| 1152 if (!ImageBitmap::isResizeOptionValid(options, exceptionState)) | 1152 if (!ImageBitmap::isResizeOptionValid(options, exceptionState)) |
| 1153 return ScriptPromise(); | 1153 return ScriptPromise(); |
| 1154 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im
ageBitmap::create(this, cropRect, options) : nullptr); | 1154 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im
ageBitmap::create(this, cropRect, options) : nullptr); |
| 1155 } | 1155 } |
| 1156 | 1156 |
| 1157 bool HTMLCanvasElement::isOpaque() const | 1157 bool HTMLCanvasElement::isOpaque() const |
| 1158 { | 1158 { |
| 1159 return m_context && !m_context->hasAlpha(); | 1159 return m_context && !m_context->creationAttributes().alpha(); |
| 1160 } | 1160 } |
| 1161 | 1161 |
| 1162 bool HTMLCanvasElement::isSupportedInteractiveCanvasFallback(const Element& elem
ent) | 1162 bool HTMLCanvasElement::isSupportedInteractiveCanvasFallback(const Element& elem
ent) |
| 1163 { | 1163 { |
| 1164 if (!element.isDescendantOf(this)) | 1164 if (!element.isDescendantOf(this)) |
| 1165 return false; | 1165 return false; |
| 1166 | 1166 |
| 1167 // An element is a supported interactive canvas fallback element if it is on
e of the following: | 1167 // An element is a supported interactive canvas fallback element if it is on
e of the following: |
| 1168 // https://html.spec.whatwg.org/multipage/scripting.html#supported-interacti
ve-canvas-fallback-element | 1168 // https://html.spec.whatwg.org/multipage/scripting.html#supported-interacti
ve-canvas-fallback-element |
| 1169 | 1169 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1233 | 1233 |
| 1234 bool HTMLCanvasElement::createSurfaceLayer() | 1234 bool HTMLCanvasElement::createSurfaceLayer() |
| 1235 { | 1235 { |
| 1236 DCHECK(!m_surfaceLayerBridge); | 1236 DCHECK(!m_surfaceLayerBridge); |
| 1237 std::unique_ptr<CanvasSurfaceLayerBridgeClient> bridgeClient = wrapUnique(ne
w CanvasSurfaceLayerBridgeClientImpl()); | 1237 std::unique_ptr<CanvasSurfaceLayerBridgeClient> bridgeClient = wrapUnique(ne
w CanvasSurfaceLayerBridgeClientImpl()); |
| 1238 m_surfaceLayerBridge = wrapUnique(new CanvasSurfaceLayerBridge(std::move(bri
dgeClient))); | 1238 m_surfaceLayerBridge = wrapUnique(new CanvasSurfaceLayerBridge(std::move(bri
dgeClient))); |
| 1239 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), this->height(
)); | 1239 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), this->height(
)); |
| 1240 } | 1240 } |
| 1241 | 1241 |
| 1242 } // namespace blink | 1242 } // namespace blink |
| OLD | NEW |