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

Side by Side Diff: Source/platform/graphics/Canvas2DLayerManager.cpp

Issue 117703004: Free temporary GPU and memory resources held by inactive or hidden 2D canvases (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: improved test Created 6 years, 11 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 Copyright (C) 2012 Google Inc. All rights reserved. 2 Copyright (C) 2012 Google Inc. All rights reserved.
3 3
4 Redistribution and use in source and binary forms, with or without 4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions 5 modification, are permitted provided that the following conditions
6 are met: 6 are met:
7 1. Redistributions of source code must retain the above copyright 7 1. Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer. 8 notice, this list of conditions and the following disclaimer.
9 2. Redistributions in binary form must reproduce the above copyright 9 2. Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the 10 notice, this list of conditions and the following disclaimer in the
(...skipping 13 matching lines...) Expand all
24 #include "config.h" 24 #include "config.h"
25 25
26 #include "platform/graphics/Canvas2DLayerManager.h" 26 #include "platform/graphics/Canvas2DLayerManager.h"
27 27
28 #include "public/platform/Platform.h" 28 #include "public/platform/Platform.h"
29 #include "wtf/StdLibExtras.h" 29 #include "wtf/StdLibExtras.h"
30 30
31 using blink::WebThread; 31 using blink::WebThread;
32 32
33 namespace { 33 namespace {
34
34 enum { 35 enum {
35 DefaultMaxBytesAllocated = 64*1024*1024, 36 DefaultMaxBytesAllocated = 64*1024*1024,
36 DefaultTargetBytesAllocated = 16*1024*1024, 37 DefaultTargetBytesAllocated = 16*1024*1024,
37 }; 38 };
38 } 39
40 } // unnamed namespace
39 41
40 namespace WebCore { 42 namespace WebCore {
41 43
42 Canvas2DLayerManager::Canvas2DLayerManager() 44 Canvas2DLayerManager::Canvas2DLayerManager()
43 : m_bytesAllocated(0) 45 : m_bytesAllocated(0)
44 , m_maxBytesAllocated(DefaultMaxBytesAllocated) 46 , m_maxBytesAllocated(DefaultMaxBytesAllocated)
45 , m_targetBytesAllocated(DefaultTargetBytesAllocated) 47 , m_targetBytesAllocated(DefaultTargetBytesAllocated)
46 , m_taskObserverActive(false) 48 , m_taskObserverActive(false)
47 { 49 {
48 } 50 }
(...skipping 25 matching lines...) Expand all
74 void Canvas2DLayerManager::willProcessTask() 76 void Canvas2DLayerManager::willProcessTask()
75 { 77 {
76 } 78 }
77 79
78 void Canvas2DLayerManager::didProcessTask() 80 void Canvas2DLayerManager::didProcessTask()
79 { 81 {
80 // Called after the script action for the current frame has been processed. 82 // Called after the script action for the current frame has been processed.
81 ASSERT(m_taskObserverActive); 83 ASSERT(m_taskObserverActive);
82 blink::Platform::current()->currentThread()->removeTaskObserver(this); 84 blink::Platform::current()->currentThread()->removeTaskObserver(this);
83 m_taskObserverActive = false; 85 m_taskObserverActive = false;
84 for (Canvas2DLayerBridge* layer = m_layerList.head(); layer; layer = layer-> next()) 86 Canvas2DLayerBridge* layer = m_layerList.head();
85 layer->limitPendingFrames(); 87 while (layer) {
88 Canvas2DLayerBridge* currentLayer = layer;
89 layer = layer->next();
Stephen White 2014/01/24 18:52:35 Could you add a comment here explaining why we hav
90 currentLayer->limitPendingFrames();
91 }
86 } 92 }
87 93
88 void Canvas2DLayerManager::layerDidDraw(Canvas2DLayerBridge* layer) 94 void Canvas2DLayerManager::layerDidDraw(Canvas2DLayerBridge* layer)
89 { 95 {
90 if (isInList(layer)) { 96 if (isInList(layer)) {
91 if (layer != m_layerList.head()) { 97 if (layer != m_layerList.head()) {
92 m_layerList.remove(layer); 98 m_layerList.remove(layer);
93 m_layerList.push(layer); // Set as MRU 99 m_layerList.push(layer); // Set as MRU
94 } 100 }
95 } else 101 }
96 addLayerToList(layer);
97 102
98 if (!m_taskObserverActive) { 103 if (!m_taskObserverActive) {
99 m_taskObserverActive = true; 104 m_taskObserverActive = true;
100 // Schedule a call to didProcessTask() after completion of the current s cript task. 105 // Schedule a call to didProcessTask() after completion of the current s cript task.
101 blink::Platform::current()->currentThread()->addTaskObserver(this); 106 blink::Platform::current()->currentThread()->addTaskObserver(this);
102 } 107 }
103 } 108 }
104 109
105 void Canvas2DLayerManager::addLayerToList(Canvas2DLayerBridge* layer) 110 void Canvas2DLayerManager::layerTransientResourceAllocationChanged(Canvas2DLayer Bridge* layer, intptr_t deltaBytes)
106 { 111 {
107 ASSERT(!isInList(layer)); 112 ASSERT((intptr_t)m_bytesAllocated + deltaBytes >= 0);
108 m_bytesAllocated += layer->bytesAllocated(); 113 m_bytesAllocated = (intptr_t)m_bytesAllocated + deltaBytes;
109 m_layerList.push(layer); // Set as MRU 114 if (!isInList(layer) && layer->hasTransientResources()) {
110 } 115 m_layerList.push(layer);
116 } else if (isInList(layer) && !layer->hasTransientResources()) {
117 m_layerList.remove(layer);
118 layer->setNext(0);
119 layer->setPrev(0);
120 }
111 121
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) 122 if (deltaBytes > 0)
121 freeMemoryIfNecessary(); 123 freeMemoryIfNecessary();
122 } 124 }
123 125
124 void Canvas2DLayerManager::layerToBeDestroyed(Canvas2DLayerBridge* layer)
125 {
126 if (isInList(layer))
127 removeLayerFromList(layer);
128 }
129
130 void Canvas2DLayerManager::freeMemoryIfNecessary() 126 void Canvas2DLayerManager::freeMemoryIfNecessary()
131 { 127 {
132 if (m_bytesAllocated > m_maxBytesAllocated) { 128 if (m_bytesAllocated >= m_maxBytesAllocated) {
133 // Pass 1: Free memory from caches 129 // Pass 1: Free memory from caches
134 Canvas2DLayerBridge* layer = m_layerList.tail(); // LRU 130 Canvas2DLayerBridge* layer = m_layerList.tail(); // LRU
135 while (m_bytesAllocated > m_targetBytesAllocated && layer) { 131 while (layer && m_bytesAllocated > m_targetBytesAllocated) {
136 layer->freeMemoryIfPossible(m_bytesAllocated - m_targetBytesAllocate d); 132 Canvas2DLayerBridge* currentLayer = layer;
137 layer = layer->prev(); 133 layer = layer->prev();
134 currentLayer->freeMemoryIfPossible(m_bytesAllocated - m_targetBytesA llocated);
135 ASSERT(isInList(currentLayer) == currentLayer->hasTransientResources ());
138 } 136 }
139 137
140 // Pass 2: Flush canvases 138 // Pass 2: Flush canvases
141 Canvas2DLayerBridge* leastRecentlyUsedLayer = m_layerList.tail(); 139 layer = m_layerList.tail();
142 while (m_bytesAllocated > m_targetBytesAllocated && leastRecentlyUsedLay er) { 140 while (m_bytesAllocated > m_targetBytesAllocated && layer) {
143 leastRecentlyUsedLayer->flush(); 141 Canvas2DLayerBridge* currentLayer = layer;
144 leastRecentlyUsedLayer->freeMemoryIfPossible(~0); 142 layer = layer->prev();
145 removeLayerFromList(leastRecentlyUsedLayer); 143 currentLayer->flush();
146 leastRecentlyUsedLayer = m_layerList.tail(); 144 currentLayer->freeMemoryIfPossible(m_bytesAllocated - m_targetBytesA llocated);
145 ASSERT(isInList(currentLayer) == currentLayer->hasTransientResources ());
147 } 146 }
148 } 147 }
149 } 148 }
150 149
151 void Canvas2DLayerManager::removeLayerFromList(Canvas2DLayerBridge* layer) 150 void Canvas2DLayerManager::removeLayerFromList(Canvas2DLayerBridge* layer)
152 { 151 {
153 ASSERT(isInList(layer)); 152 ASSERT(isInList(layer));
154 m_bytesAllocated -= layer->bytesAllocated(); 153 ASSERT(!layer->hasTransientResources());
155 m_layerList.remove(layer); 154
156 layer->setNext(0);
157 layer->setPrev(0);
158 } 155 }
159 156
160 bool Canvas2DLayerManager::isInList(Canvas2DLayerBridge* layer) 157 bool Canvas2DLayerManager::isInList(Canvas2DLayerBridge* layer) const
161 { 158 {
162 return layer->prev() || m_layerList.head() == layer; 159 return layer->prev() || m_layerList.head() == layer;
163 } 160 }
164 161
165 } 162 }
166 163
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698