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 |