| 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/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 } | 79 } |
| 80 | 80 |
| 81 private: | 81 private: |
| 82 WebGraphicsContext3D* context3d_; | 82 WebGraphicsContext3D* context3d_; |
| 83 GLenum unit_; | 83 GLenum unit_; |
| 84 }; | 84 }; |
| 85 | 85 |
| 86 } // namespace | 86 } // namespace |
| 87 | 87 |
| 88 ResourceProvider::Resource::Resource() | 88 ResourceProvider::Resource::Resource() |
| 89 : gl_id(0), | 89 : child_id(0), |
| 90 gl_id(0), |
| 90 gl_pixel_buffer_id(0), | 91 gl_pixel_buffer_id(0), |
| 91 gl_upload_query_id(0), | 92 gl_upload_query_id(0), |
| 92 pixels(NULL), | 93 pixels(NULL), |
| 93 pixel_buffer(NULL), | 94 pixel_buffer(NULL), |
| 94 lock_for_read_count(0), | 95 lock_for_read_count(0), |
| 95 imported_count(0), | 96 imported_count(0), |
| 96 exported_count(0), | 97 exported_count(0), |
| 97 locked_for_write(false), | 98 locked_for_write(false), |
| 98 external(false), | 99 external(false), |
| 99 marked_for_deletion(false), | 100 marked_for_deletion(false), |
| 100 pending_set_pixels(false), | 101 pending_set_pixels(false), |
| 101 set_pixels_completion_forced(false), | 102 set_pixels_completion_forced(false), |
| 102 allocated(false), | 103 allocated(false), |
| 103 enable_read_lock_fences(false), | 104 enable_read_lock_fences(false), |
| 104 read_lock_fence(NULL), | 105 read_lock_fence(NULL), |
| 105 size(), | 106 size(), |
| 106 original_filter(0), | 107 original_filter(0), |
| 107 filter(0), | 108 filter(0), |
| 108 target(0), | 109 target(0), |
| 109 image_id(0), | 110 image_id(0), |
| 110 texture_pool(0), | 111 texture_pool(0), |
| 111 wrap_mode(0), | 112 wrap_mode(0), |
| 112 hint(TextureUsageAny), | 113 hint(TextureUsageAny), |
| 113 type(static_cast<ResourceType>(0)), | 114 type(static_cast<ResourceType>(0)), |
| 114 format(RGBA_8888) {} | 115 format(RGBA_8888) {} |
| 115 | 116 |
| 116 ResourceProvider::Resource::~Resource() {} | 117 ResourceProvider::Resource::~Resource() {} |
| 117 | 118 |
| 118 ResourceProvider::Resource::Resource( | 119 ResourceProvider::Resource::Resource(unsigned texture_id, |
| 119 unsigned texture_id, | 120 gfx::Size size, |
| 120 gfx::Size size, | 121 GLenum filter, |
| 121 GLenum filter, | 122 GLenum texture_pool, |
| 122 GLenum texture_pool, | 123 GLint wrap_mode, |
| 123 GLint wrap_mode, | 124 TextureUsageHint hint, |
| 124 TextureUsageHint hint, | 125 ResourceFormat format) |
| 125 ResourceFormat format) | 126 : child_id(0), |
| 126 : gl_id(texture_id), | 127 gl_id(texture_id), |
| 127 gl_pixel_buffer_id(0), | 128 gl_pixel_buffer_id(0), |
| 128 gl_upload_query_id(0), | 129 gl_upload_query_id(0), |
| 129 pixels(NULL), | 130 pixels(NULL), |
| 130 pixel_buffer(NULL), | 131 pixel_buffer(NULL), |
| 131 lock_for_read_count(0), | 132 lock_for_read_count(0), |
| 132 imported_count(0), | 133 imported_count(0), |
| 133 exported_count(0), | 134 exported_count(0), |
| 134 locked_for_write(false), | 135 locked_for_write(false), |
| 135 external(false), | 136 external(false), |
| 136 marked_for_deletion(false), | 137 marked_for_deletion(false), |
| 137 pending_set_pixels(false), | 138 pending_set_pixels(false), |
| 138 set_pixels_completion_forced(false), | 139 set_pixels_completion_forced(false), |
| 139 allocated(false), | 140 allocated(false), |
| 140 enable_read_lock_fences(false), | 141 enable_read_lock_fences(false), |
| 141 read_lock_fence(NULL), | 142 read_lock_fence(NULL), |
| 142 size(size), | 143 size(size), |
| 143 original_filter(filter), | 144 original_filter(filter), |
| 144 filter(filter), | 145 filter(filter), |
| 145 target(0), | 146 target(0), |
| 146 image_id(0), | 147 image_id(0), |
| 147 texture_pool(texture_pool), | 148 texture_pool(texture_pool), |
| 148 wrap_mode(wrap_mode), | 149 wrap_mode(wrap_mode), |
| 149 hint(hint), | 150 hint(hint), |
| 150 type(GLTexture), | 151 type(GLTexture), |
| 151 format(format) { | 152 format(format) { |
| 152 DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT); | 153 DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT); |
| 153 } | 154 } |
| 154 | 155 |
| 155 ResourceProvider::Resource::Resource( | 156 ResourceProvider::Resource::Resource(uint8_t* pixels, |
| 156 uint8_t* pixels, | 157 gfx::Size size, |
| 157 gfx::Size size, | 158 GLenum filter, |
| 158 GLenum filter, | 159 GLint wrap_mode) |
| 159 GLint wrap_mode) | 160 : child_id(0), |
| 160 : gl_id(0), | 161 gl_id(0), |
| 161 gl_pixel_buffer_id(0), | 162 gl_pixel_buffer_id(0), |
| 162 gl_upload_query_id(0), | 163 gl_upload_query_id(0), |
| 163 pixels(pixels), | 164 pixels(pixels), |
| 164 pixel_buffer(NULL), | 165 pixel_buffer(NULL), |
| 165 lock_for_read_count(0), | 166 lock_for_read_count(0), |
| 166 imported_count(0), | 167 imported_count(0), |
| 167 exported_count(0), | 168 exported_count(0), |
| 168 locked_for_write(false), | 169 locked_for_write(false), |
| 169 external(false), | 170 external(false), |
| 170 marked_for_deletion(false), | 171 marked_for_deletion(false), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 } | 209 } |
| 209 | 210 |
| 210 if (!success) | 211 if (!success) |
| 211 return scoped_ptr<ResourceProvider>(); | 212 return scoped_ptr<ResourceProvider>(); |
| 212 | 213 |
| 213 DCHECK_NE(InvalidType, resource_provider->default_resource_type()); | 214 DCHECK_NE(InvalidType, resource_provider->default_resource_type()); |
| 214 return resource_provider.Pass(); | 215 return resource_provider.Pass(); |
| 215 } | 216 } |
| 216 | 217 |
| 217 ResourceProvider::~ResourceProvider() { | 218 ResourceProvider::~ResourceProvider() { |
| 219 while (!children_.empty()) |
| 220 DestroyChild(children_.begin()->first); |
| 218 while (!resources_.empty()) | 221 while (!resources_.empty()) |
| 219 DeleteResourceInternal(resources_.begin(), ForShutdown); | 222 DeleteResourceInternal(resources_.begin(), ForShutdown); |
| 220 | 223 |
| 221 CleanUpGLIfNeeded(); | 224 CleanUpGLIfNeeded(); |
| 222 } | 225 } |
| 223 | 226 |
| 224 bool ResourceProvider::InUseByConsumer(ResourceId id) { | 227 bool ResourceProvider::InUseByConsumer(ResourceId id) { |
| 225 Resource* resource = GetResource(id); | 228 Resource* resource = GetResource(id); |
| 226 return resource->lock_for_read_count > 0 || resource->exported_count > 0; | 229 return resource->lock_for_read_count > 0 || resource->exported_count > 0; |
| 227 } | 230 } |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 DCHECK(!texture_uploader_); | 806 DCHECK(!texture_uploader_); |
| 804 return; | 807 return; |
| 805 } | 808 } |
| 806 | 809 |
| 807 DCHECK(context3d); | 810 DCHECK(context3d); |
| 808 context3d->makeContextCurrent(); | 811 context3d->makeContextCurrent(); |
| 809 texture_uploader_.reset(); | 812 texture_uploader_.reset(); |
| 810 Finish(); | 813 Finish(); |
| 811 } | 814 } |
| 812 | 815 |
| 813 int ResourceProvider::CreateChild() { | 816 int ResourceProvider::CreateChild(const ReturnCallback& return_callback) { |
| 814 DCHECK(thread_checker_.CalledOnValidThread()); | 817 DCHECK(thread_checker_.CalledOnValidThread()); |
| 818 |
| 815 Child child_info; | 819 Child child_info; |
| 820 child_info.return_callback = return_callback; |
| 821 |
| 816 int child = next_child_++; | 822 int child = next_child_++; |
| 817 children_[child] = child_info; | 823 children_[child] = child_info; |
| 818 return child; | 824 return child; |
| 819 } | 825 } |
| 820 | 826 |
| 821 void ResourceProvider::DestroyChild(int child_id) { | 827 void ResourceProvider::DestroyChild(int child_id) { |
| 822 DCHECK(thread_checker_.CalledOnValidThread()); | 828 DCHECK(thread_checker_.CalledOnValidThread()); |
| 829 |
| 823 ChildMap::iterator it = children_.find(child_id); | 830 ChildMap::iterator it = children_.find(child_id); |
| 824 DCHECK(it != children_.end()); | 831 DCHECK(it != children_.end()); |
| 825 Child& child = it->second; | 832 Child& child = it->second; |
| 833 |
| 834 ResourceIdArray resources_for_child; |
| 835 |
| 826 for (ResourceIdMap::iterator child_it = child.child_to_parent_map.begin(); | 836 for (ResourceIdMap::iterator child_it = child.child_to_parent_map.begin(); |
| 827 child_it != child.child_to_parent_map.end(); | 837 child_it != child.child_to_parent_map.end(); |
| 828 ++child_it) { | 838 ++child_it) { |
| 829 ResourceId id = child_it->second; | 839 ResourceId id = child_it->second; |
| 830 // We're abandoning this resource, it will not get recycled. | 840 resources_for_child.push_back(id); |
| 831 // crbug.com/224062 | |
| 832 ResourceMap::iterator resource_it = resources_.find(id); | |
| 833 CHECK(resource_it != resources_.end()); | |
| 834 resource_it->second.imported_count = 0; | |
| 835 DeleteResource(id); | |
| 836 } | 841 } |
| 842 |
| 843 // If the child is going away, don't consider any resources in use. |
| 844 child.in_use_resources.clear(); |
| 845 |
| 846 DeleteAndReturnUnusedResourcesToChild( |
| 847 &child, ForShutdown, resources_for_child); |
| 848 |
| 837 children_.erase(it); | 849 children_.erase(it); |
| 838 } | 850 } |
| 839 | 851 |
| 840 const ResourceProvider::ResourceIdMap& ResourceProvider::GetChildToParentMap( | 852 const ResourceProvider::ResourceIdMap& ResourceProvider::GetChildToParentMap( |
| 841 int child) const { | 853 int child) const { |
| 842 DCHECK(thread_checker_.CalledOnValidThread()); | 854 DCHECK(thread_checker_.CalledOnValidThread()); |
| 843 ChildMap::const_iterator it = children_.find(child); | 855 ChildMap::const_iterator it = children_.find(child); |
| 844 DCHECK(it != children_.end()); | 856 DCHECK(it != children_.end()); |
| 845 return it->second.child_to_parent_map; | 857 return it->second.child_to_parent_map; |
| 846 } | 858 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 868 unsigned int sync_point = context3d->insertSyncPoint(); | 880 unsigned int sync_point = context3d->insertSyncPoint(); |
| 869 for (TransferableResourceArray::iterator it = list->begin(); | 881 for (TransferableResourceArray::iterator it = list->begin(); |
| 870 it != list->end(); | 882 it != list->end(); |
| 871 ++it) { | 883 ++it) { |
| 872 if (!it->sync_point) | 884 if (!it->sync_point) |
| 873 it->sync_point = sync_point; | 885 it->sync_point = sync_point; |
| 874 } | 886 } |
| 875 } | 887 } |
| 876 } | 888 } |
| 877 | 889 |
| 878 void ResourceProvider::PrepareSendReturnsToChild( | |
| 879 int child, | |
| 880 const ResourceIdArray& resources, | |
| 881 ReturnedResourceArray* list) { | |
| 882 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 883 WebGraphicsContext3D* context3d = Context3d(); | |
| 884 if (!context3d || !context3d->makeContextCurrent()) { | |
| 885 // TODO(skaslev): Implement this path for software compositing. | |
| 886 return; | |
| 887 } | |
| 888 Child& child_info = children_.find(child)->second; | |
| 889 bool need_sync_point = false; | |
| 890 for (ResourceIdArray::const_iterator it = resources.begin(); | |
| 891 it != resources.end(); ++it) { | |
| 892 Resource* resource = GetResource(*it); | |
| 893 DCHECK(!resource->locked_for_write); | |
| 894 DCHECK(!resource->lock_for_read_count); | |
| 895 DCHECK(child_info.parent_to_child_map.find(*it) != | |
| 896 child_info.parent_to_child_map.end()); | |
| 897 | |
| 898 if (resource->filter != resource->original_filter) { | |
| 899 DCHECK(resource->target); | |
| 900 DCHECK(resource->gl_id); | |
| 901 | |
| 902 GLC(context3d, context3d->bindTexture(resource->target, resource->gl_id)); | |
| 903 GLC(context3d, context3d->texParameteri(resource->target, | |
| 904 GL_TEXTURE_MIN_FILTER, | |
| 905 resource->original_filter)); | |
| 906 GLC(context3d, context3d->texParameteri(resource->target, | |
| 907 GL_TEXTURE_MAG_FILTER, | |
| 908 resource->original_filter)); | |
| 909 } | |
| 910 | |
| 911 ReturnedResource returned; | |
| 912 returned.id = child_info.parent_to_child_map[*it]; | |
| 913 returned.sync_point = resource->mailbox.sync_point(); | |
| 914 if (!returned.sync_point) | |
| 915 need_sync_point = true; | |
| 916 returned.count = resource->imported_count; | |
| 917 list->push_back(returned); | |
| 918 | |
| 919 child_info.parent_to_child_map.erase(*it); | |
| 920 child_info.child_to_parent_map.erase(returned.id); | |
| 921 resources_[*it].imported_count = 0; | |
| 922 DeleteResource(*it); | |
| 923 } | |
| 924 if (need_sync_point) { | |
| 925 unsigned int sync_point = context3d->insertSyncPoint(); | |
| 926 for (ReturnedResourceArray::iterator it = list->begin(); | |
| 927 it != list->end(); ++it) { | |
| 928 if (!it->sync_point) | |
| 929 it->sync_point = sync_point; | |
| 930 } | |
| 931 } | |
| 932 } | |
| 933 | |
| 934 void ResourceProvider::ReceiveFromChild( | 890 void ResourceProvider::ReceiveFromChild( |
| 935 int child, const TransferableResourceArray& resources) { | 891 int child, const TransferableResourceArray& resources) { |
| 936 DCHECK(thread_checker_.CalledOnValidThread()); | 892 DCHECK(thread_checker_.CalledOnValidThread()); |
| 937 WebGraphicsContext3D* context3d = Context3d(); | 893 WebGraphicsContext3D* context3d = Context3d(); |
| 938 if (!context3d || !context3d->makeContextCurrent()) { | 894 if (!context3d || !context3d->makeContextCurrent()) { |
| 939 // TODO(skaslev): Implement this path for software compositing. | 895 // TODO(skaslev): Implement this path for software compositing. |
| 940 return; | 896 return; |
| 941 } | 897 } |
| 942 Child& child_info = children_.find(child)->second; | 898 Child& child_info = children_.find(child)->second; |
| 943 for (TransferableResourceArray::const_iterator it = resources.begin(); | 899 for (TransferableResourceArray::const_iterator it = resources.begin(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 955 // deadlocks and/or security issues. The caller is responsible for | 911 // deadlocks and/or security issues. The caller is responsible for |
| 956 // waiting asynchronously, and resetting sync_point before calling this. | 912 // waiting asynchronously, and resetting sync_point before calling this. |
| 957 // However if the parent is a renderer (e.g. browser tag), it may be ok | 913 // However if the parent is a renderer (e.g. browser tag), it may be ok |
| 958 // (and is simpler) to wait. | 914 // (and is simpler) to wait. |
| 959 if (it->sync_point) | 915 if (it->sync_point) |
| 960 GLC(context3d, context3d->waitSyncPoint(it->sync_point)); | 916 GLC(context3d, context3d->waitSyncPoint(it->sync_point)); |
| 961 GLC(context3d, texture_id = context3d->createTexture()); | 917 GLC(context3d, texture_id = context3d->createTexture()); |
| 962 GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, texture_id)); | 918 GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, texture_id)); |
| 963 GLC(context3d, context3d->consumeTextureCHROMIUM(GL_TEXTURE_2D, | 919 GLC(context3d, context3d->consumeTextureCHROMIUM(GL_TEXTURE_2D, |
| 964 it->mailbox.name)); | 920 it->mailbox.name)); |
| 965 | 921 ResourceId local_id = next_id_++; |
| 966 ResourceId id = next_id_++; | 922 Resource resource(texture_id, |
| 967 Resource resource( | 923 it->size, |
| 968 texture_id, | 924 it->filter, |
| 969 it->size, | 925 0, |
| 970 it->filter, | 926 GL_CLAMP_TO_EDGE, |
| 971 0, | 927 TextureUsageAny, |
| 972 GL_CLAMP_TO_EDGE, | 928 it->format); |
| 973 TextureUsageAny, | |
| 974 it->format); | |
| 975 resource.mailbox.SetName(it->mailbox); | 929 resource.mailbox.SetName(it->mailbox); |
| 930 resource.child_id = child; |
| 976 // Don't allocate a texture for a child. | 931 // Don't allocate a texture for a child. |
| 977 resource.allocated = true; | 932 resource.allocated = true; |
| 978 resource.imported_count = 1; | 933 resource.imported_count = 1; |
| 979 resources_[id] = resource; | 934 resources_[local_id] = resource; |
| 980 child_info.parent_to_child_map[id] = it->id; | 935 child_info.parent_to_child_map[local_id] = it->id; |
| 981 child_info.child_to_parent_map[it->id] = id; | 936 child_info.child_to_parent_map[it->id] = local_id; |
| 982 } | 937 } |
| 983 } | 938 } |
| 984 | 939 |
| 940 void ResourceProvider::DeclareUsedResourcesFromChild( |
| 941 int child, |
| 942 const ResourceIdArray& resources_from_child) { |
| 943 DCHECK(thread_checker_.CalledOnValidThread()); |
| 944 |
| 945 Child& child_info = children_.find(child)->second; |
| 946 child_info.in_use_resources.clear(); |
| 947 |
| 948 for (size_t i = 0; i < resources_from_child.size(); ++i) { |
| 949 ResourceIdMap::iterator it = |
| 950 child_info.child_to_parent_map.find(resources_from_child[i]); |
| 951 DCHECK(it != child_info.child_to_parent_map.end()); |
| 952 |
| 953 ResourceId local_id = it->second; |
| 954 child_info.in_use_resources.insert(local_id); |
| 955 } |
| 956 |
| 957 ResourceIdArray unused; |
| 958 for (ResourceIdMap::iterator it = child_info.child_to_parent_map.begin(); |
| 959 it != child_info.child_to_parent_map.end(); |
| 960 ++it) { |
| 961 ResourceId local_id = it->second; |
| 962 bool resource_is_in_use = child_info.in_use_resources.count(local_id) > 0; |
| 963 if (!resource_is_in_use) |
| 964 unused.push_back(local_id); |
| 965 } |
| 966 DeleteAndReturnUnusedResourcesToChild(&child_info, Normal, unused); |
| 967 } |
| 968 |
| 969 // static |
| 970 bool ResourceProvider::CompareResourceMapIteratorsByChildId( |
| 971 const std::pair<ReturnedResource, ResourceMap::iterator>& a, |
| 972 const std::pair<ReturnedResource, ResourceMap::iterator>& b) { |
| 973 const ResourceMap::iterator& a_it = a.second; |
| 974 const ResourceMap::iterator& b_it = b.second; |
| 975 const Resource& a_resource = a_it->second; |
| 976 const Resource& b_resource = b_it->second; |
| 977 return a_resource.child_id < b_resource.child_id; |
| 978 } |
| 979 |
| 985 void ResourceProvider::ReceiveReturnsFromParent( | 980 void ResourceProvider::ReceiveReturnsFromParent( |
| 986 const ReturnedResourceArray& resources) { | 981 const ReturnedResourceArray& resources) { |
| 987 DCHECK(thread_checker_.CalledOnValidThread()); | 982 DCHECK(thread_checker_.CalledOnValidThread()); |
| 988 WebGraphicsContext3D* context3d = Context3d(); | 983 WebGraphicsContext3D* context3d = Context3d(); |
| 989 if (!context3d || !context3d->makeContextCurrent()) { | 984 if (!context3d || !context3d->makeContextCurrent()) { |
| 990 // TODO(skaslev): Implement this path for software compositing. | 985 // TODO(skaslev): Implement this path for software compositing. |
| 991 return; | 986 return; |
| 992 } | 987 } |
| 988 |
| 989 int child_id = 0; |
| 990 Child* child_info = NULL; |
| 991 ResourceIdArray resources_for_child; |
| 992 |
| 993 std::vector<std::pair<ReturnedResource, ResourceMap::iterator> > |
| 994 sorted_resources; |
| 995 |
| 993 for (ReturnedResourceArray::const_iterator it = resources.begin(); | 996 for (ReturnedResourceArray::const_iterator it = resources.begin(); |
| 994 it != resources.end(); | 997 it != resources.end(); |
| 995 ++it) { | 998 ++it) { |
| 996 ResourceMap::iterator map_iterator = resources_.find(it->id); | 999 ResourceId local_id = it->id; |
| 997 DCHECK(map_iterator != resources_.end()); | 1000 ResourceMap::iterator map_iterator = resources_.find(local_id); |
| 1001 |
| 1002 // Resource was already lost (e.g. it belonged to a child that was |
| 1003 // destroyed). |
| 1004 if (map_iterator == resources_.end()) |
| 1005 continue; |
| 1006 |
| 1007 sorted_resources.push_back( |
| 1008 std::pair<ReturnedResource, ResourceMap::iterator>(*it, map_iterator)); |
| 1009 } |
| 1010 |
| 1011 std::sort(sorted_resources.begin(), |
| 1012 sorted_resources.end(), |
| 1013 CompareResourceMapIteratorsByChildId); |
| 1014 |
| 1015 for (size_t i = 0; i < sorted_resources.size(); ++i) { |
| 1016 ReturnedResource& returned = sorted_resources[i].first; |
| 1017 ResourceMap::iterator& map_iterator = sorted_resources[i].second; |
| 1018 ResourceId local_id = map_iterator->first; |
| 998 Resource* resource = &map_iterator->second; | 1019 Resource* resource = &map_iterator->second; |
| 999 CHECK_GE(resource->exported_count, it->count); | 1020 |
| 1000 resource->exported_count -= it->count; | 1021 CHECK_GE(resource->exported_count, returned.count); |
| 1022 resource->exported_count -= returned.count; |
| 1001 if (resource->exported_count) | 1023 if (resource->exported_count) |
| 1002 continue; | 1024 continue; |
| 1025 |
| 1003 if (resource->gl_id) { | 1026 if (resource->gl_id) { |
| 1004 if (it->sync_point) | 1027 if (returned.sync_point) |
| 1005 GLC(context3d, context3d->waitSyncPoint(it->sync_point)); | 1028 GLC(context3d, context3d->waitSyncPoint(returned.sync_point)); |
| 1006 } else { | 1029 } else { |
| 1007 resource->mailbox = | 1030 resource->mailbox = |
| 1008 TextureMailbox(resource->mailbox.name(), it->sync_point); | 1031 TextureMailbox(resource->mailbox.name(), returned.sync_point); |
| 1009 } | 1032 } |
| 1010 if (resource->marked_for_deletion) | 1033 |
| 1034 if (!resource->marked_for_deletion) |
| 1035 continue; |
| 1036 |
| 1037 if (!resource->child_id) { |
| 1038 // The resource belongs to this ResourceProvider, so it can be destroyed. |
| 1011 DeleteResourceInternal(map_iterator, Normal); | 1039 DeleteResourceInternal(map_iterator, Normal); |
| 1040 continue; |
| 1041 } |
| 1042 |
| 1043 // Delete the resource and return it to the child it came from one. |
| 1044 if (resource->child_id != child_id) { |
| 1045 ChildMap::iterator child_it = children_.find(resource->child_id); |
| 1046 DCHECK(child_it != children_.end()); |
| 1047 |
| 1048 if (child_id) { |
| 1049 DCHECK_NE(resources_for_child.size(), 0u); |
| 1050 DeleteAndReturnUnusedResourcesToChild( |
| 1051 child_info, Normal, resources_for_child); |
| 1052 resources_for_child.clear(); |
| 1053 } |
| 1054 |
| 1055 child_info = &child_it->second; |
| 1056 child_id = resource->child_id; |
| 1057 } |
| 1058 resources_for_child.push_back(local_id); |
| 1059 } |
| 1060 |
| 1061 if (child_id) { |
| 1062 DCHECK_NE(resources_for_child.size(), 0u); |
| 1063 DeleteAndReturnUnusedResourcesToChild( |
| 1064 child_info, Normal, resources_for_child); |
| 1012 } | 1065 } |
| 1013 } | 1066 } |
| 1014 | 1067 |
| 1015 void ResourceProvider::TransferResource(WebGraphicsContext3D* context, | 1068 void ResourceProvider::TransferResource(WebGraphicsContext3D* context, |
| 1016 ResourceId id, | 1069 ResourceId id, |
| 1017 TransferableResource* resource) { | 1070 TransferableResource* resource) { |
| 1018 Resource* source = GetResource(id); | 1071 Resource* source = GetResource(id); |
| 1019 DCHECK(!source->locked_for_write); | 1072 DCHECK(!source->locked_for_write); |
| 1020 DCHECK(!source->lock_for_read_count); | 1073 DCHECK(!source->lock_for_read_count); |
| 1021 DCHECK(!source->external || (source->external && source->mailbox.IsValid())); | 1074 DCHECK(!source->external || (source->external && source->mailbox.IsValid())); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1039 source->mailbox.SetName(resource->mailbox); | 1092 source->mailbox.SetName(resource->mailbox); |
| 1040 } else { | 1093 } else { |
| 1041 // This is either an external resource, or a compositor resource that we | 1094 // This is either an external resource, or a compositor resource that we |
| 1042 // already exported. Make sure to forward the sync point that we were given. | 1095 // already exported. Make sure to forward the sync point that we were given. |
| 1043 resource->mailbox = source->mailbox.name(); | 1096 resource->mailbox = source->mailbox.name(); |
| 1044 resource->sync_point = source->mailbox.sync_point(); | 1097 resource->sync_point = source->mailbox.sync_point(); |
| 1045 source->mailbox.ResetSyncPoint(); | 1098 source->mailbox.ResetSyncPoint(); |
| 1046 } | 1099 } |
| 1047 } | 1100 } |
| 1048 | 1101 |
| 1102 void ResourceProvider::DeleteAndReturnUnusedResourcesToChild( |
| 1103 Child* child_info, |
| 1104 DeleteStyle style, |
| 1105 const ResourceIdArray& unused) { |
| 1106 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1107 DCHECK(child_info); |
| 1108 |
| 1109 if (unused.empty()) |
| 1110 return; |
| 1111 |
| 1112 WebGraphicsContext3D* context3d = Context3d(); |
| 1113 if (!context3d || !context3d->makeContextCurrent()) { |
| 1114 // TODO(skaslev): Implement this path for software compositing. |
| 1115 return; |
| 1116 } |
| 1117 |
| 1118 ReturnedResourceArray to_return; |
| 1119 |
| 1120 bool need_sync_point = false; |
| 1121 for (size_t i = 0; i < unused.size(); ++i) { |
| 1122 ResourceId local_id = unused[i]; |
| 1123 |
| 1124 ResourceMap::iterator it = resources_.find(local_id); |
| 1125 CHECK(it != resources_.end()); |
| 1126 Resource& resource = it->second; |
| 1127 |
| 1128 DCHECK(!resource.locked_for_write); |
| 1129 DCHECK(!resource.lock_for_read_count); |
| 1130 DCHECK_EQ(0u, child_info->in_use_resources.count(local_id)); |
| 1131 DCHECK(child_info->parent_to_child_map.count(local_id)); |
| 1132 |
| 1133 ResourceId child_id = child_info->parent_to_child_map[local_id]; |
| 1134 DCHECK(child_info->child_to_parent_map.count(child_id)); |
| 1135 |
| 1136 // TODO(danakj): bool is_lost = false; |
| 1137 if (resource.exported_count > 0) { |
| 1138 if (style != ForShutdown) { |
| 1139 // Defer this until we receive the resource back from the parent. |
| 1140 resource.marked_for_deletion = true; |
| 1141 continue; |
| 1142 } |
| 1143 |
| 1144 // We still have an exported_count, so we'll have to lose it. |
| 1145 // TODO(danakj): is_lost = true; |
| 1146 } |
| 1147 |
| 1148 if (resource.filter != resource.original_filter) { |
| 1149 DCHECK(resource.target); |
| 1150 DCHECK(resource.gl_id); |
| 1151 |
| 1152 GLC(context3d, context3d->bindTexture(resource.target, resource.gl_id)); |
| 1153 GLC(context3d, |
| 1154 context3d->texParameteri(resource.target, |
| 1155 GL_TEXTURE_MIN_FILTER, |
| 1156 resource.original_filter)); |
| 1157 GLC(context3d, |
| 1158 context3d->texParameteri(resource.target, |
| 1159 GL_TEXTURE_MAG_FILTER, |
| 1160 resource.original_filter)); |
| 1161 } |
| 1162 |
| 1163 ReturnedResource returned; |
| 1164 returned.id = child_id; |
| 1165 returned.sync_point = resource.mailbox.sync_point(); |
| 1166 if (!returned.sync_point) |
| 1167 need_sync_point = true; |
| 1168 returned.count = resource.imported_count; |
| 1169 // TODO(danakj): Save the |is_lost| bit. |
| 1170 to_return.push_back(returned); |
| 1171 |
| 1172 child_info->parent_to_child_map.erase(local_id); |
| 1173 child_info->child_to_parent_map.erase(child_id); |
| 1174 resource.imported_count = 0; |
| 1175 DeleteResourceInternal(it, style); |
| 1176 } |
| 1177 if (need_sync_point) { |
| 1178 unsigned int sync_point = context3d->insertSyncPoint(); |
| 1179 for (size_t i = 0; i < to_return.size(); ++i) { |
| 1180 if (!to_return[i].sync_point) |
| 1181 to_return[i].sync_point = sync_point; |
| 1182 } |
| 1183 } |
| 1184 |
| 1185 if (!to_return.empty()) |
| 1186 child_info->return_callback.Run(to_return); |
| 1187 } |
| 1188 |
| 1049 void ResourceProvider::AcquirePixelBuffer(ResourceId id) { | 1189 void ResourceProvider::AcquirePixelBuffer(ResourceId id) { |
| 1050 Resource* resource = GetResource(id); | 1190 Resource* resource = GetResource(id); |
| 1051 DCHECK(!resource->external); | 1191 DCHECK(!resource->external); |
| 1052 DCHECK_EQ(resource->exported_count, 0); | 1192 DCHECK_EQ(resource->exported_count, 0); |
| 1053 DCHECK(!resource->image_id); | 1193 DCHECK(!resource->image_id); |
| 1054 | 1194 |
| 1055 if (resource->type == GLTexture) { | 1195 if (resource->type == GLTexture) { |
| 1056 WebGraphicsContext3D* context3d = Context3d(); | 1196 WebGraphicsContext3D* context3d = Context3d(); |
| 1057 DCHECK(context3d); | 1197 DCHECK(context3d); |
| 1058 if (!resource->gl_pixel_buffer_id) | 1198 if (!resource->gl_pixel_buffer_id) |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1549 } | 1689 } |
| 1550 NOTREACHED(); | 1690 NOTREACHED(); |
| 1551 return GL_RGBA; | 1691 return GL_RGBA; |
| 1552 } | 1692 } |
| 1553 | 1693 |
| 1554 GLenum ResourceProvider::GetGLInternalFormat(ResourceFormat format) { | 1694 GLenum ResourceProvider::GetGLInternalFormat(ResourceFormat format) { |
| 1555 return GetGLDataFormat(format); | 1695 return GetGLDataFormat(format); |
| 1556 } | 1696 } |
| 1557 | 1697 |
| 1558 } // namespace cc | 1698 } // namespace cc |
| OLD | NEW |