| 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/tile_manager.h" | 5 #include "cc/resources/tile_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 state->SetInteger("canceled_count", stats.canceled_count); | 362 state->SetInteger("canceled_count", stats.canceled_count); |
| 363 return state.PassAs<base::Value>(); | 363 return state.PassAs<base::Value>(); |
| 364 } | 364 } |
| 365 | 365 |
| 366 // static | 366 // static |
| 367 scoped_ptr<TileManager> TileManager::Create( | 367 scoped_ptr<TileManager> TileManager::Create( |
| 368 TileManagerClient* client, | 368 TileManagerClient* client, |
| 369 ResourcePool* resource_pool, | 369 ResourcePool* resource_pool, |
| 370 Rasterizer* rasterizer, | 370 Rasterizer* rasterizer, |
| 371 Rasterizer* gpu_rasterizer, | 371 Rasterizer* gpu_rasterizer, |
| 372 size_t max_raster_usage_bytes, | |
| 373 bool use_rasterize_on_demand, | 372 bool use_rasterize_on_demand, |
| 374 RenderingStatsInstrumentation* rendering_stats_instrumentation) { | 373 RenderingStatsInstrumentation* rendering_stats_instrumentation) { |
| 375 return make_scoped_ptr(new TileManager(client, | 374 return make_scoped_ptr(new TileManager(client, |
| 376 resource_pool, | 375 resource_pool, |
| 377 rasterizer, | 376 rasterizer, |
| 378 gpu_rasterizer, | 377 gpu_rasterizer, |
| 379 max_raster_usage_bytes, | |
| 380 use_rasterize_on_demand, | 378 use_rasterize_on_demand, |
| 381 rendering_stats_instrumentation)); | 379 rendering_stats_instrumentation)); |
| 382 } | 380 } |
| 383 | 381 |
| 384 TileManager::TileManager( | 382 TileManager::TileManager( |
| 385 TileManagerClient* client, | 383 TileManagerClient* client, |
| 386 ResourcePool* resource_pool, | 384 ResourcePool* resource_pool, |
| 387 Rasterizer* rasterizer, | 385 Rasterizer* rasterizer, |
| 388 Rasterizer* gpu_rasterizer, | 386 Rasterizer* gpu_rasterizer, |
| 389 size_t max_raster_usage_bytes, | |
| 390 bool use_rasterize_on_demand, | 387 bool use_rasterize_on_demand, |
| 391 RenderingStatsInstrumentation* rendering_stats_instrumentation) | 388 RenderingStatsInstrumentation* rendering_stats_instrumentation) |
| 392 : client_(client), | 389 : client_(client), |
| 393 resource_pool_(resource_pool), | 390 resource_pool_(resource_pool), |
| 394 prioritized_tiles_dirty_(false), | 391 prioritized_tiles_dirty_(false), |
| 395 all_tiles_that_need_to_be_rasterized_have_memory_(true), | 392 all_tiles_that_need_to_be_rasterized_have_memory_(true), |
| 396 all_tiles_required_for_activation_have_memory_(true), | 393 all_tiles_required_for_activation_have_memory_(true), |
| 397 memory_required_bytes_(0), | 394 memory_required_bytes_(0), |
| 398 memory_nice_to_have_bytes_(0), | 395 memory_nice_to_have_bytes_(0), |
| 399 bytes_releasable_(0), | 396 bytes_releasable_(0), |
| 400 resources_releasable_(0), | 397 resources_releasable_(0), |
| 401 max_raster_usage_bytes_(max_raster_usage_bytes), | |
| 402 ever_exceeded_memory_budget_(false), | 398 ever_exceeded_memory_budget_(false), |
| 403 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 399 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
| 404 did_initialize_visible_tile_(false), | 400 did_initialize_visible_tile_(false), |
| 405 did_check_for_completed_tasks_since_last_schedule_tasks_(true), | 401 did_check_for_completed_tasks_since_last_schedule_tasks_(true), |
| 406 use_rasterize_on_demand_(use_rasterize_on_demand) { | 402 use_rasterize_on_demand_(use_rasterize_on_demand) { |
| 407 Rasterizer* rasterizers[NUM_RASTERIZER_TYPES] = { | 403 Rasterizer* rasterizers[NUM_RASTERIZER_TYPES] = { |
| 408 rasterizer, // RASTERIZER_TYPE_DEFAULT | 404 rasterizer, // RASTERIZER_TYPE_DEFAULT |
| 409 gpu_rasterizer, // RASTERIZER_TYPE_GPU | 405 gpu_rasterizer, // RASTERIZER_TYPE_GPU |
| 410 }; | 406 }; |
| 411 rasterizer_delegate_ = | 407 rasterizer_delegate_ = |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 | 818 |
| 823 size_t bytes_that_exceeded_memory_budget = 0; | 819 size_t bytes_that_exceeded_memory_budget = 0; |
| 824 size_t soft_bytes_left = soft_bytes_allocatable; | 820 size_t soft_bytes_left = soft_bytes_allocatable; |
| 825 size_t hard_bytes_left = hard_bytes_allocatable; | 821 size_t hard_bytes_left = hard_bytes_allocatable; |
| 826 | 822 |
| 827 size_t resources_left = resources_allocatable; | 823 size_t resources_left = resources_allocatable; |
| 828 bool oomed_soft = false; | 824 bool oomed_soft = false; |
| 829 bool oomed_hard = false; | 825 bool oomed_hard = false; |
| 830 bool have_hit_soft_memory = false; // Soft memory comes after hard. | 826 bool have_hit_soft_memory = false; // Soft memory comes after hard. |
| 831 | 827 |
| 832 // Memory we assign to raster tasks now will be deducted from our memory | |
| 833 // in future iterations if priorities change. By assigning at most half | |
| 834 // the raster limit, we will always have another 50% left even if priorities | |
| 835 // change completely (assuming we check for completed/cancelled rasters | |
| 836 // between each call to this function). | |
| 837 size_t max_raster_bytes = max_raster_usage_bytes_ / 2; | |
| 838 size_t raster_bytes = 0; | |
| 839 | |
| 840 unsigned schedule_priority = 1u; | 828 unsigned schedule_priority = 1u; |
| 841 for (PrioritizedTileSet::Iterator it(tiles, true); it; ++it) { | 829 for (PrioritizedTileSet::Iterator it(tiles, true); it; ++it) { |
| 842 Tile* tile = *it; | 830 Tile* tile = *it; |
| 843 ManagedTileState& mts = tile->managed_state(); | 831 ManagedTileState& mts = tile->managed_state(); |
| 844 | 832 |
| 845 mts.scheduled_priority = schedule_priority++; | 833 mts.scheduled_priority = schedule_priority++; |
| 846 | 834 |
| 847 mts.raster_mode = tile->DetermineOverallRasterMode(); | 835 mts.raster_mode = tile->DetermineOverallRasterMode(); |
| 848 | 836 |
| 849 ManagedTileState::TileVersion& tile_version = | 837 ManagedTileState::TileVersion& tile_version = |
| 850 mts.tile_versions[mts.raster_mode]; | 838 mts.tile_versions[mts.raster_mode]; |
| 851 | 839 |
| 852 // If this tile doesn't need a resource, then nothing to do. | 840 // If this tile doesn't need a resource, then nothing to do. |
| 853 if (!tile_version.requires_resource()) | 841 if (!tile_version.requires_resource()) |
| 854 continue; | 842 continue; |
| 855 | 843 |
| 856 // If the tile is not needed, free it up. | 844 // If the tile is not needed, free it up. |
| 857 if (mts.bin == NEVER_BIN) { | 845 if (mts.bin == NEVER_BIN) { |
| 858 FreeResourcesForTile(tile); | 846 FreeResourcesForTile(tile); |
| 859 continue; | 847 continue; |
| 860 } | 848 } |
| 861 | 849 |
| 862 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN; | 850 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN; |
| 863 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); | 851 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); |
| 864 const size_t raster_bytes_if_rastered = raster_bytes + bytes_if_allocated; | |
| 865 const size_t tile_bytes_left = | 852 const size_t tile_bytes_left = |
| 866 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left; | 853 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left; |
| 867 | 854 |
| 868 // Hard-limit is reserved for tiles that would cause a calamity | 855 // Hard-limit is reserved for tiles that would cause a calamity |
| 869 // if they were to go away, so by definition they are the highest | 856 // if they were to go away, so by definition they are the highest |
| 870 // priority memory, and must be at the front of the list. | 857 // priority memory, and must be at the front of the list. |
| 871 DCHECK(!(have_hit_soft_memory && tile_uses_hard_limit)); | 858 DCHECK(!(have_hit_soft_memory && tile_uses_hard_limit)); |
| 872 have_hit_soft_memory |= !tile_uses_hard_limit; | 859 have_hit_soft_memory |= !tile_uses_hard_limit; |
| 873 | 860 |
| 874 size_t tile_bytes = 0; | 861 size_t tile_bytes = 0; |
| 875 size_t tile_resources = 0; | 862 size_t tile_resources = 0; |
| 876 | 863 |
| 877 // It costs to maintain a resource. | 864 // It costs to maintain a resource. |
| 878 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | 865 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| 879 if (mts.tile_versions[mode].resource_) { | 866 if (mts.tile_versions[mode].resource_) { |
| 880 tile_bytes += bytes_if_allocated; | 867 tile_bytes += bytes_if_allocated; |
| 881 tile_resources++; | 868 tile_resources++; |
| 882 } | 869 } |
| 883 } | 870 } |
| 884 | 871 |
| 885 // Allow lower priority tiles with initialized resources to keep | 872 // Allow lower priority tiles with initialized resources to keep |
| 886 // their memory by only assigning memory to new raster tasks if | 873 // their memory by only assigning memory to new raster tasks if |
| 887 // they can be scheduled. | 874 // they can be scheduled. |
| 888 if (raster_bytes_if_rastered <= max_raster_bytes) { | 875 bool reached_scheduled_raster_tasks_limit = |
| 876 tiles_that_need_to_be_rasterized->size() >= kScheduledRasterTasksLimit; |
| 877 if (!reached_scheduled_raster_tasks_limit) { |
| 889 // If we don't have the required version, and it's not in flight | 878 // If we don't have the required version, and it's not in flight |
| 890 // then we'll have to pay to create a new task. | 879 // then we'll have to pay to create a new task. |
| 891 if (!tile_version.resource_ && !tile_version.raster_task_) { | 880 if (!tile_version.resource_ && !tile_version.raster_task_) { |
| 892 tile_bytes += bytes_if_allocated; | 881 tile_bytes += bytes_if_allocated; |
| 893 tile_resources++; | 882 tile_resources++; |
| 894 } | 883 } |
| 895 } | 884 } |
| 896 | 885 |
| 897 // Tile is OOM. | 886 // Tile is OOM. |
| 898 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { | 887 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 922 | 911 |
| 923 // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized| | 912 // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized| |
| 924 // has reached it's limit or we've failed to assign gpu memory to this | 913 // has reached it's limit or we've failed to assign gpu memory to this |
| 925 // or any higher priority tile. Preventing tiles that fit into memory | 914 // or any higher priority tile. Preventing tiles that fit into memory |
| 926 // budget to be rasterized when higher priority tile is oom is | 915 // budget to be rasterized when higher priority tile is oom is |
| 927 // important for two reasons: | 916 // important for two reasons: |
| 928 // 1. Tile size should not impact raster priority. | 917 // 1. Tile size should not impact raster priority. |
| 929 // 2. Tiles with existing raster task could otherwise incorrectly | 918 // 2. Tiles with existing raster task could otherwise incorrectly |
| 930 // be added as they are not affected by |bytes_allocatable|. | 919 // be added as they are not affected by |bytes_allocatable|. |
| 931 bool can_schedule_tile = | 920 bool can_schedule_tile = |
| 932 !oomed_soft && raster_bytes_if_rastered <= max_raster_bytes && | 921 !oomed_soft && !reached_scheduled_raster_tasks_limit; |
| 933 tiles_that_need_to_be_rasterized->size() < kScheduledRasterTasksLimit; | |
| 934 | 922 |
| 935 if (!can_schedule_tile) { | 923 if (!can_schedule_tile) { |
| 936 all_tiles_that_need_to_be_rasterized_have_memory_ = false; | 924 all_tiles_that_need_to_be_rasterized_have_memory_ = false; |
| 937 if (tile->required_for_activation()) | 925 if (tile->required_for_activation()) |
| 938 all_tiles_required_for_activation_have_memory_ = false; | 926 all_tiles_required_for_activation_have_memory_ = false; |
| 939 it.DisablePriorityOrdering(); | 927 it.DisablePriorityOrdering(); |
| 940 continue; | 928 continue; |
| 941 } | 929 } |
| 942 | 930 |
| 943 raster_bytes = raster_bytes_if_rastered; | |
| 944 tiles_that_need_to_be_rasterized->push_back(tile); | 931 tiles_that_need_to_be_rasterized->push_back(tile); |
| 945 } | 932 } |
| 946 | 933 |
| 947 // OOM reporting uses hard-limit, soft-OOM is normal depending on limit. | 934 // OOM reporting uses hard-limit, soft-OOM is normal depending on limit. |
| 948 ever_exceeded_memory_budget_ |= oomed_hard; | 935 ever_exceeded_memory_budget_ |= oomed_hard; |
| 949 if (ever_exceeded_memory_budget_) { | 936 if (ever_exceeded_memory_budget_) { |
| 950 TRACE_COUNTER_ID2("cc", | 937 TRACE_COUNTER_ID2("cc", |
| 951 "over_memory_budget", | 938 "over_memory_budget", |
| 952 this, | 939 this, |
| 953 "budget", | 940 "budget", |
| (...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1623 | 1610 |
| 1624 if (b_priority.resolution != a_priority.resolution) { | 1611 if (b_priority.resolution != a_priority.resolution) { |
| 1625 return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || | 1612 return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || |
| 1626 (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || | 1613 (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || |
| 1627 (a_priority.resolution == NON_IDEAL_RESOLUTION); | 1614 (a_priority.resolution == NON_IDEAL_RESOLUTION); |
| 1628 } | 1615 } |
| 1629 return a_priority.IsHigherPriorityThan(b_priority); | 1616 return a_priority.IsHigherPriorityThan(b_priority); |
| 1630 } | 1617 } |
| 1631 | 1618 |
| 1632 } // namespace cc | 1619 } // namespace cc |
| OLD | NEW |