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

Side by Side Diff: cc/ThrottledTextureUploader.cpp

Issue 10916292: Adaptively throttle texture uploads (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Address comments in PS2, except constant partials Created 8 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
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6
7 #include "ThrottledTextureUploader.h" 6 #include "ThrottledTextureUploader.h"
8 7
9 #include "Extensions3DChromium.h" 8 #include "Extensions3DChromium.h"
9 #include <algorithm>
10 #include <public/WebGraphicsContext3D.h> 10 #include <public/WebGraphicsContext3D.h>
11 #include <vector>
11 12
12 namespace { 13 namespace {
13 14
14 // Number of pending texture update queries to allow. 15 // Number of pending texture update queries to allow.
15 static const size_t maxPendingQueries = 2; 16 static const size_t maxPendingQueries = 2;
16 17
18 // How many previous uploads to use when predicting future throughput.
19 static const size_t uploadHistorySize = 10;
20
21 // Global estimated number of pixels per second to maintain estimates across
22 // subsequent instances of ThrottledTextureUploader.
23 // More than one thread will not access this variable, so we do not need to sync hronize access.
24 static double estimatedPixelsPerSecondGlobal = 256.0 * 256.0 * 48.0 * 60.0;
25
17 } // anonymous namespace 26 } // anonymous namespace
18 27
19 namespace WebCore { 28 namespace WebCore {
20 29
21 ThrottledTextureUploader::Query::Query(WebKit::WebGraphicsContext3D* context) 30 ThrottledTextureUploader::Query::Query(WebKit::WebGraphicsContext3D* context)
22 : m_context(context) 31 : m_context(context)
23 , m_queryId(0) 32 , m_queryId(0)
33 , m_value(0)
34 , m_hasValue(false)
35 , m_pixelsUploaded(0)
24 { 36 {
25 m_queryId = m_context->createQueryEXT(); 37 m_queryId = m_context->createQueryEXT();
26 } 38 }
27 39
28 ThrottledTextureUploader::Query::~Query() 40 ThrottledTextureUploader::Query::~Query()
29 { 41 {
30 m_context->deleteQueryEXT(m_queryId); 42 m_context->deleteQueryEXT(m_queryId);
31 } 43 }
32 44
33 void ThrottledTextureUploader::Query::begin() 45 void ThrottledTextureUploader::Query::begin()
34 { 46 {
35 m_context->beginQueryEXT(Extensions3DChromium::COMMANDS_ISSUED_CHROMIUM, m_q ueryId); 47 m_context->beginQueryEXT(Extensions3DChromium::COMMANDS_ISSUED_CHROMIUM, m_q ueryId);
36 } 48 }
37 49
38 void ThrottledTextureUploader::Query::end() 50 void ThrottledTextureUploader::Query::end(double pixelsUploaded)
39 { 51 {
40 m_context->endQueryEXT(Extensions3DChromium::COMMANDS_ISSUED_CHROMIUM); 52 m_context->endQueryEXT(Extensions3DChromium::COMMANDS_ISSUED_CHROMIUM);
53 m_pixelsUploaded = pixelsUploaded;
41 } 54 }
42 55
43 bool ThrottledTextureUploader::Query::isPending() 56 bool ThrottledTextureUploader::Query::isPending()
44 { 57 {
45 unsigned available = 1; 58 unsigned available = 1;
46 m_context->getQueryObjectuivEXT(m_queryId, Extensions3DChromium::QUERY_RESUL T_AVAILABLE_EXT, &available); 59 m_context->getQueryObjectuivEXT(m_queryId, Extensions3DChromium::QUERY_RESUL T_AVAILABLE_EXT, &available);
47 return !available; 60 return !available;
48 } 61 }
49 62
50 void ThrottledTextureUploader::Query::wait() 63 void ThrottledTextureUploader::Query::wait()
51 { 64 {
52 unsigned result; 65 value();
53 m_context->getQueryObjectuivEXT(m_queryId, Extensions3DChromium::QUERY_RESUL T_EXT, &result); 66 return;
67 }
68
69 unsigned ThrottledTextureUploader::Query::value()
70 {
71 if (!m_hasValue)
72 m_context->getQueryObjectuivEXT(m_queryId, Extensions3DChromium::QUERY_R ESULT_EXT, &m_value);
73 return m_value;
74 }
75
76 double ThrottledTextureUploader::Query::pixelsUploaded()
77 {
78 return m_pixelsUploaded;
54 } 79 }
55 80
56 ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* context) 81 ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* context)
57 : m_context(context) 82 : m_context(context)
58 , m_maxPendingQueries(maxPendingQueries) 83 , m_maxPendingQueries(maxPendingQueries)
84 , m_pixelsPerSecondHistory(uploadHistorySize, estimatedPixelsPerSecondGlobal )
85 , m_pixelsUploaded(0)
59 { 86 {
60 } 87 }
61 88
62 ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* context, size_t pendingUploadLimit) 89 ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* context, size_t pendingUploadLimit)
63 : m_context(context) 90 : m_context(context)
64 , m_maxPendingQueries(pendingUploadLimit) 91 , m_maxPendingQueries(pendingUploadLimit)
92 , m_pixelsPerSecondHistory(uploadHistorySize, estimatedPixelsPerSecondGlobal )
93 , m_pixelsUploaded(0)
65 { 94 {
66 ASSERT(m_context); 95 ASSERT(m_context);
67 } 96 }
68 97
69 ThrottledTextureUploader::~ThrottledTextureUploader() 98 ThrottledTextureUploader::~ThrottledTextureUploader()
70 { 99 {
71 } 100 }
72
73 bool ThrottledTextureUploader::isBusy() 101 bool ThrottledTextureUploader::isBusy()
74 { 102 {
75 processQueries(); 103 processQueries();
76 104
77 if (!m_availableQueries.isEmpty()) 105 if (!m_availableQueries.isEmpty())
78 return false; 106 return false;
79 107
80 if (m_pendingQueries.size() == m_maxPendingQueries) 108 if (m_pendingQueries.size() == m_maxPendingQueries)
81 return true; 109 return true;
82 110
83 m_availableQueries.append(Query::create(m_context)); 111 m_availableQueries.append(Query::create(m_context));
84 return false; 112 return false;
85 } 113 }
86 114
115 double ThrottledTextureUploader::estimatedPixelsPerSecond()
116 {
117 processQueries();
118
119 // The history should never be empty because we initialize all elements with an estimate.
120 ASSERT(m_pixelsPerSecondHistory.size() == uploadHistorySize);
121
122 // Sort the history and use the median as our estimate.
123 std::vector<double> sortedHistory(m_pixelsPerSecondHistory.begin(),
124 m_pixelsPerSecondHistory.end());
125 std::sort(sortedHistory.begin(), sortedHistory.end());
126
127 estimatedPixelsPerSecondGlobal = sortedHistory[sortedHistory.size() / 2];
128 return estimatedPixelsPerSecondGlobal;
129 }
130
87 void ThrottledTextureUploader::beginUploads() 131 void ThrottledTextureUploader::beginUploads()
88 { 132 {
133 m_pixelsUploaded = 0;
134
89 // Wait for query to become available. 135 // Wait for query to become available.
90 while (isBusy()) 136 while (isBusy())
91 m_pendingQueries.first()->wait(); 137 m_pendingQueries.first()->wait();
92 138
93 ASSERT(!m_availableQueries.isEmpty()); 139 ASSERT(!m_availableQueries.isEmpty());
94 m_availableQueries.first()->begin(); 140 m_availableQueries.first()->begin();
95 } 141 }
96 142
97 void ThrottledTextureUploader::endUploads() 143 void ThrottledTextureUploader::endUploads()
98 { 144 {
99 m_availableQueries.first()->end(); 145 m_availableQueries.first()->end(m_pixelsUploaded);
100 m_pendingQueries.append(m_availableQueries.takeFirst()); 146 m_pendingQueries.append(m_availableQueries.takeFirst());
101 } 147 }
102 148
103 void ThrottledTextureUploader::uploadTexture(CCResourceProvider* resourceProvide r, Parameters upload) 149 void ThrottledTextureUploader::uploadTexture(CCResourceProvider* resourceProvide r, Parameters upload)
104 { 150 {
151 m_pixelsUploaded += upload.sourceRect.width() * upload.sourceRect.width();
105 upload.texture->updateRect(resourceProvider, upload.sourceRect, upload.destO ffset); 152 upload.texture->updateRect(resourceProvider, upload.sourceRect, upload.destO ffset);
106 } 153 }
107 154
108 void ThrottledTextureUploader::processQueries() 155 void ThrottledTextureUploader::processQueries()
109 { 156 {
110 while (!m_pendingQueries.isEmpty()) { 157 while (!m_pendingQueries.isEmpty()) {
111 if (m_pendingQueries.first()->isPending()) 158 if (m_pendingQueries.first()->isPending())
112 break; 159 break;
113 160
161 unsigned usElapsed = m_pendingQueries.first()->value();
162 double pixelsPerSecond = m_pendingQueries.first()->pixelsUploaded() / (u sElapsed * 1e-6);
163
164 // Remove the oldest values from our history and insert the new one
165 m_pixelsPerSecondHistory.pop_back();
166 m_pixelsPerSecondHistory.push_front(pixelsPerSecond);
167
114 m_availableQueries.append(m_pendingQueries.takeFirst()); 168 m_availableQueries.append(m_pendingQueries.takeFirst());
115 } 169 }
116 } 170 }
117 171
118 } 172 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698