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/resources/resource_provider.h" | 5 #include "cc/resources/resource_provider.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/atomic_sequence_num.h" | 10 #include "base/atomic_sequence_num.h" |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
317 | 317 |
318 ResourceProvider::Child::~Child() {} | 318 ResourceProvider::Child::~Child() {} |
319 | 319 |
320 scoped_ptr<ResourceProvider> ResourceProvider::Create( | 320 scoped_ptr<ResourceProvider> ResourceProvider::Create( |
321 OutputSurface* output_surface, | 321 OutputSurface* output_surface, |
322 SharedBitmapManager* shared_bitmap_manager, | 322 SharedBitmapManager* shared_bitmap_manager, |
323 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, | 323 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, |
324 BlockingTaskRunner* blocking_main_thread_task_runner, | 324 BlockingTaskRunner* blocking_main_thread_task_runner, |
325 int highp_threshold_min, | 325 int highp_threshold_min, |
326 size_t id_allocation_chunk_size, | 326 size_t id_allocation_chunk_size, |
327 bool use_gpu_memory_buffers_by_default, | |
327 const std::vector<unsigned>& use_image_texture_targets) { | 328 const std::vector<unsigned>& use_image_texture_targets) { |
328 scoped_ptr<ResourceProvider> resource_provider(new ResourceProvider( | 329 scoped_ptr<ResourceProvider> resource_provider(new ResourceProvider( |
329 output_surface, shared_bitmap_manager, gpu_memory_buffer_manager, | 330 output_surface, shared_bitmap_manager, gpu_memory_buffer_manager, |
330 blocking_main_thread_task_runner, highp_threshold_min, | 331 blocking_main_thread_task_runner, highp_threshold_min, |
331 id_allocation_chunk_size, use_image_texture_targets)); | 332 id_allocation_chunk_size, use_gpu_memory_buffers_by_default, |
333 use_image_texture_targets)); | |
332 resource_provider->Initialize(); | 334 resource_provider->Initialize(); |
333 return resource_provider; | 335 return resource_provider; |
334 } | 336 } |
335 | 337 |
336 ResourceProvider::~ResourceProvider() { | 338 ResourceProvider::~ResourceProvider() { |
337 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( | 339 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( |
338 this); | 340 this); |
339 | 341 |
340 while (!children_.empty()) | 342 while (!children_.empty()) |
341 DestroyChildInternal(children_.begin(), FOR_SHUTDOWN); | 343 DestroyChildInternal(children_.begin(), FOR_SHUTDOWN); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 DCHECK(resource); | 381 DCHECK(resource); |
380 resource->lost = true; | 382 resource->lost = true; |
381 } | 383 } |
382 | 384 |
383 ResourceId ResourceProvider::CreateResource(const gfx::Size& size, | 385 ResourceId ResourceProvider::CreateResource(const gfx::Size& size, |
384 TextureHint hint, | 386 TextureHint hint, |
385 ResourceFormat format) { | 387 ResourceFormat format) { |
386 DCHECK(!size.IsEmpty()); | 388 DCHECK(!size.IsEmpty()); |
387 switch (default_resource_type_) { | 389 switch (default_resource_type_) { |
388 case RESOURCE_TYPE_GL_TEXTURE: | 390 case RESOURCE_TYPE_GL_TEXTURE: |
389 return CreateGLTexture(size, | 391 return CreateGLTexture(size, use_gpu_memory_buffers_by_default_ |
390 GL_TEXTURE_2D, | 392 ? GetImageTextureTarget(format) |
391 hint, | 393 : GL_TEXTURE_2D, |
392 format); | 394 hint, format); |
393 case RESOURCE_TYPE_BITMAP: | 395 case RESOURCE_TYPE_BITMAP: |
394 DCHECK_EQ(RGBA_8888, format); | 396 DCHECK_EQ(RGBA_8888, format); |
395 return CreateBitmap(size); | 397 return CreateBitmap(size); |
396 } | 398 } |
397 | 399 |
398 LOG(FATAL) << "Invalid default resource type."; | 400 LOG(FATAL) << "Invalid default resource type."; |
399 return 0; | 401 return 0; |
400 } | 402 } |
401 | 403 |
402 ResourceId ResourceProvider::CreateResourceWithImageTextureTarget( | 404 ResourceId ResourceProvider::CreateResourceWithImageTextureTarget( |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
853 | 855 |
854 ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() { | 856 ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() { |
855 DCHECK(thread_checker_.CalledOnValidThread()); | 857 DCHECK(thread_checker_.CalledOnValidThread()); |
856 resource_provider_->UnlockForWrite(resource_); | 858 resource_provider_->UnlockForWrite(resource_); |
857 } | 859 } |
858 | 860 |
859 ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: | 861 ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: |
860 ScopedWriteLockGpuMemoryBuffer(ResourceProvider* resource_provider, | 862 ScopedWriteLockGpuMemoryBuffer(ResourceProvider* resource_provider, |
861 ResourceId resource_id) | 863 ResourceId resource_id) |
862 : resource_provider_(resource_provider), | 864 : resource_provider_(resource_provider), |
863 resource_(resource_provider->LockForWrite(resource_id)), | 865 resource_(resource_provider->LockForWrite(resource_id)) { |
864 gpu_memory_buffer_manager_(resource_provider->gpu_memory_buffer_manager_), | |
865 gpu_memory_buffer_(nullptr), | |
866 size_(resource_->size), | |
867 format_(resource_->format) { | |
868 DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource_->type); | 866 DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource_->type); |
869 std::swap(gpu_memory_buffer_, resource_->gpu_memory_buffer); | 867 gpu_memory_buffer_.reset(resource_->gpu_memory_buffer); |
868 resource_->gpu_memory_buffer = nullptr; | |
870 } | 869 } |
871 | 870 |
872 ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: | 871 ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: |
873 ~ScopedWriteLockGpuMemoryBuffer() { | 872 ~ScopedWriteLockGpuMemoryBuffer() { |
874 DCHECK(thread_checker_.CalledOnValidThread()); | 873 DCHECK(thread_checker_.CalledOnValidThread()); |
875 resource_provider_->UnlockForWrite(resource_); | 874 resource_provider_->UnlockForWrite(resource_); |
876 if (!gpu_memory_buffer_) | 875 if (!gpu_memory_buffer_) |
877 return; | 876 return; |
878 | 877 |
879 resource_provider_->LazyCreate(resource_); | 878 resource_provider_->SetGpuMemoryBuffer(resource_, gpu_memory_buffer_.Pass()); |
880 | |
881 if (!resource_->image_id) { | |
882 GLES2Interface* gl = resource_provider_->ContextGL(); | |
883 DCHECK(gl); | |
884 | |
885 #if defined(OS_CHROMEOS) | |
886 // TODO(reveman): GL_COMMANDS_ISSUED_CHROMIUM is used for synchronization | |
887 // on ChromeOS to avoid some performance issues. This only works with | |
888 // shared memory backed buffers. crbug.com/436314 | |
889 DCHECK_EQ(gpu_memory_buffer_->GetHandle().type, gfx::SHARED_MEMORY_BUFFER); | |
890 #endif | |
891 | |
892 resource_->image_id = gl->CreateImageCHROMIUM( | |
893 gpu_memory_buffer_->AsClientBuffer(), size_.width(), size_.height(), | |
894 GLInternalFormat(resource_->format)); | |
895 } | |
896 | |
897 std::swap(resource_->gpu_memory_buffer, gpu_memory_buffer_); | |
898 resource_->allocated = true; | |
899 resource_->dirty_image = true; | |
900 | 879 |
901 // GpuMemoryBuffer provides direct access to the memory used by the GPU. | 880 // GpuMemoryBuffer provides direct access to the memory used by the GPU. |
902 // Read lock fences are required to ensure that we're not trying to map a | 881 // Read lock fences are required to ensure that we're not trying to map a |
903 // buffer that is currently in-use by the GPU. | 882 // buffer that is currently in-use by the GPU. |
904 resource_->read_lock_fences_enabled = true; | 883 resource_->read_lock_fences_enabled = true; |
905 } | 884 } |
906 | 885 |
907 gfx::GpuMemoryBuffer* | 886 gfx::GpuMemoryBuffer* |
908 ResourceProvider::ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() { | 887 ResourceProvider::ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() { |
909 if (gpu_memory_buffer_) | 888 if (!gpu_memory_buffer_) { |
910 return gpu_memory_buffer_; | 889 gpu_memory_buffer_ = |
911 scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer = | 890 resource_provider_->gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( |
912 gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( | 891 resource_->size, BufferFormat(resource_->format), |
913 size_, BufferFormat(format_), | 892 gfx::BufferUsage::GPU_READ_CPU_READ_WRITE); |
914 gfx::BufferUsage::GPU_READ_CPU_READ_WRITE); | 893 } |
915 gpu_memory_buffer_ = gpu_memory_buffer.release(); | 894 return gpu_memory_buffer_.get(); |
916 return gpu_memory_buffer_; | |
917 } | 895 } |
918 | 896 |
919 ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr( | 897 ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr( |
920 ResourceProvider* resource_provider, | 898 ResourceProvider* resource_provider, |
921 ResourceId resource_id) | 899 ResourceId resource_id) |
922 : resource_provider_(resource_provider), | 900 : resource_provider_(resource_provider), |
923 resource_(resource_provider->LockForWrite(resource_id)) { | 901 resource_(resource_provider->LockForWrite(resource_id)) { |
924 DCHECK(thread_checker_.CalledOnValidThread()); | 902 DCHECK(thread_checker_.CalledOnValidThread()); |
925 resource_provider_->LazyAllocate(resource_); | 903 resource_provider_->LazyAllocate(resource_); |
926 } | 904 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
995 gl_->Finish(); | 973 gl_->Finish(); |
996 } | 974 } |
997 | 975 |
998 ResourceProvider::ResourceProvider( | 976 ResourceProvider::ResourceProvider( |
999 OutputSurface* output_surface, | 977 OutputSurface* output_surface, |
1000 SharedBitmapManager* shared_bitmap_manager, | 978 SharedBitmapManager* shared_bitmap_manager, |
1001 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, | 979 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, |
1002 BlockingTaskRunner* blocking_main_thread_task_runner, | 980 BlockingTaskRunner* blocking_main_thread_task_runner, |
1003 int highp_threshold_min, | 981 int highp_threshold_min, |
1004 size_t id_allocation_chunk_size, | 982 size_t id_allocation_chunk_size, |
983 bool use_gpu_memory_buffers_by_default, | |
1005 const std::vector<unsigned>& use_image_texture_targets) | 984 const std::vector<unsigned>& use_image_texture_targets) |
1006 : output_surface_(output_surface), | 985 : output_surface_(output_surface), |
1007 shared_bitmap_manager_(shared_bitmap_manager), | 986 shared_bitmap_manager_(shared_bitmap_manager), |
1008 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), | 987 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), |
1009 blocking_main_thread_task_runner_(blocking_main_thread_task_runner), | 988 blocking_main_thread_task_runner_(blocking_main_thread_task_runner), |
1010 lost_output_surface_(false), | 989 lost_output_surface_(false), |
1011 highp_threshold_min_(highp_threshold_min), | 990 highp_threshold_min_(highp_threshold_min), |
1012 next_id_(1), | 991 next_id_(1), |
1013 next_child_(1), | 992 next_child_(1), |
1014 default_resource_type_(RESOURCE_TYPE_BITMAP), | 993 default_resource_type_(RESOURCE_TYPE_BITMAP), |
994 use_gpu_memory_buffers_by_default_(use_gpu_memory_buffers_by_default), | |
1015 use_texture_storage_ext_(false), | 995 use_texture_storage_ext_(false), |
1016 use_texture_format_bgra_(false), | 996 use_texture_format_bgra_(false), |
1017 use_texture_usage_hint_(false), | 997 use_texture_usage_hint_(false), |
1018 use_compressed_texture_etc1_(false), | 998 use_compressed_texture_etc1_(false), |
1019 yuv_resource_format_(LUMINANCE_8), | 999 yuv_resource_format_(LUMINANCE_8), |
1020 max_texture_size_(0), | 1000 max_texture_size_(0), |
1021 best_texture_format_(RGBA_8888), | 1001 best_texture_format_(RGBA_8888), |
1022 best_render_buffer_format_(RGBA_8888), | 1002 best_render_buffer_format_(RGBA_8888), |
1023 id_allocation_chunk_size_(id_allocation_chunk_size), | 1003 id_allocation_chunk_size_(id_allocation_chunk_size), |
1024 use_sync_query_(false), | 1004 use_sync_query_(false), |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1302 resource->read_lock_fences_enabled = source->read_lock_fences_enabled; | 1282 resource->read_lock_fences_enabled = source->read_lock_fences_enabled; |
1303 resource->is_overlay_candidate = source->is_overlay_candidate; | 1283 resource->is_overlay_candidate = source->is_overlay_candidate; |
1304 | 1284 |
1305 if (source->type == RESOURCE_TYPE_BITMAP) { | 1285 if (source->type == RESOURCE_TYPE_BITMAP) { |
1306 resource->mailbox_holder.mailbox = source->shared_bitmap_id; | 1286 resource->mailbox_holder.mailbox = source->shared_bitmap_id; |
1307 resource->is_software = true; | 1287 resource->is_software = true; |
1308 } else if (!source->mailbox.IsValid()) { | 1288 } else if (!source->mailbox.IsValid()) { |
1309 LazyCreate(source); | 1289 LazyCreate(source); |
1310 DCHECK(source->gl_id); | 1290 DCHECK(source->gl_id); |
1311 DCHECK(source->origin == Resource::INTERNAL); | 1291 DCHECK(source->origin == Resource::INTERNAL); |
1312 if (source->image_id) { | 1292 if (source->image_id && source->dirty_image) { |
1313 DCHECK(source->dirty_image); | |
1314 gl->BindTexture(resource->mailbox_holder.texture_target, source->gl_id); | 1293 gl->BindTexture(resource->mailbox_holder.texture_target, source->gl_id); |
1315 BindImageForSampling(source); | 1294 BindImageForSampling(source); |
1316 } | 1295 } |
1317 // This is a resource allocated by the compositor, we need to produce it. | 1296 // This is a resource allocated by the compositor, we need to produce it. |
1318 // Don't set a sync point, the caller will do it. | 1297 // Don't set a sync point, the caller will do it. |
1319 gl->GenMailboxCHROMIUM(resource->mailbox_holder.mailbox.name); | 1298 gl->GenMailboxCHROMIUM(resource->mailbox_holder.mailbox.name); |
1320 gl->ProduceTextureDirectCHROMIUM(source->gl_id, | 1299 gl->ProduceTextureDirectCHROMIUM(source->gl_id, |
1321 resource->mailbox_holder.texture_target, | 1300 resource->mailbox_holder.texture_target, |
1322 resource->mailbox_holder.mailbox.name); | 1301 resource->mailbox_holder.mailbox.name); |
1323 | 1302 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1508 if (resource->allocated) | 1487 if (resource->allocated) |
1509 return; | 1488 return; |
1510 LazyCreate(resource); | 1489 LazyCreate(resource); |
1511 if (!resource->gl_id) | 1490 if (!resource->gl_id) |
1512 return; | 1491 return; |
1513 resource->allocated = true; | 1492 resource->allocated = true; |
1514 GLES2Interface* gl = ContextGL(); | 1493 GLES2Interface* gl = ContextGL(); |
1515 gfx::Size& size = resource->size; | 1494 gfx::Size& size = resource->size; |
1516 ResourceFormat format = resource->format; | 1495 ResourceFormat format = resource->format; |
1517 gl->BindTexture(resource->target, resource->gl_id); | 1496 gl->BindTexture(resource->target, resource->gl_id); |
1518 if (use_texture_storage_ext_ && | 1497 if (use_gpu_memory_buffers_by_default_) { |
1519 IsFormatSupportedForStorage(format, use_texture_format_bgra_) && | 1498 SetGpuMemoryBuffer( |
1520 (resource->hint & TEXTURE_HINT_IMMUTABLE)) { | 1499 resource, gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( |
1500 size, BufferFormat(format), gfx::BufferUsage::SCANOUT)); | |
1501 BindImageForSampling(resource); | |
reveman
2015/11/02 17:28:53
Why is this BindImageForSampling call needed?
ccameron
2015/11/02 22:07:34
This can be moved to the ScopedWriteLockGL this to
| |
1502 } else if (use_texture_storage_ext_ && | |
1503 IsFormatSupportedForStorage(format, use_texture_format_bgra_) && | |
1504 (resource->hint & TEXTURE_HINT_IMMUTABLE)) { | |
1521 GLenum storage_format = TextureToStorageFormat(format); | 1505 GLenum storage_format = TextureToStorageFormat(format); |
1522 gl->TexStorage2DEXT(resource->target, 1, storage_format, size.width(), | 1506 gl->TexStorage2DEXT(resource->target, 1, storage_format, size.width(), |
1523 size.height()); | 1507 size.height()); |
1524 } else { | 1508 } else { |
1525 // ETC1 does not support preallocation. | 1509 // ETC1 does not support preallocation. |
1526 if (format != ETC1) { | 1510 if (format != ETC1) { |
1527 gl->TexImage2D(resource->target, 0, GLInternalFormat(format), | 1511 gl->TexImage2D(resource->target, 0, GLInternalFormat(format), |
1528 size.width(), size.height(), 0, GLDataFormat(format), | 1512 size.width(), size.height(), 0, GLDataFormat(format), |
1529 GLDataType(format), NULL); | 1513 GLDataType(format), NULL); |
1530 } | 1514 } |
1531 } | 1515 } |
1532 } | 1516 } |
1533 | 1517 |
1518 void ResourceProvider::SetGpuMemoryBuffer( | |
reveman
2015/11/02 17:28:53
hm, this function is marking the image as dirty an
ccameron
2015/11/02 22:07:34
Sounds better --done.
| |
1519 Resource* resource, | |
1520 scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer) { | |
1521 DCHECK(!resource->gpu_memory_buffer); | |
reveman
2015/11/02 17:28:53
can these 3 lines just become DCHECK(resource->gpu
ccameron
2015/11/02 22:07:34
Yeah, this becomes much simpler this way.
| |
1522 if (!gpu_memory_buffer) | |
1523 return; | |
1524 | |
1525 LazyCreate(resource); | |
reveman
2015/11/02 17:28:53
I think this should be moved out of this function
ccameron
2015/11/02 22:07:34
Sg. Added a LazyCreate to the ~ScopedWriteLockGpuM
| |
1526 | |
1527 if (!resource->image_id) { | |
1528 GLES2Interface* gl = ContextGL(); | |
1529 DCHECK(gl); | |
1530 | |
1531 #if defined(OS_CHROMEOS) | |
1532 // TODO(reveman): GL_COMMANDS_ISSUED_CHROMIUM is used for synchronization | |
1533 // on ChromeOS to avoid some performance issues. This only works with | |
1534 // shared memory backed buffers. crbug.com/436314 | |
1535 DCHECK_EQ(gpu_memory_buffer->GetHandle().type, gfx::SHARED_MEMORY_BUFFER); | |
1536 #endif | |
1537 resource->image_id = gl->CreateImageCHROMIUM( | |
1538 gpu_memory_buffer->AsClientBuffer(), resource->size.width(), | |
1539 resource->size.height(), GLInternalFormat(resource->format)); | |
1540 } | |
1541 | |
1542 resource->gpu_memory_buffer = gpu_memory_buffer.release(); | |
1543 resource->allocated = true; | |
reveman
2015/11/02 17:28:53
hm, this should not be set here as that means sett
ccameron
2015/11/02 22:07:34
Moved up to the caller and added a DCHECK for it.
| |
1544 resource->dirty_image = true; | |
1545 resource->is_overlay_candidate = true; | |
reveman
2015/11/02 17:28:53
might be better to set this by the code that alloc
ccameron
2015/11/02 22:07:34
Done.
| |
1546 } | |
1547 | |
1534 void ResourceProvider::BindImageForSampling(Resource* resource) { | 1548 void ResourceProvider::BindImageForSampling(Resource* resource) { |
1535 GLES2Interface* gl = ContextGL(); | 1549 GLES2Interface* gl = ContextGL(); |
1536 DCHECK(resource->gl_id); | 1550 DCHECK(resource->gl_id); |
1537 DCHECK(resource->image_id); | 1551 DCHECK(resource->image_id); |
1538 | 1552 |
1539 // Release image currently bound to texture. | 1553 // Release image currently bound to texture. |
1540 if (resource->bound_image_id) | 1554 if (resource->bound_image_id) |
1541 gl->ReleaseTexImage2DCHROMIUM(resource->target, resource->bound_image_id); | 1555 gl->ReleaseTexImage2DCHROMIUM(resource->target, resource->bound_image_id); |
1542 gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id); | 1556 gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id); |
1543 resource->bound_image_id = resource->image_id; | 1557 resource->bound_image_id = resource->image_id; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1637 const int kImportance = 2; | 1651 const int kImportance = 2; |
1638 pmd->CreateSharedGlobalAllocatorDump(guid); | 1652 pmd->CreateSharedGlobalAllocatorDump(guid); |
1639 pmd->AddOwnershipEdge(dump->guid(), guid, kImportance); | 1653 pmd->AddOwnershipEdge(dump->guid(), guid, kImportance); |
1640 } | 1654 } |
1641 } | 1655 } |
1642 | 1656 |
1643 return true; | 1657 return true; |
1644 } | 1658 } |
1645 | 1659 |
1646 } // namespace cc | 1660 } // namespace cc |
OLD | NEW |