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

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

Issue 1482363004: Fixing laggy chrome on a multitude of accelerated canvases (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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
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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 const int DefaultHeight = 150; 73 const int DefaultHeight = 150;
74 74
75 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo re it 75 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo re it
76 // reaches that limit. We limit by area instead, giving us larger maximum dimens ions, 76 // reaches that limit. We limit by area instead, giving us larger maximum dimens ions,
77 // in exchange for a smaller maximum canvas size. 77 // in exchange for a smaller maximum canvas size.
78 const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels 78 const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels
79 79
80 // In Skia, we will also limit width/height to 32767. 80 // In Skia, we will also limit width/height to 32767.
81 const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. 81 const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels.
82 82
83 // Max Limit of Externally Allocated Memory
danakj 2015/11/30 23:07:03 comments are sentences, please add periods, and do
84 // Equivalent to memory used by 80 accelerated canvases, each has a size of 1000 *500 and 2d context
85 const int MaxTotalExternallyAllocatedMemory = 6000000 * 80;
danakj 2015/11/30 23:07:03 also, naming for contants is kNameOfConstant. but
danakj 2015/11/30 23:07:03 can you write it as like 1000*500*4.. i'm not sure
xlai (Olivia) 2015/12/01 21:50:25 Refactored all the constants in this file to fit t
86
83 // A default value of quality argument for toDataURL and toBlob 87 // A default value of quality argument for toDataURL and toBlob
84 // It is in an invalid range (outside 0.0 - 1.0) so that it will not be misinter preted as a user-input value 88 // It is in an invalid range (outside 0.0 - 1.0) so that it will not be misinter preted as a user-input value
85 const int UndefinedQualityValue = -1.0; 89 const int UndefinedQualityValue = -1.0;
86 90
87 // Default image mime type for toDataURL and toBlob functions 91 // Default image mime type for toDataURL and toBlob functions
88 const char DefaultMimeType[] = "image/png"; 92 const char DefaultMimeType[] = "image/png";
89 93
90 bool canCreateImageBuffer(const IntSize& size) 94 bool canCreateImageBuffer(const IntSize& size)
91 { 95 {
92 if (size.isEmpty()) 96 if (size.isEmpty())
(...skipping 24 matching lines...) Expand all
117 , m_originClean(true) 121 , m_originClean(true)
118 , m_didFailToCreateImageBuffer(false) 122 , m_didFailToCreateImageBuffer(false)
119 , m_imageBufferIsClear(false) 123 , m_imageBufferIsClear(false)
120 { 124 {
121 setHasCustomStyleCallbacks(); 125 setHasCustomStyleCallbacks();
122 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::CanvasCreated); 126 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::CanvasCreated);
123 } 127 }
124 128
125 DEFINE_NODE_FACTORY(HTMLCanvasElement) 129 DEFINE_NODE_FACTORY(HTMLCanvasElement)
126 130
131 intptr_t HTMLCanvasElement::s_totalMemoryForAcceleratedCanvases = 0;
132
127 HTMLCanvasElement::~HTMLCanvasElement() 133 HTMLCanvasElement::~HTMLCanvasElement()
128 { 134 {
129 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_external lyAllocatedMemory); 135 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_external lyAllocatedMemory);
136 if (m_imageBuffer && m_imageBuffer->isAccelerated())
137 updateTotalMemoryForAcceleratedCanvases(-m_externallyAllocatedMemory);
130 #if !ENABLE(OILPAN) 138 #if !ENABLE(OILPAN)
131 // Ensure these go away before the ImageBuffer. 139 // Ensure these go away before the ImageBuffer.
132 m_context.clear(); 140 m_context.clear();
133 #endif 141 #endif
134 } 142 }
135 143
136 void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicSt ring& value) 144 void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicSt ring& value)
137 { 145 {
138 if (name == widthAttr || name == heightAttr) 146 if (name == widthAttr || name == heightAttr)
139 reset(); 147 reset();
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 #if 0 606 #if 0
599 // TODO(junov): re-enable this code once we solve the problem of recordi ng 607 // TODO(junov): re-enable this code once we solve the problem of recordi ng
600 // GPU-backed images to an SkPicture for cross-context rendering crbug.c om/490328 608 // GPU-backed images to an SkPicture for cross-context rendering crbug.c om/490328
601 609
602 // If the compositor provides GPU acceleration to display list canvases, we 610 // If the compositor provides GPU acceleration to display list canvases, we
603 // prefer that over direct acceleration. 611 // prefer that over direct acceleration.
604 if (document().viewportDescription().matchesHeuristicsForGpuRasterizatio n()) 612 if (document().viewportDescription().matchesHeuristicsForGpuRasterizatio n())
605 return false; 613 return false;
606 #endif 614 #endif
607 // If the GPU resources would be very expensive, prefer a display list. 615 // If the GPU resources would be very expensive, prefer a display list.
608 if (canvasPixelCount > ExpensiveCanvasHeuristicParameters::PreferDisplay ListOverGpuSizeThreshold) 616 if (canvasPixelCount >= ExpensiveCanvasHeuristicParameters::PreferDispla yListOverGpuSizeThreshold)
danakj 2015/11/30 23:07:03 This looks like a separate CL, cuz it's an unrelat
xlai (Olivia) 2015/12/01 21:50:25 Sorry that's a careless mistake. Had corrected it.
609 return false; 617 return false;
610 } 618 }
611 619
612 // Do not use acceleration for small canvas. 620 // Do not use acceleration for small canvas.
613 if (canvasPixelCount < settings->minimumAccelerated2dCanvasSize()) 621 if (canvasPixelCount < settings->minimumAccelerated2dCanvasSize())
614 return false; 622 return false;
615 623
616 if (!Platform::current()->canAccelerate2dCanvas()) 624 if (!Platform::current()->canAccelerate2dCanvas())
617 return false; 625 return false;
618 626
627 // When GPU allocated memory runs low (due to having created too many accele rated canvases), the
628 // compositor starves and browser becomes laggy. Thus, we should stop allo cating more GPU memory to
danakj 2015/11/30 23:07:03 don't indent comments extra, all lines get the sam
629 // new canvases created when the current memory usage exceeds the threshol d.
630 if (s_totalMemoryForAcceleratedCanvases >= MaxTotalExternallyAllocatedMemory )
danakj 2015/11/30 23:07:03 You'll go over the budget before you start rejecti
xlai (Olivia) 2015/12/01 21:50:25 I think the max limit here is more like a soft lim
631 return false;
632 #if defined(OS_ANDROID)
danakj 2015/11/30 23:07:03 I think you can do this ifdefing around what the l
xlai (Olivia) 2015/12/01 21:50:25 Acknowledged. Moved the code to the front in setti
633 // We estimate that the max limit for android phones is half of that for des ktops
634 // based on local experimental results on Android One
635 // (though a very slight lagginess on Android One is still expected, other d evices should work fine)
636 if (s_totalMemoryForAcceleratedCanvases >= MaxTotalExternallyAllocatedMemory / 2)
637 return false;
638 #endif
639
619 return true; 640 return true;
620 } 641 }
621 642
622 class UnacceleratedSurfaceFactory : public RecordingImageBufferFallbackSurfaceFa ctory { 643 class UnacceleratedSurfaceFactory : public RecordingImageBufferFallbackSurfaceFa ctory {
623 public: 644 public:
624 virtual PassOwnPtr<ImageBufferSurface> createSurface(const IntSize& size, Op acityMode opacityMode) 645 virtual PassOwnPtr<ImageBufferSurface> createSurface(const IntSize& size, Op acityMode opacityMode)
625 { 646 {
626 return adoptPtr(new UnacceleratedImageBufferSurface(size, opacityMode)); 647 return adoptPtr(new UnacceleratedImageBufferSurface(size, opacityMode));
627 } 648 }
628 649
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 if (is3D()) 790 if (is3D())
770 checkedExternallyAllocatedMemory += m_context->externallyAllocatedBytesP erPixel(); 791 checkedExternallyAllocatedMemory += m_context->externallyAllocatedBytesP erPixel();
771 792
772 checkedExternallyAllocatedMemory *= width(); 793 checkedExternallyAllocatedMemory *= width();
773 checkedExternallyAllocatedMemory *= height(); 794 checkedExternallyAllocatedMemory *= height();
774 intptr_t externallyAllocatedMemory; 795 intptr_t externallyAllocatedMemory;
775 if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == C heckedState::DidOverflow) 796 if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == C heckedState::DidOverflow)
776 externallyAllocatedMemory = std::numeric_limits<intptr_t>::max(); 797 externallyAllocatedMemory = std::numeric_limits<intptr_t>::max();
777 798
778 // Subtracting two intptr_t that are known to be positive will never underfl ow. 799 // Subtracting two intptr_t that are known to be positive will never underfl ow.
779 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyA llocatedMemory - m_externallyAllocatedMemory); 800 intptr_t diffFromCurrAllocatedMemory = externallyAllocatedMemory - m_externa llyAllocatedMemory;
801 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(diffFromCur rAllocatedMemory);
780 m_externallyAllocatedMemory = externallyAllocatedMemory; 802 m_externallyAllocatedMemory = externallyAllocatedMemory;
803
804 if (m_imageBuffer && m_imageBuffer->isAccelerated())
805 updateTotalMemoryForAcceleratedCanvases(diffFromCurrAllocatedMemory);
806 }
807
808 void HTMLCanvasElement::updateTotalMemoryForAcceleratedCanvases(intptr_t diffFro mCurrAllocatedMemory)
809 {
810 ASSERT(isMainThread());
811
812 Checked<intptr_t, RecordOverflow> checkedExternallyAllocatedMemory = s_total MemoryForAcceleratedCanvases;
813 checkedExternallyAllocatedMemory += diffFromCurrAllocatedMemory;
814 intptr_t externallyAllocatedMemory;
815 if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == C heckedState::DidOverflow)
816 externallyAllocatedMemory = std::numeric_limits<intptr_t>::max();
817
818 s_totalMemoryForAcceleratedCanvases = externallyAllocatedMemory;
781 } 819 }
782 820
783 SkCanvas* HTMLCanvasElement::drawingCanvas() const 821 SkCanvas* HTMLCanvasElement::drawingCanvas() const
784 { 822 {
785 return buffer() ? m_imageBuffer->canvas() : nullptr; 823 return buffer() ? m_imageBuffer->canvas() : nullptr;
786 } 824 }
787 825
788 void HTMLCanvasElement::disableDeferral() const 826 void HTMLCanvasElement::disableDeferral() const
789 { 827 {
790 if (buffer()) 828 if (buffer())
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 } 990 }
953 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im ageBitmap::create(this, IntRect(sx, sy, sw, sh)) : nullptr); 991 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im ageBitmap::create(this, IntRect(sx, sy, sw, sh)) : nullptr);
954 } 992 }
955 993
956 bool HTMLCanvasElement::isOpaque() const 994 bool HTMLCanvasElement::isOpaque() const
957 { 995 {
958 return m_context && !m_context->hasAlpha(); 996 return m_context && !m_context->hasAlpha();
959 } 997 }
960 998
961 } // blink 999 } // blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698