| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 gfx::Vector2d dest_offset, | 136 gfx::Vector2d dest_offset, |
| 137 ResourceFormat format, | 137 ResourceFormat format, |
| 138 gfx::Size size) { | 138 gfx::Size size) { |
| 139 CHECK(image_rect.Contains(source_rect)); | 139 CHECK(image_rect.Contains(source_rect)); |
| 140 | 140 |
| 141 bool is_full_upload = dest_offset.IsZero() && source_rect.size() == size; | 141 bool is_full_upload = dest_offset.IsZero() && source_rect.size() == size; |
| 142 | 142 |
| 143 if (is_full_upload) | 143 if (is_full_upload) |
| 144 BeginQuery(); | 144 BeginQuery(); |
| 145 | 145 |
| 146 if (format == ETC1) { |
| 147 // ETC1 does not support subimage uploads. |
| 148 DCHECK(is_full_upload); |
| 149 UploadWithTexImageETC1(image, size); |
| 150 return; |
| 151 } |
| 152 |
| 146 if (use_map_tex_sub_image_) { | 153 if (use_map_tex_sub_image_) { |
| 147 UploadWithMapTexSubImage( | 154 UploadWithMapTexSubImage( |
| 148 image, image_rect, source_rect, dest_offset, format); | 155 image, image_rect, source_rect, dest_offset, format); |
| 149 } else { | 156 } else { |
| 150 UploadWithTexSubImage(image, image_rect, source_rect, dest_offset, format); | 157 UploadWithTexSubImage(image, image_rect, source_rect, dest_offset, format); |
| 151 } | 158 } |
| 152 | 159 |
| 153 if (is_full_upload) | 160 if (is_full_upload) |
| 154 EndQuery(); | 161 EndQuery(); |
| 155 | 162 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 183 // Early-out if this is a no-op, and assert that |image| be valid if this is | 190 // Early-out if this is a no-op, and assert that |image| be valid if this is |
| 184 // not a no-op. | 191 // not a no-op. |
| 185 if (source_rect.IsEmpty()) | 192 if (source_rect.IsEmpty()) |
| 186 return; | 193 return; |
| 187 DCHECK(image); | 194 DCHECK(image); |
| 188 | 195 |
| 189 // Offset from image-rect to source-rect. | 196 // Offset from image-rect to source-rect. |
| 190 gfx::Vector2d offset(source_rect.origin() - image_rect.origin()); | 197 gfx::Vector2d offset(source_rect.origin() - image_rect.origin()); |
| 191 | 198 |
| 192 const uint8* pixel_source; | 199 const uint8* pixel_source; |
| 193 unsigned bytes_per_pixel = BytesPerPixel(format); | 200 unsigned bytes_per_pixel = BitsPerPixel(format) / 8; |
| 194 // Use 4-byte row alignment (OpenGL default) for upload performance. | 201 // Use 4-byte row alignment (OpenGL default) for upload performance. |
| 195 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. | 202 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. |
| 196 unsigned upload_image_stride = | 203 unsigned upload_image_stride = |
| 197 RoundUp(bytes_per_pixel * source_rect.width(), 4u); | 204 RoundUp(bytes_per_pixel * source_rect.width(), 4u); |
| 198 | 205 |
| 199 if (upload_image_stride == image_rect.width() * bytes_per_pixel && | 206 if (upload_image_stride == image_rect.width() * bytes_per_pixel && |
| 200 !offset.x()) { | 207 !offset.x()) { |
| 201 pixel_source = &image[image_rect.width() * bytes_per_pixel * offset.y()]; | 208 pixel_source = &image[image_rect.width() * bytes_per_pixel * offset.y()]; |
| 202 } else { | 209 } else { |
| 203 size_t needed_size = upload_image_stride * source_rect.height(); | 210 size_t needed_size = upload_image_stride * source_rect.height(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 232 gfx::Rect source_rect, | 239 gfx::Rect source_rect, |
| 233 gfx::Vector2d dest_offset, | 240 gfx::Vector2d dest_offset, |
| 234 ResourceFormat format) { | 241 ResourceFormat format) { |
| 235 TRACE_EVENT0("cc", "TextureUploader::UploadWithMapTexSubImage"); | 242 TRACE_EVENT0("cc", "TextureUploader::UploadWithMapTexSubImage"); |
| 236 | 243 |
| 237 // Early-out if this is a no-op, and assert that |image| be valid if this is | 244 // Early-out if this is a no-op, and assert that |image| be valid if this is |
| 238 // not a no-op. | 245 // not a no-op. |
| 239 if (source_rect.IsEmpty()) | 246 if (source_rect.IsEmpty()) |
| 240 return; | 247 return; |
| 241 DCHECK(image); | 248 DCHECK(image); |
| 249 // Compressed textures have no implementation of mapTexSubImage. |
| 250 DCHECK_NE(ETC1, format); |
| 242 | 251 |
| 243 // Offset from image-rect to source-rect. | 252 // Offset from image-rect to source-rect. |
| 244 gfx::Vector2d offset(source_rect.origin() - image_rect.origin()); | 253 gfx::Vector2d offset(source_rect.origin() - image_rect.origin()); |
| 245 | 254 |
| 246 unsigned bytes_per_pixel = BytesPerPixel(format); | 255 unsigned bytes_per_pixel = BitsPerPixel(format) / 8; |
| 247 // Use 4-byte row alignment (OpenGL default) for upload performance. | 256 // Use 4-byte row alignment (OpenGL default) for upload performance. |
| 248 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. | 257 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. |
| 249 unsigned upload_image_stride = | 258 unsigned upload_image_stride = |
| 250 RoundUp(bytes_per_pixel * source_rect.width(), 4u); | 259 RoundUp(bytes_per_pixel * source_rect.width(), 4u); |
| 251 | 260 |
| 252 // Upload tile data via a mapped transfer buffer | 261 // Upload tile data via a mapped transfer buffer |
| 253 uint8* pixel_dest = static_cast<uint8*>( | 262 uint8* pixel_dest = static_cast<uint8*>( |
| 254 context_->mapTexSubImage2DCHROMIUM(GL_TEXTURE_2D, | 263 context_->mapTexSubImage2DCHROMIUM(GL_TEXTURE_2D, |
| 255 0, | 264 0, |
| 256 dest_offset.x(), | 265 dest_offset.x(), |
| (...skipping 21 matching lines...) Expand all Loading... |
| 278 memcpy(&pixel_dest[upload_image_stride * row], | 287 memcpy(&pixel_dest[upload_image_stride * row], |
| 279 &image[bytes_per_pixel * | 288 &image[bytes_per_pixel * |
| 280 (offset.x() + (offset.y() + row) * image_rect.width())], | 289 (offset.x() + (offset.y() + row) * image_rect.width())], |
| 281 source_rect.width() * bytes_per_pixel); | 290 source_rect.width() * bytes_per_pixel); |
| 282 } | 291 } |
| 283 } | 292 } |
| 284 | 293 |
| 285 context_->unmapTexSubImage2DCHROMIUM(pixel_dest); | 294 context_->unmapTexSubImage2DCHROMIUM(pixel_dest); |
| 286 } | 295 } |
| 287 | 296 |
| 297 void TextureUploader::UploadWithTexImageETC1(const uint8* image, |
| 298 gfx::Size size) { |
| 299 TRACE_EVENT0("cc", "TextureUploader::UploadWithTexImageETC1"); |
| 300 DCHECK_EQ(0, size.width() % 4); |
| 301 DCHECK_EQ(0, size.height() % 4); |
| 302 |
| 303 context_->compressedTexImage2D(GL_TEXTURE_2D, |
| 304 0, |
| 305 GLInternalFormat(ETC1), |
| 306 size.width(), |
| 307 size.height(), |
| 308 0, |
| 309 Resource::MemorySizeBytes(size, ETC1), |
| 310 image); |
| 311 } |
| 312 |
| 288 void TextureUploader::ProcessQueries() { | 313 void TextureUploader::ProcessQueries() { |
| 289 while (!pending_queries_.empty()) { | 314 while (!pending_queries_.empty()) { |
| 290 if (pending_queries_.front()->IsPending()) | 315 if (pending_queries_.front()->IsPending()) |
| 291 break; | 316 break; |
| 292 | 317 |
| 293 unsigned us_elapsed = pending_queries_.front()->Value(); | 318 unsigned us_elapsed = pending_queries_.front()->Value(); |
| 294 UMA_HISTOGRAM_CUSTOM_COUNTS( | 319 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 295 "Renderer4.TextureGpuUploadTimeUS", us_elapsed, 0, 100000, 50); | 320 "Renderer4.TextureGpuUploadTimeUS", us_elapsed, 0, 100000, 50); |
| 296 | 321 |
| 297 // Clamp the queries to saner values in case the queries fail. | 322 // Clamp the queries to saner values in case the queries fail. |
| 298 us_elapsed = std::max(1u, us_elapsed); | 323 us_elapsed = std::max(1u, us_elapsed); |
| 299 us_elapsed = std::min(15000u, us_elapsed); | 324 us_elapsed = std::min(15000u, us_elapsed); |
| 300 | 325 |
| 301 if (!pending_queries_.front()->is_non_blocking()) | 326 if (!pending_queries_.front()->is_non_blocking()) |
| 302 num_blocking_texture_uploads_--; | 327 num_blocking_texture_uploads_--; |
| 303 | 328 |
| 304 // Remove the min and max value from our history and insert the new one. | 329 // 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); | 330 double textures_per_second = 1.0 / (us_elapsed * 1e-6); |
| 306 if (textures_per_second_history_.size() >= kUploadHistorySizeMax) { | 331 if (textures_per_second_history_.size() >= kUploadHistorySizeMax) { |
| 307 textures_per_second_history_.erase(textures_per_second_history_.begin()); | 332 textures_per_second_history_.erase(textures_per_second_history_.begin()); |
| 308 textures_per_second_history_.erase(--textures_per_second_history_.end()); | 333 textures_per_second_history_.erase(--textures_per_second_history_.end()); |
| 309 } | 334 } |
| 310 textures_per_second_history_.insert(textures_per_second); | 335 textures_per_second_history_.insert(textures_per_second); |
| 311 | 336 |
| 312 available_queries_.push_back(pending_queries_.take_front()); | 337 available_queries_.push_back(pending_queries_.take_front()); |
| 313 } | 338 } |
| 314 } | 339 } |
| 315 | 340 |
| 316 } // namespace cc | 341 } // namespace cc |
| OLD | NEW |