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 "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" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 69 unsigned TextureUploader::Query::Value() { | 69 unsigned TextureUploader::Query::Value() { |
| 70 if (!has_value_) { | 70 if (!has_value_) { |
| 71 context_->getQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &value_); | 71 context_->getQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &value_); |
| 72 has_value_ = true; | 72 has_value_ = true; |
| 73 } | 73 } |
| 74 return value_; | 74 return value_; |
| 75 } | 75 } |
| 76 | 76 |
| 77 TextureUploader::TextureUploader(WebKit::WebGraphicsContext3D* context, | 77 TextureUploader::TextureUploader(WebKit::WebGraphicsContext3D* context, |
| 78 bool use_map_tex_sub_image, | 78 bool use_map_tex_sub_image, |
| 79 bool use_shallow_flush) | 79 bool use_shallow_flush, |
| 80 bool use_compressed_texture_etc1) | |
| 80 : context_(context), | 81 : context_(context), |
| 81 num_blocking_texture_uploads_(0), | 82 num_blocking_texture_uploads_(0), |
| 82 use_map_tex_sub_image_(use_map_tex_sub_image), | 83 use_map_tex_sub_image_(use_map_tex_sub_image), |
| 83 sub_image_size_(0), | 84 sub_image_size_(0), |
| 84 use_shallow_flush_(use_shallow_flush), | 85 use_shallow_flush_(use_shallow_flush), |
| 85 num_texture_uploads_since_last_flush_(0) { | 86 num_texture_uploads_since_last_flush_(0), |
| 87 use_compressed_texture_etc1_(use_compressed_texture_etc1) { | |
|
no sievers
2013/10/23 20:33:15
nit: I'd rename this to 'have_compressed_texture_e
powei
2013/10/23 22:20:07
Done. Removed.
| |
| 86 for (size_t i = kUploadHistorySizeInitial; i > 0; i--) | 88 for (size_t i = kUploadHistorySizeInitial; i > 0; i--) |
| 87 textures_per_second_history_.insert(kDefaultEstimatedTexturesPerSecond); | 89 textures_per_second_history_.insert(kDefaultEstimatedTexturesPerSecond); |
| 88 } | 90 } |
| 89 | 91 |
| 90 TextureUploader::~TextureUploader() {} | 92 TextureUploader::~TextureUploader() {} |
| 91 | 93 |
| 92 size_t TextureUploader::NumBlockingUploads() { | 94 size_t TextureUploader::NumBlockingUploads() { |
| 93 ProcessQueries(); | 95 ProcessQueries(); |
| 94 return num_blocking_texture_uploads_; | 96 return num_blocking_texture_uploads_; |
| 95 } | 97 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 gfx::Vector2d dest_offset, | 181 gfx::Vector2d dest_offset, |
| 180 ResourceFormat format) { | 182 ResourceFormat format) { |
| 181 TRACE_EVENT0("cc", "TextureUploader::UploadWithTexSubImage"); | 183 TRACE_EVENT0("cc", "TextureUploader::UploadWithTexSubImage"); |
| 182 | 184 |
| 183 // Early-out if this is a no-op, and assert that |image| be valid if this is | 185 // Early-out if this is a no-op, and assert that |image| be valid if this is |
| 184 // not a no-op. | 186 // not a no-op. |
| 185 if (source_rect.IsEmpty()) | 187 if (source_rect.IsEmpty()) |
| 186 return; | 188 return; |
| 187 DCHECK(image); | 189 DCHECK(image); |
| 188 | 190 |
| 191 if (format == ETC1) { | |
| 192 UploadWithTexSubImageETC1( | |
| 193 image, image_rect, source_rect, dest_offset, format); | |
| 194 return; | |
| 195 } | |
| 196 | |
| 189 // Offset from image-rect to source-rect. | 197 // Offset from image-rect to source-rect. |
| 190 gfx::Vector2d offset(source_rect.origin() - image_rect.origin()); | 198 gfx::Vector2d offset(source_rect.origin() - image_rect.origin()); |
| 191 | 199 |
| 192 const uint8* pixel_source; | 200 const uint8* pixel_source; |
| 193 unsigned bytes_per_pixel = BytesPerPixel(format); | 201 unsigned bytes_per_pixel = BitsPerPixel(format) / 8; |
|
kaanb
2013/10/23 20:30:09
could you keep a BytesPerPixel method in resource_
powei
2013/10/23 22:20:07
Done.
| |
| 194 // Use 4-byte row alignment (OpenGL default) for upload performance. | 202 // Use 4-byte row alignment (OpenGL default) for upload performance. |
| 195 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. | 203 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. |
| 196 unsigned upload_image_stride = | 204 unsigned upload_image_stride = |
| 197 RoundUp(bytes_per_pixel * source_rect.width(), 4u); | 205 RoundUp(bytes_per_pixel * source_rect.width(), 4u); |
| 198 | 206 |
| 199 if (upload_image_stride == image_rect.width() * bytes_per_pixel && | 207 if (upload_image_stride == image_rect.width() * bytes_per_pixel && |
| 200 !offset.x()) { | 208 !offset.x()) { |
| 201 pixel_source = &image[image_rect.width() * bytes_per_pixel * offset.y()]; | 209 pixel_source = &image[image_rect.width() * bytes_per_pixel * offset.y()]; |
| 202 } else { | 210 } else { |
| 203 size_t needed_size = upload_image_stride * source_rect.height(); | 211 size_t needed_size = upload_image_stride * source_rect.height(); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 232 gfx::Rect source_rect, | 240 gfx::Rect source_rect, |
| 233 gfx::Vector2d dest_offset, | 241 gfx::Vector2d dest_offset, |
| 234 ResourceFormat format) { | 242 ResourceFormat format) { |
| 235 TRACE_EVENT0("cc", "TextureUploader::UploadWithMapTexSubImage"); | 243 TRACE_EVENT0("cc", "TextureUploader::UploadWithMapTexSubImage"); |
| 236 | 244 |
| 237 // Early-out if this is a no-op, and assert that |image| be valid if this is | 245 // Early-out if this is a no-op, and assert that |image| be valid if this is |
| 238 // not a no-op. | 246 // not a no-op. |
| 239 if (source_rect.IsEmpty()) | 247 if (source_rect.IsEmpty()) |
| 240 return; | 248 return; |
| 241 DCHECK(image); | 249 DCHECK(image); |
| 250 // Compressed textures have no implementation of mapTexSubImage. | |
| 251 DCHECK_NE(ETC1, format); | |
| 242 | 252 |
| 243 // Offset from image-rect to source-rect. | 253 // Offset from image-rect to source-rect. |
| 244 gfx::Vector2d offset(source_rect.origin() - image_rect.origin()); | 254 gfx::Vector2d offset(source_rect.origin() - image_rect.origin()); |
| 245 | 255 |
| 246 unsigned bytes_per_pixel = BytesPerPixel(format); | 256 unsigned bytes_per_pixel = BitsPerPixel(format) / 8; |
| 247 // Use 4-byte row alignment (OpenGL default) for upload performance. | 257 // Use 4-byte row alignment (OpenGL default) for upload performance. |
| 248 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. | 258 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. |
| 249 unsigned upload_image_stride = | 259 unsigned upload_image_stride = |
| 250 RoundUp(bytes_per_pixel * source_rect.width(), 4u); | 260 RoundUp(bytes_per_pixel * source_rect.width(), 4u); |
| 251 | 261 |
| 252 // Upload tile data via a mapped transfer buffer | 262 // Upload tile data via a mapped transfer buffer |
| 253 uint8* pixel_dest = static_cast<uint8*>( | 263 uint8* pixel_dest = static_cast<uint8*>( |
| 254 context_->mapTexSubImage2DCHROMIUM(GL_TEXTURE_2D, | 264 context_->mapTexSubImage2DCHROMIUM(GL_TEXTURE_2D, |
| 255 0, | 265 0, |
| 256 dest_offset.x(), | 266 dest_offset.x(), |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 278 memcpy(&pixel_dest[upload_image_stride * row], | 288 memcpy(&pixel_dest[upload_image_stride * row], |
| 279 &image[bytes_per_pixel * | 289 &image[bytes_per_pixel * |
| 280 (offset.x() + (offset.y() + row) * image_rect.width())], | 290 (offset.x() + (offset.y() + row) * image_rect.width())], |
| 281 source_rect.width() * bytes_per_pixel); | 291 source_rect.width() * bytes_per_pixel); |
| 282 } | 292 } |
| 283 } | 293 } |
| 284 | 294 |
| 285 context_->unmapTexSubImage2DCHROMIUM(pixel_dest); | 295 context_->unmapTexSubImage2DCHROMIUM(pixel_dest); |
| 286 } | 296 } |
| 287 | 297 |
| 298 void TextureUploader::UploadWithTexSubImageETC1(const uint8* image, | |
| 299 gfx::Rect image_rect, | |
| 300 gfx::Rect source_rect, | |
| 301 gfx::Vector2d dest_offset, | |
| 302 ResourceFormat format) { | |
| 303 TRACE_EVENT0("cc", "TextureUploader::UploadWithTexSubImageETC1"); | |
| 304 DCHECK(use_compressed_texture_etc1_); | |
| 305 // ETC1 does not support subimage uploads yet. | |
| 306 DCHECK(image_rect == source_rect); | |
| 307 DCHECK_EQ(0, dest_offset.x()); | |
| 308 DCHECK_EQ(0, dest_offset.y()); | |
| 309 | |
| 310 gfx::Size size = source_rect.size(); | |
| 311 DCHECK_EQ(0, size.width() % 4); | |
| 312 DCHECK_EQ(0, size.height() % 4); | |
| 313 | |
| 314 context_->compressedTexSubImage2D( | |
|
no sievers
2013/10/23 20:33:15
Wait, I'm confused. Like your comment says above,
powei
2013/10/23 22:20:07
Done. My comment above was to discourage users fr
| |
| 315 GL_TEXTURE_2D, | |
| 316 0, /* level */ | |
| 317 0, /* x */ | |
| 318 0, /* y */ | |
| 319 size.width(), | |
| 320 size.height(), | |
| 321 GLDataFormat(format), | |
| 322 Resource::MemorySizeBytes(size, format), | |
| 323 image); | |
| 324 } | |
| 325 | |
| 288 void TextureUploader::ProcessQueries() { | 326 void TextureUploader::ProcessQueries() { |
| 289 while (!pending_queries_.empty()) { | 327 while (!pending_queries_.empty()) { |
| 290 if (pending_queries_.front()->IsPending()) | 328 if (pending_queries_.front()->IsPending()) |
| 291 break; | 329 break; |
| 292 | 330 |
| 293 unsigned us_elapsed = pending_queries_.front()->Value(); | 331 unsigned us_elapsed = pending_queries_.front()->Value(); |
| 294 UMA_HISTOGRAM_CUSTOM_COUNTS( | 332 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 295 "Renderer4.TextureGpuUploadTimeUS", us_elapsed, 0, 100000, 50); | 333 "Renderer4.TextureGpuUploadTimeUS", us_elapsed, 0, 100000, 50); |
| 296 | 334 |
| 297 // Clamp the queries to saner values in case the queries fail. | 335 // Clamp the queries to saner values in case the queries fail. |
| 298 us_elapsed = std::max(1u, us_elapsed); | 336 us_elapsed = std::max(1u, us_elapsed); |
| 299 us_elapsed = std::min(15000u, us_elapsed); | 337 us_elapsed = std::min(15000u, us_elapsed); |
| 300 | 338 |
| 301 if (!pending_queries_.front()->is_non_blocking()) | 339 if (!pending_queries_.front()->is_non_blocking()) |
| 302 num_blocking_texture_uploads_--; | 340 num_blocking_texture_uploads_--; |
| 303 | 341 |
| 304 // Remove the min and max value from our history and insert the new one. | 342 // Remove the min and max value from our history and insert the new one. |
| 305 double textures_per_second = 1.0 / (us_elapsed * 1e-6); | 343 double textures_per_second = 1.0 / (us_elapsed * 1e-6); |
| 306 if (textures_per_second_history_.size() >= kUploadHistorySizeMax) { | 344 if (textures_per_second_history_.size() >= kUploadHistorySizeMax) { |
| 307 textures_per_second_history_.erase(textures_per_second_history_.begin()); | 345 textures_per_second_history_.erase(textures_per_second_history_.begin()); |
| 308 textures_per_second_history_.erase(--textures_per_second_history_.end()); | 346 textures_per_second_history_.erase(--textures_per_second_history_.end()); |
| 309 } | 347 } |
| 310 textures_per_second_history_.insert(textures_per_second); | 348 textures_per_second_history_.insert(textures_per_second); |
| 311 | 349 |
| 312 available_queries_.push_back(pending_queries_.take_front()); | 350 available_queries_.push_back(pending_queries_.take_front()); |
| 313 } | 351 } |
| 314 } | 352 } |
| 315 | 353 |
| 316 } // namespace cc | 354 } // namespace cc |
| OLD | NEW |