Index: cc/resources/tile_manager.cc |
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc |
index 8edacf6896dbeeefb13022df1f679404577f09f4..0d0afd8b8eca8d1ddf9c5ac797abd34dc17f8316 100644 |
--- a/cc/resources/tile_manager.cc |
+++ b/cc/resources/tile_manager.cc |
@@ -16,6 +16,7 @@ |
#include "cc/resources/image_raster_worker_pool.h" |
#include "cc/resources/pixel_buffer_raster_worker_pool.h" |
#include "cc/resources/tile.h" |
+#include "skia/ext/paint_simplifier.h" |
#include "third_party/skia/include/core/SkCanvas.h" |
#include "ui/gfx/rect_conversions.h" |
@@ -23,6 +24,18 @@ namespace cc { |
namespace { |
+class DisableLCDTextFilter : public SkDrawFilter { |
+ public: |
+ // SkDrawFilter interface. |
+ virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) OVERRIDE { |
+ if (type != SkDrawFilter::kText_Type) |
+ return true; |
+ |
+ paint->setLCDRenderText(false); |
+ return true; |
+ } |
+}; |
+ |
// Determine bin based on three categories of tiles: things we need now, |
// things we need soon, and eventually. |
inline TileManagerBin BinFromTilePriority(const TilePriority& prio) { |
@@ -306,15 +319,21 @@ void TileManager::CheckForCompletedTileUploads() { |
it != tiles_that_need_to_be_initialized_for_activation_.end(); |
++it) { |
Tile* tile = *it; |
- if (!tile->managed_state().raster_task.is_null() && |
- !tile->tile_version().forced_upload_) { |
- if (!raster_worker_pool_->ForceUploadToComplete( |
- tile->managed_state().raster_task)) |
- continue; |
+ ManagedTileState& mts = tile->managed_state(); |
- // Setting |forced_upload_| to true makes this tile ready to draw. |
reveman
2013/06/05 18:01:32
lets keep this comment. just s/this tile/this tile
vmpstr
2013/06/06 01:54:20
Done.
|
- tile->tile_version().forced_upload_ = true; |
- initialized_tiles.insert(tile); |
+ for (int mode = NUM_RASTER_MODES - 1; mode >= 0; --mode) { |
+ ManagedTileState::TileVersion& pending_version = |
+ mts.tile_versions[mode]; |
+ if (!pending_version.raster_task_.is_null() && |
+ !pending_version.forced_upload_) { |
+ if (!raster_worker_pool_->ForceUploadToComplete( |
+ pending_version.raster_task_)) { |
+ continue; |
+ } |
+ pending_version.forced_upload_ = true; |
+ initialized_tiles.insert(tile); |
+ break; |
+ } |
} |
} |
@@ -393,6 +412,22 @@ void TileManager::AddRequiredTileForActivation(Tile* tile) { |
tiles_that_need_to_be_initialized_for_activation_.insert(tile); |
} |
+TileRasterMode TileManager::DetermineRasterMode(const Tile* tile) const { |
+ DCHECK(tile); |
+ DCHECK(tile->picture_pile()); |
+ |
+ TileRasterMode raster_mode; |
+ |
+ if (tile->managed_state().resolution == LOW_RESOLUTION) |
+ raster_mode = LOW_QUALITY_RASTER_MODE; |
+ else if (!tile->picture_pile()->can_use_lcd_text()) |
+ raster_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; |
+ else |
+ raster_mode = HIGH_QUALITY_RASTER_MODE; |
+ |
+ return raster_mode; |
+} |
+ |
void TileManager::AssignGpuMemoryToTiles() { |
TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
@@ -429,7 +464,9 @@ void TileManager::AssignGpuMemoryToTiles() { |
++it) { |
Tile* tile = *it; |
ManagedTileState& mts = tile->managed_state(); |
- ManagedTileState::TileVersion& tile_version = tile->tile_version(); |
+ mts.raster_mode = DetermineRasterMode(tile); |
reveman
2013/06/05 18:01:32
Please DCHECK that new raster_mode is not worse th
vmpstr
2013/06/06 01:54:20
Turns out that when you switch tabs, the inactive
|
+ ManagedTileState::TileVersion& tile_version = |
+ mts.tile_versions[mts.raster_mode]; |
// If this tile doesn't need a resource, then nothing to do. |
if (!tile_version.requires_resource()) |
@@ -444,14 +481,16 @@ void TileManager::AssignGpuMemoryToTiles() { |
size_t tile_bytes = 0; |
// It costs to maintain a resource. |
- if (tile_version.resource_) |
- tile_bytes += tile->bytes_consumed_if_allocated(); |
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
+ if (mts.tile_versions[mode].resource_) |
+ tile_bytes += tile->bytes_consumed_if_allocated(); |
+ } |
- // It will cost to allocate a resource. |
- // Note that this is separate from the above condition, |
- // so that it's clear why we're adding memory. |
- if (!tile_version.resource_ && mts.raster_task.is_null()) |
+ // If we don't have the required version, and it's not in flight |
+ // then we'll have to pay to create a new task. |
+ if (!tile_version.resource_ && tile_version.raster_task_.is_null()) { |
tile_bytes += tile->bytes_consumed_if_allocated(); |
+ } |
reveman
2013/06/05 18:01:32
nit: {} not required
vmpstr
2013/06/06 01:54:20
Done.
|
// Tile is OOM. |
if (tile_bytes > bytes_left) { |
@@ -480,8 +519,11 @@ void TileManager::AssignGpuMemoryToTiles() { |
if (!tile_version.resource_) |
tiles_that_need_to_be_rasterized_.push_back(tile); |
- if (!tile_version.resource_ && tile->required_for_activation()) |
+ if (!tile_version.resource_ && |
reveman
2013/06/05 18:01:32
should the "!tile_version.resource_" be here? seem
vmpstr
2013/06/06 01:54:20
Done.
|
+ !tile->tile_version().IsReadyToDraw() && |
+ tile->required_for_activation()) { |
AddRequiredTileForActivation(tile); |
+ } |
} |
// In OOM situation, we iterate tiles_, remove the memory for active tree |
@@ -491,7 +533,8 @@ void TileManager::AssignGpuMemoryToTiles() { |
for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
Tile* tile = *it; |
ManagedTileState& mts = tile->managed_state(); |
- ManagedTileState::TileVersion& tile_version = tile->tile_version(); |
+ ManagedTileState::TileVersion& tile_version = |
+ mts.tile_versions[mts.raster_mode]; |
reveman
2013/06/05 18:01:32
Do you need a TileRasterMode loop here to free all
vmpstr
2013/06/06 01:54:20
Done.
|
if (tile_version.resource_ && |
mts.tree_bin[PENDING_TREE] == NEVER_BIN && |
mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { |
@@ -514,10 +557,11 @@ void TileManager::AssignGpuMemoryToTiles() { |
it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0; |
++it) { |
Tile* tile = *it; |
+ ManagedTileState& mts = tile->managed_state(); |
size_t bytes_needed = tile->bytes_consumed_if_allocated(); |
if (bytes_needed > bytes_freed) |
continue; |
- tile->tile_version().set_use_resource(); |
+ mts.tile_versions[mts.raster_mode].set_use_resource(); |
bytes_freed -= bytes_needed; |
tiles_that_need_to_be_rasterized_.push_back(tile); |
if (tile->required_for_activation()) |
@@ -543,9 +587,24 @@ void TileManager::AssignGpuMemoryToTiles() { |
} |
void TileManager::FreeResourcesForTile(Tile* tile) { |
- if (tile->tile_version().resource_) { |
- resource_pool_->ReleaseResource( |
- tile->tile_version().resource_.Pass()); |
+ ManagedTileState& mts = tile->managed_state(); |
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
+ if (mts.tile_versions[mode].resource_) { |
+ resource_pool_->ReleaseResource( |
+ mts.tile_versions[mode].resource_.Pass()); |
+ } |
+ } |
+} |
+ |
+void TileManager::FreeUnusedResourcesForTile(Tile* tile) { |
+ ManagedTileState& mts = tile->managed_state(); |
+ ManagedTileState::TileVersion& used_tile_version = tile->tile_version(); |
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
+ if (&mts.tile_versions[mode] != &used_tile_version && |
+ mts.tile_versions[mode].resource_) { |
+ resource_pool_->ReleaseResource( |
+ mts.tile_versions[mode].resource_.Pass()); |
+ } |
} |
} |
@@ -560,16 +619,15 @@ void TileManager::ScheduleTasks() { |
++it) { |
Tile* tile = *it; |
ManagedTileState& mts = tile->managed_state(); |
+ ManagedTileState::TileVersion& tile_version = |
+ mts.tile_versions[mts.raster_mode]; |
- DCHECK(tile->tile_version().requires_resource()); |
- DCHECK(!tile->tile_version().resource_); |
+ DCHECK(tile_version.requires_resource()); |
- // Create raster task for this tile if necessary. |
- if (mts.raster_task.is_null()) |
- mts.raster_task = CreateRasterTask(tile); |
+ if (tile_version.raster_task_.is_null()) |
+ tile_version.raster_task_ = CreateRasterTask(tile); |
- // Finally append raster task. |
- tasks.Append(mts.raster_task); |
+ tasks.Append(tile_version.raster_task_); |
} |
// Schedule running of |tasks|. This replaces any previously |
@@ -611,6 +669,7 @@ TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( |
metadata.layer_id = tile.layer_id(); |
metadata.tile_id = &tile; |
metadata.source_frame_number = tile.source_frame_number(); |
+ metadata.raster_mode = mts.raster_mode; |
return metadata; |
} |
@@ -623,7 +682,8 @@ RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) { |
tile->tile_version().resource_format_); |
const Resource* const_resource = resource.get(); |
- tile->tile_version().resource_id_ = resource->id(); |
+ ManagedTileState& mts = tile->managed_state(); |
+ mts.tile_versions[mts.raster_mode].resource_id_ = resource->id(); |
PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; |
@@ -656,6 +716,7 @@ RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) { |
pending_decode_tasks_[id] = decode_task; |
} |
+ RasterTaskMetadata metadata = GetRasterTaskMetadata(*tile); |
return RasterWorkerPool::RasterTask( |
tile->picture_pile(), |
const_resource, |
@@ -665,19 +726,20 @@ RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) { |
tile->content_rect(), |
tile->contents_scale(), |
use_color_estimator_, |
- GetRasterTaskMetadata(*tile), |
+ metadata, |
rendering_stats_instrumentation_), |
base::Bind(&TileManager::RunRasterTask, |
analysis, |
tile->content_rect(), |
tile->contents_scale(), |
- GetRasterTaskMetadata(*tile), |
+ metadata, |
rendering_stats_instrumentation_)), |
base::Bind(&TileManager::OnRasterTaskCompleted, |
base::Unretained(this), |
make_scoped_refptr(tile), |
base::Passed(&resource), |
- base::Owned(analysis)), |
+ base::Owned(analysis), |
+ metadata.raster_mode), |
&decode_tasks); |
} |
@@ -685,16 +747,20 @@ void TileManager::OnRasterTaskCompleted( |
scoped_refptr<Tile> tile, |
scoped_ptr<ResourcePool::Resource> resource, |
PicturePileImpl::Analysis* analysis, |
+ TileRasterMode raster_mode, |
bool was_canceled) { |
TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted", |
"was_canceled", was_canceled); |
ManagedTileState& mts = tile->managed_state(); |
- DCHECK(!mts.raster_task.is_null()); |
reveman
2013/06/05 18:01:32
please keep this DCHECK.
vmpstr
2013/06/06 01:54:20
Done.
|
- mts.raster_task.Reset(); |
+ ManagedTileState::TileVersion& tile_version = |
+ mts.tile_versions[raster_mode]; |
+ tile_version.raster_task_.Reset(); |
+ tile_version.resource_ = resource.Pass(); |
reveman
2013/06/05 18:01:32
can you do this below the was_canceled check as be
vmpstr
2013/06/06 01:54:20
Done.
|
+ tile_version.forced_upload_ = false; |
reveman
2013/06/05 18:01:32
this is new. do we need it?
vmpstr
2013/06/06 01:54:20
I don't really see where the flag is reset back in
reveman
2013/06/06 06:02:02
Good call. This might be causing some of the rende
|
if (was_canceled) { |
- resource_pool_->ReleaseResource(resource.Pass()); |
+ resource_pool_->ReleaseResource(tile_version.resource_.Pass()); |
return; |
} |
@@ -702,12 +768,12 @@ void TileManager::OnRasterTaskCompleted( |
mts.picture_pile_analyzed = true; |
if (analysis->is_solid_color) { |
- tile->tile_version().set_solid_color(analysis->solid_color); |
- resource_pool_->ReleaseResource(resource.Pass()); |
- } else { |
- tile->tile_version().resource_ = resource.Pass(); |
+ resource_pool_->ReleaseResource(tile_version.resource_.Pass()); |
+ tile_version.set_solid_color(analysis->solid_color); |
} |
+ FreeUnusedResourcesForTile(tile.get()); |
+ |
DidFinishTileInitialization(tile.get()); |
} |
@@ -791,6 +857,7 @@ scoped_ptr<base::Value> TileManager::RasterTaskMetadata::AsValue() const { |
is_tile_in_pending_tree_now_bin); |
res->Set("resolution", TileResolutionAsValue(tile_resolution).release()); |
res->SetInteger("source_frame_number", source_frame_number); |
+ res->SetInteger("raster_mode", raster_mode); |
return res.PassAs<base::Value>(); |
} |
@@ -818,6 +885,23 @@ bool TileManager::RunRasterTask( |
SkCanvas canvas(device); |
+ skia::RefPtr<SkDrawFilter> draw_filter; |
+ switch (metadata.raster_mode) { |
+ case LOW_QUALITY_RASTER_MODE: |
+ draw_filter = skia::AdoptRef(new skia::PaintSimplifier); |
+ break; |
+ case HIGH_QUALITY_NO_LCD_RASTER_MODE: |
+ draw_filter = skia::AdoptRef(new DisableLCDTextFilter); |
+ break; |
+ case HIGH_QUALITY_RASTER_MODE: |
+ break; |
+ case NUM_RASTER_MODES: |
+ default: |
+ NOTREACHED(); |
+ } |
+ |
+ canvas.setDrawFilter(draw_filter.get()); |
+ |
if (stats_instrumentation->record_rendering_stats()) { |
PicturePileImpl::RasterStats raster_stats; |
picture_pile->RasterToBitmap(&canvas, rect, contents_scale, &raster_stats); |