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 |