| 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_raster_buffer_provider.h" | 
| 6 | 6 | 
| 7 #include <stdint.h> | 7 #include <stdint.h> | 
| 8 | 8 | 
| 9 #include <algorithm> | 9 #include <algorithm> | 
| 10 #include <limits> | 10 #include <limits> | 
| 11 #include <utility> | 11 #include <utility> | 
| 12 | 12 | 
| 13 #include "base/macros.h" | 13 #include "base/macros.h" | 
| 14 #include "cc/base/math_util.h" | 14 #include "cc/base/math_util.h" | 
| 15 #include "cc/raster/staging_buffer_pool.h" | 15 #include "cc/raster/staging_buffer_pool.h" | 
| 16 #include "cc/resources/platform_color.h" | 16 #include "cc/resources/platform_color.h" | 
| 17 #include "cc/resources/resource_format.h" | 17 #include "cc/resources/resource_format.h" | 
| 18 #include "cc/resources/resource_util.h" | 18 #include "cc/resources/resource_util.h" | 
| 19 #include "cc/resources/scoped_resource.h" | 19 #include "cc/resources/scoped_resource.h" | 
| 20 #include "gpu/GLES2/gl2extchromium.h" | 20 #include "gpu/GLES2/gl2extchromium.h" | 
| 21 #include "gpu/command_buffer/client/gles2_interface.h" | 21 #include "gpu/command_buffer/client/gles2_interface.h" | 
| 22 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" | 22 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" | 
| 23 #include "ui/gfx/buffer_format_util.h" | 23 #include "ui/gfx/buffer_format_util.h" | 
| 24 | 24 | 
| 25 namespace cc { | 25 namespace cc { | 
| 26 namespace { | 26 namespace { | 
| 27 | 27 | 
| 28 class RasterBufferImpl : public RasterBuffer { | 28 class RasterBufferImpl : public RasterBuffer { | 
| 29  public: | 29  public: | 
| 30   RasterBufferImpl(OneCopyTileTaskWorkerPool* worker_pool, | 30   RasterBufferImpl(OneCopyRasterBufferProvider* worker_pool, | 
| 31                    ResourceProvider* resource_provider, | 31                    ResourceProvider* resource_provider, | 
| 32                    ResourceFormat resource_format, | 32                    ResourceFormat resource_format, | 
| 33                    const Resource* resource, | 33                    const Resource* resource, | 
| 34                    uint64_t previous_content_id) | 34                    uint64_t previous_content_id) | 
| 35       : worker_pool_(worker_pool), | 35       : worker_pool_(worker_pool), | 
| 36         resource_(resource), | 36         resource_(resource), | 
| 37         lock_(resource_provider, resource->id()), | 37         lock_(resource_provider, resource->id()), | 
| 38         previous_content_id_(previous_content_id) {} | 38         previous_content_id_(previous_content_id) {} | 
| 39 | 39 | 
| 40   ~RasterBufferImpl() override {} | 40   ~RasterBufferImpl() override {} | 
| 41 | 41 | 
| 42   // Overridden from RasterBuffer: | 42   // Overridden from RasterBuffer: | 
| 43   void Playback( | 43   void Playback( | 
| 44       const RasterSource* raster_source, | 44       const RasterSource* raster_source, | 
| 45       const gfx::Rect& raster_full_rect, | 45       const gfx::Rect& raster_full_rect, | 
| 46       const gfx::Rect& raster_dirty_rect, | 46       const gfx::Rect& raster_dirty_rect, | 
| 47       uint64_t new_content_id, | 47       uint64_t new_content_id, | 
| 48       float scale, | 48       float scale, | 
| 49       const RasterSource::PlaybackSettings& playback_settings) override { | 49       const RasterSource::PlaybackSettings& playback_settings) override { | 
| 50     worker_pool_->PlaybackAndCopyOnWorkerThread( | 50     worker_pool_->PlaybackAndCopyOnWorkerThread( | 
| 51         resource_, &lock_, raster_source, raster_full_rect, raster_dirty_rect, | 51         resource_, &lock_, raster_source, raster_full_rect, raster_dirty_rect, | 
| 52         scale, playback_settings, previous_content_id_, new_content_id); | 52         scale, playback_settings, previous_content_id_, new_content_id); | 
| 53   } | 53   } | 
| 54 | 54 | 
| 55  private: | 55  private: | 
| 56   OneCopyTileTaskWorkerPool* worker_pool_; | 56   OneCopyRasterBufferProvider* worker_pool_; | 
| 57   const Resource* resource_; | 57   const Resource* resource_; | 
| 58   ResourceProvider::ScopedWriteLockGL lock_; | 58   ResourceProvider::ScopedWriteLockGL lock_; | 
| 59   uint64_t previous_content_id_; | 59   uint64_t previous_content_id_; | 
| 60 | 60 | 
| 61   DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); | 61   DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); | 
| 62 }; | 62 }; | 
| 63 | 63 | 
| 64 // 4MiB is the size of 4 512x512 tiles, which has proven to be a good | 64 // 4MiB is the size of 4 512x512 tiles, which has proven to be a good | 
| 65 // default batch size for copy operations. | 65 // default batch size for copy operations. | 
| 66 const int kMaxBytesPerCopyOperation = 1024 * 1024 * 4; | 66 const int kMaxBytesPerCopyOperation = 1024 * 1024 * 4; | 
| 67 | 67 | 
| 68 }  // namespace | 68 }  // namespace | 
| 69 | 69 | 
| 70 // static | 70 // static | 
| 71 std::unique_ptr<TileTaskWorkerPool> OneCopyTileTaskWorkerPool::Create( | 71 std::unique_ptr<RasterBufferProvider> OneCopyRasterBufferProvider::Create( | 
| 72     base::SequencedTaskRunner* task_runner, | 72     base::SequencedTaskRunner* task_runner, | 
| 73     TaskGraphRunner* task_graph_runner, |  | 
| 74     ContextProvider* context_provider, | 73     ContextProvider* context_provider, | 
| 75     ResourceProvider* resource_provider, | 74     ResourceProvider* resource_provider, | 
| 76     int max_copy_texture_chromium_size, | 75     int max_copy_texture_chromium_size, | 
| 77     bool use_partial_raster, | 76     bool use_partial_raster, | 
| 78     int max_staging_buffer_usage_in_bytes, | 77     int max_staging_buffer_usage_in_bytes, | 
| 79     ResourceFormat preferred_tile_format) { | 78     ResourceFormat preferred_tile_format) { | 
| 80   return base::WrapUnique<TileTaskWorkerPool>(new OneCopyTileTaskWorkerPool( | 79   return base::WrapUnique<RasterBufferProvider>(new OneCopyRasterBufferProvider( | 
| 81       task_runner, task_graph_runner, resource_provider, | 80       task_runner, resource_provider, max_copy_texture_chromium_size, | 
| 82       max_copy_texture_chromium_size, use_partial_raster, | 81       use_partial_raster, max_staging_buffer_usage_in_bytes, | 
| 83       max_staging_buffer_usage_in_bytes, preferred_tile_format)); | 82       preferred_tile_format)); | 
| 84 } | 83 } | 
| 85 | 84 | 
| 86 OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool( | 85 OneCopyRasterBufferProvider::OneCopyRasterBufferProvider( | 
| 87     base::SequencedTaskRunner* task_runner, | 86     base::SequencedTaskRunner* task_runner, | 
| 88     TaskGraphRunner* task_graph_runner, |  | 
| 89     ResourceProvider* resource_provider, | 87     ResourceProvider* resource_provider, | 
| 90     int max_copy_texture_chromium_size, | 88     int max_copy_texture_chromium_size, | 
| 91     bool use_partial_raster, | 89     bool use_partial_raster, | 
| 92     int max_staging_buffer_usage_in_bytes, | 90     int max_staging_buffer_usage_in_bytes, | 
| 93     ResourceFormat preferred_tile_format) | 91     ResourceFormat preferred_tile_format) | 
| 94     : task_graph_runner_(task_graph_runner), | 92     : resource_provider_(resource_provider), | 
| 95       namespace_token_(task_graph_runner->GetNamespaceToken()), |  | 
| 96       resource_provider_(resource_provider), |  | 
| 97       max_bytes_per_copy_operation_( | 93       max_bytes_per_copy_operation_( | 
| 98           max_copy_texture_chromium_size | 94           max_copy_texture_chromium_size | 
| 99               ? std::min(kMaxBytesPerCopyOperation, | 95               ? std::min(kMaxBytesPerCopyOperation, | 
| 100                          max_copy_texture_chromium_size) | 96                          max_copy_texture_chromium_size) | 
| 101               : kMaxBytesPerCopyOperation), | 97               : kMaxBytesPerCopyOperation), | 
| 102       use_partial_raster_(use_partial_raster), | 98       use_partial_raster_(use_partial_raster), | 
| 103       bytes_scheduled_since_last_flush_(0), | 99       bytes_scheduled_since_last_flush_(0), | 
| 104       preferred_tile_format_(preferred_tile_format) { | 100       preferred_tile_format_(preferred_tile_format) { | 
| 105   staging_pool_ = StagingBufferPool::Create(task_runner, resource_provider, | 101   staging_pool_ = StagingBufferPool::Create(task_runner, resource_provider, | 
| 106                                             use_partial_raster, | 102                                             use_partial_raster, | 
| 107                                             max_staging_buffer_usage_in_bytes); | 103                                             max_staging_buffer_usage_in_bytes); | 
| 108 } | 104 } | 
| 109 | 105 | 
| 110 OneCopyTileTaskWorkerPool::~OneCopyTileTaskWorkerPool() { | 106 OneCopyRasterBufferProvider::~OneCopyRasterBufferProvider() {} | 
|  | 107 | 
|  | 108 std::unique_ptr<RasterBuffer> | 
|  | 109 OneCopyRasterBufferProvider::AcquireBufferForRaster( | 
|  | 110     const Resource* resource, | 
|  | 111     uint64_t resource_content_id, | 
|  | 112     uint64_t previous_content_id) { | 
|  | 113   // TODO(danakj): If resource_content_id != 0, we only need to copy/upload | 
|  | 114   // the dirty rect. | 
|  | 115   return base::WrapUnique<RasterBuffer>( | 
|  | 116       new RasterBufferImpl(this, resource_provider_, resource->format(), | 
|  | 117                            resource, previous_content_id)); | 
| 111 } | 118 } | 
| 112 | 119 | 
| 113 void OneCopyTileTaskWorkerPool::Shutdown() { | 120 void OneCopyRasterBufferProvider::ReleaseBufferForRaster( | 
| 114   TRACE_EVENT0("cc", "OneCopyTileTaskWorkerPool::Shutdown"); | 121     std::unique_ptr<RasterBuffer> buffer) { | 
| 115 | 122   // Nothing to do here. RasterBufferImpl destructor cleans up after itself. | 
| 116   TaskGraph empty; |  | 
| 117   task_graph_runner_->ScheduleTasks(namespace_token_, &empty); |  | 
| 118   task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); |  | 
| 119 |  | 
| 120   staging_pool_->Shutdown(); |  | 
| 121 } | 123 } | 
| 122 | 124 | 
| 123 void OneCopyTileTaskWorkerPool::ScheduleTasks(TaskGraph* graph) { | 125 void OneCopyRasterBufferProvider::OrderingBarrier() { | 
| 124   TRACE_EVENT0("cc", "OneCopyTileTaskWorkerPool::ScheduleTasks"); | 126   TRACE_EVENT0("cc", "OneCopyRasterBufferProvider::OrderingBarrier"); | 
| 125 | 127 | 
| 126   ScheduleTasksOnOriginThread(this, graph); |  | 
| 127 |  | 
| 128   // Barrier to sync any new resources to the worker context. |  | 
| 129   resource_provider_->output_surface() | 128   resource_provider_->output_surface() | 
| 130       ->context_provider() | 129       ->context_provider() | 
| 131       ->ContextGL() | 130       ->ContextGL() | 
| 132       ->OrderingBarrierCHROMIUM(); | 131       ->OrderingBarrierCHROMIUM(); | 
| 133 |  | 
| 134   task_graph_runner_->ScheduleTasks(namespace_token_, graph); |  | 
| 135 } | 132 } | 
| 136 | 133 | 
| 137 void OneCopyTileTaskWorkerPool::CheckForCompletedTasks() { | 134 ResourceFormat OneCopyRasterBufferProvider::GetResourceFormat( | 
| 138   TRACE_EVENT0("cc", "OneCopyTileTaskWorkerPool::CheckForCompletedTasks"); |  | 
| 139 |  | 
| 140   task_graph_runner_->CollectCompletedTasks(namespace_token_, |  | 
| 141                                             &completed_tasks_); |  | 
| 142 |  | 
| 143   for (Task::Vector::const_iterator it = completed_tasks_.begin(); |  | 
| 144        it != completed_tasks_.end(); ++it) { |  | 
| 145     TileTask* task = static_cast<TileTask*>(it->get()); |  | 
| 146 |  | 
| 147     task->WillComplete(); |  | 
| 148     task->CompleteOnOriginThread(this); |  | 
| 149     task->DidComplete(); |  | 
| 150   } |  | 
| 151   completed_tasks_.clear(); |  | 
| 152 } |  | 
| 153 |  | 
| 154 ResourceFormat OneCopyTileTaskWorkerPool::GetResourceFormat( |  | 
| 155     bool must_support_alpha) const { | 135     bool must_support_alpha) const { | 
| 156   if (resource_provider_->IsResourceFormatSupported(preferred_tile_format_) && | 136   if (resource_provider_->IsResourceFormatSupported(preferred_tile_format_) && | 
| 157       (DoesResourceFormatSupportAlpha(preferred_tile_format_) || | 137       (DoesResourceFormatSupportAlpha(preferred_tile_format_) || | 
| 158        !must_support_alpha)) { | 138        !must_support_alpha)) { | 
| 159     return preferred_tile_format_; | 139     return preferred_tile_format_; | 
| 160   } | 140   } | 
| 161 | 141 | 
| 162   return resource_provider_->best_texture_format(); | 142   return resource_provider_->best_texture_format(); | 
| 163 } | 143 } | 
| 164 | 144 | 
| 165 bool OneCopyTileTaskWorkerPool::GetResourceRequiresSwizzle( | 145 bool OneCopyRasterBufferProvider::GetResourceRequiresSwizzle( | 
| 166     bool must_support_alpha) const { | 146     bool must_support_alpha) const { | 
| 167   return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha)); | 147   return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha)); | 
| 168 } | 148 } | 
| 169 | 149 | 
| 170 RasterBufferProvider* OneCopyTileTaskWorkerPool::AsRasterBufferProvider() { | 150 void OneCopyRasterBufferProvider::Shutdown() { | 
| 171   return this; | 151   staging_pool_->Shutdown(); | 
| 172 } | 152 } | 
| 173 | 153 | 
| 174 std::unique_ptr<RasterBuffer> OneCopyTileTaskWorkerPool::AcquireBufferForRaster( | 154 void OneCopyRasterBufferProvider::PlaybackAndCopyOnWorkerThread( | 
| 175     const Resource* resource, |  | 
| 176     uint64_t resource_content_id, |  | 
| 177     uint64_t previous_content_id) { |  | 
| 178   // TODO(danakj): If resource_content_id != 0, we only need to copy/upload |  | 
| 179   // the dirty rect. |  | 
| 180   return base::WrapUnique<RasterBuffer>( |  | 
| 181       new RasterBufferImpl(this, resource_provider_, resource->format(), |  | 
| 182                            resource, previous_content_id)); |  | 
| 183 } |  | 
| 184 |  | 
| 185 void OneCopyTileTaskWorkerPool::ReleaseBufferForRaster( |  | 
| 186     std::unique_ptr<RasterBuffer> buffer) { |  | 
| 187   // Nothing to do here. RasterBufferImpl destructor cleans up after itself. |  | 
| 188 } |  | 
| 189 |  | 
| 190 void OneCopyTileTaskWorkerPool::PlaybackAndCopyOnWorkerThread( |  | 
| 191     const Resource* resource, | 155     const Resource* resource, | 
| 192     ResourceProvider::ScopedWriteLockGL* resource_lock, | 156     ResourceProvider::ScopedWriteLockGL* resource_lock, | 
| 193     const RasterSource* raster_source, | 157     const RasterSource* raster_source, | 
| 194     const gfx::Rect& raster_full_rect, | 158     const gfx::Rect& raster_full_rect, | 
| 195     const gfx::Rect& raster_dirty_rect, | 159     const gfx::Rect& raster_dirty_rect, | 
| 196     float scale, | 160     float scale, | 
| 197     const RasterSource::PlaybackSettings& playback_settings, | 161     const RasterSource::PlaybackSettings& playback_settings, | 
| 198     uint64_t previous_content_id, | 162     uint64_t previous_content_id, | 
| 199     uint64_t new_content_id) { | 163     uint64_t new_content_id) { | 
| 200   std::unique_ptr<StagingBuffer> staging_buffer = | 164   std::unique_ptr<StagingBuffer> staging_buffer = | 
| 201       staging_pool_->AcquireStagingBuffer(resource, previous_content_id); | 165       staging_pool_->AcquireStagingBuffer(resource, previous_content_id); | 
| 202 | 166 | 
| 203   PlaybackToStagingBuffer(staging_buffer.get(), resource, raster_source, | 167   PlaybackToStagingBuffer(staging_buffer.get(), resource, raster_source, | 
| 204                           raster_full_rect, raster_dirty_rect, scale, | 168                           raster_full_rect, raster_dirty_rect, scale, | 
| 205                           playback_settings, previous_content_id, | 169                           playback_settings, previous_content_id, | 
| 206                           new_content_id); | 170                           new_content_id); | 
| 207 | 171 | 
| 208   CopyOnWorkerThread(staging_buffer.get(), resource, resource_lock, | 172   CopyOnWorkerThread(staging_buffer.get(), resource, resource_lock, | 
| 209                      raster_source, previous_content_id, new_content_id); | 173                      raster_source, previous_content_id, new_content_id); | 
| 210 | 174 | 
| 211   staging_pool_->ReleaseStagingBuffer(std::move(staging_buffer)); | 175   staging_pool_->ReleaseStagingBuffer(std::move(staging_buffer)); | 
| 212 } | 176 } | 
| 213 | 177 | 
| 214 void OneCopyTileTaskWorkerPool::PlaybackToStagingBuffer( | 178 void OneCopyRasterBufferProvider::PlaybackToStagingBuffer( | 
| 215     StagingBuffer* staging_buffer, | 179     StagingBuffer* staging_buffer, | 
| 216     const Resource* resource, | 180     const Resource* resource, | 
| 217     const RasterSource* raster_source, | 181     const RasterSource* raster_source, | 
| 218     const gfx::Rect& raster_full_rect, | 182     const gfx::Rect& raster_full_rect, | 
| 219     const gfx::Rect& raster_dirty_rect, | 183     const gfx::Rect& raster_dirty_rect, | 
| 220     float scale, | 184     float scale, | 
| 221     const RasterSource::PlaybackSettings& playback_settings, | 185     const RasterSource::PlaybackSettings& playback_settings, | 
| 222     uint64_t previous_content_id, | 186     uint64_t previous_content_id, | 
| 223     uint64_t new_content_id) { | 187     uint64_t new_content_id) { | 
| 224   // Allocate GpuMemoryBuffer if necessary. If using partial raster, we | 188   // Allocate GpuMemoryBuffer if necessary. If using partial raster, we | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 241     if (previous_content_id == staging_buffer->content_id) | 205     if (previous_content_id == staging_buffer->content_id) | 
| 242       playback_rect.Intersect(raster_dirty_rect); | 206       playback_rect.Intersect(raster_dirty_rect); | 
| 243   } | 207   } | 
| 244 | 208 | 
| 245   if (staging_buffer->gpu_memory_buffer) { | 209   if (staging_buffer->gpu_memory_buffer) { | 
| 246     gfx::GpuMemoryBuffer* buffer = staging_buffer->gpu_memory_buffer.get(); | 210     gfx::GpuMemoryBuffer* buffer = staging_buffer->gpu_memory_buffer.get(); | 
| 247     DCHECK_EQ(1u, gfx::NumberOfPlanesForBufferFormat(buffer->GetFormat())); | 211     DCHECK_EQ(1u, gfx::NumberOfPlanesForBufferFormat(buffer->GetFormat())); | 
| 248     bool rv = buffer->Map(); | 212     bool rv = buffer->Map(); | 
| 249     DCHECK(rv); | 213     DCHECK(rv); | 
| 250     DCHECK(buffer->memory(0)); | 214     DCHECK(buffer->memory(0)); | 
| 251     // TileTaskWorkerPool::PlaybackToMemory only supports unsigned strides. | 215     // RasterBufferProvider::PlaybackToMemory only supports unsigned strides. | 
| 252     DCHECK_GE(buffer->stride(0), 0); | 216     DCHECK_GE(buffer->stride(0), 0); | 
| 253 | 217 | 
| 254     DCHECK(!playback_rect.IsEmpty()) | 218     DCHECK(!playback_rect.IsEmpty()) | 
| 255         << "Why are we rastering a tile that's not dirty?"; | 219         << "Why are we rastering a tile that's not dirty?"; | 
| 256     TileTaskWorkerPool::PlaybackToMemory( | 220     RasterBufferProvider::PlaybackToMemory( | 
| 257         buffer->memory(0), resource->format(), staging_buffer->size, | 221         buffer->memory(0), resource->format(), staging_buffer->size, | 
| 258         buffer->stride(0), raster_source, raster_full_rect, playback_rect, | 222         buffer->stride(0), raster_source, raster_full_rect, playback_rect, | 
| 259         scale, playback_settings); | 223         scale, playback_settings); | 
| 260     buffer->Unmap(); | 224     buffer->Unmap(); | 
| 261     staging_buffer->content_id = new_content_id; | 225     staging_buffer->content_id = new_content_id; | 
| 262   } | 226   } | 
| 263 } | 227 } | 
| 264 | 228 | 
| 265 void OneCopyTileTaskWorkerPool::CopyOnWorkerThread( | 229 void OneCopyRasterBufferProvider::CopyOnWorkerThread( | 
| 266     StagingBuffer* staging_buffer, | 230     StagingBuffer* staging_buffer, | 
| 267     const Resource* resource, | 231     const Resource* resource, | 
| 268     ResourceProvider::ScopedWriteLockGL* resource_lock, | 232     ResourceProvider::ScopedWriteLockGL* resource_lock, | 
| 269     const RasterSource* raster_source, | 233     const RasterSource* raster_source, | 
| 270     uint64_t previous_content_id, | 234     uint64_t previous_content_id, | 
| 271     uint64_t new_content_id) { | 235     uint64_t new_content_id) { | 
| 272   ContextProvider* context_provider = | 236   ContextProvider* context_provider = | 
| 273       resource_provider_->output_surface()->worker_context_provider(); | 237       resource_provider_->output_surface()->worker_context_provider(); | 
| 274   DCHECK(context_provider); | 238   DCHECK(context_provider); | 
| 275 | 239 | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 375     gl->OrderingBarrierCHROMIUM(); | 339     gl->OrderingBarrierCHROMIUM(); | 
| 376 | 340 | 
| 377     // Generate sync token after the barrier for cross context synchronization. | 341     // Generate sync token after the barrier for cross context synchronization. | 
| 378     gpu::SyncToken sync_token; | 342     gpu::SyncToken sync_token; | 
| 379     gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); | 343     gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); | 
| 380     resource_lock->UpdateResourceSyncToken(sync_token); | 344     resource_lock->UpdateResourceSyncToken(sync_token); | 
| 381   } | 345   } | 
| 382 } | 346 } | 
| 383 | 347 | 
| 384 }  // namespace cc | 348 }  // namespace cc | 
| OLD | NEW | 
|---|