Index: cc/tiles/gpu_image_decode_cache.cc |
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc |
index 3ae2645f4b50695e545c5cabd4228115e8d3aa4f..7f75c888d8adc413831e88726b609c0cd00a0d1e 100644 |
--- a/cc/tiles/gpu_image_decode_cache.cc |
+++ b/cc/tiles/gpu_image_decode_cache.cc |
@@ -149,11 +149,13 @@ class ImageDecodeTaskImpl : public TileTask { |
public: |
ImageDecodeTaskImpl(GpuImageDecodeCache* cache, |
const DrawImage& draw_image, |
- const ImageDecodeCache::TracingInfo& tracing_info) |
+ const ImageDecodeCache::TracingInfo& tracing_info, |
+ GpuImageDecodeCache::DecodeTaskType task_type) |
: TileTask(true), |
cache_(cache), |
image_(draw_image), |
- tracing_info_(tracing_info) { |
+ tracing_info_(tracing_info), |
+ task_type_(task_type) { |
DCHECK(!SkipImage(draw_image)); |
} |
@@ -169,7 +171,7 @@ class ImageDecodeTaskImpl : public TileTask { |
// Overridden from TileTask: |
void OnTaskCompleted() override { |
- cache_->OnImageDecodeTaskCompleted(image_); |
+ cache_->OnImageDecodeTaskCompleted(image_, task_type_); |
} |
protected: |
@@ -179,6 +181,7 @@ class ImageDecodeTaskImpl : public TileTask { |
GpuImageDecodeCache* cache_; |
DrawImage image_; |
const ImageDecodeCache::TracingInfo tracing_info_; |
+ const GpuImageDecodeCache::DecodeTaskType task_type_; |
DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); |
}; |
@@ -380,6 +383,22 @@ GpuImageDecodeCache::~GpuImageDecodeCache() { |
bool GpuImageDecodeCache::GetTaskForImageAndRef(const DrawImage& draw_image, |
const TracingInfo& tracing_info, |
scoped_refptr<TileTask>* task) { |
+ return GetTaskForImageAndRefInternal( |
+ draw_image, tracing_info, DecodeTaskType::PART_OF_UPLOAD_TASK, task); |
+} |
+ |
+bool GpuImageDecodeCache::GetOutOfRasterDecodeTaskForImageAndRef( |
+ const DrawImage& draw_image, |
+ scoped_refptr<TileTask>* task) { |
+ return GetTaskForImageAndRefInternal( |
+ draw_image, TracingInfo(), DecodeTaskType::STAND_ALONE_DECODE_TASK, task); |
+} |
+ |
+bool GpuImageDecodeCache::GetTaskForImageAndRefInternal( |
+ const DrawImage& draw_image, |
+ const TracingInfo& tracing_info, |
+ DecodeTaskType task_type, |
+ scoped_refptr<TileTask>* task) { |
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
"GpuImageDecodeCache::GetTaskForImageAndRef"); |
if (SkipImage(draw_image)) { |
@@ -408,11 +427,18 @@ bool GpuImageDecodeCache::GetTaskForImageAndRef(const DrawImage& draw_image, |
RefImage(draw_image); |
*task = nullptr; |
return true; |
- } else if (image_data->upload.task) { |
+ } else if (task_type == DecodeTaskType::PART_OF_UPLOAD_TASK && |
+ image_data->upload.task) { |
// We had an existing upload task, ref the image and return the task. |
RefImage(draw_image); |
*task = image_data->upload.task; |
return true; |
+ } else if (task_type == DecodeTaskType::STAND_ALONE_DECODE_TASK && |
+ image_data->decode.stand_alone_task) { |
+ // We had an existing out of raster task, ref the image and return the task. |
+ RefImage(draw_image); |
+ *task = image_data->decode.stand_alone_task; |
+ return true; |
} |
// Ensure that the image we're about to decode/upload will fit in memory. |
@@ -427,13 +453,18 @@ bool GpuImageDecodeCache::GetTaskForImageAndRef(const DrawImage& draw_image, |
if (new_data) |
persistent_cache_.Put(image_id, std::move(new_data)); |
- // Ref image and create a upload and decode tasks. We will release this ref |
- // in UploadTaskCompleted. |
- RefImage(draw_image); |
- *task = make_scoped_refptr(new ImageUploadTaskImpl( |
- this, draw_image, GetImageDecodeTaskAndRef(draw_image, tracing_info), |
- tracing_info)); |
- image_data->upload.task = *task; |
+ if (task_type == DecodeTaskType::PART_OF_UPLOAD_TASK) { |
+ // Ref image and create a upload and decode tasks. We will release this ref |
+ // in UploadTaskCompleted. |
+ RefImage(draw_image); |
+ *task = make_scoped_refptr(new ImageUploadTaskImpl( |
+ this, draw_image, |
+ GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type), |
+ tracing_info)); |
+ image_data->upload.task = *task; |
+ } else { |
+ *task = GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type); |
+ } |
// Ref the image again - this ref is owned by the caller, and it is their |
// responsibility to release it by calling UnrefImage. |
@@ -647,15 +678,22 @@ void GpuImageDecodeCache::UploadImage(const DrawImage& draw_image) { |
} |
void GpuImageDecodeCache::OnImageDecodeTaskCompleted( |
- const DrawImage& draw_image) { |
+ const DrawImage& draw_image, |
+ DecodeTaskType task_type) { |
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
"GpuImageDecodeCache::OnImageDecodeTaskCompleted"); |
base::AutoLock lock(lock_); |
// Decode task is complete, remove our reference to it. |
ImageData* image_data = GetImageDataForDrawImage(draw_image); |
DCHECK(image_data); |
- DCHECK(image_data->decode.task); |
- image_data->decode.task = nullptr; |
+ if (task_type == DecodeTaskType::PART_OF_UPLOAD_TASK) { |
+ DCHECK(image_data->decode.task); |
+ image_data->decode.task = nullptr; |
+ } else { |
+ DCHECK(task_type == DecodeTaskType::STAND_ALONE_DECODE_TASK); |
+ DCHECK(image_data->decode.stand_alone_task); |
+ image_data->decode.stand_alone_task = nullptr; |
+ } |
// While the decode task is active, we keep a ref on the decoded data. |
// Release that ref now. |
@@ -684,14 +722,16 @@ void GpuImageDecodeCache::OnImageUploadTaskCompleted( |
// the requested decode. |
scoped_refptr<TileTask> GpuImageDecodeCache::GetImageDecodeTaskAndRef( |
const DrawImage& draw_image, |
- const TracingInfo& tracing_info) { |
+ const TracingInfo& tracing_info, |
+ DecodeTaskType task_type) { |
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
"GpuImageDecodeCache::GetImageDecodeTaskAndRef"); |
lock_.AssertAcquired(); |
// This ref is kept alive while an upload task may need this decode. We |
// release this ref in UploadTaskCompleted. |
- RefImageDecode(draw_image); |
+ if (task_type == DecodeTaskType::PART_OF_UPLOAD_TASK) |
+ RefImageDecode(draw_image); |
ImageData* image_data = GetImageDataForDrawImage(draw_image); |
DCHECK(image_data); |
@@ -704,13 +744,16 @@ scoped_refptr<TileTask> GpuImageDecodeCache::GetImageDecodeTaskAndRef( |
} |
// We didn't have an existing locked image, create a task to lock or decode. |
- scoped_refptr<TileTask>& existing_task = image_data->decode.task; |
+ scoped_refptr<TileTask>& existing_task = |
+ (task_type == DecodeTaskType::PART_OF_UPLOAD_TASK) |
+ ? image_data->decode.task |
+ : image_data->decode.stand_alone_task; |
if (!existing_task) { |
// Ref image decode and create a decode task. This ref will be released in |
// DecodeTaskCompleted. |
RefImageDecode(draw_image); |
existing_task = make_scoped_refptr( |
- new ImageDecodeTaskImpl(this, draw_image, tracing_info)); |
+ new ImageDecodeTaskImpl(this, draw_image, tracing_info, task_type)); |
} |
return existing_task; |
} |
@@ -857,10 +900,11 @@ void GpuImageDecodeCache::OwnershipChanged(const DrawImage& draw_image, |
// We should unlock the discardable memory for the image in two cases: |
// 1) The image is no longer being used (no decode or upload refs). |
// 2) This is a GPU backed image that has already been uploaded (no decode |
- // refs). |
+ // refs, and we actually already have an image). |
bool should_unlock_discardable = |
- !has_any_refs || (image_data->mode == DecodedDataMode::GPU && |
- !image_data->decode.ref_count); |
+ !has_any_refs || |
+ (image_data->mode == DecodedDataMode::GPU && |
+ !image_data->decode.ref_count && image_data->upload.image()); |
if (should_unlock_discardable && image_data->decode.is_locked()) { |
DCHECK(image_data->decode.data()); |