Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 | 6 |
| 7 #include "cc/texture_uploader.h" | 7 #include "cc/texture_uploader.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/debug/alias.h" | 12 #include "base/debug/alias.h" |
| 13 #include "base/debug/trace_event.h" | 13 #include "base/debug/trace_event.h" |
| 14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
| 15 #include "cc/prioritized_texture.h" | 15 #include "cc/prioritized_texture.h" |
| 16 #include "third_party/khronos/GLES2/gl2.h" | 16 #include "third_party/khronos/GLES2/gl2.h" |
| 17 #include "third_party/khronos/GLES2/gl2ext.h" | 17 #include "third_party/khronos/GLES2/gl2ext.h" |
| 18 #include <public/WebGraphicsContext3D.h> | 18 #include <public/WebGraphicsContext3D.h> |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 // How many previous uploads to use when predicting future throughput. | 22 // How many previous uploads to use when predicting future throughput. |
| 23 static const size_t uploadHistorySize = 100; | 23 static const size_t uploadHistorySizeMax = 1000; |
| 24 static const size_t uploadHistorySizeInitial = 100; | |
| 24 | 25 |
| 25 // Global estimated number of textures per second to maintain estimates across | 26 // Global estimated number of textures per second to maintain estimates across |
| 26 // subsequent instances of TextureUploader. | 27 // subsequent instances of TextureUploader. |
| 27 // More than one thread will not access this variable, so we do not need to sync hronize access. | 28 // More than one thread will not access this variable, so we do not need to sync hronize access. |
| 28 static double estimatedTexturesPerSecondGlobal = 48.0 * 60.0; | 29 static double estimatedTexturesPerSecondGlobal = 48.0 * 60.0; |
|
reveman
2012/10/23 21:06:58
Please make this a constant instead. The TextureUp
| |
| 29 | 30 |
| 30 } // anonymous namespace | 31 } // anonymous namespace |
| 31 | 32 |
| 32 namespace cc { | 33 namespace cc { |
| 33 | 34 |
| 34 TextureUploader::Query::Query(WebKit::WebGraphicsContext3D* context) | 35 TextureUploader::Query::Query(WebKit::WebGraphicsContext3D* context) |
| 35 : m_context(context) | 36 : m_context(context) |
| 36 , m_queryId(0) | 37 , m_queryId(0) |
| 37 , m_value(0) | 38 , m_value(0) |
| 38 , m_hasValue(false) | 39 , m_hasValue(false) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 } | 81 } |
| 81 | 82 |
| 82 bool TextureUploader::Query::isNonBlocking() | 83 bool TextureUploader::Query::isNonBlocking() |
| 83 { | 84 { |
| 84 return m_isNonBlocking; | 85 return m_isNonBlocking; |
| 85 } | 86 } |
| 86 | 87 |
| 87 TextureUploader::TextureUploader( | 88 TextureUploader::TextureUploader( |
| 88 WebKit::WebGraphicsContext3D* context, bool useMapTexSubImage) | 89 WebKit::WebGraphicsContext3D* context, bool useMapTexSubImage) |
| 89 : m_context(context) | 90 : m_context(context) |
| 90 , m_texturesPerSecondHistory(uploadHistorySize, | |
| 91 estimatedTexturesPerSecondGlobal) | |
| 92 , m_numBlockingTextureUploads(0) | 91 , m_numBlockingTextureUploads(0) |
| 93 , m_useMapTexSubImage(useMapTexSubImage) | 92 , m_useMapTexSubImage(useMapTexSubImage) |
| 94 , m_subImageSize(0) | 93 , m_subImageSize(0) |
| 95 { | 94 { |
| 95 for (size_t i = uploadHistorySizeInitial; i > 0; i--) | |
| 96 m_texturesPerSecondHistory.insert(estimatedTexturesPerSecondGlobal); | |
| 96 } | 97 } |
| 97 | 98 |
| 98 TextureUploader::~TextureUploader() | 99 TextureUploader::~TextureUploader() |
| 99 { | 100 { |
| 100 } | 101 } |
| 101 | 102 |
| 102 size_t TextureUploader::numBlockingUploads() | 103 size_t TextureUploader::numBlockingUploads() |
| 103 { | 104 { |
| 104 processQueries(); | 105 processQueries(); |
| 105 return m_numBlockingTextureUploads; | 106 return m_numBlockingTextureUploads; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 116 (*it)->markAsNonBlocking(); | 117 (*it)->markAsNonBlocking(); |
| 117 } | 118 } |
| 118 | 119 |
| 119 DCHECK(!m_numBlockingTextureUploads); | 120 DCHECK(!m_numBlockingTextureUploads); |
| 120 } | 121 } |
| 121 | 122 |
| 122 double TextureUploader::estimatedTexturesPerSecond() | 123 double TextureUploader::estimatedTexturesPerSecond() |
| 123 { | 124 { |
| 124 processQueries(); | 125 processQueries(); |
| 125 | 126 |
| 126 // The history should never be empty because we initialize all elements with an estimate. | 127 // Use the median as our estimate. |
| 127 DCHECK(m_texturesPerSecondHistory.size() == uploadHistorySize); | 128 std::set<double>::iterator median = m_texturesPerSecondHistory.begin(); |
| 128 | 129 std::advance(median, m_texturesPerSecondHistory.size() / 2); |
| 129 // Sort the history and use the median as our estimate. | 130 estimatedTexturesPerSecondGlobal = *median; |
| 130 std::vector<double> sortedHistory(m_texturesPerSecondHistory.begin(), | |
| 131 m_texturesPerSecondHistory.end()); | |
| 132 std::sort(sortedHistory.begin(), sortedHistory.end()); | |
| 133 | |
| 134 estimatedTexturesPerSecondGlobal = sortedHistory[sortedHistory.size() * 2 / 3]; | |
| 135 TRACE_COUNTER1("cc", "estimatedTexturesPerSecond", estimatedTexturesPerSecon dGlobal); | 131 TRACE_COUNTER1("cc", "estimatedTexturesPerSecond", estimatedTexturesPerSecon dGlobal); |
| 136 return estimatedTexturesPerSecondGlobal; | 132 return estimatedTexturesPerSecondGlobal; |
| 137 } | 133 } |
| 138 | 134 |
| 139 void TextureUploader::beginQuery() | 135 void TextureUploader::beginQuery() |
| 140 { | 136 { |
| 141 if (m_availableQueries.isEmpty()) | 137 if (m_availableQueries.isEmpty()) |
| 142 m_availableQueries.append(Query::create(m_context)); | 138 m_availableQueries.append(Query::create(m_context)); |
| 143 | 139 |
| 144 m_availableQueries.first()->begin(); | 140 m_availableQueries.first()->begin(); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 332 while (!m_pendingQueries.isEmpty()) { | 328 while (!m_pendingQueries.isEmpty()) { |
| 333 if (m_pendingQueries.first()->isPending()) | 329 if (m_pendingQueries.first()->isPending()) |
| 334 break; | 330 break; |
| 335 | 331 |
| 336 unsigned usElapsed = m_pendingQueries.first()->value(); | 332 unsigned usElapsed = m_pendingQueries.first()->value(); |
| 337 HISTOGRAM_CUSTOM_COUNTS("Renderer4.TextureGpuUploadTimeUS", usElapsed, 0 , 100000, 50); | 333 HISTOGRAM_CUSTOM_COUNTS("Renderer4.TextureGpuUploadTimeUS", usElapsed, 0 , 100000, 50); |
| 338 | 334 |
| 339 if (!m_pendingQueries.first()->isNonBlocking()) | 335 if (!m_pendingQueries.first()->isNonBlocking()) |
| 340 m_numBlockingTextureUploads--; | 336 m_numBlockingTextureUploads--; |
| 341 | 337 |
| 342 // Remove the oldest values from our history and insert the new one | 338 // Remove the min and max value from our history and insert the new one. |
| 343 double texturesPerSecond = 1.0 / (usElapsed * 1e-6); | 339 double texturesPerSecond = 1.0 / (usElapsed * 1e-6); |
| 344 m_texturesPerSecondHistory.pop_back(); | 340 if (m_texturesPerSecondHistory.size() >= uploadHistorySizeMax) { |
| 345 m_texturesPerSecondHistory.push_front(texturesPerSecond); | 341 m_texturesPerSecondHistory.erase(m_texturesPerSecondHistory.begin()) ; |
| 342 m_texturesPerSecondHistory.erase(--m_texturesPerSecondHistory.end()) ; | |
| 343 } | |
| 344 m_texturesPerSecondHistory.insert(texturesPerSecond); | |
| 346 | 345 |
| 347 m_availableQueries.append(m_pendingQueries.takeFirst()); | 346 m_availableQueries.append(m_pendingQueries.takeFirst()); |
| 348 } | 347 } |
| 349 } | 348 } |
| 350 | 349 |
| 351 } | 350 } |
| OLD | NEW |