OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/raster/one_copy_tile_task_worker_pool.h" | 5 #include "cc/raster/one_copy_tile_task_worker_pool.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds( | 93 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds( |
94 kCheckForQueryResultAvailableTickRateMs)); | 94 kCheckForQueryResultAvailableTickRateMs)); |
95 } | 95 } |
96 | 96 |
97 unsigned result = 0; | 97 unsigned result = 0; |
98 gl->GetQueryObjectuivEXT(query_id, GL_QUERY_RESULT_EXT, &result); | 98 gl->GetQueryObjectuivEXT(query_id, GL_QUERY_RESULT_EXT, &result); |
99 } | 99 } |
100 | 100 |
101 } // namespace | 101 } // namespace |
102 | 102 |
103 OneCopyTileTaskWorkerPool::StagingBuffer::StagingBuffer(const gfx::Size& size) | 103 OneCopyTileTaskWorkerPool::StagingBuffer::StagingBuffer(const gfx::Size& size, |
104 : size(size), texture_id(0), image_id(0), query_id(0), content_id(0) {} | 104 ResourceFormat format) |
| 105 : size(size), |
| 106 format(format), |
| 107 texture_id(0), |
| 108 image_id(0), |
| 109 query_id(0), |
| 110 content_id(0) {} |
105 | 111 |
106 OneCopyTileTaskWorkerPool::StagingBuffer::~StagingBuffer() { | 112 OneCopyTileTaskWorkerPool::StagingBuffer::~StagingBuffer() { |
107 DCHECK_EQ(texture_id, 0u); | 113 DCHECK_EQ(texture_id, 0u); |
108 DCHECK_EQ(image_id, 0u); | 114 DCHECK_EQ(image_id, 0u); |
109 DCHECK_EQ(query_id, 0u); | 115 DCHECK_EQ(query_id, 0u); |
110 } | 116 } |
111 | 117 |
112 void OneCopyTileTaskWorkerPool::StagingBuffer::DestroyGLResources( | 118 void OneCopyTileTaskWorkerPool::StagingBuffer::DestroyGLResources( |
113 gpu::gles2::GLES2Interface* gl) { | 119 gpu::gles2::GLES2Interface* gl) { |
114 if (query_id) { | 120 if (query_id) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 } | 168 } |
163 | 169 |
164 // static | 170 // static |
165 scoped_ptr<TileTaskWorkerPool> OneCopyTileTaskWorkerPool::Create( | 171 scoped_ptr<TileTaskWorkerPool> OneCopyTileTaskWorkerPool::Create( |
166 base::SequencedTaskRunner* task_runner, | 172 base::SequencedTaskRunner* task_runner, |
167 TaskGraphRunner* task_graph_runner, | 173 TaskGraphRunner* task_graph_runner, |
168 ContextProvider* context_provider, | 174 ContextProvider* context_provider, |
169 ResourceProvider* resource_provider, | 175 ResourceProvider* resource_provider, |
170 int max_copy_texture_chromium_size, | 176 int max_copy_texture_chromium_size, |
171 bool use_persistent_gpu_memory_buffers, | 177 bool use_persistent_gpu_memory_buffers, |
172 int max_staging_buffer_usage_in_bytes) { | 178 int max_staging_buffer_usage_in_bytes, |
| 179 bool use_rgba_4444_texture_format) { |
173 return make_scoped_ptr<TileTaskWorkerPool>(new OneCopyTileTaskWorkerPool( | 180 return make_scoped_ptr<TileTaskWorkerPool>(new OneCopyTileTaskWorkerPool( |
174 task_runner, task_graph_runner, resource_provider, | 181 task_runner, task_graph_runner, resource_provider, |
175 max_copy_texture_chromium_size, use_persistent_gpu_memory_buffers, | 182 max_copy_texture_chromium_size, use_persistent_gpu_memory_buffers, |
176 max_staging_buffer_usage_in_bytes)); | 183 max_staging_buffer_usage_in_bytes, use_rgba_4444_texture_format)); |
177 } | 184 } |
178 | 185 |
179 OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool( | 186 OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool( |
180 base::SequencedTaskRunner* task_runner, | 187 base::SequencedTaskRunner* task_runner, |
181 TaskGraphRunner* task_graph_runner, | 188 TaskGraphRunner* task_graph_runner, |
182 ResourceProvider* resource_provider, | 189 ResourceProvider* resource_provider, |
183 int max_copy_texture_chromium_size, | 190 int max_copy_texture_chromium_size, |
184 bool use_persistent_gpu_memory_buffers, | 191 bool use_persistent_gpu_memory_buffers, |
185 int max_staging_buffer_usage_in_bytes) | 192 int max_staging_buffer_usage_in_bytes, |
| 193 bool use_rgba_4444_texture_format) |
186 : task_runner_(task_runner), | 194 : task_runner_(task_runner), |
187 task_graph_runner_(task_graph_runner), | 195 task_graph_runner_(task_graph_runner), |
188 namespace_token_(task_graph_runner->GetNamespaceToken()), | 196 namespace_token_(task_graph_runner->GetNamespaceToken()), |
189 resource_provider_(resource_provider), | 197 resource_provider_(resource_provider), |
190 max_bytes_per_copy_operation_( | 198 max_bytes_per_copy_operation_( |
191 max_copy_texture_chromium_size | 199 max_copy_texture_chromium_size |
192 ? std::min(kMaxBytesPerCopyOperation, | 200 ? std::min(kMaxBytesPerCopyOperation, |
193 max_copy_texture_chromium_size) | 201 max_copy_texture_chromium_size) |
194 : kMaxBytesPerCopyOperation), | 202 : kMaxBytesPerCopyOperation), |
195 use_persistent_gpu_memory_buffers_(use_persistent_gpu_memory_buffers), | 203 use_persistent_gpu_memory_buffers_(use_persistent_gpu_memory_buffers), |
196 bytes_scheduled_since_last_flush_(0), | 204 bytes_scheduled_since_last_flush_(0), |
197 max_staging_buffer_usage_in_bytes_(max_staging_buffer_usage_in_bytes), | 205 max_staging_buffer_usage_in_bytes_(max_staging_buffer_usage_in_bytes), |
| 206 use_rgba_4444_texture_format_(use_rgba_4444_texture_format), |
198 staging_buffer_usage_in_bytes_(0), | 207 staging_buffer_usage_in_bytes_(0), |
199 free_staging_buffer_usage_in_bytes_(0), | 208 free_staging_buffer_usage_in_bytes_(0), |
200 staging_buffer_expiration_delay_( | 209 staging_buffer_expiration_delay_( |
201 base::TimeDelta::FromMilliseconds(kStagingBufferExpirationDelayMs)), | 210 base::TimeDelta::FromMilliseconds(kStagingBufferExpirationDelayMs)), |
202 reduce_memory_usage_pending_(false), | 211 reduce_memory_usage_pending_(false), |
203 weak_ptr_factory_(this), | 212 weak_ptr_factory_(this), |
204 task_set_finished_weak_ptr_factory_(this) { | 213 task_set_finished_weak_ptr_factory_(this) { |
205 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( | 214 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
206 this, base::ThreadTaskRunnerHandle::Get()); | 215 this, base::ThreadTaskRunnerHandle::Get()); |
207 reduce_memory_usage_callback_ = | 216 reduce_memory_usage_callback_ = |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 it != completed_tasks_.end(); ++it) { | 328 it != completed_tasks_.end(); ++it) { |
320 TileTask* task = static_cast<TileTask*>(it->get()); | 329 TileTask* task = static_cast<TileTask*>(it->get()); |
321 | 330 |
322 task->WillComplete(); | 331 task->WillComplete(); |
323 task->CompleteOnOriginThread(this); | 332 task->CompleteOnOriginThread(this); |
324 task->DidComplete(); | 333 task->DidComplete(); |
325 } | 334 } |
326 completed_tasks_.clear(); | 335 completed_tasks_.clear(); |
327 } | 336 } |
328 | 337 |
329 ResourceFormat OneCopyTileTaskWorkerPool::GetResourceFormat() const { | 338 ResourceFormat OneCopyTileTaskWorkerPool::GetResourceFormat( |
330 return resource_provider_->memory_efficient_texture_format(); | 339 bool must_support_alpha) const { |
| 340 return use_rgba_4444_texture_format_ |
| 341 ? RGBA_4444 |
| 342 : resource_provider_->best_texture_format(); |
331 } | 343 } |
332 | 344 |
333 bool OneCopyTileTaskWorkerPool::GetResourceRequiresSwizzle() const { | 345 bool OneCopyTileTaskWorkerPool::GetResourceRequiresSwizzle( |
334 return !PlatformColor::SameComponentOrder(GetResourceFormat()); | 346 bool must_support_alpha) const { |
| 347 return !PlatformColor::SameComponentOrder( |
| 348 GetResourceFormat(must_support_alpha)); |
335 } | 349 } |
336 | 350 |
337 scoped_ptr<RasterBuffer> OneCopyTileTaskWorkerPool::AcquireBufferForRaster( | 351 scoped_ptr<RasterBuffer> OneCopyTileTaskWorkerPool::AcquireBufferForRaster( |
338 const Resource* resource, | 352 const Resource* resource, |
339 uint64_t resource_content_id, | 353 uint64_t resource_content_id, |
340 uint64_t previous_content_id) { | 354 uint64_t previous_content_id) { |
341 // TODO(danakj): If resource_content_id != 0, we only need to copy/upload | 355 // TODO(danakj): If resource_content_id != 0, we only need to copy/upload |
342 // the dirty rect. | 356 // the dirty rect. |
343 DCHECK_EQ(resource->format(), | 357 return make_scoped_ptr<RasterBuffer>( |
344 resource_provider_->memory_efficient_texture_format()); | 358 new RasterBufferImpl(this, resource_provider_, resource->format(), |
345 return make_scoped_ptr<RasterBuffer>(new RasterBufferImpl( | 359 resource, previous_content_id)); |
346 this, resource_provider_, | |
347 resource_provider_->memory_efficient_texture_format(), resource, | |
348 previous_content_id)); | |
349 } | 360 } |
350 | 361 |
351 void OneCopyTileTaskWorkerPool::ReleaseBufferForRaster( | 362 void OneCopyTileTaskWorkerPool::ReleaseBufferForRaster( |
352 scoped_ptr<RasterBuffer> buffer) { | 363 scoped_ptr<RasterBuffer> buffer) { |
353 // Nothing to do here. RasterBufferImpl destructor cleans up after itself. | 364 // Nothing to do here. RasterBufferImpl destructor cleans up after itself. |
354 } | 365 } |
355 | 366 |
356 void OneCopyTileTaskWorkerPool::PlaybackAndCopyOnWorkerThread( | 367 void OneCopyTileTaskWorkerPool::PlaybackAndCopyOnWorkerThread( |
357 const Resource* resource, | 368 const Resource* resource, |
358 const ResourceProvider::ScopedWriteLockGL* resource_lock, | 369 const ResourceProvider::ScopedWriteLockGL* resource_lock, |
(...skipping 10 matching lines...) Expand all Loading... |
369 AcquireStagingBuffer(resource, previous_content_id); | 380 AcquireStagingBuffer(resource, previous_content_id); |
370 DCHECK(staging_buffer); | 381 DCHECK(staging_buffer); |
371 | 382 |
372 { | 383 { |
373 base::AutoUnlock unlock(lock_); | 384 base::AutoUnlock unlock(lock_); |
374 | 385 |
375 // Allocate GpuMemoryBuffer if necessary. | 386 // Allocate GpuMemoryBuffer if necessary. |
376 if (!staging_buffer->gpu_memory_buffer) { | 387 if (!staging_buffer->gpu_memory_buffer) { |
377 staging_buffer->gpu_memory_buffer = | 388 staging_buffer->gpu_memory_buffer = |
378 resource_provider_->gpu_memory_buffer_manager() | 389 resource_provider_->gpu_memory_buffer_manager() |
379 ->AllocateGpuMemoryBuffer( | 390 ->AllocateGpuMemoryBuffer(staging_buffer->size, |
380 staging_buffer->size, | 391 BufferFormat(resource->format()), |
381 BufferFormat( | 392 use_persistent_gpu_memory_buffers_ |
382 resource_provider_->memory_efficient_texture_format()), | 393 ? gfx::BufferUsage::PERSISTENT_MAP |
383 use_persistent_gpu_memory_buffers_ | 394 : gfx::BufferUsage::MAP); |
384 ? gfx::BufferUsage::PERSISTENT_MAP | |
385 : gfx::BufferUsage::MAP); | |
386 DCHECK_EQ(gfx::NumberOfPlanesForBufferFormat( | 395 DCHECK_EQ(gfx::NumberOfPlanesForBufferFormat( |
387 staging_buffer->gpu_memory_buffer->GetFormat()), | 396 staging_buffer->gpu_memory_buffer->GetFormat()), |
388 1u); | 397 1u); |
389 } | 398 } |
390 | 399 |
391 gfx::Rect playback_rect = raster_full_rect; | 400 gfx::Rect playback_rect = raster_full_rect; |
392 if (use_persistent_gpu_memory_buffers_ && previous_content_id) { | 401 if (use_persistent_gpu_memory_buffers_ && previous_content_id) { |
393 // Reduce playback rect to dirty region if the content id of the staging | 402 // Reduce playback rect to dirty region if the content id of the staging |
394 // buffer matches the prevous content id. | 403 // buffer matches the prevous content id. |
395 if (previous_content_id == staging_buffer->content_id) | 404 if (previous_content_id == staging_buffer->content_id) |
396 playback_rect.Intersect(raster_dirty_rect); | 405 playback_rect.Intersect(raster_dirty_rect); |
397 } | 406 } |
398 | 407 |
399 if (staging_buffer->gpu_memory_buffer) { | 408 if (staging_buffer->gpu_memory_buffer) { |
400 void* data = nullptr; | 409 void* data = nullptr; |
401 bool rv = staging_buffer->gpu_memory_buffer->Map(&data); | 410 bool rv = staging_buffer->gpu_memory_buffer->Map(&data); |
402 DCHECK(rv); | 411 DCHECK(rv); |
403 int stride; | 412 int stride; |
404 staging_buffer->gpu_memory_buffer->GetStride(&stride); | 413 staging_buffer->gpu_memory_buffer->GetStride(&stride); |
405 // TileTaskWorkerPool::PlaybackToMemory only supports unsigned strides. | 414 // TileTaskWorkerPool::PlaybackToMemory only supports unsigned strides. |
406 DCHECK_GE(stride, 0); | 415 DCHECK_GE(stride, 0); |
407 | 416 |
408 DCHECK(!playback_rect.IsEmpty()) | 417 DCHECK(!playback_rect.IsEmpty()) |
409 << "Why are we rastering a tile that's not dirty?"; | 418 << "Why are we rastering a tile that's not dirty?"; |
410 TileTaskWorkerPool::PlaybackToMemory( | 419 TileTaskWorkerPool::PlaybackToMemory( |
411 data, resource_provider_->memory_efficient_texture_format(), | 420 data, resource->format(), staging_buffer->size, |
412 staging_buffer->size, static_cast<size_t>(stride), raster_source, | 421 static_cast<size_t>(stride), raster_source, raster_full_rect, |
413 raster_full_rect, playback_rect, scale, include_images); | 422 playback_rect, scale, include_images); |
414 staging_buffer->gpu_memory_buffer->Unmap(); | 423 staging_buffer->gpu_memory_buffer->Unmap(); |
415 staging_buffer->content_id = new_content_id; | 424 staging_buffer->content_id = new_content_id; |
416 } | 425 } |
417 } | 426 } |
418 | 427 |
419 ContextProvider* context_provider = | 428 ContextProvider* context_provider = |
420 resource_provider_->output_surface()->worker_context_provider(); | 429 resource_provider_->output_surface()->worker_context_provider(); |
421 DCHECK(context_provider); | 430 DCHECK(context_provider); |
422 | 431 |
423 { | 432 { |
424 ContextProvider::ScopedContextLock scoped_context(context_provider); | 433 ContextProvider::ScopedContextLock scoped_context(context_provider); |
425 | 434 |
426 gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); | 435 gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); |
427 DCHECK(gl); | 436 DCHECK(gl); |
428 | 437 |
429 unsigned image_target = resource_provider_->GetImageTextureTarget( | 438 unsigned image_target = |
430 resource_provider_->memory_efficient_texture_format()); | 439 resource_provider_->GetImageTextureTarget(resource->format()); |
431 | 440 |
432 // Create and bind staging texture. | 441 // Create and bind staging texture. |
433 if (!staging_buffer->texture_id) { | 442 if (!staging_buffer->texture_id) { |
434 gl->GenTextures(1, &staging_buffer->texture_id); | 443 gl->GenTextures(1, &staging_buffer->texture_id); |
435 gl->BindTexture(image_target, staging_buffer->texture_id); | 444 gl->BindTexture(image_target, staging_buffer->texture_id); |
436 gl->TexParameteri(image_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 445 gl->TexParameteri(image_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
437 gl->TexParameteri(image_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 446 gl->TexParameteri(image_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
438 gl->TexParameteri(image_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 447 gl->TexParameteri(image_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
439 gl->TexParameteri(image_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 448 gl->TexParameteri(image_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
440 } else { | 449 } else { |
441 gl->BindTexture(image_target, staging_buffer->texture_id); | 450 gl->BindTexture(image_target, staging_buffer->texture_id); |
442 } | 451 } |
443 | 452 |
444 // Create and bind image. | 453 // Create and bind image. |
445 if (!staging_buffer->image_id) { | 454 if (!staging_buffer->image_id) { |
446 if (staging_buffer->gpu_memory_buffer) { | 455 if (staging_buffer->gpu_memory_buffer) { |
447 staging_buffer->image_id = gl->CreateImageCHROMIUM( | 456 staging_buffer->image_id = gl->CreateImageCHROMIUM( |
448 staging_buffer->gpu_memory_buffer->AsClientBuffer(), | 457 staging_buffer->gpu_memory_buffer->AsClientBuffer(), |
449 staging_buffer->size.width(), staging_buffer->size.height(), | 458 staging_buffer->size.width(), staging_buffer->size.height(), |
450 GLInternalFormat( | 459 GLInternalFormat(resource->format())); |
451 resource_provider_->memory_efficient_texture_format())); | |
452 gl->BindTexImage2DCHROMIUM(image_target, staging_buffer->image_id); | 460 gl->BindTexImage2DCHROMIUM(image_target, staging_buffer->image_id); |
453 } | 461 } |
454 } else { | 462 } else { |
455 gl->ReleaseTexImage2DCHROMIUM(image_target, staging_buffer->image_id); | 463 gl->ReleaseTexImage2DCHROMIUM(image_target, staging_buffer->image_id); |
456 gl->BindTexImage2DCHROMIUM(image_target, staging_buffer->image_id); | 464 gl->BindTexImage2DCHROMIUM(image_target, staging_buffer->image_id); |
457 } | 465 } |
458 | 466 |
459 // Unbind staging texture. | 467 // Unbind staging texture. |
460 gl->BindTexture(image_target, 0); | 468 gl->BindTexture(image_target, 0); |
461 | 469 |
462 if (resource_provider_->use_sync_query()) { | 470 if (resource_provider_->use_sync_query()) { |
463 if (!staging_buffer->query_id) | 471 if (!staging_buffer->query_id) |
464 gl->GenQueriesEXT(1, &staging_buffer->query_id); | 472 gl->GenQueriesEXT(1, &staging_buffer->query_id); |
465 | 473 |
466 #if defined(OS_CHROMEOS) | 474 #if defined(OS_CHROMEOS) |
467 // TODO(reveman): This avoids a performance problem on some ChromeOS | 475 // TODO(reveman): This avoids a performance problem on some ChromeOS |
468 // devices. This needs to be removed to support native GpuMemoryBuffer | 476 // devices. This needs to be removed to support native GpuMemoryBuffer |
469 // implementations. crbug.com/436314 | 477 // implementations. crbug.com/436314 |
470 gl->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, staging_buffer->query_id); | 478 gl->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, staging_buffer->query_id); |
471 #else | 479 #else |
472 gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, | 480 gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, |
473 staging_buffer->query_id); | 481 staging_buffer->query_id); |
474 #endif | 482 #endif |
475 } | 483 } |
476 | 484 |
477 int bytes_per_row = | 485 int bytes_per_row = |
478 (BitsPerPixel(resource_provider_->memory_efficient_texture_format()) * | 486 (BitsPerPixel(resource->format()) * resource->size().width()) / 8; |
479 resource->size().width()) / | |
480 8; | |
481 int chunk_size_in_rows = | 487 int chunk_size_in_rows = |
482 std::max(1, max_bytes_per_copy_operation_ / bytes_per_row); | 488 std::max(1, max_bytes_per_copy_operation_ / bytes_per_row); |
483 // Align chunk size to 4. Required to support compressed texture formats. | 489 // Align chunk size to 4. Required to support compressed texture formats. |
484 chunk_size_in_rows = MathUtil::UncheckedRoundUp(chunk_size_in_rows, 4); | 490 chunk_size_in_rows = MathUtil::UncheckedRoundUp(chunk_size_in_rows, 4); |
485 int y = 0; | 491 int y = 0; |
486 int height = resource->size().height(); | 492 int height = resource->size().height(); |
487 while (y < height) { | 493 while (y < height) { |
488 // Copy at most |chunk_size_in_rows|. | 494 // Copy at most |chunk_size_in_rows|. |
489 int rows_to_copy = std::min(chunk_size_in_rows, height - y); | 495 int rows_to_copy = std::min(chunk_size_in_rows, height - y); |
490 DCHECK_GT(rows_to_copy, 0); | 496 DCHECK_GT(rows_to_copy, 0); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 | 528 |
523 ScheduleReduceMemoryUsage(); | 529 ScheduleReduceMemoryUsage(); |
524 } | 530 } |
525 | 531 |
526 bool OneCopyTileTaskWorkerPool::OnMemoryDump( | 532 bool OneCopyTileTaskWorkerPool::OnMemoryDump( |
527 const base::trace_event::MemoryDumpArgs& args, | 533 const base::trace_event::MemoryDumpArgs& args, |
528 base::trace_event::ProcessMemoryDump* pmd) { | 534 base::trace_event::ProcessMemoryDump* pmd) { |
529 base::AutoLock lock(lock_); | 535 base::AutoLock lock(lock_); |
530 | 536 |
531 for (const auto& buffer : buffers_) { | 537 for (const auto& buffer : buffers_) { |
532 buffer->OnMemoryDump(pmd, | 538 buffer->OnMemoryDump(pmd, buffer->format, |
533 resource_provider_->memory_efficient_texture_format(), | |
534 std::find(free_buffers_.begin(), free_buffers_.end(), | 539 std::find(free_buffers_.begin(), free_buffers_.end(), |
535 buffer) != free_buffers_.end()); | 540 buffer) != free_buffers_.end()); |
536 } | 541 } |
537 | 542 |
538 return true; | 543 return true; |
539 } | 544 } |
540 | 545 |
541 void OneCopyTileTaskWorkerPool::AddStagingBuffer( | 546 void OneCopyTileTaskWorkerPool::AddStagingBuffer( |
542 const StagingBuffer* staging_buffer) { | 547 const StagingBuffer* staging_buffer, |
| 548 ResourceFormat format) { |
543 lock_.AssertAcquired(); | 549 lock_.AssertAcquired(); |
544 | 550 |
545 DCHECK(buffers_.find(staging_buffer) == buffers_.end()); | 551 DCHECK(buffers_.find(staging_buffer) == buffers_.end()); |
546 buffers_.insert(staging_buffer); | 552 buffers_.insert(staging_buffer); |
547 int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( | 553 int buffer_usage_in_bytes = |
548 staging_buffer->size, | 554 ResourceUtil::UncheckedSizeInBytes<int>(staging_buffer->size, format); |
549 resource_provider_->memory_efficient_texture_format()); | |
550 staging_buffer_usage_in_bytes_ += buffer_usage_in_bytes; | 555 staging_buffer_usage_in_bytes_ += buffer_usage_in_bytes; |
551 } | 556 } |
552 | 557 |
553 void OneCopyTileTaskWorkerPool::RemoveStagingBuffer( | 558 void OneCopyTileTaskWorkerPool::RemoveStagingBuffer( |
554 const StagingBuffer* staging_buffer) { | 559 const StagingBuffer* staging_buffer) { |
555 lock_.AssertAcquired(); | 560 lock_.AssertAcquired(); |
556 | 561 |
557 DCHECK(buffers_.find(staging_buffer) != buffers_.end()); | 562 DCHECK(buffers_.find(staging_buffer) != buffers_.end()); |
558 buffers_.erase(staging_buffer); | 563 buffers_.erase(staging_buffer); |
559 int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( | 564 int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( |
560 staging_buffer->size, | 565 staging_buffer->size, staging_buffer->format); |
561 resource_provider_->memory_efficient_texture_format()); | |
562 DCHECK_GE(staging_buffer_usage_in_bytes_, buffer_usage_in_bytes); | 566 DCHECK_GE(staging_buffer_usage_in_bytes_, buffer_usage_in_bytes); |
563 staging_buffer_usage_in_bytes_ -= buffer_usage_in_bytes; | 567 staging_buffer_usage_in_bytes_ -= buffer_usage_in_bytes; |
564 } | 568 } |
565 | 569 |
566 void OneCopyTileTaskWorkerPool::MarkStagingBufferAsFree( | 570 void OneCopyTileTaskWorkerPool::MarkStagingBufferAsFree( |
567 const StagingBuffer* staging_buffer) { | 571 const StagingBuffer* staging_buffer) { |
568 lock_.AssertAcquired(); | 572 lock_.AssertAcquired(); |
569 | 573 |
570 int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( | 574 int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( |
571 staging_buffer->size, | 575 staging_buffer->size, staging_buffer->format); |
572 resource_provider_->memory_efficient_texture_format()); | |
573 free_staging_buffer_usage_in_bytes_ += buffer_usage_in_bytes; | 576 free_staging_buffer_usage_in_bytes_ += buffer_usage_in_bytes; |
574 } | 577 } |
575 | 578 |
576 void OneCopyTileTaskWorkerPool::MarkStagingBufferAsBusy( | 579 void OneCopyTileTaskWorkerPool::MarkStagingBufferAsBusy( |
577 const StagingBuffer* staging_buffer) { | 580 const StagingBuffer* staging_buffer) { |
578 lock_.AssertAcquired(); | 581 lock_.AssertAcquired(); |
579 | 582 |
580 int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( | 583 int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( |
581 staging_buffer->size, | 584 staging_buffer->size, staging_buffer->format); |
582 resource_provider_->memory_efficient_texture_format()); | |
583 DCHECK_GE(free_staging_buffer_usage_in_bytes_, buffer_usage_in_bytes); | 585 DCHECK_GE(free_staging_buffer_usage_in_bytes_, buffer_usage_in_bytes); |
584 free_staging_buffer_usage_in_bytes_ -= buffer_usage_in_bytes; | 586 free_staging_buffer_usage_in_bytes_ -= buffer_usage_in_bytes; |
585 } | 587 } |
586 | 588 |
587 scoped_ptr<OneCopyTileTaskWorkerPool::StagingBuffer> | 589 scoped_ptr<OneCopyTileTaskWorkerPool::StagingBuffer> |
588 OneCopyTileTaskWorkerPool::AcquireStagingBuffer(const Resource* resource, | 590 OneCopyTileTaskWorkerPool::AcquireStagingBuffer(const Resource* resource, |
589 uint64_t previous_content_id) { | 591 uint64_t previous_content_id) { |
590 lock_.AssertAcquired(); | 592 lock_.AssertAcquired(); |
591 | 593 |
592 scoped_ptr<StagingBuffer> staging_buffer; | 594 scoped_ptr<StagingBuffer> staging_buffer; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 std::find_if(free_buffers_.begin(), free_buffers_.end(), | 642 std::find_if(free_buffers_.begin(), free_buffers_.end(), |
641 [previous_content_id](const StagingBuffer* buffer) { | 643 [previous_content_id](const StagingBuffer* buffer) { |
642 return buffer->content_id == previous_content_id; | 644 return buffer->content_id == previous_content_id; |
643 }); | 645 }); |
644 if (it != free_buffers_.end()) { | 646 if (it != free_buffers_.end()) { |
645 staging_buffer = free_buffers_.take(it); | 647 staging_buffer = free_buffers_.take(it); |
646 MarkStagingBufferAsBusy(staging_buffer.get()); | 648 MarkStagingBufferAsBusy(staging_buffer.get()); |
647 } | 649 } |
648 } | 650 } |
649 | 651 |
650 // Find staging buffer of correct size. | 652 // Find staging buffer of correct size and format. |
651 if (!staging_buffer) { | 653 if (!staging_buffer) { |
652 StagingBufferDeque::iterator it = | 654 StagingBufferDeque::iterator it = |
653 std::find_if(free_buffers_.begin(), free_buffers_.end(), | 655 std::find_if(free_buffers_.begin(), free_buffers_.end(), |
654 [resource](const StagingBuffer* buffer) { | 656 [resource](const StagingBuffer* buffer) { |
655 return buffer->size == resource->size(); | 657 return buffer->size == resource->size() && |
| 658 buffer->format == resource->format(); |
656 }); | 659 }); |
657 if (it != free_buffers_.end()) { | 660 if (it != free_buffers_.end()) { |
658 staging_buffer = free_buffers_.take(it); | 661 staging_buffer = free_buffers_.take(it); |
659 MarkStagingBufferAsBusy(staging_buffer.get()); | 662 MarkStagingBufferAsBusy(staging_buffer.get()); |
660 } | 663 } |
661 } | 664 } |
662 | 665 |
663 // Create new staging buffer if necessary. | 666 // Create new staging buffer if necessary. |
664 if (!staging_buffer) { | 667 if (!staging_buffer) { |
665 staging_buffer = make_scoped_ptr(new StagingBuffer(resource->size())); | 668 staging_buffer = make_scoped_ptr( |
666 AddStagingBuffer(staging_buffer.get()); | 669 new StagingBuffer(resource->size(), resource->format())); |
| 670 AddStagingBuffer(staging_buffer.get(), resource->format()); |
667 } | 671 } |
668 | 672 |
669 // Release enough free buffers to stay within the limit. | 673 // Release enough free buffers to stay within the limit. |
670 while (staging_buffer_usage_in_bytes_ > max_staging_buffer_usage_in_bytes_) { | 674 while (staging_buffer_usage_in_bytes_ > max_staging_buffer_usage_in_bytes_) { |
671 if (free_buffers_.empty()) | 675 if (free_buffers_.empty()) |
672 break; | 676 break; |
673 | 677 |
674 free_buffers_.front()->DestroyGLResources(gl); | 678 free_buffers_.front()->DestroyGLResources(gl); |
675 MarkStagingBufferAsBusy(free_buffers_.front()); | 679 MarkStagingBufferAsBusy(free_buffers_.front()); |
676 RemoveStagingBuffer(free_buffers_.front()); | 680 RemoveStagingBuffer(free_buffers_.front()); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 | 811 |
808 staging_state->SetInteger("staging_buffer_count", | 812 staging_state->SetInteger("staging_buffer_count", |
809 static_cast<int>(buffers_.size())); | 813 static_cast<int>(buffers_.size())); |
810 staging_state->SetInteger("busy_count", | 814 staging_state->SetInteger("busy_count", |
811 static_cast<int>(busy_buffers_.size())); | 815 static_cast<int>(busy_buffers_.size())); |
812 staging_state->SetInteger("free_count", | 816 staging_state->SetInteger("free_count", |
813 static_cast<int>(free_buffers_.size())); | 817 static_cast<int>(free_buffers_.size())); |
814 } | 818 } |
815 | 819 |
816 } // namespace cc | 820 } // namespace cc |
OLD | NEW |