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

Side by Side Diff: Source/web/tests/Canvas2DLayerManagerTest.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: fixed upstream git branch Created 7 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 | 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 23 matching lines...) Expand all
34 #include "web/tests/MockWebGraphicsContext3D.h" 34 #include "web/tests/MockWebGraphicsContext3D.h"
35 35
36 #include <gmock/gmock.h> 36 #include <gmock/gmock.h>
37 #include <gtest/gtest.h> 37 #include <gtest/gtest.h>
38 38
39 using namespace WebCore; 39 using namespace WebCore;
40 using testing::InSequence; 40 using testing::InSequence;
41 using testing::Return; 41 using testing::Return;
42 using testing::Test; 42 using testing::Test;
43 43
44 namespace {
45
46 class FakeCanvas2DLayerBridgeClient : public Canvas2DLayerBridgeClient {
47 public:
48 FakeCanvas2DLayerBridgeClient() { m_hidden = false; }
49 virtual ~FakeCanvas2DLayerBridgeClient() { }
50 virtual bool hidden() const OVERRIDE { return m_hidden; }
51 void fakeHidden(bool value) { m_hidden = value; }
52 private:
53 bool m_hidden;
54 };
44 55
45 class FakeCanvas2DLayerBridge : public Canvas2DLayerBridge { 56 class FakeCanvas2DLayerBridge : public Canvas2DLayerBridge {
46 public: 57 public:
47 FakeCanvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<Sk DeferredCanvas> canvas) 58 FakeCanvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<Sk DeferredCanvas> canvas)
48 : Canvas2DLayerBridge(context, canvas, 0, NonOpaque) 59 : Canvas2DLayerBridge(&m_client, context, canvas, 0, NonOpaque)
49 , m_freeableBytes(0) 60 , m_freeableBytes(0)
50 , m_freeMemoryIfPossibleCount(0) 61 , m_freeMemoryIfPossibleCount(0)
51 , m_flushCount(0) 62 , m_flushCount(0)
52 { 63 {
53 } 64 }
54 65
55 virtual size_t storageAllocatedForRecording() OVERRIDE 66 virtual size_t storageAllocatedForRecording() OVERRIDE
56 { 67 {
57 // Because the fake layer has no canvas to query, just 68 // Because the fake layer has no canvas to query, just
58 // return status quo. Allocation changes that would normally be 69 // return status quo. Allocation changes that would normally be
59 // initiated by the canvas can be faked by invoking 70 // initiated by the canvas can be faked by invoking
60 // storageAllocatedForRecordingChanged directly from the test code. 71 // storageAllocatedForRecordingChanged directly from the test code.
61 return m_bytesAllocated; 72 return m_bytesAllocated;
62 } 73 }
63 74
64 void fakeFreeableBytes(size_t size) 75 void fakeFreeableBytes(size_t size)
65 { 76 {
66 m_freeableBytes = size; 77 m_freeableBytes = size;
67 } 78 }
68 79
69 virtual size_t freeMemoryIfPossible(size_t size) OVERRIDE 80 virtual size_t freeMemoryIfPossible(size_t size) OVERRIDE
70 { 81 {
71 m_freeMemoryIfPossibleCount++; 82 m_freeMemoryIfPossibleCount++;
72 size_t bytesFreed = size < m_freeableBytes ? size : m_freeableBytes; 83 size_t bytesFreed = size < m_freeableBytes ? size : m_freeableBytes;
73 m_freeableBytes -= bytesFreed; 84 m_freeableBytes -= bytesFreed;
74 if (bytesFreed) 85 if (bytesFreed)
75 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, -((in tptr_t)bytesFreed)); 86 storageAllocatedForRecordingChanged(m_bytesAllocated - bytesFreed);
76 m_bytesAllocated -= bytesFreed;
77 return bytesFreed; 87 return bytesFreed;
78 } 88 }
79 89
80 virtual void flush() OVERRIDE 90 virtual void flush() OVERRIDE
81 { 91 {
82 flushedDrawCommands(); 92 flushedDrawCommands();
93 m_freeableBytes = bytesAllocated();
83 m_flushCount++; 94 m_flushCount++;
84 } 95 }
85 96
86 public: 97 public:
98 FakeCanvas2DLayerBridgeClient m_client;
87 size_t m_freeableBytes; 99 size_t m_freeableBytes;
88 int m_freeMemoryIfPossibleCount; 100 int m_freeMemoryIfPossibleCount;
89 int m_flushCount; 101 int m_flushCount;
90 }; 102 };
91 103
92 class FakeCanvas2DLayerBridgePtr { 104 class FakeCanvas2DLayerBridgePtr {
93 public: 105 public:
94 FakeCanvas2DLayerBridgePtr(PassRefPtr<FakeCanvas2DLayerBridge> layerBridge) 106 FakeCanvas2DLayerBridgePtr(PassRefPtr<FakeCanvas2DLayerBridge> layerBridge)
95 : m_layerBridge(layerBridge) { } 107 : m_layerBridge(layerBridge) { }
96 108
97 ~FakeCanvas2DLayerBridgePtr() 109 ~FakeCanvas2DLayerBridgePtr()
98 { 110 {
99 m_layerBridge->beginDestruction(); 111 m_layerBridge->beginDestruction();
100 } 112 }
101 113
102 FakeCanvas2DLayerBridge* operator->() { return m_layerBridge.get(); } 114 FakeCanvas2DLayerBridge* operator->() { return m_layerBridge.get(); }
103 FakeCanvas2DLayerBridge* get() { return m_layerBridge.get(); } 115 FakeCanvas2DLayerBridge* get() { return m_layerBridge.get(); }
104 116
105 private: 117 private:
106 RefPtr<FakeCanvas2DLayerBridge> m_layerBridge; 118 RefPtr<FakeCanvas2DLayerBridge> m_layerBridge;
107 }; 119 };
108 120
109 static PassOwnPtr<SkDeferredCanvas> createCanvas(GraphicsContext3D* context) 121 static PassOwnPtr<SkDeferredCanvas> createCanvas(GraphicsContext3D* context)
110 { 122 {
111 return adoptPtr(SkDeferredCanvas::Create(SkSurface::NewRasterPMColor(1, 1))) ; 123 return adoptPtr(SkDeferredCanvas::Create(SkSurface::NewRasterPMColor(1, 1))) ;
112 } 124 }
113 125
126 } // unnamed namespace
127
114 class Canvas2DLayerManagerTest : public Test { 128 class Canvas2DLayerManagerTest : public Test {
115 protected: 129 protected:
116 void storageAllocationTrackingTest() 130 void storageAllocationTrackingTest()
117 { 131 {
118 Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 132 Canvas2DLayerManager& manager = Canvas2DLayerManager::get();
119 manager.init(10, 10); 133 manager.init(10, 10);
120 { 134 {
121 RefPtr<GraphicsContext3D> context = GraphicsContext3D::createGraphic sContextFromWebContext(adoptPtr(new blink::MockWebGraphicsContext3D)); 135 RefPtr<GraphicsContext3D> context = GraphicsContext3D::createGraphic sContextFromWebContext(adoptPtr(new blink::MockWebGraphicsContext3D));
122 OwnPtr<SkDeferredCanvas> canvas1 = createCanvas(context.get()); 136 OwnPtr<SkDeferredCanvas> canvas1 = createCanvas(context.get());
123 FakeCanvas2DLayerBridgePtr layer1(adoptRef(new FakeCanvas2DLayerBrid ge(context, canvas1.release()))); 137 FakeCanvas2DLayerBridgePtr layer1(adoptRef(new FakeCanvas2DLayerBrid ge(context, canvas1.release())));
(...skipping 29 matching lines...) Expand all
153 layer->fakeFreeableBytes(10); 167 layer->fakeFreeableBytes(10);
154 layer->storageAllocatedForRecordingChanged(8); // under the max 168 layer->storageAllocatedForRecordingChanged(8); // under the max
155 EXPECT_EQ(0, layer->m_freeMemoryIfPossibleCount); 169 EXPECT_EQ(0, layer->m_freeMemoryIfPossibleCount);
156 layer->storageAllocatedForRecordingChanged(12); // over the max 170 layer->storageAllocatedForRecordingChanged(12); // over the max
157 EXPECT_EQ(1, layer->m_freeMemoryIfPossibleCount); 171 EXPECT_EQ(1, layer->m_freeMemoryIfPossibleCount);
158 EXPECT_EQ((size_t)3, layer->m_freeableBytes); 172 EXPECT_EQ((size_t)3, layer->m_freeableBytes);
159 EXPECT_EQ(0, layer->m_flushCount); // eviction succeeded without trigger ing a flush 173 EXPECT_EQ(0, layer->m_flushCount); // eviction succeeded without trigger ing a flush
160 EXPECT_EQ((size_t)5, layer->bytesAllocated()); 174 EXPECT_EQ((size_t)5, layer->bytesAllocated());
161 } 175 }
162 176
177 void hiddenCanvasTest()
178 {
179 RefPtr<GraphicsContext3D> context = GraphicsContext3D::createGraphicsCon textFromWebContext(adoptPtr(new blink::MockWebGraphicsContext3D));
180 Canvas2DLayerManager& manager = Canvas2DLayerManager::get();
181 manager.init(20, 5);
182 OwnPtr<SkDeferredCanvas> canvas = createCanvas(context.get());
183 FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(co ntext, canvas.release())));
184 layer->fakeFreeableBytes(5);
185 layer->storageAllocatedForRecordingChanged(10);
186 manager.didHidePage(); // does nothing because no canvases are hidden
187 EXPECT_EQ(0, layer->m_freeMemoryIfPossibleCount);
188 EXPECT_EQ(0, layer->m_flushCount);
189 layer->m_client.fakeHidden(true);
190 manager.didHidePage();
191 EXPECT_EQ(1, layer->m_freeMemoryIfPossibleCount);
192 EXPECT_EQ((size_t)0, layer->m_freeableBytes);
193 EXPECT_EQ((size_t)0, layer->bytesAllocated());
194 EXPECT_EQ(1, layer->m_flushCount);
195 }
196
197 void addRemoveLayerTest()
198 {
199 RefPtr<GraphicsContext3D> context = GraphicsContext3D::createGraphicsCon textFromWebContext(adoptPtr(new blink::MockWebGraphicsContext3D));
200 Canvas2DLayerManager& manager = Canvas2DLayerManager::get();
201 manager.init(10, 5);
202 OwnPtr<SkDeferredCanvas> canvas = createCanvas(context.get());
203 FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(co ntext, canvas.release())));
204 EXPECT_FALSE(manager.isInList(layer.get()));
205 layer->storageAllocatedForRecordingChanged(5);
206 EXPECT_TRUE(manager.isInList(layer.get()));
207 layer->storageAllocatedForRecordingChanged(0);
208 EXPECT_FALSE(manager.isInList(layer.get()));
209 }
210
163 void flushEvictionTest() 211 void flushEvictionTest()
164 { 212 {
165 RefPtr<GraphicsContext3D> context = GraphicsContext3D::createGraphicsCon textFromWebContext(adoptPtr(new blink::MockWebGraphicsContext3D)); 213 RefPtr<GraphicsContext3D> context = GraphicsContext3D::createGraphicsCon textFromWebContext(adoptPtr(new blink::MockWebGraphicsContext3D));
166 Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 214 Canvas2DLayerManager& manager = Canvas2DLayerManager::get();
167 manager.init(10, 5); 215 manager.init(10, 5);
168 OwnPtr<SkDeferredCanvas> canvas = createCanvas(context.get()); 216 OwnPtr<SkDeferredCanvas> canvas = createCanvas(context.get());
169 FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(co ntext, canvas.release()))); 217 FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(co ntext, canvas.release())));
170 layer->fakeFreeableBytes(1); // Not enough freeable bytes, will cause ag gressive eviction by flushing 218 layer->fakeFreeableBytes(1); // Not enough freeable bytes, will cause ag gressive eviction by flushing
171 layer->storageAllocatedForRecordingChanged(8); // under the max 219 layer->storageAllocatedForRecordingChanged(8); // under the max
172 EXPECT_EQ(0, layer->m_freeMemoryIfPossibleCount); 220 EXPECT_EQ(0, layer->m_freeMemoryIfPossibleCount);
173 layer->storageAllocatedForRecordingChanged(12); // over the max 221 layer->storageAllocatedForRecordingChanged(12); // over the max
174 EXPECT_EQ(2, layer->m_freeMemoryIfPossibleCount); // Two tries, one befo re flush, one after flush 222 EXPECT_EQ(2, layer->m_freeMemoryIfPossibleCount); // Two tries, one befo re flush, one after flush
175 EXPECT_EQ((size_t)0, layer->m_freeableBytes); 223 EXPECT_EQ((size_t)5, layer->m_freeableBytes);
176 EXPECT_EQ(1, layer->m_flushCount); // flush was attempted 224 EXPECT_EQ(1, layer->m_flushCount); // flush was attempted
177 EXPECT_EQ((size_t)11, layer->bytesAllocated()); // flush drops the layer from manager's tracking list 225 EXPECT_EQ((size_t)5, layer->bytesAllocated());
178 EXPECT_FALSE(manager.isInList(layer.get())); 226 EXPECT_TRUE(manager.isInList(layer.get()));
179 } 227 }
180 228
181 void doDeferredFrameTestTask(FakeCanvas2DLayerBridge* layer, bool skipComman ds) 229 void doDeferredFrameTestTask(FakeCanvas2DLayerBridge* layer, bool skipComman ds)
182 { 230 {
183 EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 231 EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive);
184 layer->willUse(); 232 layer->willUse();
185 layer->storageAllocatedForRecordingChanged(1); 233 layer->storageAllocatedForRecordingChanged(1);
186 EXPECT_TRUE(Canvas2DLayerManager::get().m_taskObserverActive); 234 EXPECT_TRUE(Canvas2DLayerManager::get().m_taskObserverActive);
187 if (skipCommands) { 235 if (skipCommands) {
188 layer->willUse(); 236 layer->willUse();
189 layer->storageAllocatedForRecordingChanged(0);
190 layer->skippedPendingDrawCommands(); 237 layer->skippedPendingDrawCommands();
191 } 238 }
192 blink::Platform::current()->currentThread()->exitRunLoop(); 239 blink::Platform::current()->currentThread()->exitRunLoop();
193 } 240 }
194 241
195 class DeferredFrameTestTask : public blink::WebThread::Task { 242 class DeferredFrameTestTask : public blink::WebThread::Task {
196 public: 243 public:
197 DeferredFrameTestTask(Canvas2DLayerManagerTest* test, FakeCanvas2DLayerB ridge* layer, bool skipCommands) 244 DeferredFrameTestTask(Canvas2DLayerManagerTest* test, FakeCanvas2DLayerB ridge* layer, bool skipCommands)
198 { 245 {
199 m_test = test; 246 m_test = test;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 TEST_F(Canvas2DLayerManagerTest, testFlushEviction) 310 TEST_F(Canvas2DLayerManagerTest, testFlushEviction)
264 { 311 {
265 flushEvictionTest(); 312 flushEvictionTest();
266 } 313 }
267 314
268 TEST_F(Canvas2DLayerManagerTest, testDeferredFrame) 315 TEST_F(Canvas2DLayerManagerTest, testDeferredFrame)
269 { 316 {
270 deferredFrameTest(); 317 deferredFrameTest();
271 } 318 }
272 319
273 } // namespace 320 TEST_F(Canvas2DLayerManagerTest, testHiddenCanvas)
321 {
322 hiddenCanvasTest();
323 }
274 324
325 TEST_F(Canvas2DLayerManagerTest, testAddRemoveLayer)
326 {
327 addRemoveLayerTest();
328 }
329
330 } // unnamed namespace
331
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698