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

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

Issue 2280723003: Avoid making the shared main thread context if we won't use it. (Closed)
Patch Set: regress: name Created 4 years, 3 months 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
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLCanvasElement.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 724 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 return document().getSecurityOrigin(); 735 return document().getSecurityOrigin();
736 } 736 }
737 737
738 bool HTMLCanvasElement::originClean() const 738 bool HTMLCanvasElement::originClean() const
739 { 739 {
740 if (document().settings() && document().settings()->disableReadingFromCanvas ()) 740 if (document().settings() && document().settings()->disableReadingFromCanvas ())
741 return false; 741 return false;
742 return m_originClean; 742 return m_originClean;
743 } 743 }
744 744
745 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size, const WebGraphicsC ontext3DProvider* sharedMainThreadContextProvider) const 745 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
746 { 746 {
747 if (m_context && !m_context->is2d()) 747 if (m_context && !m_context->is2d())
748 return false; 748 return false;
749 749
750 if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled()) 750 if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled())
751 return false; 751 return false;
752 752
753 if (!RuntimeEnabledFeatures::accelerated2dCanvasEnabled()) 753 if (!RuntimeEnabledFeatures::accelerated2dCanvasEnabled())
754 return false; 754 return false;
755 755
(...skipping 22 matching lines...) Expand all
778 // If the GPU resources would be very expensive, prefer a display list. 778 // If the GPU resources would be very expensive, prefer a display list.
779 if (canvasPixelCount > ExpensiveCanvasHeuristicParameters::PreferDisplay ListOverGpuSizeThreshold) 779 if (canvasPixelCount > ExpensiveCanvasHeuristicParameters::PreferDisplay ListOverGpuSizeThreshold)
780 return false; 780 return false;
781 } 781 }
782 782
783 // Do not use acceleration for small canvas. 783 // Do not use acceleration for small canvas.
784 Settings* settings = document().settings(); 784 Settings* settings = document().settings();
785 if (!settings || canvasPixelCount < settings->minimumAccelerated2dCanvasSize ()) 785 if (!settings || canvasPixelCount < settings->minimumAccelerated2dCanvasSize ())
786 return false; 786 return false;
787 787
788 if (sharedMainThreadContextProvider->isSoftwareRendering())
789 return false;
790
791 // When GPU allocated memory runs low (due to having created too many 788 // When GPU allocated memory runs low (due to having created too many
792 // accelerated canvases), the compositor starves and browser becomes laggy. 789 // accelerated canvases), the compositor starves and browser becomes laggy.
793 // Thus, we should stop allocating more GPU memory to new canvases created 790 // Thus, we should stop allocating more GPU memory to new canvases created
794 // when the current memory usage exceeds the threshold. 791 // when the current memory usage exceeds the threshold.
795 if (ImageBuffer::getGlobalGPUMemoryUsage() >= MaxGlobalGPUMemoryUsage) 792 if (ImageBuffer::getGlobalGPUMemoryUsage() >= MaxGlobalGPUMemoryUsage)
796 return false; 793 return false;
797 794
798 // Allocating too many GPU resources can makes us run into the driver's 795 // Allocating too many GPU resources can makes us run into the driver's
799 // resource limits. So we need to keep the number of texture resources 796 // resource limits. So we need to keep the number of texture resources
800 // under tight control 797 // under tight control
(...skipping 17 matching lines...) Expand all
818 { 815 {
819 if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled()) 816 if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled())
820 return true; 817 return true;
821 818
822 if (!RuntimeEnabledFeatures::displayList2dCanvasEnabled()) 819 if (!RuntimeEnabledFeatures::displayList2dCanvasEnabled())
823 return false; 820 return false;
824 821
825 return true; 822 return true;
826 } 823 }
827 824
828 std::unique_ptr<ImageBufferSurface> HTMLCanvasElement::createImageBufferSurface( const IntSize& deviceSize, int* msaaSampleCount, sk_sp<SkColorSpace> colorSpace) 825 std::unique_ptr<ImageBufferSurface> HTMLCanvasElement::createAcceleratedImageBuf ferSurface(const IntSize& deviceSize, OpacityMode opacityMode, sk_sp<SkColorSpac e> colorSpace, int* msaaSampleCount)
829 { 826 {
830 OpacityMode opacityMode = !m_context || m_context->creationAttributes().alph a() ? NonOpaque : Opaque;
831
832 *msaaSampleCount = 0;
833 if (is3D()) { 827 if (is3D()) {
834 // If 3d, but the use of the canvas will be for non-accelerated content 828 // 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 829 // 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. 830 // Image will require a pixel readback, but that is unavoidable in this case.
837 return wrapUnique(new AcceleratedImageBufferSurface(deviceSize, opacityM ode, colorSpace)); 831 return wrapUnique(new AcceleratedImageBufferSurface(deviceSize, opacityM ode, colorSpace));
838 } 832 }
839 833
840 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = wrapUnique(P latform::current()->createSharedOffscreenGraphicsContext3DProvider()); 834 if (!shouldAccelerate(deviceSize))
835 return nullptr;
836
837 if (document().settings())
838 *msaaSampleCount = document().settings()->accelerated2dCanvasMSAASampleC ount();
839
840 // Avoid creating |contextProvider| until we're sure we want to try use it,
841 // since it costs us GPU memory.
842 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider(Platform::curr ent()->createSharedOffscreenGraphicsContext3DProvider());
841 if (!contextProvider) { 843 if (!contextProvider) {
842 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Accelerated2DCanva sGPUContextLost); 844 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Accelerated2DCanva sGPUContextLost);
843 } else if (shouldAccelerate(deviceSize, contextProvider.get())) { 845 return nullptr;
844 if (document().settings())
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, colorSpace));
847 if (surface->isValid()) {
848 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated 2DCanvasImageBufferCreated);
849 return surface;
850 }
851 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCa nvasImageBufferCreationFailed);
852 } 846 }
853 847
854 std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> surfaceFactory = wrapUnique(new UnacceleratedSurfaceFactory()); 848 if (contextProvider->isSoftwareRendering())
849 return nullptr; // Don't use accelerated canvas with swiftshader.
855 850
851 std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new Canvas2DImageBu fferSurface(std::move(contextProvider), deviceSize, *msaaSampleCount, opacityMod e, Canvas2DLayerBridge::EnableAcceleration, std::move(colorSpace)));
852 if (surface->isValid()) {
853 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCa nvasImageBufferCreated);
854 return surface;
855 }
856
857 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCanvas ImageBufferCreationFailed);
858 return nullptr;
859 }
860
861 std::unique_ptr<ImageBufferSurface> HTMLCanvasElement::createUnacceleratedImageB ufferSurface(const IntSize& deviceSize, OpacityMode opacityMode, sk_sp<SkColorSp ace> colorSpace)
862 {
856 if (shouldUseDisplayList(deviceSize)) { 863 if (shouldUseDisplayList(deviceSize)) {
857 std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new RecordingIm ageBufferSurface(deviceSize, std::move(surfaceFactory), opacityMode, colorSpace) ); 864 auto surface = wrapUnique(new RecordingImageBufferSurface(deviceSize, wr apUnique(new UnacceleratedSurfaceFactory), opacityMode, colorSpace));
858 if (surface->isValid()) { 865 if (surface->isValid()) {
859 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::DisplayList2DC anvasImageBufferCreated); 866 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::DisplayList2DC anvasImageBufferCreated);
860 return surface; 867 return std::move(surface);
861 } 868 }
862 surfaceFactory = wrapUnique(new UnacceleratedSurfaceFactory()); // recre ate because previous one was released 869 // We fallback to a non-display-list surface without recording a metric here.
863 } 870 }
864 auto surface = surfaceFactory->createSurface(deviceSize, opacityMode, colorS pace); 871
865 if (!surface->isValid()) { 872 auto surfaceFactory = wrapUnique(new UnacceleratedSurfaceFactory());
866 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCan vasImageBufferCreationFailed); 873 auto surface = surfaceFactory->createSurface(deviceSize, opacityMode, std::m ove(colorSpace));
867 } else { 874 if (surface->isValid()) {
868 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCan vasImageBufferCreated); 875 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCan vasImageBufferCreated);
876 return surface;
869 } 877 }
870 return surface; 878
879 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCanvasI mageBufferCreationFailed);
880 return nullptr;
871 } 881 }
872 882
873 void HTMLCanvasElement::createImageBuffer() 883 void HTMLCanvasElement::createImageBuffer()
874 { 884 {
875 createImageBufferInternal(nullptr); 885 createImageBufferInternal(nullptr);
876 if (m_didFailToCreateImageBuffer && m_context->is2d() && !size().isEmpty()) 886 if (m_didFailToCreateImageBuffer && m_context->is2d() && !size().isEmpty())
877 m_context->loseContext(CanvasRenderingContext::SyntheticLostContext); 887 m_context->loseContext(CanvasRenderingContext::SyntheticLostContext);
878 } 888 }
879 889
880 void HTMLCanvasElement::createImageBufferInternal(std::unique_ptr<ImageBufferSur face> externalSurface) 890 void HTMLCanvasElement::createImageBufferInternal(std::unique_ptr<ImageBufferSur face> externalSurface)
881 { 891 {
882 DCHECK(!m_imageBuffer); 892 DCHECK(!m_imageBuffer);
883 893
884 m_didFailToCreateImageBuffer = true; 894 m_didFailToCreateImageBuffer = true;
885 m_imageBufferIsClear = true; 895 m_imageBufferIsClear = true;
886 896
887 if (!ImageBuffer::canCreateImageBuffer(size())) 897 if (!ImageBuffer::canCreateImageBuffer(size()))
888 return; 898 return;
889 899
900 OpacityMode opacityMode = !m_context || m_context->creationAttributes().alph a() ? NonOpaque : Opaque;
890 int msaaSampleCount = 0; 901 int msaaSampleCount = 0;
891 std::unique_ptr<ImageBufferSurface> surface; 902 std::unique_ptr<ImageBufferSurface> surface = std::move(externalSurface);
892 if (externalSurface) { 903 if (!surface)
893 surface = std::move(externalSurface); 904 surface = createAcceleratedImageBufferSurface(size(), opacityMode, m_con text->skColorSpace(), &msaaSampleCount);
894 } else { 905 if (!surface)
895 surface = createImageBufferSurface(size(), &msaaSampleCount, m_context-> skColorSpace()); 906 surface = createUnacceleratedImageBufferSurface(size(), opacityMode, m_c ontext->skColorSpace());
896 } 907 if (!surface)
908 return;
909 DCHECK(surface->isValid());
897 m_imageBuffer = ImageBuffer::create(std::move(surface)); 910 m_imageBuffer = ImageBuffer::create(std::move(surface));
898 if (!m_imageBuffer) 911 DCHECK(m_imageBuffer);
899 return;
900 m_imageBuffer->setClient(this); 912 m_imageBuffer->setClient(this);
901 913
902 m_didFailToCreateImageBuffer = false; 914 m_didFailToCreateImageBuffer = false;
903 915
904 updateExternallyAllocatedMemory(); 916 updateExternallyAllocatedMemory();
905 917
906 if (is3D()) { 918 if (is3D()) {
907 // Early out for WebGL canvases 919 // Early out for WebGL canvases
908 return; 920 return;
909 } 921 }
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 1245
1234 bool HTMLCanvasElement::createSurfaceLayer() 1246 bool HTMLCanvasElement::createSurfaceLayer()
1235 { 1247 {
1236 DCHECK(!m_surfaceLayerBridge); 1248 DCHECK(!m_surfaceLayerBridge);
1237 std::unique_ptr<CanvasSurfaceLayerBridgeClient> bridgeClient = wrapUnique(ne w CanvasSurfaceLayerBridgeClientImpl()); 1249 std::unique_ptr<CanvasSurfaceLayerBridgeClient> bridgeClient = wrapUnique(ne w CanvasSurfaceLayerBridgeClientImpl());
1238 m_surfaceLayerBridge = wrapUnique(new CanvasSurfaceLayerBridge(std::move(bri dgeClient))); 1250 m_surfaceLayerBridge = wrapUnique(new CanvasSurfaceLayerBridge(std::move(bri dgeClient)));
1239 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), this->height( )); 1251 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), this->height( ));
1240 } 1252 }
1241 1253
1242 } // namespace blink 1254 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLCanvasElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698