| OLD | NEW |
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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/trees/layer_tree_host_impl.h" | 5 #include "cc/trees/layer_tree_host_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 // that time interval, and then uploads should have a chance to be processed. | 146 // that time interval, and then uploads should have a chance to be processed. |
| 147 size_t ms_per_frame = std::floor(1000.0 / refresh_rate); | 147 size_t ms_per_frame = std::floor(1000.0 / refresh_rate); |
| 148 size_t max_transfer_buffer_usage_bytes = | 148 size_t max_transfer_buffer_usage_bytes = |
| 149 ms_per_frame * kMaxBytesUploadedPerMs; | 149 ms_per_frame * kMaxBytesUploadedPerMs; |
| 150 | 150 |
| 151 // The context may request a lower limit based on the device capabilities. | 151 // The context may request a lower limit based on the device capabilities. |
| 152 return std::min(context_capabilities.max_transfer_buffer_usage_bytes, | 152 return std::min(context_capabilities.max_transfer_buffer_usage_bytes, |
| 153 max_transfer_buffer_usage_bytes); | 153 max_transfer_buffer_usage_bytes); |
| 154 } | 154 } |
| 155 | 155 |
| 156 size_t GetMaxStagingResourceCount() { | |
| 157 // Upper bound for number of staging resource to allow. | |
| 158 return 32; | |
| 159 } | |
| 160 | |
| 161 size_t GetDefaultMemoryAllocationLimit() { | 156 size_t GetDefaultMemoryAllocationLimit() { |
| 162 // TODO(ccameron): (http://crbug.com/137094) This 64MB default is a straggler | 157 // TODO(ccameron): (http://crbug.com/137094) This 64MB default is a straggler |
| 163 // from the old texture manager and is just to give us a default memory | 158 // from the old texture manager and is just to give us a default memory |
| 164 // allocation before we get a callback from the GPU memory manager. We | 159 // allocation before we get a callback from the GPU memory manager. We |
| 165 // should probaby either: | 160 // should probaby either: |
| 166 // - wait for the callback before rendering anything instead | 161 // - wait for the callback before rendering anything instead |
| 167 // - push this into the GPU memory manager somehow. | 162 // - push this into the GPU memory manager somehow. |
| 168 return 64 * 1024 * 1024; | 163 return 64 * 1024 * 1024; |
| 169 } | 164 } |
| 170 | 165 |
| (...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1229 // TODO(reveman): We should avoid keeping around unused resources if | 1224 // TODO(reveman): We should avoid keeping around unused resources if |
| 1230 // possible. crbug.com/224475 | 1225 // possible. crbug.com/224475 |
| 1231 // Unused limit is calculated from soft-limit, as hard-limit may | 1226 // Unused limit is calculated from soft-limit, as hard-limit may |
| 1232 // be very high and shouldn't typically be exceeded. | 1227 // be very high and shouldn't typically be exceeded. |
| 1233 size_t unused_memory_limit_in_bytes = static_cast<size_t>( | 1228 size_t unused_memory_limit_in_bytes = static_cast<size_t>( |
| 1234 (static_cast<int64>(global_tile_state_.soft_memory_limit_in_bytes) * | 1229 (static_cast<int64>(global_tile_state_.soft_memory_limit_in_bytes) * |
| 1235 settings_.max_unused_resource_memory_percentage) / | 1230 settings_.max_unused_resource_memory_percentage) / |
| 1236 100); | 1231 100); |
| 1237 | 1232 |
| 1238 DCHECK(resource_pool_); | 1233 DCHECK(resource_pool_); |
| 1239 resource_pool_->CheckBusyResources(false); | 1234 resource_pool_->CheckBusyResources(); |
| 1240 // Soft limit is used for resource pool such that memory returns to soft | 1235 // Soft limit is used for resource pool such that memory returns to soft |
| 1241 // limit after going over. | 1236 // limit after going over. |
| 1242 resource_pool_->SetResourceUsageLimits( | 1237 resource_pool_->SetResourceUsageLimits( |
| 1243 global_tile_state_.soft_memory_limit_in_bytes, | 1238 global_tile_state_.soft_memory_limit_in_bytes, |
| 1244 unused_memory_limit_in_bytes, | 1239 unused_memory_limit_in_bytes, |
| 1245 global_tile_state_.num_resources_limit); | 1240 global_tile_state_.num_resources_limit); |
| 1246 | 1241 |
| 1247 // Release all staging resources when invisible. | |
| 1248 if (staging_resource_pool_) { | |
| 1249 staging_resource_pool_->CheckBusyResources(false); | |
| 1250 staging_resource_pool_->SetResourceUsageLimits( | |
| 1251 std::numeric_limits<size_t>::max(), | |
| 1252 std::numeric_limits<size_t>::max(), | |
| 1253 visible_ ? GetMaxStagingResourceCount() : 0); | |
| 1254 } | |
| 1255 | |
| 1256 DidModifyTilePriorities(); | 1242 DidModifyTilePriorities(); |
| 1257 } | 1243 } |
| 1258 | 1244 |
| 1259 void LayerTreeHostImpl::DidModifyTilePriorities() { | 1245 void LayerTreeHostImpl::DidModifyTilePriorities() { |
| 1260 // Mark priorities as dirty and schedule a PrepareTiles(). | 1246 // Mark priorities as dirty and schedule a PrepareTiles(). |
| 1261 tile_priorities_dirty_ = true; | 1247 tile_priorities_dirty_ = true; |
| 1262 client_->SetNeedsPrepareTilesOnImplThread(); | 1248 client_->SetNeedsPrepareTilesOnImplThread(); |
| 1263 } | 1249 } |
| 1264 | 1250 |
| 1265 scoped_ptr<RasterTilePriorityQueue> LayerTreeHostImpl::BuildRasterQueue( | 1251 scoped_ptr<RasterTilePriorityQueue> LayerTreeHostImpl::BuildRasterQueue( |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1459 | 1445 |
| 1460 void LayerTreeHostImpl::ReclaimResources(const CompositorFrameAck* ack) { | 1446 void LayerTreeHostImpl::ReclaimResources(const CompositorFrameAck* ack) { |
| 1461 // TODO(piman): We may need to do some validation on this ack before | 1447 // TODO(piman): We may need to do some validation on this ack before |
| 1462 // processing it. | 1448 // processing it. |
| 1463 if (renderer_) | 1449 if (renderer_) |
| 1464 renderer_->ReceiveSwapBuffersAck(*ack); | 1450 renderer_->ReceiveSwapBuffersAck(*ack); |
| 1465 | 1451 |
| 1466 // In OOM, we now might be able to release more resources that were held | 1452 // In OOM, we now might be able to release more resources that were held |
| 1467 // because they were exported. | 1453 // because they were exported. |
| 1468 if (resource_pool_) { | 1454 if (resource_pool_) { |
| 1469 resource_pool_->CheckBusyResources(false); | 1455 resource_pool_->CheckBusyResources(); |
| 1470 resource_pool_->ReduceResourceUsage(); | 1456 resource_pool_->ReduceResourceUsage(); |
| 1471 } | 1457 } |
| 1472 // If we're not visible, we likely released resources, so we want to | 1458 // If we're not visible, we likely released resources, so we want to |
| 1473 // aggressively flush here to make sure those DeleteTextures make it to the | 1459 // aggressively flush here to make sure those DeleteTextures make it to the |
| 1474 // GPU process to free up the memory. | 1460 // GPU process to free up the memory. |
| 1475 if (output_surface_->context_provider() && !visible_) { | 1461 if (output_surface_->context_provider() && !visible_) { |
| 1476 output_surface_->context_provider()->ContextGL()->ShallowFlushCHROMIUM(); | 1462 output_surface_->context_provider()->ContextGL()->ShallowFlushCHROMIUM(); |
| 1477 } | 1463 } |
| 1478 } | 1464 } |
| 1479 | 1465 |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2070 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs to be | 2056 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs to be |
| 2071 // initialized to get max texture size. Also, after releasing resources, | 2057 // initialized to get max texture size. Also, after releasing resources, |
| 2072 // trees need another update to generate new ones. | 2058 // trees need another update to generate new ones. |
| 2073 active_tree_->set_needs_update_draw_properties(); | 2059 active_tree_->set_needs_update_draw_properties(); |
| 2074 if (pending_tree_) | 2060 if (pending_tree_) |
| 2075 pending_tree_->set_needs_update_draw_properties(); | 2061 pending_tree_->set_needs_update_draw_properties(); |
| 2076 client_->UpdateRendererCapabilitiesOnImplThread(); | 2062 client_->UpdateRendererCapabilitiesOnImplThread(); |
| 2077 } | 2063 } |
| 2078 | 2064 |
| 2079 void LayerTreeHostImpl::CreateTileManagerResources() { | 2065 void LayerTreeHostImpl::CreateTileManagerResources() { |
| 2080 CreateResourceAndTileTaskWorkerPool(&tile_task_worker_pool_, &resource_pool_, | 2066 CreateResourceAndTileTaskWorkerPool(&tile_task_worker_pool_, &resource_pool_); |
| 2081 &staging_resource_pool_); | |
| 2082 // TODO(vmpstr): Initialize tile task limit at ctor time. | 2067 // TODO(vmpstr): Initialize tile task limit at ctor time. |
| 2083 tile_manager_->SetResources( | 2068 tile_manager_->SetResources( |
| 2084 resource_pool_.get(), tile_task_worker_pool_->AsTileTaskRunner(), | 2069 resource_pool_.get(), tile_task_worker_pool_->AsTileTaskRunner(), |
| 2085 is_synchronous_single_threaded_ ? std::numeric_limits<size_t>::max() | 2070 is_synchronous_single_threaded_ ? std::numeric_limits<size_t>::max() |
| 2086 : settings_.scheduled_raster_task_limit); | 2071 : settings_.scheduled_raster_task_limit); |
| 2087 UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); | 2072 UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); |
| 2088 } | 2073 } |
| 2089 | 2074 |
| 2090 void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool( | 2075 void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool( |
| 2091 scoped_ptr<TileTaskWorkerPool>* tile_task_worker_pool, | 2076 scoped_ptr<TileTaskWorkerPool>* tile_task_worker_pool, |
| 2092 scoped_ptr<ResourcePool>* resource_pool, | 2077 scoped_ptr<ResourcePool>* resource_pool) { |
| 2093 scoped_ptr<ResourcePool>* staging_resource_pool) { | |
| 2094 DCHECK(GetTaskRunner()); | 2078 DCHECK(GetTaskRunner()); |
| 2095 // TODO(vmpstr): Make this a DCHECK (or remove) when crbug.com/419086 is | 2079 // TODO(vmpstr): Make this a DCHECK (or remove) when crbug.com/419086 is |
| 2096 // resolved. | 2080 // resolved. |
| 2097 CHECK(resource_provider_); | 2081 CHECK(resource_provider_); |
| 2098 | 2082 |
| 2099 // Pass the single-threaded synchronous task graph runner to the worker pool | 2083 // Pass the single-threaded synchronous task graph runner to the worker pool |
| 2100 // if we're in synchronous single-threaded mode. | 2084 // if we're in synchronous single-threaded mode. |
| 2101 TaskGraphRunner* task_graph_runner = task_graph_runner_; | 2085 TaskGraphRunner* task_graph_runner = task_graph_runner_; |
| 2102 if (is_synchronous_single_threaded_) { | 2086 if (is_synchronous_single_threaded_) { |
| 2103 DCHECK(!single_thread_synchronous_task_graph_runner_); | 2087 DCHECK(!single_thread_synchronous_task_graph_runner_); |
| 2104 single_thread_synchronous_task_graph_runner_.reset(new TaskGraphRunner); | 2088 single_thread_synchronous_task_graph_runner_.reset(new TaskGraphRunner); |
| 2105 task_graph_runner = single_thread_synchronous_task_graph_runner_.get(); | 2089 task_graph_runner = single_thread_synchronous_task_graph_runner_.get(); |
| 2106 } | 2090 } |
| 2107 | 2091 |
| 2108 ContextProvider* context_provider = output_surface_->context_provider(); | 2092 ContextProvider* context_provider = output_surface_->context_provider(); |
| 2109 if (!context_provider) { | 2093 if (!context_provider) { |
| 2110 *resource_pool = | 2094 *resource_pool = |
| 2111 ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D); | 2095 ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D); |
| 2112 | 2096 |
| 2113 *tile_task_worker_pool = BitmapTileTaskWorkerPool::Create( | 2097 *tile_task_worker_pool = BitmapTileTaskWorkerPool::Create( |
| 2114 GetTaskRunner(), task_graph_runner, resource_provider_.get()); | 2098 GetTaskRunner(), task_graph_runner, resource_provider_.get()); |
| 2115 return; | 2099 return; |
| 2116 } | 2100 } |
| 2117 | 2101 |
| 2118 if (use_gpu_rasterization_) { | 2102 if (use_gpu_rasterization_) { |
| 2103 DCHECK(resource_provider_->output_surface()->worker_context_provider()); |
| 2104 |
| 2119 *resource_pool = | 2105 *resource_pool = |
| 2120 ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D); | 2106 ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D); |
| 2121 | 2107 |
| 2122 int msaa_sample_count = use_msaa_ ? RequestedMSAASampleCount() : 0; | 2108 int msaa_sample_count = use_msaa_ ? RequestedMSAASampleCount() : 0; |
| 2123 | 2109 |
| 2124 *tile_task_worker_pool = GpuTileTaskWorkerPool::Create( | 2110 *tile_task_worker_pool = GpuTileTaskWorkerPool::Create( |
| 2125 GetTaskRunner(), task_graph_runner, context_provider, | 2111 GetTaskRunner(), task_graph_runner, context_provider, |
| 2126 resource_provider_.get(), settings_.use_distance_field_text, | 2112 resource_provider_.get(), settings_.use_distance_field_text, |
| 2127 msaa_sample_count); | 2113 msaa_sample_count); |
| 2128 return; | 2114 return; |
| 2129 } | 2115 } |
| 2130 | 2116 |
| 2131 DCHECK(GetRendererCapabilities().using_image); | 2117 DCHECK(GetRendererCapabilities().using_image); |
| 2132 | 2118 |
| 2133 if (settings_.use_zero_copy) { | 2119 bool use_zero_copy = settings_.use_zero_copy; |
| 2120 // TODO(reveman): Remove this when mojo supports worker contexts. |
| 2121 // crbug.com/522440 |
| 2122 if (!resource_provider_->output_surface()->worker_context_provider()) { |
| 2123 LOG(ERROR) |
| 2124 << "Forcing zero-copy tile initialization as worker context is missing"; |
| 2125 use_zero_copy = true; |
| 2126 } |
| 2127 |
| 2128 if (use_zero_copy) { |
| 2134 *resource_pool = ResourcePool::Create(resource_provider_.get()); | 2129 *resource_pool = ResourcePool::Create(resource_provider_.get()); |
| 2135 | 2130 |
| 2136 *tile_task_worker_pool = ZeroCopyTileTaskWorkerPool::Create( | 2131 *tile_task_worker_pool = ZeroCopyTileTaskWorkerPool::Create( |
| 2137 GetTaskRunner(), task_graph_runner, resource_provider_.get()); | 2132 GetTaskRunner(), task_graph_runner, resource_provider_.get()); |
| 2138 return; | 2133 return; |
| 2139 } | 2134 } |
| 2140 | 2135 |
| 2141 if (settings_.use_one_copy) { | 2136 if (settings_.use_one_copy) { |
| 2142 // Synchronous single-threaded mode depends on tiles being ready to | |
| 2143 // draw when raster is complete. Therefore, it must use one of zero | |
| 2144 // copy, software raster, or GPU raster. | |
| 2145 DCHECK(!is_synchronous_single_threaded_); | |
| 2146 | |
| 2147 // We need to create a staging resource pool when using copy rasterizer. | |
| 2148 *staging_resource_pool = ResourcePool::Create(resource_provider_.get()); | |
| 2149 *resource_pool = | 2137 *resource_pool = |
| 2150 ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D); | 2138 ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D); |
| 2151 | 2139 |
| 2152 int max_copy_texture_chromium_size = | 2140 int max_copy_texture_chromium_size = |
| 2153 context_provider->ContextCapabilities() | 2141 context_provider->ContextCapabilities() |
| 2154 .gpu.max_copy_texture_chromium_size; | 2142 .gpu.max_copy_texture_chromium_size; |
| 2155 | 2143 |
| 2156 *tile_task_worker_pool = OneCopyTileTaskWorkerPool::Create( | 2144 *tile_task_worker_pool = OneCopyTileTaskWorkerPool::Create( |
| 2157 GetTaskRunner(), task_graph_runner, context_provider, | 2145 GetTaskRunner(), task_graph_runner, context_provider, |
| 2158 resource_provider_.get(), staging_resource_pool_.get(), | 2146 resource_provider_.get(), max_copy_texture_chromium_size, |
| 2159 max_copy_texture_chromium_size, | 2147 settings_.use_persistent_map_for_gpu_memory_buffers, |
| 2160 settings_.use_persistent_map_for_gpu_memory_buffers); | 2148 settings_.max_staging_buffers); |
| 2161 return; | 2149 return; |
| 2162 } | 2150 } |
| 2163 | 2151 |
| 2164 // Synchronous single-threaded mode depends on tiles being ready to | 2152 // Synchronous single-threaded mode depends on tiles being ready to |
| 2165 // draw when raster is complete. Therefore, it must use one of zero | 2153 // draw when raster is complete. Therefore, it must use one of zero |
| 2166 // copy, software raster, or GPU raster (in the branches above). | 2154 // copy, software raster, or GPU raster (in the branches above). |
| 2167 DCHECK(!is_synchronous_single_threaded_); | 2155 DCHECK(!is_synchronous_single_threaded_); |
| 2168 | 2156 |
| 2169 *resource_pool = ResourcePool::Create( | 2157 *resource_pool = ResourcePool::Create( |
| 2170 resource_provider_.get(), GL_TEXTURE_2D); | 2158 resource_provider_.get(), GL_TEXTURE_2D); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2193 void LayerTreeHostImpl::PostFrameTimingEvents( | 2181 void LayerTreeHostImpl::PostFrameTimingEvents( |
| 2194 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, | 2182 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events, |
| 2195 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) { | 2183 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) { |
| 2196 client_->PostFrameTimingEventsOnImplThread(composite_events.Pass(), | 2184 client_->PostFrameTimingEventsOnImplThread(composite_events.Pass(), |
| 2197 main_frame_events.Pass()); | 2185 main_frame_events.Pass()); |
| 2198 } | 2186 } |
| 2199 | 2187 |
| 2200 void LayerTreeHostImpl::CleanUpTileManager() { | 2188 void LayerTreeHostImpl::CleanUpTileManager() { |
| 2201 tile_manager_->FinishTasksAndCleanUp(); | 2189 tile_manager_->FinishTasksAndCleanUp(); |
| 2202 resource_pool_ = nullptr; | 2190 resource_pool_ = nullptr; |
| 2203 staging_resource_pool_ = nullptr; | |
| 2204 tile_task_worker_pool_ = nullptr; | 2191 tile_task_worker_pool_ = nullptr; |
| 2205 single_thread_synchronous_task_graph_runner_ = nullptr; | 2192 single_thread_synchronous_task_graph_runner_ = nullptr; |
| 2206 } | 2193 } |
| 2207 | 2194 |
| 2208 bool LayerTreeHostImpl::InitializeRenderer( | 2195 bool LayerTreeHostImpl::InitializeRenderer( |
| 2209 scoped_ptr<OutputSurface> output_surface) { | 2196 scoped_ptr<OutputSurface> output_surface) { |
| 2210 TRACE_EVENT0("cc", "LayerTreeHostImpl::InitializeRenderer"); | 2197 TRACE_EVENT0("cc", "LayerTreeHostImpl::InitializeRenderer"); |
| 2211 | 2198 |
| 2212 // Since we will create a new resource provider, we cannot continue to use | 2199 // Since we will create a new resource provider, we cannot continue to use |
| 2213 // the old resources (i.e. render_surfaces and texture IDs). Clear them | 2200 // the old resources (i.e. render_surfaces and texture IDs). Clear them |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2227 return false; | 2214 return false; |
| 2228 } | 2215 } |
| 2229 | 2216 |
| 2230 output_surface_ = output_surface.Pass(); | 2217 output_surface_ = output_surface.Pass(); |
| 2231 resource_provider_ = ResourceProvider::Create( | 2218 resource_provider_ = ResourceProvider::Create( |
| 2232 output_surface_.get(), shared_bitmap_manager_, gpu_memory_buffer_manager_, | 2219 output_surface_.get(), shared_bitmap_manager_, gpu_memory_buffer_manager_, |
| 2233 proxy_->blocking_main_thread_task_runner(), | 2220 proxy_->blocking_main_thread_task_runner(), |
| 2234 settings_.renderer_settings.highp_threshold_min, | 2221 settings_.renderer_settings.highp_threshold_min, |
| 2235 settings_.renderer_settings.use_rgba_4444_textures, | 2222 settings_.renderer_settings.use_rgba_4444_textures, |
| 2236 settings_.renderer_settings.texture_id_allocation_chunk_size, | 2223 settings_.renderer_settings.texture_id_allocation_chunk_size, |
| 2237 settings_.use_persistent_map_for_gpu_memory_buffers, | |
| 2238 settings_.use_image_texture_targets); | 2224 settings_.use_image_texture_targets); |
| 2239 | 2225 |
| 2240 CreateAndSetRenderer(); | 2226 CreateAndSetRenderer(); |
| 2241 | 2227 |
| 2242 // Since the new renderer may be capable of MSAA, update status here. | 2228 // Since the new renderer may be capable of MSAA, update status here. |
| 2243 UpdateGpuRasterizationStatus(); | 2229 UpdateGpuRasterizationStatus(); |
| 2244 | 2230 |
| 2245 CreateTileManagerResources(); | 2231 CreateTileManagerResources(); |
| 2246 RecreateTreeResources(); | 2232 RecreateTreeResources(); |
| 2247 | 2233 |
| (...skipping 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3645 if (active_tree()) { | 3631 if (active_tree()) { |
| 3646 LayerAnimationValueProvider* layer = active_tree()->LayerById(layer_id); | 3632 LayerAnimationValueProvider* layer = active_tree()->LayerById(layer_id); |
| 3647 if (layer) | 3633 if (layer) |
| 3648 return layer->ScrollOffsetForAnimation(); | 3634 return layer->ScrollOffsetForAnimation(); |
| 3649 } | 3635 } |
| 3650 | 3636 |
| 3651 return gfx::ScrollOffset(); | 3637 return gfx::ScrollOffset(); |
| 3652 } | 3638 } |
| 3653 | 3639 |
| 3654 } // namespace cc | 3640 } // namespace cc |
| OLD | NEW |