Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Unified Diff: cc/resources/tile_manager.cc

Issue 15995033: cc: Low quality support for low res tiles (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: unittest fix Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/resources/tile_manager.cc
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index 8edacf6896dbeeefb13022df1f679404577f09f4..65572d624c9fb563cee3495764914df662b7ed85 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,23 @@ 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.
- tile->tile_version().forced_upload_ = true;
- initialized_tiles.insert(tile);
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++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;
+ }
+ // Setting |forced_upload_| to true makes this tile version
+ // ready to draw.
+ pending_version.forced_upload_ = true;
+ initialized_tiles.insert(tile);
+ break;
+ }
}
}
@@ -323,7 +344,7 @@ void TileManager::CheckForCompletedTileUploads() {
++it) {
Tile* tile = *it;
DidFinishTileInitialization(tile);
- DCHECK(tile->tile_version().IsReadyToDraw());
+ DCHECK(tile->IsReadyToDraw(NULL));
}
}
@@ -338,10 +359,14 @@ void TileManager::GetMemoryStats(
it != tiles_.end();
++it) {
const Tile* tile = *it;
- if (!tile->tile_version().requires_resource())
- continue;
-
const ManagedTileState& mts = tile->managed_state();
+
+ TileRasterMode mode;
+ if (tile->IsReadyToDraw(&mode)) {
+ if (!mts.tile_versions[mode].requires_resource())
reveman 2013/06/06 06:02:02 use one if statement with && instead
vmpstr 2013/06/06 15:20:22 Done.
+ continue;
+ }
+
size_t tile_bytes = tile->bytes_consumed_if_allocated();
if (mts.gpu_memmgr_stats_bin == NOW_BIN)
*memory_required_bytes += tile_bytes;
@@ -393,6 +418,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");
@@ -406,8 +447,11 @@ void TileManager::AssignGpuMemoryToTiles() {
it != tiles_.end();
++it) {
const Tile* tile = *it;
- if (tile->tile_version().resource_)
- bytes_releasable += tile->bytes_consumed_if_allocated();
+ const ManagedTileState& mts = tile->managed_state();
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ if (mts.tile_versions[mode].resource_)
+ bytes_releasable += tile->bytes_consumed_if_allocated();
+ }
}
// Cast to prevent overflow.
@@ -429,7 +473,15 @@ void TileManager::AssignGpuMemoryToTiles() {
++it) {
Tile* tile = *it;
ManagedTileState& mts = tile->managed_state();
- ManagedTileState::TileVersion& tile_version = tile->tile_version();
+
+ TileRasterMode ready_mode;
+ TileRasterMode desired_mode = DetermineRasterMode(tile);
+ if (tile->IsReadyToDraw(&ready_mode) && (ready_mode > desired_mode))
vmpstr 2013/06/06 02:08:35 That should read ready_mode < desired_mode. I'll f
reveman 2013/06/06 06:02:02 why IsReadyToDraw? If you prevent new tasks from b
vmpstr 2013/06/06 15:20:22 Good point, changed this to min
+ desired_mode = ready_mode;
+
+ mts.raster_mode = desired_mode;
+ 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,18 +496,19 @@ 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();
// Tile is OOM.
if (tile_bytes > bytes_left) {
- tile->tile_version().set_rasterize_on_demand();
+ mts.tile_versions[mts.raster_mode].set_rasterize_on_demand();
if (mts.tree_bin[PENDING_TREE] == NOW_BIN) {
tiles_requiring_memory_but_oomed.push_back(tile);
bytes_oom_in_now_bin_on_pending_tree += tile_bytes;
@@ -480,8 +533,10 @@ 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->IsReadyToDraw(NULL) &&
+ tile->required_for_activation()) {
AddRequiredTileForActivation(tile);
+ }
}
// In OOM situation, we iterate tiles_, remove the memory for active tree
@@ -491,33 +546,44 @@ 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();
- if (tile_version.resource_ &&
- mts.tree_bin[PENDING_TREE] == NEVER_BIN &&
+ if (mts.tree_bin[PENDING_TREE] == NEVER_BIN &&
mts.tree_bin[ACTIVE_TREE] != NOW_BIN) {
- DCHECK(!tile->required_for_activation());
- FreeResourcesForTile(tile);
- tile_version.set_rasterize_on_demand();
- bytes_freed += tile->bytes_consumed_if_allocated();
- TileVector::iterator it = std::find(
- tiles_that_need_to_be_rasterized_.begin(),
- tiles_that_need_to_be_rasterized_.end(),
- tile);
- if (it != tiles_that_need_to_be_rasterized_.end())
- tiles_that_need_to_be_rasterized_.erase(it);
- if (bytes_oom_in_now_bin_on_pending_tree <= bytes_freed)
- break;
+ bool has_memory = false;
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ ManagedTileState::TileVersion& tile_version =
+ mts.tile_versions[mode];
+ if (tile_version.resource_) {
+ DCHECK(!tile->required_for_activation());
+ bytes_freed += tile->bytes_consumed_if_allocated();
+ has_memory = true;
+ }
+ }
+
+ if (has_memory) {
reveman 2013/06/06 06:02:02 is this conditional necessary?
vmpstr 2013/06/06 15:20:22 I changed this a bit. I prefer to still keep this
+ FreeResourcesForTile(tile);
+ mts.tile_versions[mts.raster_mode].set_rasterize_on_demand();
+ TileVector::iterator it = std::find(
+ tiles_that_need_to_be_rasterized_.begin(),
+ tiles_that_need_to_be_rasterized_.end(),
+ tile);
+ if (it != tiles_that_need_to_be_rasterized_.end())
+ tiles_that_need_to_be_rasterized_.erase(it);
+ }
}
+
+ if (bytes_oom_in_now_bin_on_pending_tree <= bytes_freed)
+ break;
}
for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin();
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 +609,25 @@ 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());
+ }
reveman 2013/06/06 06:02:02 maybe move the inner part of this loop to a FreeRe
vmpstr 2013/06/06 15:20:22 Done.
+ }
+}
+
+void TileManager::FreeUnusedResourcesForTile(Tile* tile) {
+ ManagedTileState& mts = tile->managed_state();
+ TileRasterMode used_mode;
+ bool version_is_used = tile->IsReadyToDraw(&used_mode);
+ for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
+ if ((!version_is_used || mode != used_mode) &&
+ mts.tile_versions[mode].resource_) {
+ resource_pool_->ReleaseResource(
+ mts.tile_versions[mode].resource_.Pass());
+ }
}
}
@@ -560,16 +642,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_);
reveman 2013/06/06 06:02:02 Why has this DCHECK been removed?
vmpstr 2013/06/06 15:20:22 Whoops. Added it back.
+ 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,19 +692,22 @@ 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;
}
RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) {
TRACE_EVENT0("cc", "TileManager::CreateRasterTask");
+ ManagedTileState& mts = tile->managed_state();
+
scoped_ptr<ResourcePool::Resource> resource =
resource_pool_->AcquireResource(
tile->tile_size_.size(),
- tile->tile_version().resource_format_);
+ mts.tile_versions[mts.raster_mode].resource_format_);
const Resource* const_resource = resource.get();
- tile->tile_version().resource_id_ = resource->id();
+ mts.tile_versions[mts.raster_mode].resource_id_ = resource->id();
PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis;
@@ -656,6 +740,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 +750,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,13 +771,17 @@ 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());
- mts.raster_task.Reset();
+ ManagedTileState::TileVersion& tile_version =
+ mts.tile_versions[raster_mode];
+ DCHECK(!mts.tile_versions[raster_mode].raster_task_.is_null());
+ tile_version.raster_task_.Reset();
+ tile_version.forced_upload_ = false;
if (was_canceled) {
resource_pool_->ReleaseResource(resource.Pass());
@@ -702,12 +792,14 @@ void TileManager::OnRasterTaskCompleted(
mts.picture_pile_analyzed = true;
if (analysis->is_solid_color) {
- tile->tile_version().set_solid_color(analysis->solid_color);
+ tile_version.set_solid_color(analysis->solid_color);
resource_pool_->ReleaseResource(resource.Pass());
} else {
- tile->tile_version().resource_ = resource.Pass();
+ tile_version.resource_ = resource.Pass();
}
+ FreeUnusedResourcesForTile(tile.get());
+
DidFinishTileInitialization(tile.get());
}
@@ -791,6 +883,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 +911,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);
« cc/resources/tile.h ('K') | « cc/resources/tile_manager.h ('k') | cc/test/skia_common.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698