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

Side by Side Diff: cc/scheduler/texture_uploader.cc

Issue 105103004: Convert cc resource system over to GLES2Interface (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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
« no previous file with comments | « cc/scheduler/texture_uploader.h ('k') | cc/scheduler/texture_uploader_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "cc/scheduler/texture_uploader.h" 5 #include "cc/scheduler/texture_uploader.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "cc/base/util.h" 12 #include "cc/base/util.h"
13 #include "cc/resources/prioritized_resource.h" 13 #include "cc/resources/prioritized_resource.h"
14 #include "cc/resources/resource.h" 14 #include "cc/resources/resource.h"
15 #include "gpu/GLES2/gl2extchromium.h" 15 #include "gpu/GLES2/gl2extchromium.h"
16 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 16 #include "gpu/command_buffer/client/gles2_interface.h"
17 #include "third_party/khronos/GLES2/gl2.h" 17 #include "third_party/khronos/GLES2/gl2.h"
18 #include "third_party/khronos/GLES2/gl2ext.h" 18 #include "third_party/khronos/GLES2/gl2ext.h"
19 #include "ui/gfx/rect.h" 19 #include "ui/gfx/rect.h"
20 #include "ui/gfx/vector2d.h" 20 #include "ui/gfx/vector2d.h"
21 21
22 using gpu::gles2::GLES2Interface;
23
22 namespace { 24 namespace {
23 25
24 // How many previous uploads to use when predicting future throughput. 26 // How many previous uploads to use when predicting future throughput.
25 static const size_t kUploadHistorySizeMax = 1000; 27 static const size_t kUploadHistorySizeMax = 1000;
26 static const size_t kUploadHistorySizeInitial = 100; 28 static const size_t kUploadHistorySizeInitial = 100;
27 29
28 // Global estimated number of textures per second to maintain estimates across 30 // Global estimated number of textures per second to maintain estimates across
29 // subsequent instances of TextureUploader. 31 // subsequent instances of TextureUploader.
30 // More than one thread will not access this variable, so we do not need to 32 // More than one thread will not access this variable, so we do not need to
31 // synchronize access. 33 // synchronize access.
32 static const double kDefaultEstimatedTexturesPerSecond = 48.0 * 60.0; 34 static const double kDefaultEstimatedTexturesPerSecond = 48.0 * 60.0;
33 35
34 // Flush interval when performing texture uploads. 36 // Flush interval when performing texture uploads.
35 static const size_t kTextureUploadFlushPeriod = 4; 37 static const size_t kTextureUploadFlushPeriod = 4;
36 38
37 } // anonymous namespace 39 } // anonymous namespace
38 40
39 namespace cc { 41 namespace cc {
40 42
41 TextureUploader::Query::Query(blink::WebGraphicsContext3D* context) 43 TextureUploader::Query::Query(GLES2Interface* gl)
42 : context_(context), 44 : gl_(gl),
43 query_id_(0), 45 query_id_(0),
44 value_(0), 46 value_(0),
45 has_value_(false), 47 has_value_(false),
46 is_non_blocking_(false) { 48 is_non_blocking_(false) {
47 query_id_ = context_->createQueryEXT(); 49 gl_->GenQueriesEXT(1, &query_id_);
48 } 50 }
49 51
50 TextureUploader::Query::~Query() { context_->deleteQueryEXT(query_id_); } 52 TextureUploader::Query::~Query() { gl_->DeleteQueriesEXT(1, &query_id_); }
51 53
52 void TextureUploader::Query::Begin() { 54 void TextureUploader::Query::Begin() {
53 has_value_ = false; 55 has_value_ = false;
54 is_non_blocking_ = false; 56 is_non_blocking_ = false;
55 context_->beginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, query_id_); 57 gl_->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, query_id_);
56 } 58 }
57 59
58 void TextureUploader::Query::End() { 60 void TextureUploader::Query::End() {
59 context_->endQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM); 61 gl_->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
60 } 62 }
61 63
62 bool TextureUploader::Query::IsPending() { 64 bool TextureUploader::Query::IsPending() {
63 unsigned available = 1; 65 unsigned available = 1;
64 context_->getQueryObjectuivEXT( 66 gl_->GetQueryObjectuivEXT(
65 query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available); 67 query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
66 return !available; 68 return !available;
67 } 69 }
68 70
69 unsigned TextureUploader::Query::Value() { 71 unsigned TextureUploader::Query::Value() {
70 if (!has_value_) { 72 if (!has_value_) {
71 context_->getQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &value_); 73 gl_->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &value_);
72 has_value_ = true; 74 has_value_ = true;
73 } 75 }
74 return value_; 76 return value_;
75 } 77 }
76 78
77 TextureUploader::TextureUploader(blink::WebGraphicsContext3D* context) 79 TextureUploader::TextureUploader(GLES2Interface* gl)
78 : context_(context), 80 : gl_(gl),
79 num_blocking_texture_uploads_(0), 81 num_blocking_texture_uploads_(0),
80 sub_image_size_(0), 82 sub_image_size_(0),
81 num_texture_uploads_since_last_flush_(0) { 83 num_texture_uploads_since_last_flush_(0) {
82 for (size_t i = kUploadHistorySizeInitial; i > 0; i--) 84 for (size_t i = kUploadHistorySizeInitial; i > 0; i--)
83 textures_per_second_history_.insert(kDefaultEstimatedTexturesPerSecond); 85 textures_per_second_history_.insert(kDefaultEstimatedTexturesPerSecond);
84 } 86 }
85 87
86 TextureUploader::~TextureUploader() {} 88 TextureUploader::~TextureUploader() {}
87 89
88 size_t TextureUploader::NumBlockingUploads() { 90 size_t TextureUploader::NumBlockingUploads() {
(...skipping 19 matching lines...) Expand all
108 ProcessQueries(); 110 ProcessQueries();
109 111
110 // Use the median as our estimate. 112 // Use the median as our estimate.
111 std::multiset<double>::iterator median = textures_per_second_history_.begin(); 113 std::multiset<double>::iterator median = textures_per_second_history_.begin();
112 std::advance(median, textures_per_second_history_.size() / 2); 114 std::advance(median, textures_per_second_history_.size() / 2);
113 return *median; 115 return *median;
114 } 116 }
115 117
116 void TextureUploader::BeginQuery() { 118 void TextureUploader::BeginQuery() {
117 if (available_queries_.empty()) 119 if (available_queries_.empty())
118 available_queries_.push_back(Query::Create(context_)); 120 available_queries_.push_back(Query::Create(gl_));
119 121
120 available_queries_.front()->Begin(); 122 available_queries_.front()->Begin();
121 } 123 }
122 124
123 void TextureUploader::EndQuery() { 125 void TextureUploader::EndQuery() {
124 available_queries_.front()->End(); 126 available_queries_.front()->End();
125 pending_queries_.push_back(available_queries_.take_front()); 127 pending_queries_.push_back(available_queries_.take_front());
126 num_blocking_texture_uploads_++; 128 num_blocking_texture_uploads_++;
127 } 129 }
128 130
(...skipping 24 matching lines...) Expand all
153 155
154 num_texture_uploads_since_last_flush_++; 156 num_texture_uploads_since_last_flush_++;
155 if (num_texture_uploads_since_last_flush_ >= kTextureUploadFlushPeriod) 157 if (num_texture_uploads_since_last_flush_ >= kTextureUploadFlushPeriod)
156 Flush(); 158 Flush();
157 } 159 }
158 160
159 void TextureUploader::Flush() { 161 void TextureUploader::Flush() {
160 if (!num_texture_uploads_since_last_flush_) 162 if (!num_texture_uploads_since_last_flush_)
161 return; 163 return;
162 164
163 context_->shallowFlushCHROMIUM(); 165 gl_->ShallowFlushCHROMIUM();
164 166
165 num_texture_uploads_since_last_flush_ = 0; 167 num_texture_uploads_since_last_flush_ = 0;
166 } 168 }
167 169
168 void TextureUploader::ReleaseCachedQueries() { 170 void TextureUploader::ReleaseCachedQueries() {
169 ProcessQueries(); 171 ProcessQueries();
170 available_queries_.clear(); 172 available_queries_.clear();
171 } 173 }
172 174
173 void TextureUploader::UploadWithTexSubImage(const uint8* image, 175 void TextureUploader::UploadWithTexSubImage(const uint8* image,
(...skipping 26 matching lines...) Expand all
200 size_t needed_size = upload_image_stride * source_rect.height(); 202 size_t needed_size = upload_image_stride * source_rect.height();
201 if (sub_image_size_ < needed_size) { 203 if (sub_image_size_ < needed_size) {
202 sub_image_.reset(new uint8[needed_size]); 204 sub_image_.reset(new uint8[needed_size]);
203 sub_image_size_ = needed_size; 205 sub_image_size_ = needed_size;
204 } 206 }
205 // Strides not equal, so do a row-by-row memcpy from the 207 // Strides not equal, so do a row-by-row memcpy from the
206 // paint results into a temp buffer for uploading. 208 // paint results into a temp buffer for uploading.
207 for (int row = 0; row < source_rect.height(); ++row) 209 for (int row = 0; row < source_rect.height(); ++row)
208 memcpy(&sub_image_[upload_image_stride * row], 210 memcpy(&sub_image_[upload_image_stride * row],
209 &image[bytes_per_pixel * 211 &image[bytes_per_pixel *
210 (offset.x() + (offset.y() + row) * image_rect.width())], 212 (offset.x() + (offset.y() + row) * image_rect.width())],
211 source_rect.width() * bytes_per_pixel); 213 source_rect.width() * bytes_per_pixel);
212 214
213 pixel_source = &sub_image_[0]; 215 pixel_source = &sub_image_[0];
214 } 216 }
215 217
216 context_->texSubImage2D(GL_TEXTURE_2D, 218 gl_->TexSubImage2D(GL_TEXTURE_2D,
217 0, 219 0,
218 dest_offset.x(), 220 dest_offset.x(),
219 dest_offset.y(), 221 dest_offset.y(),
220 source_rect.width(), 222 source_rect.width(),
221 source_rect.height(), 223 source_rect.height(),
222 GLDataFormat(format), 224 GLDataFormat(format),
223 GLDataType(format), 225 GLDataType(format),
224 pixel_source); 226 pixel_source);
225 } 227 }
226 228
227 void TextureUploader::UploadWithMapTexSubImage(const uint8* image, 229 void TextureUploader::UploadWithMapTexSubImage(const uint8* image,
228 gfx::Rect image_rect, 230 gfx::Rect image_rect,
229 gfx::Rect source_rect, 231 gfx::Rect source_rect,
230 gfx::Vector2d dest_offset, 232 gfx::Vector2d dest_offset,
231 ResourceFormat format) { 233 ResourceFormat format) {
232 TRACE_EVENT0("cc", "TextureUploader::UploadWithMapTexSubImage"); 234 TRACE_EVENT0("cc", "TextureUploader::UploadWithMapTexSubImage");
233 235
234 // Early-out if this is a no-op, and assert that |image| be valid if this is 236 // Early-out if this is a no-op, and assert that |image| be valid if this is
235 // not a no-op. 237 // not a no-op.
236 if (source_rect.IsEmpty()) 238 if (source_rect.IsEmpty())
237 return; 239 return;
238 DCHECK(image); 240 DCHECK(image);
239 // Compressed textures have no implementation of mapTexSubImage. 241 // Compressed textures have no implementation of mapTexSubImage.
240 DCHECK_NE(ETC1, format); 242 DCHECK_NE(ETC1, format);
241 243
242 // Offset from image-rect to source-rect. 244 // Offset from image-rect to source-rect.
243 gfx::Vector2d offset(source_rect.origin() - image_rect.origin()); 245 gfx::Vector2d offset(source_rect.origin() - image_rect.origin());
244 246
245 unsigned bytes_per_pixel = BitsPerPixel(format) / 8; 247 unsigned bytes_per_pixel = BitsPerPixel(format) / 8;
246 // Use 4-byte row alignment (OpenGL default) for upload performance. 248 // Use 4-byte row alignment (OpenGL default) for upload performance.
247 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. 249 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
248 unsigned upload_image_stride = 250 unsigned upload_image_stride =
249 RoundUp(bytes_per_pixel * source_rect.width(), 4u); 251 RoundUp(bytes_per_pixel * source_rect.width(), 4u);
250 252
251 // Upload tile data via a mapped transfer buffer 253 // Upload tile data via a mapped transfer buffer
252 uint8* pixel_dest = static_cast<uint8*>( 254 uint8* pixel_dest =
253 context_->mapTexSubImage2DCHROMIUM(GL_TEXTURE_2D, 255 static_cast<uint8*>(gl_->MapTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
254 0, 256 0,
255 dest_offset.x(), 257 dest_offset.x(),
256 dest_offset.y(), 258 dest_offset.y(),
257 source_rect.width(), 259 source_rect.width(),
258 source_rect.height(), 260 source_rect.height(),
259 GLDataFormat(format), 261 GLDataFormat(format),
260 GLDataType(format), 262 GLDataType(format),
261 GL_WRITE_ONLY)); 263 GL_WRITE_ONLY));
262 264
263 if (!pixel_dest) { 265 if (!pixel_dest) {
264 UploadWithTexSubImage(image, image_rect, source_rect, dest_offset, format); 266 UploadWithTexSubImage(image, image_rect, source_rect, dest_offset, format);
265 return; 267 return;
266 } 268 }
267 269
268 if (upload_image_stride == image_rect.width() * bytes_per_pixel && 270 if (upload_image_stride == image_rect.width() * bytes_per_pixel &&
269 !offset.x()) { 271 !offset.x()) {
270 memcpy(pixel_dest, 272 memcpy(pixel_dest,
271 &image[image_rect.width() * bytes_per_pixel * offset.y()], 273 &image[image_rect.width() * bytes_per_pixel * offset.y()],
272 source_rect.height() * image_rect.width() * bytes_per_pixel); 274 source_rect.height() * image_rect.width() * bytes_per_pixel);
273 } else { 275 } else {
274 // Strides not equal, so do a row-by-row memcpy from the 276 // Strides not equal, so do a row-by-row memcpy from the
275 // paint results into the pixel_dest. 277 // paint results into the pixel_dest.
276 for (int row = 0; row < source_rect.height(); ++row) { 278 for (int row = 0; row < source_rect.height(); ++row) {
277 memcpy(&pixel_dest[upload_image_stride * row], 279 memcpy(&pixel_dest[upload_image_stride * row],
278 &image[bytes_per_pixel * 280 &image[bytes_per_pixel *
279 (offset.x() + (offset.y() + row) * image_rect.width())], 281 (offset.x() + (offset.y() + row) * image_rect.width())],
280 source_rect.width() * bytes_per_pixel); 282 source_rect.width() * bytes_per_pixel);
281 } 283 }
282 } 284 }
283 285
284 context_->unmapTexSubImage2DCHROMIUM(pixel_dest); 286 gl_->UnmapTexSubImage2DCHROMIUM(pixel_dest);
285 } 287 }
286 288
287 void TextureUploader::UploadWithTexImageETC1(const uint8* image, 289 void TextureUploader::UploadWithTexImageETC1(const uint8* image,
288 gfx::Size size) { 290 gfx::Size size) {
289 TRACE_EVENT0("cc", "TextureUploader::UploadWithTexImageETC1"); 291 TRACE_EVENT0("cc", "TextureUploader::UploadWithTexImageETC1");
290 DCHECK_EQ(0, size.width() % 4); 292 DCHECK_EQ(0, size.width() % 4);
291 DCHECK_EQ(0, size.height() % 4); 293 DCHECK_EQ(0, size.height() % 4);
292 294
293 context_->compressedTexImage2D(GL_TEXTURE_2D, 295 gl_->CompressedTexImage2D(GL_TEXTURE_2D,
294 0, 296 0,
295 GLInternalFormat(ETC1), 297 GLInternalFormat(ETC1),
296 size.width(), 298 size.width(),
297 size.height(), 299 size.height(),
298 0, 300 0,
299 Resource::MemorySizeBytes(size, ETC1), 301 Resource::MemorySizeBytes(size, ETC1),
300 image); 302 image);
301 } 303 }
302 304
303 void TextureUploader::ProcessQueries() { 305 void TextureUploader::ProcessQueries() {
304 while (!pending_queries_.empty()) { 306 while (!pending_queries_.empty()) {
305 if (pending_queries_.front()->IsPending()) 307 if (pending_queries_.front()->IsPending())
306 break; 308 break;
307 309
308 unsigned us_elapsed = pending_queries_.front()->Value(); 310 unsigned us_elapsed = pending_queries_.front()->Value();
309 UMA_HISTOGRAM_CUSTOM_COUNTS( 311 UMA_HISTOGRAM_CUSTOM_COUNTS(
310 "Renderer4.TextureGpuUploadTimeUS", us_elapsed, 0, 100000, 50); 312 "Renderer4.TextureGpuUploadTimeUS", us_elapsed, 0, 100000, 50);
(...skipping 11 matching lines...) Expand all
322 textures_per_second_history_.erase(textures_per_second_history_.begin()); 324 textures_per_second_history_.erase(textures_per_second_history_.begin());
323 textures_per_second_history_.erase(--textures_per_second_history_.end()); 325 textures_per_second_history_.erase(--textures_per_second_history_.end());
324 } 326 }
325 textures_per_second_history_.insert(textures_per_second); 327 textures_per_second_history_.insert(textures_per_second);
326 328
327 available_queries_.push_back(pending_queries_.take_front()); 329 available_queries_.push_back(pending_queries_.take_front());
328 } 330 }
329 } 331 }
330 332
331 } // namespace cc 333 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/texture_uploader.h ('k') | cc/scheduler/texture_uploader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698