OLD | NEW |
| (Empty) |
1 /* | |
2 Copyright (C) 2012 Google Inc. All rights reserved. | |
3 | |
4 Redistribution and use in source and binary forms, with or without | |
5 modification, are permitted provided that the following conditions | |
6 are met: | |
7 1. Redistributions of source code must retain the above copyright | |
8 notice, this list of conditions and the following disclaimer. | |
9 2. Redistributions in binary form must reproduce the above copyright | |
10 notice, this list of conditions and the following disclaimer in the | |
11 documentation and/or other materials provided with the distribution. | |
12 | |
13 THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY | |
14 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
15 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
16 DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY | |
17 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
18 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
19 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
20 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
21 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
22 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
23 */ | |
24 #include "config.h" | |
25 | |
26 #include "core/platform/graphics/Canvas2DLayerManager.h" | |
27 | |
28 #include "public/platform/Platform.h" | |
29 #include "wtf/StdLibExtras.h" | |
30 | |
31 using blink::WebThread; | |
32 | |
33 namespace { | |
34 enum { | |
35 DefaultMaxBytesAllocated = 64*1024*1024, | |
36 DefaultTargetBytesAllocated = 16*1024*1024, | |
37 }; | |
38 } | |
39 | |
40 namespace WebCore { | |
41 | |
42 Canvas2DLayerManager::Canvas2DLayerManager() | |
43 : m_bytesAllocated(0) | |
44 , m_maxBytesAllocated(DefaultMaxBytesAllocated) | |
45 , m_targetBytesAllocated(DefaultTargetBytesAllocated) | |
46 , m_taskObserverActive(false) | |
47 { | |
48 } | |
49 | |
50 Canvas2DLayerManager::~Canvas2DLayerManager() | |
51 { | |
52 ASSERT(!m_bytesAllocated); | |
53 ASSERT(!m_layerList.head()); | |
54 ASSERT(!m_taskObserverActive); | |
55 } | |
56 | |
57 void Canvas2DLayerManager::init(size_t maxBytesAllocated, size_t targetBytesAllo
cated) | |
58 { | |
59 ASSERT(maxBytesAllocated >= targetBytesAllocated); | |
60 m_maxBytesAllocated = maxBytesAllocated; | |
61 m_targetBytesAllocated = targetBytesAllocated; | |
62 if (m_taskObserverActive) { | |
63 blink::Platform::current()->currentThread()->removeTaskObserver(this); | |
64 m_taskObserverActive = false; | |
65 } | |
66 } | |
67 | |
68 Canvas2DLayerManager& Canvas2DLayerManager::get() | |
69 { | |
70 DEFINE_STATIC_LOCAL(Canvas2DLayerManager, manager, ()); | |
71 return manager; | |
72 } | |
73 | |
74 void Canvas2DLayerManager::willProcessTask() | |
75 { | |
76 } | |
77 | |
78 void Canvas2DLayerManager::didProcessTask() | |
79 { | |
80 // Called after the script action for the current frame has been processed. | |
81 ASSERT(m_taskObserverActive); | |
82 blink::Platform::current()->currentThread()->removeTaskObserver(this); | |
83 m_taskObserverActive = false; | |
84 for (Canvas2DLayerBridge* layer = m_layerList.head(); layer; layer = layer->
next()) | |
85 layer->limitPendingFrames(); | |
86 } | |
87 | |
88 void Canvas2DLayerManager::layerDidDraw(Canvas2DLayerBridge* layer) | |
89 { | |
90 if (isInList(layer)) { | |
91 if (layer != m_layerList.head()) { | |
92 m_layerList.remove(layer); | |
93 m_layerList.push(layer); // Set as MRU | |
94 } | |
95 } else | |
96 addLayerToList(layer); | |
97 | |
98 if (!m_taskObserverActive) { | |
99 m_taskObserverActive = true; | |
100 // Schedule a call to didProcessTask() after completion of the current s
cript task. | |
101 blink::Platform::current()->currentThread()->addTaskObserver(this); | |
102 } | |
103 } | |
104 | |
105 void Canvas2DLayerManager::addLayerToList(Canvas2DLayerBridge* layer) | |
106 { | |
107 ASSERT(!isInList(layer)); | |
108 m_bytesAllocated += layer->bytesAllocated(); | |
109 m_layerList.push(layer); // Set as MRU | |
110 } | |
111 | |
112 void Canvas2DLayerManager::layerAllocatedStorageChanged(Canvas2DLayerBridge* lay
er, intptr_t deltaBytes) | |
113 { | |
114 if (!isInList(layer)) | |
115 addLayerToList(layer); | |
116 else { | |
117 ASSERT((intptr_t)m_bytesAllocated + deltaBytes >= 0); | |
118 m_bytesAllocated = (intptr_t)m_bytesAllocated + deltaBytes; | |
119 } | |
120 if (deltaBytes > 0) | |
121 freeMemoryIfNecessary(); | |
122 } | |
123 | |
124 void Canvas2DLayerManager::layerToBeDestroyed(Canvas2DLayerBridge* layer) | |
125 { | |
126 if (isInList(layer)) | |
127 removeLayerFromList(layer); | |
128 } | |
129 | |
130 void Canvas2DLayerManager::freeMemoryIfNecessary() | |
131 { | |
132 if (m_bytesAllocated > m_maxBytesAllocated) { | |
133 // Pass 1: Free memory from caches | |
134 Canvas2DLayerBridge* layer = m_layerList.tail(); // LRU | |
135 while (m_bytesAllocated > m_targetBytesAllocated && layer) { | |
136 layer->freeMemoryIfPossible(m_bytesAllocated - m_targetBytesAllocate
d); | |
137 layer = layer->prev(); | |
138 } | |
139 | |
140 // Pass 2: Flush canvases | |
141 Canvas2DLayerBridge* leastRecentlyUsedLayer = m_layerList.tail(); | |
142 while (m_bytesAllocated > m_targetBytesAllocated && leastRecentlyUsedLay
er) { | |
143 leastRecentlyUsedLayer->flush(); | |
144 leastRecentlyUsedLayer->freeMemoryIfPossible(~0); | |
145 removeLayerFromList(leastRecentlyUsedLayer); | |
146 leastRecentlyUsedLayer = m_layerList.tail(); | |
147 } | |
148 } | |
149 } | |
150 | |
151 void Canvas2DLayerManager::removeLayerFromList(Canvas2DLayerBridge* layer) | |
152 { | |
153 ASSERT(isInList(layer)); | |
154 m_bytesAllocated -= layer->bytesAllocated(); | |
155 m_layerList.remove(layer); | |
156 layer->setNext(0); | |
157 layer->setPrev(0); | |
158 } | |
159 | |
160 bool Canvas2DLayerManager::isInList(Canvas2DLayerBridge* layer) | |
161 { | |
162 return layer->prev() || m_layerList.head() == layer; | |
163 } | |
164 | |
165 } | |
166 | |
OLD | NEW |