summaryrefslogtreecommitdiff
path: root/chromium/cc/tiles
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 10:22:43 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 12:36:28 +0000
commit271a6c3487a14599023a9106329505597638d793 (patch)
treee040d58ffc86c1480b79ca8528020ca9ec919bf8 /chromium/cc/tiles
parent7b2ffa587235a47d4094787d72f38102089f402a (diff)
downloadqtwebengine-chromium-271a6c3487a14599023a9106329505597638d793.tar.gz
BASELINE: Update Chromium to 77.0.3865.59
Change-Id: I1e89a5f3b009a9519a6705102ad65c92fe736f21 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/cc/tiles')
-rw-r--r--chromium/cc/tiles/checker_image_tracker.cc3
-rw-r--r--chromium/cc/tiles/checker_image_tracker.h2
-rw-r--r--chromium/cc/tiles/decoded_image_tracker.cc3
-rw-r--r--chromium/cc/tiles/decoded_image_tracker.h2
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.cc364
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.h61
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_perftest.cc11
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_unittest.cc1369
-rw-r--r--chromium/cc/tiles/image_controller.cc42
-rw-r--r--chromium/cc/tiles/image_controller.h32
-rw-r--r--chromium/cc/tiles/image_controller_unittest.cc28
-rw-r--r--chromium/cc/tiles/image_decode_cache.cc8
-rw-r--r--chromium/cc/tiles/image_decode_cache.h3
-rw-r--r--chromium/cc/tiles/paint_worklet_image_cache.cc146
-rw-r--r--chromium/cc/tiles/paint_worklet_image_cache.h87
-rw-r--r--chromium/cc/tiles/paint_worklet_image_cache_unittest.cc261
-rw-r--r--chromium/cc/tiles/picture_layer_tiling.h8
-rw-r--r--chromium/cc/tiles/picture_layer_tiling_set.cc2
-rw-r--r--chromium/cc/tiles/prioritized_tile.h4
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.cc38
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.h16
-rw-r--r--chromium/cc/tiles/software_image_decode_cache_utils.h11
-rw-r--r--chromium/cc/tiles/tile_manager.cc30
-rw-r--r--chromium/cc/tiles/tile_manager.h8
-rw-r--r--chromium/cc/tiles/tile_manager_unittest.cc2
-rw-r--r--chromium/cc/tiles/tile_task_manager.cc6
26 files changed, 1271 insertions, 1276 deletions
diff --git a/chromium/cc/tiles/checker_image_tracker.cc b/chromium/cc/tiles/checker_image_tracker.cc
index 6eda401d7a5..c31c7b5e3e9 100644
--- a/chromium/cc/tiles/checker_image_tracker.cc
+++ b/chromium/cc/tiles/checker_image_tracker.cc
@@ -135,8 +135,7 @@ CheckerImageTracker::CheckerImageTracker(ImageController* image_controller,
: image_controller_(image_controller),
client_(client),
enable_checker_imaging_(enable_checker_imaging),
- min_image_bytes_to_checker_(min_image_bytes_to_checker),
- weak_factory_(this) {}
+ min_image_bytes_to_checker_(min_image_bytes_to_checker) {}
CheckerImageTracker::~CheckerImageTracker() = default;
diff --git a/chromium/cc/tiles/checker_image_tracker.h b/chromium/cc/tiles/checker_image_tracker.h
index ee5578f8fef..7628689915b 100644
--- a/chromium/cc/tiles/checker_image_tracker.h
+++ b/chromium/cc/tiles/checker_image_tracker.h
@@ -208,7 +208,7 @@ class CC_EXPORT CheckerImageTracker {
base::flat_map<PaintImage::Id, PaintImage::DecodingMode> decoding_mode_map_;
- base::WeakPtrFactory<CheckerImageTracker> weak_factory_;
+ base::WeakPtrFactory<CheckerImageTracker> weak_factory_{this};
};
} // namespace cc
diff --git a/chromium/cc/tiles/decoded_image_tracker.cc b/chromium/cc/tiles/decoded_image_tracker.cc
index 5db3f198b6d..a7aa6b497ad 100644
--- a/chromium/cc/tiles/decoded_image_tracker.cc
+++ b/chromium/cc/tiles/decoded_image_tracker.cc
@@ -28,8 +28,7 @@ DecodedImageTracker::DecodedImageTracker(
scoped_refptr<base::SequencedTaskRunner> task_runner)
: image_controller_(controller),
task_runner_(std::move(task_runner)),
- tick_clock_(base::DefaultTickClock::GetInstance()),
- weak_ptr_factory_(this) {
+ tick_clock_(base::DefaultTickClock::GetInstance()) {
DCHECK(image_controller_);
}
diff --git a/chromium/cc/tiles/decoded_image_tracker.h b/chromium/cc/tiles/decoded_image_tracker.h
index 4803dfa3a2e..c3bf49793bc 100644
--- a/chromium/cc/tiles/decoded_image_tracker.h
+++ b/chromium/cc/tiles/decoded_image_tracker.h
@@ -93,7 +93,7 @@ class CC_EXPORT DecodedImageTracker {
// Defaults to base::TimeTicks::Now(), but overrideable for testing.
const base::TickClock* tick_clock_;
- base::WeakPtrFactory<DecodedImageTracker> weak_ptr_factory_;
+ base::WeakPtrFactory<DecodedImageTracker> weak_ptr_factory_{this};
};
} // namespace cc
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.cc b/chromium/cc/tiles/gpu_image_decode_cache.cc
index 30ce3e45e4d..78dd9c6b720 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache.cc
@@ -8,7 +8,9 @@
#include "base/auto_reset.h"
#include "base/bind.h"
+#include "base/containers/span.h"
#include "base/debug/alias.h"
+#include "base/feature_list.h"
#include "base/hash/hash.h"
#include "base/memory/discardable_memory_allocator.h"
#include "base/metrics/histogram_macros.h"
@@ -18,7 +20,6 @@
#include "base/trace_event/memory_dump_manager.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
-#include "cc/paint/image_transfer_cache_entry.h"
#include "cc/raster/scoped_grcontext_access.h"
#include "cc/raster/tile_task.h"
#include "cc/tiles/mipmap_util.h"
@@ -26,6 +27,8 @@
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/raster_interface.h"
+#include "gpu/command_buffer/common/sync_token.h"
+#include "gpu/config/gpu_finch_features.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -33,6 +36,8 @@
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/GrTexture.h"
+#include "ui/gfx/color_space.h"
+#include "ui/gfx/geometry/size.h"
#include "ui/gfx/skia_util.h"
#include "ui/gl/trace_util.h"
@@ -160,6 +165,16 @@ bool ShouldGenerateMips(const DrawImage& draw_image,
return false;
}
+// This helper method takes in
+// - |yuva_size_info| corresponding to the plane dimensions of a YUV image
+// - |info| indicating SkAlphaType and SkColorSpace per plane (though the final
+// image color space is currently indicated through other means at creation
+// of the YUV SkImage)
+// - |memory_ptr| pointing to sufficient contiguous memory for the planes
+//
+// It then sets each SkPixmap to have the dimensions specified by its respective
+// SkYUVAIndex within |yuva_size_info| and to point to bytes in memory at
+// |planes[index]|.
void SetYuvPixmapsFromSizeInfo(SkPixmap* pixmap_y,
SkPixmap* pixmap_u,
SkPixmap* pixmap_v,
@@ -189,6 +204,41 @@ void SetYuvPixmapsFromSizeInfo(SkPixmap* pixmap_y,
v_decode_info.minRowBytes());
}
+// Helper method to fill in |scaled_u_size| and |scaled_v_size| by computing
+// the mip level for each plane given the final raster dimensions and the
+// unscaled U and V plane sizes. Also takes in |draw_image| to compute the Y
+// plane mip level and DCHECK that the computed mip levels for U and V are
+// reasonable.
+//
+// TODO(crbug.com/915972): Assumes 420 subsampling and DCHECKs the size ratios.
+void ComputeMippedUVPlaneSizes(const gfx::Size& target_raster_size,
+ const gfx::Size& unscaled_u_size,
+ const gfx::Size& unscaled_v_size,
+ const DrawImage& draw_image,
+ gfx::Size* scaled_u_size,
+ gfx::Size* scaled_v_size) {
+ DCHECK(scaled_u_size);
+ DCHECK(scaled_v_size);
+ DCHECK_EQ(unscaled_u_size, unscaled_v_size);
+ DCHECK_EQ((draw_image.paint_image().width() + 1) / 2,
+ unscaled_u_size.width());
+ const int uv_mip_level =
+ MipMapUtil::GetLevelForSize(unscaled_u_size, target_raster_size);
+ // Check that the chroma planes do not shrink *more* than the luma.
+ // At least for YUV420, they will shrink at most one mip level below luma,
+ // which avoids blurriness.
+ DCHECK_GE(uv_mip_level, 0);
+ if (CalculateUploadScaleMipLevel(draw_image) == 0) {
+ // If Y is not scaled, then U and V shouldn't be either.
+ DCHECK_EQ(uv_mip_level, 0);
+ } else {
+ DCHECK_EQ(CalculateUploadScaleMipLevel(draw_image) - 1, uv_mip_level);
+ }
+
+ *scaled_u_size = MipMapUtil::GetSizeForLevel(unscaled_u_size, uv_mip_level);
+ *scaled_v_size = *scaled_u_size;
+}
+
// Draws and scales the provided |draw_image| into the |target_pixmap|. If the
// draw/scale can be done directly, calls directly into PaintImage::Decode.
// if not, decodes to a compatible temporary pixmap and then converts that into
@@ -316,23 +366,34 @@ bool DrawAndScaleImage(const DrawImage& draw_image,
&unscaled_pixmap_v, yuva_size_info, planes,
decode_info, decode_pixmap.writable_addr());
- // Assumes YUV420 and splits decode_pixmap into pixmaps for each plane.
- // TODO(crbug.com/915972): Fix this assumption.
const SkImageInfo y_info_scaled = info.makeColorType(kGray_8_SkColorType);
- const size_t uv_width_scaled = (y_info_scaled.width() + 1) / 2;
- const size_t uv_height_scaled = (y_info_scaled.height() + 1) / 2;
- const SkImageInfo uv_info_scaled =
- y_info_scaled.makeWH(uv_width_scaled, uv_height_scaled);
+ // The target raster dimensions get passed through:
+ // |target_pixmap|.info() -> |pixmap|->info() -> |info| -> |y_info_scaled|
+ const gfx::Size target_raster_size(y_info_scaled.width(),
+ y_info_scaled.height());
+ gfx::Size unscaled_u_size(unscaled_pixmap_u.width(),
+ unscaled_pixmap_u.height());
+ gfx::Size unscaled_v_size(unscaled_pixmap_v.width(),
+ unscaled_pixmap_v.height());
+ gfx::Size scaled_u_size;
+ gfx::Size scaled_v_size;
+ ComputeMippedUVPlaneSizes(target_raster_size, unscaled_u_size,
+ unscaled_v_size, draw_image, &scaled_u_size,
+ &scaled_v_size);
+ const SkImageInfo u_info_scaled =
+ y_info_scaled.makeWH(scaled_u_size.width(), scaled_u_size.height());
+ const SkImageInfo v_info_scaled =
+ y_info_scaled.makeWH(scaled_v_size.width(), scaled_v_size.height());
const size_t y_plane_bytes = y_info_scaled.computeMinByteSize();
- const size_t u_plane_bytes = uv_info_scaled.computeMinByteSize();
+ const size_t u_plane_bytes = u_info_scaled.computeMinByteSize();
DCHECK(!SkImageInfo::ByteSizeOverflowed(y_plane_bytes));
DCHECK(!SkImageInfo::ByteSizeOverflowed(u_plane_bytes));
pixmap_y->reset(y_info_scaled, data_ptr, y_info_scaled.minRowBytes());
- pixmap_u->reset(uv_info_scaled, data_ptr + y_plane_bytes,
- uv_info_scaled.minRowBytes());
- pixmap_v->reset(uv_info_scaled, data_ptr + y_plane_bytes + u_plane_bytes,
- uv_info_scaled.minRowBytes());
+ pixmap_u->reset(u_info_scaled, data_ptr + y_plane_bytes,
+ u_info_scaled.minRowBytes());
+ pixmap_v->reset(v_info_scaled, data_ptr + y_plane_bytes + u_plane_bytes,
+ v_info_scaled.minRowBytes());
const bool all_planes_scaled_successfully =
unscaled_pixmap_y.scalePixels(*pixmap_y, filter_quality) &&
@@ -520,10 +581,12 @@ class ImageUploadTaskImpl : public TileTask {
ImageUploadTaskImpl(GpuImageDecodeCache* cache,
const DrawImage& draw_image,
scoped_refptr<TileTask> decode_dependency,
+ sk_sp<SkData> encoded_data,
const ImageDecodeCache::TracingInfo& tracing_info)
: TileTask(false),
cache_(cache),
image_(draw_image),
+ encoded_data_(std::move(encoded_data)),
tracing_info_(tracing_info) {
DCHECK(!SkipImage(draw_image));
// If an image is already decoded and locked, we will not generate a
@@ -539,7 +602,7 @@ class ImageUploadTaskImpl : public TileTask {
void RunOnWorkerThread() override {
TRACE_EVENT2("cc", "ImageUploadTaskImpl::RunOnWorkerThread", "mode", "gpu",
"source_prepare_tiles_id", tracing_info_.prepare_tiles_id);
- cache_->UploadImageInTask(image_);
+ cache_->UploadImageInTask(image_, std::move(encoded_data_));
}
// Overridden from TileTask:
@@ -553,6 +616,7 @@ class ImageUploadTaskImpl : public TileTask {
private:
GpuImageDecodeCache* cache_;
DrawImage image_;
+ sk_sp<SkData> encoded_data_;
const ImageDecodeCache::TracingInfo tracing_info_;
};
@@ -601,8 +665,11 @@ int GpuImageDecodeCache::ImageDataBase::UsageState() const {
return state;
}
-GpuImageDecodeCache::DecodedImageData::DecodedImageData(bool is_bitmap_backed)
- : is_bitmap_backed_(is_bitmap_backed) {}
+GpuImageDecodeCache::DecodedImageData::DecodedImageData(
+ bool is_bitmap_backed,
+ bool do_hardware_accelerated_decode)
+ : is_bitmap_backed_(is_bitmap_backed),
+ do_hardware_accelerated_decode_(do_hardware_accelerated_decode) {}
GpuImageDecodeCache::DecodedImageData::~DecodedImageData() {
ResetData();
}
@@ -684,6 +751,14 @@ void GpuImageDecodeCache::DecodedImageData::ResetData() {
}
void GpuImageDecodeCache::DecodedImageData::ReportUsageStats() const {
+ if (do_hardware_accelerated_decode_) {
+ // When doing hardware decode acceleration, we don't want to record usage
+ // stats for the decode data. The reason is that the decode is done in the
+ // GPU process and the decoded result stays there. On the renderer side, we
+ // don't use or lock the decoded data, so reporting this status would
+ // incorrectly distort the software decoding statistics.
+ return;
+ }
UMA_HISTOGRAM_ENUMERATION("Renderer4.GpuImageDecodeState",
static_cast<ImageUsageState>(UsageState()),
IMAGE_USAGE_STATE_COUNT);
@@ -786,6 +861,7 @@ GpuImageDecodeCache::ImageData::ImageData(
int upload_scale_mip_level,
bool needs_mips,
bool is_bitmap_backed,
+ bool do_hardware_accelerated_decode,
bool is_yuv_format)
: paint_image_id(paint_image_id),
mode(mode),
@@ -796,7 +872,7 @@ GpuImageDecodeCache::ImageData::ImageData(
needs_mips(needs_mips),
is_bitmap_backed(is_bitmap_backed),
is_yuv(is_yuv_format),
- decode(is_bitmap_backed) {}
+ decode(is_bitmap_backed, do_hardware_accelerated_decode) {}
GpuImageDecodeCache::ImageData::~ImageData() {
// We should never delete ImageData while it is in use or before it has been
@@ -923,9 +999,17 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
const InUseCacheKey cache_key = InUseCacheKey::FromDrawImage(draw_image);
ImageData* image_data = GetImageDataForDrawImage(draw_image, cache_key);
scoped_refptr<ImageData> new_data;
+ sk_sp<SkData> encoded_data;
if (!image_data) {
- // We need an ImageData, create one now.
- new_data = CreateImageData(draw_image);
+ // We need an ImageData, create one now. Note that hardware decode
+ // acceleration is allowed only in the DecodeTaskType::kPartOfUploadTask
+ // case. This prevents the img.decode() and checkerboard images paths from
+ // going through hardware decode acceleration.
+ new_data = CreateImageData(
+ draw_image,
+ task_type ==
+ DecodeTaskType::kPartOfUploadTask /* allow_hardware_decode */,
+ &encoded_data);
image_data = new_data.get();
} else if (image_data->decode.decode_failure) {
// We have already tried and failed to decode this image, so just return.
@@ -976,7 +1060,7 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
task = base::MakeRefCounted<ImageUploadTaskImpl>(
this, draw_image,
GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type),
- tracing_info);
+ std::move(encoded_data), tracing_info);
image_data->upload.task = task;
} else {
task = GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type);
@@ -1015,9 +1099,11 @@ DecodedDrawImage GpuImageDecodeCache::GetDecodedImageForDraw(
base::AutoLock lock(lock_);
const InUseCacheKey cache_key = InUseCacheKey::FromDrawImage(draw_image);
ImageData* image_data = GetImageDataForDrawImage(draw_image, cache_key);
+ sk_sp<SkData> encoded_data;
if (!image_data) {
// We didn't find the image, create a new entry.
- auto data = CreateImageData(draw_image);
+ auto data = CreateImageData(draw_image, true /* allow_hardware_decode */,
+ &encoded_data);
image_data = data.get();
AddToPersistentCache(draw_image, std::move(data));
}
@@ -1032,7 +1118,7 @@ DecodedDrawImage GpuImageDecodeCache::GetDecodedImageForDraw(
// We may or may not need to decode and upload the image we've found, the
// following functions early-out to if we already decoded.
DecodeImageIfNecessary(draw_image, image_data, TaskType::kInRaster);
- UploadImageIfNecessary(draw_image, image_data);
+ UploadImageIfNecessary(draw_image, image_data, std::move(encoded_data));
// Unref the image decode, but not the image. The image ref will be released
// in DrawWithImageFinished.
UnrefImageDecode(draw_image, cache_key);
@@ -1299,7 +1385,8 @@ void GpuImageDecodeCache::DecodeImageInTask(const DrawImage& draw_image,
DecodeImageIfNecessary(draw_image, image_data, task_type);
}
-void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image) {
+void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image,
+ sk_sp<SkData> encoded_data) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"GpuImageDecodeCache::UploadImage");
base::Optional<viz::RasterContextProvider::ScopedRasterContextLock>
@@ -1319,7 +1406,7 @@ void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image) {
if (image_data->is_bitmap_backed)
DecodeImageIfNecessary(draw_image, image_data, TaskType::kInRaster);
- UploadImageIfNecessary(draw_image, image_data);
+ UploadImageIfNecessary(draw_image, image_data, std::move(encoded_data));
}
void GpuImageDecodeCache::OnImageDecodeTaskCompleted(
@@ -1365,8 +1452,7 @@ void GpuImageDecodeCache::OnImageUploadTaskCompleted(
UnrefImageInternal(draw_image, cache_key);
}
-// Checks if an existing image decode exists. If not, returns a task to produce
-// the requested decode.
+// Checks if an image decode needs a decode task and returns it.
scoped_refptr<TileTask> GpuImageDecodeCache::GetImageDecodeTaskAndRef(
const DrawImage& draw_image,
const TracingInfo& tracing_info,
@@ -1384,6 +1470,9 @@ scoped_refptr<TileTask> GpuImageDecodeCache::GetImageDecodeTaskAndRef(
ImageData* image_data = GetImageDataForDrawImage(draw_image, cache_key);
DCHECK(image_data);
+ if (image_data->decode.do_hardware_accelerated_decode())
+ return nullptr;
+
// No decode is necessary for bitmap backed images.
if (image_data->decode.is_locked() || image_data->is_bitmap_backed) {
// We should never be creating a decode task for a not budgeted image.
@@ -1625,6 +1714,28 @@ bool GpuImageDecodeCache::ExceedsPreferredCount() const {
return persistent_cache_.size() > items_limit;
}
+void GpuImageDecodeCache::InsertTransferCacheEntry(
+ const ClientImageTransferCacheEntry& image_entry,
+ ImageData* image_data) {
+ DCHECK(image_data);
+ uint32_t size = image_entry.SerializedSize();
+ void* data = context_->ContextSupport()->MapTransferCacheEntry(size);
+ if (data) {
+ bool succeeded = image_entry.Serialize(
+ base::make_span(reinterpret_cast<uint8_t*>(data), size));
+ DCHECK(succeeded);
+ context_->ContextSupport()->UnmapAndCreateTransferCacheEntry(
+ image_entry.UnsafeType(), image_entry.Id());
+ image_data->upload.SetTransferCacheId(image_entry.Id());
+ } else {
+ // Transfer cache entry can fail due to a lost gpu context or failure
+ // to allocate shared memory. Handle this gracefully. Mark this
+ // image as "decode failed" so that we do not try to handle it again.
+ // If this was a lost context, we'll recreate this image decode cache.
+ image_data->decode.decode_failure = true;
+ }
+}
+
void GpuImageDecodeCache::DecodeImageIfNecessary(const DrawImage& draw_image,
ImageData* image_data,
TaskType task_type) {
@@ -1632,6 +1743,11 @@ void GpuImageDecodeCache::DecodeImageIfNecessary(const DrawImage& draw_image,
DCHECK_GT(image_data->decode.ref_count, 0u);
+ if (image_data->decode.do_hardware_accelerated_decode()) {
+ // We get here in the case of an at-raster decode.
+ return;
+ }
+
if (image_data->decode.decode_failure) {
// We have already tried and failed to decode this image. Don't try again.
return;
@@ -1661,7 +1777,6 @@ void GpuImageDecodeCache::DecodeImageIfNecessary(const DrawImage& draw_image,
}
TRACE_EVENT0("cc,benchmark", "GpuImageDecodeCache::DecodeImage");
- RecordImageMipLevelUMA(image_data->upload_scale_mip_level);
image_data->decode.ResetData();
std::unique_ptr<base::DiscardableMemory> backing_memory;
@@ -1747,7 +1862,8 @@ void GpuImageDecodeCache::DecodeImageIfNecessary(const DrawImage& draw_image,
}
void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
- ImageData* image_data) {
+ ImageData* image_data,
+ sk_sp<SkData> encoded_data) {
CheckContextLockAcquiredIfNecessary();
lock_.AssertAcquired();
@@ -1776,11 +1892,15 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
return;
TRACE_EVENT0("cc", "GpuImageDecodeCache::UploadImage");
- DCHECK(image_data->decode.is_locked());
+ if (!image_data->decode.do_hardware_accelerated_decode()) {
+ // These are not needed for accelerated decodes because there was no decode
+ // task.
+ DCHECK(image_data->decode.is_locked());
+ image_data->decode.mark_used();
+ }
DCHECK_GT(image_data->decode.ref_count, 0u);
DCHECK_GT(image_data->upload.ref_count, 0u);
- image_data->decode.mark_used();
sk_sp<SkColorSpace> color_space =
SupportsColorSpaceConversion() &&
draw_image.target_color_space().IsValid()
@@ -1799,27 +1919,76 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
if (image_data->mode == DecodedDataMode::kTransferCache) {
DCHECK(use_transfer_cache_);
- SkPixmap pixmap;
- if (!image_data->decode.image()->peekPixels(&pixmap))
+ if (image_data->decode.do_hardware_accelerated_decode()) {
+ // The assumption is that scaling is not currently supported for
+ // hardware-accelerated decodes.
+ DCHECK_EQ(0, image_data->upload_scale_mip_level);
+ const gfx::Size output_size(draw_image.paint_image().width(),
+ draw_image.paint_image().height());
+ // Try to get the encoded data if we don't have it already: this can
+ // happen, e.g., if we create an upload task using a pre-existing
+ // ImageData. In that case, we previously decided to do hardware decode
+ // acceleration but we didn't cache the encoded data.
+ if (!encoded_data) {
+ encoded_data = draw_image.paint_image().GetSkImage()->refEncodedData();
+ DCHECK(encoded_data);
+ }
+ const uint32_t transfer_cache_id =
+ ClientImageTransferCacheEntry::GetNextId();
+ const gpu::SyncToken decode_sync_token =
+ context_->RasterInterface()->ScheduleImageDecode(
+ base::make_span<const uint8_t>(encoded_data->bytes(),
+ encoded_data->size()),
+ output_size, transfer_cache_id,
+ color_space ? gfx::ColorSpace(*color_space) : gfx::ColorSpace(),
+ image_data->needs_mips);
+
+ if (!decode_sync_token.HasData()) {
+ image_data->decode.decode_failure = true;
+ return;
+ }
+
+ image_data->upload.SetTransferCacheId(transfer_cache_id);
+
+ // Note that we wait for the decode sync token here for two reasons:
+ //
+ // 1) To make sure that raster work that depends on the image decode
+ // happens after the decode completes.
+ //
+ // 2) To protect the transfer cache entry from being unlocked on the
+ // service side before the decode is completed.
+ context_->RasterInterface()->WaitSyncTokenCHROMIUM(
+ decode_sync_token.GetConstData());
+
return;
+ }
- ClientImageTransferCacheEntry image_entry(&pixmap, color_space.get(),
- image_data->needs_mips);
- uint32_t size = image_entry.SerializedSize();
- void* data = context_->ContextSupport()->MapTransferCacheEntry(size);
- if (data) {
- bool succeeded = image_entry.Serialize(
- base::make_span(reinterpret_cast<uint8_t*>(data), size));
- DCHECK(succeeded);
- context_->ContextSupport()->UnmapAndCreateTransferCacheEntry(
- image_entry.UnsafeType(), image_entry.Id());
- image_data->upload.SetTransferCacheId(image_entry.Id());
+ // Non-hardware-accelerated path.
+ if (image_data->is_yuv) {
+ SkPixmap y_pixmap;
+ SkPixmap u_pixmap;
+ SkPixmap v_pixmap;
+ if (!image_data->decode.y_image()->peekPixels(&y_pixmap) ||
+ !image_data->decode.u_image()->peekPixels(&u_pixmap) ||
+ !image_data->decode.v_image()->peekPixels(&v_pixmap)) {
+ return;
+ }
+ // WebP documentation says to use Rec 601 for converting to RGB.
+ // TODO(crbug.com/915707): Change QueryYUVA8 to set the colorspace based
+ // on image type.
+ SkYUVColorSpace yuva_color_space =
+ SkYUVColorSpace::kRec601_SkYUVColorSpace;
+ ClientImageTransferCacheEntry image_entry(
+ &y_pixmap, &u_pixmap, &v_pixmap, decoded_target_colorspace.get(),
+ yuva_color_space, image_data->needs_mips);
+ InsertTransferCacheEntry(image_entry, image_data);
} else {
- // Transfer cache entry can fail due to a lost gpu context or failure
- // to allocate shared memory. Handle this gracefully. Mark this
- // image as "decode failed" so that we do not try to handle it again.
- // If this was a lost context, we'll recreate this image decode cache.
- image_data->decode.decode_failure = true;
+ SkPixmap pixmap;
+ if (!image_data->decode.image()->peekPixels(&pixmap))
+ return;
+ ClientImageTransferCacheEntry image_entry(&pixmap, color_space.get(),
+ image_data->needs_mips);
+ InsertTransferCacheEntry(image_entry, image_data);
}
return;
@@ -1968,7 +2137,9 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
}
scoped_refptr<GpuImageDecodeCache::ImageData>
-GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image) {
+GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image,
+ bool allow_hardware_decode,
+ sk_sp<SkData>* encoded_data) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"GpuImageDecodeCache::CreateImageData");
lock_.AssertAcquired();
@@ -1977,12 +2148,13 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image) {
bool needs_mips = ShouldGenerateMips(draw_image, upload_scale_mip_level);
SkImageInfo image_info =
CreateImageInfoForDrawImage(draw_image, upload_scale_mip_level);
-
+ const bool image_larger_than_max_texture =
+ image_info.width() > max_texture_size_ ||
+ image_info.height() > max_texture_size_;
DecodedDataMode mode;
if (use_transfer_cache_) {
mode = DecodedDataMode::kTransferCache;
- } else if (image_info.width() > max_texture_size_ ||
- image_info.height() > max_texture_size_) {
+ } else if (image_larger_than_max_texture) {
// Image too large to upload. Try to use SW fallback.
mode = DecodedDataMode::kCpu;
} else {
@@ -2009,18 +2181,84 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image) {
const bool is_bitmap_backed = !draw_image.paint_image().IsLazyGenerated() &&
upload_scale_mip_level == 0 &&
!cache_color_conversion_on_cpu;
- const bool is_yuv =
- draw_image.paint_image().IsYuv() && mode == DecodedDataMode::kGpu;
+
+ // Figure out if we will do hardware accelerated decoding. The criteria is as
+ // follows:
+ //
+ // - The kVaapiJpegImageDecodeAcceleration feature is enabled.
+ // - The caller allows hardware decodes.
+ // - We are using the transfer cache (OOP-R).
+ // - The image does not require downscaling for uploading (see TODO below).
+ // - All the encoded data was received prior to any decoding work. Otherwise,
+ // it means that the software decoder has already started decoding the
+ // image, so we just let it finish.
+ // - The image's color space is sRGB. This is because we don't currently
+ // support detecting embedded color profiles.
+ // - The image is supported according to the profiles advertised by the GPU
+ // service. Checking this involves obtaining the contiguous encoded data
+ // which may require a copy if the data is not already contiguous. Because
+ // of this, we return a pointer to the contiguous data (as |encoded_data|)
+ // so that we can re-use it later (when requesting the image decode).
+ //
+ // TODO(crbug.com/953363): ideally, we can make the hardware decoder support
+ // decision without requiring contiguous data.
+ //
+ // TODO(crbug.com/953367): currently, we don't support scaling with hardware
+ // decode acceleration. Note that it's still okay for the image to be
+ // downscaled by Skia using the GPU.
+ //
+ // TODO(crbug.com/981208): |data_size| needs to be set to the size of the
+ // decoded data, but for accelerated decodes we won't know until the driver
+ // gives us the result in the GPU process. Figure out what to do.
+ bool do_hardware_accelerated_decode = false;
+ if (base::FeatureList::IsEnabled(
+ features::kVaapiJpegImageDecodeAcceleration) &&
+ allow_hardware_decode && mode == DecodedDataMode::kTransferCache &&
+ upload_scale_mip_level == 0 &&
+ draw_image.paint_image().IsEligibleForAcceleratedDecoding() &&
+ draw_image.paint_image().color_space() &&
+ draw_image.paint_image().color_space()->isSRGB()) {
+ sk_sp<SkData> tmp_encoded_data =
+ draw_image.paint_image().GetSkImage()
+ ? draw_image.paint_image().GetSkImage()->refEncodedData()
+ : nullptr;
+ if (tmp_encoded_data &&
+ context_->ContextSupport()->CanDecodeWithHardwareAcceleration(
+ base::make_span<const uint8_t>(tmp_encoded_data->bytes(),
+ tmp_encoded_data->size()))) {
+ do_hardware_accelerated_decode = true;
+ DCHECK(encoded_data);
+ *encoded_data = std::move(tmp_encoded_data);
+ }
+ }
+
+ // If draw_image.paint_image().IsEligibleForAcceleratedDecoding() returns
+ // true, the image should not be backed by a bitmap.
+ DCHECK(!do_hardware_accelerated_decode || !is_bitmap_backed);
+
+ SkYUVASizeInfo target_yuva_size_info;
+ const bool is_yuv = !do_hardware_accelerated_decode &&
+ draw_image.paint_image().IsYuv(&target_yuva_size_info) &&
+ mode != DecodedDataMode::kCpu &&
+ !image_larger_than_max_texture;
// TODO(crbug.com/910276): Change after alpha support.
- // TODO(crbug.com/915972): Remove YUV420 assumption.
if (is_yuv) {
- // We can't use |temp_yuva_size_info| because it doesn't know about
- // any scaling based on mip levels that |image_info| does incorporate.
size_t y_size_bytes = image_info.width() * image_info.height();
- size_t u_size_bytes =
- ((image_info.width() + 1) / 2) * ((image_info.height() + 1) / 2);
- size_t v_size_bytes = u_size_bytes;
+ const gfx::Size target_raster_size(image_info.width(), image_info.height());
+ gfx::Size unscaled_u_size(
+ target_yuva_size_info.fSizes[SkYUVAIndex::kU_Index].width(),
+ target_yuva_size_info.fSizes[SkYUVAIndex::kU_Index].height());
+ gfx::Size unscaled_v_size(
+ target_yuva_size_info.fSizes[SkYUVAIndex::kV_Index].width(),
+ target_yuva_size_info.fSizes[SkYUVAIndex::kV_Index].height());
+ gfx::Size scaled_u_size;
+ gfx::Size scaled_v_size;
+ ComputeMippedUVPlaneSizes(target_raster_size, unscaled_u_size,
+ unscaled_v_size, draw_image, &scaled_u_size,
+ &scaled_v_size);
+ size_t u_size_bytes = base::checked_cast<size_t>(scaled_u_size.GetArea());
+ size_t v_size_bytes = base::checked_cast<size_t>(scaled_v_size.GetArea());
data_size = y_size_bytes + u_size_bytes + v_size_bytes;
}
@@ -2028,7 +2266,7 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image) {
draw_image.paint_image().stable_id(), mode, data_size,
draw_image.target_color_space(),
CalculateDesiredFilterQuality(draw_image), upload_scale_mip_level,
- needs_mips, is_bitmap_backed, is_yuv));
+ needs_mips, is_bitmap_backed, do_hardware_accelerated_decode, is_yuv));
}
void GpuImageDecodeCache::WillAddCacheEntry(const DrawImage& draw_image) {
@@ -2350,7 +2588,8 @@ bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data,
size_t GpuImageDecodeCache::GetDrawImageSizeForTesting(const DrawImage& image) {
base::AutoLock lock(lock_);
- scoped_refptr<ImageData> data = CreateImageData(image);
+ scoped_refptr<ImageData> data = CreateImageData(
+ image, false /* allow_hardware_decode */, nullptr /* encoded_data */);
return data->size;
}
@@ -2394,6 +2633,9 @@ sk_sp<SkImage> GpuImageDecodeCache::GetSWImageDecodeForTesting(
return image_data->decode.ImageForTesting();
}
+// Used for in-process-raster YUV decoding tests, where we often need the
+// SkImages for each underlying plane because asserting or requesting fields for
+// the YUV SkImage may flatten it to RGB or not be possible to request.
sk_sp<SkImage> GpuImageDecodeCache::GetUploadedPlaneForTesting(
const DrawImage& draw_image,
size_t index) {
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.h b/chromium/cc/tiles/gpu_image_decode_cache.h
index 81ca6286703..638a77f2388 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.h
+++ b/chromium/cc/tiles/gpu_image_decode_cache.h
@@ -16,7 +16,9 @@
#include "base/synchronization/lock.h"
#include "base/trace_event/memory_dump_provider.h"
#include "cc/cc_export.h"
+#include "cc/paint/image_transfer_cache_entry.h"
#include "cc/tiles/image_decode_cache.h"
+#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkYUVAIndex.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
@@ -36,9 +38,9 @@ namespace cc {
// Generally, when an image is required for raster, GpuImageDecodeCache
// creates two tasks, one to decode the image, and one to upload the image to
// the GPU. These tasks are completed before the raster task which depends on
-// the image. We need to seperate decode and upload tasks, as decode can occur
+// the image. We need to separate decode and upload tasks, as decode can occur
// simultaneously on multiple threads, while upload requires the GL context
-// lock must happen on our non-concurrent raster thread.
+// lock so it must happen on our non-concurrent raster thread.
//
// Decoded and Uploaded image data share a single cache entry. Depending on how
// far we've progressed, this cache entry may contain CPU-side decoded data,
@@ -97,6 +99,35 @@ namespace cc {
// keeps an ImageData alive while it is present in either the
// |persistent_cache_| or |in_use_cache_|.
//
+// HARDWARE ACCELERATED DECODES:
+//
+// In Chrome OS, we have the ability to use specialized hardware to decode
+// certain images. Because this requires interacting with drivers, it must be
+// done in the GPU process. Therefore, we follow a different path than the usual
+// decode -> upload tasks:
+// 1) We decide whether to do hardware decode acceleration for an image before
+// we create the decode/upload tasks. Under the hood, this involves parsing
+// the image and checking if it's supported by the hardware decoder
+// according to information advertised by the GPU process. Also, we only
+// allow hardware decoding in OOP-R mode.
+// 2) If we do decide to do hardware decoding, we don't create a decode task.
+// Instead, we create only an upload task and store enough state to
+// indicate that the image will go through this hardware accelerated path.
+// The reason that we use the upload task is that we need to hold the
+// context lock in order to schedule the image decode.
+// 3) When the upload task runs, we send a request to the GPU process to start
+// the image decode. This is an IPC message that does not require us to
+// wait for the response. Instead, we get a sync token that is signalled
+// when the decode completes. We insert a wait for this sync token right
+// after sending the decode request.
+//
+// We also handle the more unusual case where images are decoded at raster time.
+// The process is similar: we skip the software decode and then request the
+// hardware decode in the same way as step (3) above.
+//
+// Note that the decoded data never makes it back to the renderer. It stays in
+// the GPU process. The sync token ensures that any raster work that needs the
+// image happens after the decode completes.
class CC_EXPORT GpuImageDecodeCache
: public ImageDecodeCache,
public base::trace_event::MemoryDumpProvider {
@@ -144,7 +175,7 @@ class CC_EXPORT GpuImageDecodeCache
// Called by Decode / Upload tasks.
void DecodeImageInTask(const DrawImage& image, TaskType task_type);
- void UploadImageInTask(const DrawImage& image);
+ void UploadImageInTask(const DrawImage& image, sk_sp<SkData> encoded_data);
// Called by Decode / Upload tasks when tasks are finished.
void OnImageDecodeTaskCompleted(const DrawImage& image,
@@ -216,7 +247,8 @@ class CC_EXPORT GpuImageDecodeCache
// Stores the CPU-side decoded bits of an image and supporting fields.
struct DecodedImageData : public ImageDataBase {
- explicit DecodedImageData(bool is_bitmap_backed);
+ explicit DecodedImageData(bool is_bitmap_backed,
+ bool do_hardware_accelerated_decode);
~DecodedImageData();
bool Lock();
@@ -255,6 +287,10 @@ class CC_EXPORT GpuImageDecodeCache
bool is_yuv() const { return image_yuv_planes_.has_value(); }
+ bool do_hardware_accelerated_decode() const {
+ return do_hardware_accelerated_decode_;
+ }
+
// Test-only functions.
sk_sp<SkImage> ImageForTesting() const { return image_; }
@@ -278,6 +314,12 @@ class CC_EXPORT GpuImageDecodeCache
std::unique_ptr<base::DiscardableMemory> data_;
sk_sp<SkImage> image_; // RGBX (or null in YUV decode path)
base::Optional<YUVSkImages> image_yuv_planes_;
+
+ // |do_hardware_accelerated_decode_| keeps track of images that should go
+ // through hardware decode acceleration. Currently, this path is intended
+ // only for Chrome OS and only for some JPEG images (see
+ // https://crbug.com/868400).
+ bool do_hardware_accelerated_decode_;
};
// Stores the GPU-side image and supporting fields.
@@ -447,6 +489,7 @@ class CC_EXPORT GpuImageDecodeCache
int upload_scale_mip_level,
bool needs_mips,
bool is_bitmap_backed,
+ bool do_hardware_accelerated_decode,
bool is_yuv_format);
bool IsGpuOrTransferCache() const;
@@ -543,6 +586,9 @@ class CC_EXPORT GpuImageDecodeCache
bool CanFitInWorkingSet(size_t size) const;
bool ExceedsPreferredCount() const;
+ void InsertTransferCacheEntry(
+ const ClientImageTransferCacheEntry& image_entry,
+ ImageData* image_data);
void DecodeImageIfNecessary(const DrawImage& draw_image,
ImageData* image_data,
TaskType task_type);
@@ -557,7 +603,9 @@ class CC_EXPORT GpuImageDecodeCache
sk_sp<SkColorSpace> decoded_color_space) const;
scoped_refptr<GpuImageDecodeCache::ImageData> CreateImageData(
- const DrawImage& image);
+ const DrawImage& image,
+ bool allow_hardware_decode,
+ sk_sp<SkData>* encoded_data);
void WillAddCacheEntry(const DrawImage& draw_image);
SkImageInfo CreateImageInfoForDrawImage(const DrawImage& draw_image,
int upload_scale_mip_level) const;
@@ -591,7 +639,8 @@ class CC_EXPORT GpuImageDecodeCache
// Requires that the |context_| lock be held when calling.
void UploadImageIfNecessary(const DrawImage& draw_image,
- ImageData* image_data);
+ ImageData* image_data,
+ sk_sp<SkData> encoded_data);
// Flush pending operations on context_->GrContext() for each element of
// |yuv_images| and then clear the vector.
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc b/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
index a3b7e86666e..70807864351 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc
@@ -8,8 +8,8 @@
#include "cc/paint/draw_image.h"
#include "cc/paint/paint_image_builder.h"
#include "cc/raster/tile_task.h"
-#include "cc/test/test_in_process_context_provider.h"
#include "cc/tiles/gpu_image_decode_cache.h"
+#include "components/viz/test/test_in_process_context_provider.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"
@@ -45,9 +45,10 @@ class GpuImageDecodeCachePerfTest
: timer_(kWarmupRuns,
base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
kTimeCheckInterval),
- context_provider_(base::MakeRefCounted<TestInProcessContextProvider>(
- UseTransferCache(),
- false /* support_locking */)),
+ context_provider_(
+ base::MakeRefCounted<viz::TestInProcessContextProvider>(
+ UseTransferCache(),
+ false /* support_locking */)),
cache_(context_provider_.get(),
UseTransferCache(),
kRGBA_8888_SkColorType,
@@ -87,7 +88,7 @@ class GpuImageDecodeCachePerfTest
}
base::LapTimer timer_;
- scoped_refptr<TestInProcessContextProvider> context_provider_;
+ scoped_refptr<viz::TestInProcessContextProvider> context_provider_;
GpuImageDecodeCache cache_;
};
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
index 77f3210c518..c30c1b1c101 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/test/scoped_feature_list.h"
#include "cc/paint/draw_image.h"
#include "cc/paint/image_transfer_cache_entry.h"
#include "cc/paint/paint_image_builder.h"
@@ -15,12 +16,20 @@
#include "cc/test/transfer_cache_test_helper.h"
#include "components/viz/test/test_context_provider.h"
#include "components/viz/test/test_gles2_interface.h"
+#include "gpu/command_buffer/client/raster_implementation_gles.h"
+#include "gpu/command_buffer/common/command_buffer_id.h"
+#include "gpu/command_buffer/common/constants.h"
+#include "gpu/config/gpu_finch_features.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkImageGenerator.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
+using testing::_;
+using testing::StrictMock;
+
namespace cc {
namespace {
@@ -101,13 +110,15 @@ class FakeGPUImageDecodeTestGLES2Interface : public viz::TestGLES2Interface,
public:
explicit FakeGPUImageDecodeTestGLES2Interface(
FakeDiscardableManager* discardable_manager,
- TransferCacheTestHelper* transfer_cache_helper)
+ TransferCacheTestHelper* transfer_cache_helper,
+ bool advertise_accelerated_decoding)
: extension_string_(
"GL_EXT_texture_format_BGRA8888 GL_OES_rgb8_rgba8 "
"GL_OES_texture_npot GL_EXT_texture_rg "
"GL_OES_texture_half_float GL_OES_texture_half_float_linear"),
discardable_manager_(discardable_manager),
- transfer_cache_helper_(transfer_cache_helper) {}
+ transfer_cache_helper_(transfer_cache_helper),
+ advertise_accelerated_decoding_(advertise_accelerated_decoding) {}
~FakeGPUImageDecodeTestGLES2Interface() override {
// All textures / framebuffers / renderbuffers should be cleaned up.
@@ -161,6 +172,11 @@ class FakeGPUImageDecodeTestGLES2Interface : public viz::TestGLES2Interface,
transfer_cache_helper_->DeleteEntryDirect(MakeEntryKey(type, id));
}
+ bool CanDecodeWithHardwareAcceleration(
+ base::span<const uint8_t> encoded_data) const override {
+ return advertise_accelerated_decoding_;
+ }
+
std::pair<TransferCacheEntryType, uint32_t> MakeEntryKey(uint32_t type,
uint32_t id) {
DCHECK_LE(type, static_cast<uint32_t>(TransferCacheEntryType::kLast));
@@ -213,39 +229,78 @@ class FakeGPUImageDecodeTestGLES2Interface : public viz::TestGLES2Interface,
const std::string extension_string_;
FakeDiscardableManager* discardable_manager_;
TransferCacheTestHelper* transfer_cache_helper_;
+ bool advertise_accelerated_decoding_ = false;
size_t mapped_entry_size_ = 0;
std::unique_ptr<uint8_t[]> mapped_entry_;
};
+class MockRasterImplementation : public gpu::raster::RasterImplementationGLES {
+ public:
+ explicit MockRasterImplementation(gpu::gles2::GLES2Interface* gl)
+ : RasterImplementationGLES(gl) {}
+ ~MockRasterImplementation() override = default;
+
+ gpu::SyncToken ScheduleImageDecode(base::span<const uint8_t> encoded_data,
+ const gfx::Size& output_size,
+ uint32_t transfer_cache_entry_id,
+ const gfx::ColorSpace& target_color_space,
+ bool needs_mips) override {
+ DoScheduleImageDecode(output_size, transfer_cache_entry_id,
+ target_color_space, needs_mips);
+ if (!next_accelerated_decode_fails_) {
+ return gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
+ gpu::CommandBufferId::FromUnsafeValue(1u),
+ next_release_count_++);
+ }
+ return gpu::SyncToken();
+ }
+
+ void SetAcceleratedDecodingFailed() { next_accelerated_decode_fails_ = true; }
+
+ MOCK_METHOD4(DoScheduleImageDecode,
+ void(const gfx::Size& /* output_size */,
+ uint32_t /* transfer_cache_entry_id */,
+ const gfx::ColorSpace& /* target_color_space */,
+ bool /* needs_mips */));
+
+ private:
+ bool next_accelerated_decode_fails_ = false;
+ uint64_t next_release_count_ = 1u;
+};
+
class GPUImageDecodeTestMockContextProvider : public viz::TestContextProvider {
public:
static scoped_refptr<GPUImageDecodeTestMockContextProvider> Create(
FakeDiscardableManager* discardable_manager,
- TransferCacheTestHelper* transfer_cache_helper) {
+ TransferCacheTestHelper* transfer_cache_helper,
+ bool advertise_accelerated_decoding) {
+ auto support = std::make_unique<FakeGPUImageDecodeTestGLES2Interface>(
+ discardable_manager, transfer_cache_helper,
+ advertise_accelerated_decoding);
+ auto gl = std::make_unique<FakeGPUImageDecodeTestGLES2Interface>(
+ discardable_manager, transfer_cache_helper,
+ false /* advertise_accelerated_decoding */);
+ auto raster =
+ std::make_unique<StrictMock<MockRasterImplementation>>(gl.get());
return new GPUImageDecodeTestMockContextProvider(
- std::make_unique<FakeGPUImageDecodeTestGLES2Interface>(
- discardable_manager, transfer_cache_helper),
- std::make_unique<FakeGPUImageDecodeTestGLES2Interface>(
- discardable_manager, transfer_cache_helper));
+ std::move(support), std::move(gl), std::move(raster));
}
private:
~GPUImageDecodeTestMockContextProvider() override = default;
GPUImageDecodeTestMockContextProvider(
std::unique_ptr<viz::TestContextSupport> support,
- std::unique_ptr<viz::TestGLES2Interface> gl)
- : TestContextProvider(std::move(support), std::move(gl), true) {}
+ std::unique_ptr<viz::TestGLES2Interface> gl,
+ std::unique_ptr<gpu::raster::RasterInterface> raster)
+ : TestContextProvider(std::move(support),
+ std::move(gl),
+ std::move(raster),
+ true) {}
};
-SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) {
+SkMatrix CreateMatrix(const SkSize& scale) {
SkMatrix matrix;
matrix.setScale(scale.width(), scale.height());
-
- if (!is_decomposable) {
- // Perspective is not decomposable, add it.
- matrix[SkMatrix::kMPersp0] = 0.1f;
- }
-
return matrix;
}
@@ -260,13 +315,21 @@ SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) {
size_t kGpuMemoryLimitBytes = 96 * 1024 * 1024;
class GpuImageDecodeCacheTest
- : public ::testing::TestWithParam<std::tuple<SkColorType,
- bool /* use_transfer_cache */,
- bool /* do_yuv_decode */>> {
+ : public ::testing::TestWithParam<
+ std::tuple<SkColorType,
+ bool /* use_transfer_cache */,
+ bool /* do_yuv_decode */,
+ bool /* advertise_accelerated_decoding */>> {
public:
void SetUp() override {
+ advertise_accelerated_decoding_ = std::get<3>(GetParam());
+ if (advertise_accelerated_decoding_) {
+ feature_list_.InitAndEnableFeature(
+ features::kVaapiJpegImageDecodeAcceleration);
+ }
context_provider_ = GPUImageDecodeTestMockContextProvider::Create(
- &discardable_manager_, &transfer_cache_helper_);
+ &discardable_manager_, &transfer_cache_helper_,
+ advertise_accelerated_decoding_);
discardable_manager_.SetGLES2Interface(
context_provider_->UnboundTestContextGL());
context_provider_->BindToCurrentThread();
@@ -351,6 +414,28 @@ class GpuImageDecodeCacheTest
gfx::ColorSpace::TransferID::LINEAR);
}
+ DrawImage CreateDrawImageInternal(
+ const PaintImage& paint_image,
+ const SkMatrix& matrix = SkMatrix::I(),
+ gfx::ColorSpace* color_space = nullptr,
+ SkFilterQuality filter_quality = kMedium_SkFilterQuality,
+ SkIRect* src_rect = nullptr,
+ size_t frame_index = PaintImage::kDefaultFrameIndex) {
+ SkIRect src_rectangle;
+ gfx::ColorSpace cs;
+ if (!src_rect) {
+ src_rectangle =
+ SkIRect::MakeWH(paint_image.width(), paint_image.height());
+ src_rect = &src_rectangle;
+ }
+ if (!color_space) {
+ cs = DefaultColorSpace();
+ color_space = &cs;
+ }
+ return DrawImage(paint_image, *src_rect, filter_quality, matrix,
+ frame_index, *color_space);
+ }
+
GPUImageDecodeTestMockContextProvider* context_provider() {
return context_provider_.get();
}
@@ -404,14 +489,27 @@ class GpuImageDecodeCacheTest
return static_cast<ServiceImageTransferCacheEntry*>(entry)->image();
}
- void CompareAllPlanesToMippedVersions(GpuImageDecodeCache* cache,
- const DrawImage& draw_image,
- bool should_have_mips) {
+ void CompareAllPlanesToMippedVersions(
+ GpuImageDecodeCache* cache,
+ const DrawImage& draw_image,
+ const base::Optional<uint32_t> transfer_cache_id,
+ bool should_have_mips) {
for (size_t i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
// TODO(crbug.com/910276): Skip alpha plane until supported in cache.
if (i != SkYUVAIndex::kA_Index) {
- auto original_uploaded_plane =
- cache->GetUploadedPlaneForTesting(draw_image, i);
+ sk_sp<SkImage> original_uploaded_plane;
+ if (use_transfer_cache_) {
+ DCHECK(transfer_cache_id.has_value());
+ const uint32_t id = transfer_cache_id.value();
+ auto* image_entry =
+ transfer_cache_helper_.GetEntryAs<ServiceImageTransferCacheEntry>(
+ id);
+ original_uploaded_plane = image_entry->GetPlaneImage(i);
+ } else {
+ original_uploaded_plane =
+ cache->GetUploadedPlaneForTesting(draw_image, i);
+ }
+
ASSERT_TRUE(original_uploaded_plane);
auto plane_with_mips = original_uploaded_plane->makeTextureImage(
context_provider()->GrContext(), nullptr /* color space */,
@@ -422,35 +520,60 @@ class GpuImageDecodeCacheTest
}
}
+ void VerifyUploadedPlaneSizes(
+ GpuImageDecodeCache* cache,
+ const DrawImage& draw_image,
+ const base::Optional<uint32_t> transfer_cache_id,
+ const SkISize plane_sizes[SkYUVASizeInfo::kMaxCount]) {
+ for (size_t i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
+ // TODO(crbug.com/910276): Skip alpha plane until supported in cache.
+ if (i != SkYUVAIndex::kA_Index) {
+ sk_sp<SkImage> uploaded_plane;
+ if (use_transfer_cache_) {
+ DCHECK(transfer_cache_id.has_value());
+ const uint32_t id = transfer_cache_id.value();
+ auto* image_entry =
+ transfer_cache_helper_.GetEntryAs<ServiceImageTransferCacheEntry>(
+ id);
+ uploaded_plane = image_entry->GetPlaneImage(i);
+ } else {
+ uploaded_plane = cache->GetUploadedPlaneForTesting(draw_image, i);
+ }
+ ASSERT_TRUE(uploaded_plane);
+ EXPECT_EQ(plane_sizes[i], uploaded_plane->dimensions());
+ }
+ }
+ }
+
protected:
+ base::test::ScopedFeatureList feature_list_;
+
+ // The order of these members is important because |context_provider_| depends
+ // on |discardable_manager_| and |transfer_cache_helper_|.
FakeDiscardableManager discardable_manager_;
- scoped_refptr<GPUImageDecodeTestMockContextProvider> context_provider_;
TransferCacheTestHelper transfer_cache_helper_;
+ scoped_refptr<GPUImageDecodeTestMockContextProvider> context_provider_;
+
bool use_transfer_cache_;
SkColorType color_type_;
bool do_yuv_decode_;
+ bool advertise_accelerated_decoding_;
int max_texture_size_ = 0;
};
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSameImage) {
auto cache = CreateCache();
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(1.5f, 1.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
EXPECT_TRUE(result.task);
- DrawImage another_draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage another_draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(1.5f, 1.5f)));
ImageDecodeCache::TaskResult another_result = cache->GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(another_result.need_unref);
@@ -466,13 +589,8 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSameImage) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSmallerScale) {
auto cache = CreateCache();
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(1.5f, 1.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -482,10 +600,8 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSmallerScale) {
EXPECT_EQ(result.task->dependencies().size(), 1u);
EXPECT_TRUE(result.task->dependencies()[0]);
- DrawImage another_draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage another_draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult another_result = cache->GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
@@ -508,21 +624,15 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSmallerScale) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLowerQuality) {
auto cache = CreateCache();
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- bool is_decomposable = true;
- SkMatrix matrix = CreateMatrix(SkSize::Make(0.4f, 0.4f), is_decomposable);
-
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- kHigh_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ SkMatrix matrix = CreateMatrix(SkSize::Make(0.4f, 0.4f));
+ DrawImage draw_image = CreateDrawImageInternal(image, matrix);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
EXPECT_TRUE(result.task);
- DrawImage another_draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()),
- kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ DrawImage another_draw_image = CreateDrawImageInternal(
+ image, matrix, nullptr /* color_space */, kLow_SkFilterQuality);
ImageDecodeCache::TaskResult another_result = cache->GetTaskForImageAndRef(
another_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(another_result.need_unref);
@@ -537,25 +647,18 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLowerQuality) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentImage) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
PaintImage first_image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage first_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage first_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
EXPECT_TRUE(first_result.task);
PaintImage second_image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage second_draw_image(
- second_image,
- SkIRect::MakeWH(second_image.width(), second_image.height()), quality,
- CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage second_draw_image = CreateDrawImageInternal(
+ second_image, CreateMatrix(SkSize::Make(0.25f, 0.25f)));
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -573,14 +676,10 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentImage) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScale) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
PaintImage first_image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage first_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage first_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -591,20 +690,15 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScale) {
cache->UnrefImage(first_draw_image);
- DrawImage second_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage second_draw_image = CreateDrawImageInternal(first_image);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
EXPECT_TRUE(second_result.task);
EXPECT_TRUE(first_result.task.get() != second_result.task.get());
- DrawImage third_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage third_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult third_result = cache->GetTaskForImageAndRef(
third_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(third_result.need_unref);
@@ -619,33 +713,23 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScale) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScaleNoReuse) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage first_image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage first_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage first_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
EXPECT_TRUE(first_result.task);
- DrawImage second_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage second_draw_image = CreateDrawImageInternal(first_image);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
EXPECT_TRUE(second_result.task);
EXPECT_TRUE(first_result.task.get() != second_result.task.get());
- DrawImage third_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage third_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult third_result = cache->GetTaskForImageAndRef(
third_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(third_result.need_unref);
@@ -663,14 +747,10 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScaleNoReuse) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageHigherQuality) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkMatrix matrix = CreateMatrix(SkSize::Make(0.4f, 0.4f), is_decomposable);
-
+ SkMatrix matrix = CreateMatrix(SkSize::Make(0.4f, 0.4f));
PaintImage first_image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage first_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- kLow_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ DrawImage first_draw_image = CreateDrawImageInternal(
+ first_image, matrix, nullptr /* color_space */, kLow_SkFilterQuality);
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -681,10 +761,8 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageHigherQuality) {
cache->UnrefImage(first_draw_image);
- DrawImage second_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ DrawImage second_draw_image = CreateDrawImageInternal(
+ first_image, matrix, nullptr /* color_space */, kMedium_SkFilterQuality);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -698,14 +776,9 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageHigherQuality) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyDecodedAndLocked) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -740,14 +813,9 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyDecodedAndLocked) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyDecodedNotLocked) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -782,14 +850,9 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyDecodedNotLocked) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyUploaded) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -813,14 +876,9 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyUploaded) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageCanceledGetsNewTask) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -856,14 +914,9 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageCanceledGetsNewTask) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageCanceledWhileReffedGetsNewTask) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -903,14 +956,9 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageCanceledWhileReffedGetsNewTask) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageUploadCanceledButDecodeRun) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -932,14 +980,9 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageUploadCanceledButDecodeRun) {
TEST_P(GpuImageDecodeCacheTest, NoTaskForImageAlreadyFailedDecoding) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -962,14 +1005,9 @@ TEST_P(GpuImageDecodeCacheTest, NoTaskForImageAlreadyFailedDecoding) {
TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDraw) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -996,14 +1034,9 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDraw) {
TEST_P(GpuImageDecodeCacheTest, GetLargeDecodedImageForDraw) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreateLargePaintImageForSoftwareFallback();
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(1.0f, 1.0f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1030,16 +1063,11 @@ TEST_P(GpuImageDecodeCacheTest, GetLargeDecodedImageForDraw) {
TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
cache->SetWorkingSetLimitsForTesting(0 /* max_bytes */, 0 /* max_items */);
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(1.0f, 1.0f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1066,14 +1094,10 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) {
TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawLargerScale) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- kLow_SkFilterQuality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)),
+ nullptr /* color_space */, kLow_SkFilterQuality);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1082,10 +1106,8 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawLargerScale) {
TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
TestTileTaskRunner::ProcessTask(result.task.get());
- DrawImage larger_draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage larger_draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(1.5f, 1.5f)));
ImageDecodeCache::TaskResult larger_result = cache->GetTaskForImageAndRef(
larger_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(larger_result.need_unref);
@@ -1121,13 +1143,10 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawLargerScale) {
TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawHigherQuality) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkMatrix matrix = CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable);
-
+ SkMatrix matrix = CreateMatrix(SkSize::Make(0.5f, 0.5f));
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- kLow_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(
+ image, matrix, nullptr /* color_space */, kLow_SkFilterQuality);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1136,10 +1155,7 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawHigherQuality) {
TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
TestTileTaskRunner::ProcessTask(result.task.get());
- DrawImage higher_quality_draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()),
- kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ DrawImage higher_quality_draw_image = CreateDrawImageInternal(image, matrix);
ImageDecodeCache::TaskResult hq_result = cache->GetTaskForImageAndRef(
higher_quality_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(hq_result.need_unref);
@@ -1174,14 +1190,9 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawHigherQuality) {
TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawNegative) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(-0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(-0.5f, 0.5f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1212,15 +1223,11 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawNegative) {
TEST_P(GpuImageDecodeCacheTest, GetLargeScaledDecodedImageForDraw) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreateLargePaintImageForSoftwareFallback(
gfx::Size(GetLargeImageSize().width(), GetLargeImageSize().height() * 2));
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)),
+ nullptr /* color_space */, kHigh_SkFilterQuality);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1253,17 +1260,11 @@ TEST_P(GpuImageDecodeCacheTest, GetLargeScaledDecodedImageForDraw) {
TEST_P(GpuImageDecodeCacheTest, AtRasterUsedDirectlyIfSpaceAllows) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
const gfx::Size test_image_size = GetNormalImageSize();
-
cache->SetWorkingSetLimitsForTesting(0 /* max_bytes */, 0 /* max_items */);
PaintImage image = CreatePaintImageInternal(test_image_size);
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1297,16 +1298,11 @@ TEST_P(GpuImageDecodeCacheTest, AtRasterUsedDirectlyIfSpaceAllows) {
TEST_P(GpuImageDecodeCacheTest,
GetDecodedImageForDrawAtRasterDecodeMultipleTimes) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
cache->SetWorkingSetLimitsForTesting(0 /* max_bytes */, 0 /* max_items */);
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
@@ -1335,16 +1331,10 @@ TEST_P(GpuImageDecodeCacheTest,
TEST_P(GpuImageDecodeCacheTest,
GetLargeDecodedImageForDrawAtRasterDecodeMultipleTimes) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
cache->SetWorkingSetLimitsForTesting(0 /* max_bytes */, 0 /* max_items */);
PaintImage image = CreateLargePaintImageForSoftwareFallback();
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
@@ -1374,14 +1364,9 @@ TEST_P(GpuImageDecodeCacheTest,
TEST_P(GpuImageDecodeCacheTest, ZeroSizedImagesAreSkipped) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.f, 0.f)));
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1400,15 +1385,12 @@ TEST_P(GpuImageDecodeCacheTest, ZeroSizedImagesAreSkipped) {
TEST_P(GpuImageDecodeCacheTest, NonOverlappingSrcRectImagesAreSkipped) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
DrawImage draw_image(image,
SkIRect::MakeXYWH(image.width() + 1, image.height() + 1,
image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
+ kMedium_SkFilterQuality,
+ CreateMatrix(SkSize::Make(1.f, 1.f)),
PaintImage::kDefaultFrameIndex, DefaultColorSpace());
ImageDecodeCache::TaskResult result =
@@ -1428,14 +1410,11 @@ TEST_P(GpuImageDecodeCacheTest, NonOverlappingSrcRectImagesAreSkipped) {
TEST_P(GpuImageDecodeCacheTest, CanceledTasksDoNotCountAgainstBudget) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(
- image, SkIRect::MakeXYWH(0, 0, image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ SkIRect src_rect = SkIRect::MakeXYWH(0, 0, image.width(), image.height());
+ DrawImage draw_image = CreateDrawImageInternal(
+ image, CreateMatrix(SkSize::Make(1.f, 1.f)), nullptr /* color_space */,
+ kMedium_SkFilterQuality, &src_rect);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -1454,14 +1433,9 @@ TEST_P(GpuImageDecodeCacheTest, CanceledTasksDoNotCountAgainstBudget) {
TEST_P(GpuImageDecodeCacheTest, ShouldAggressivelyFreeResources) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
{
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
@@ -1515,15 +1489,10 @@ TEST_P(GpuImageDecodeCacheTest, ShouldAggressivelyFreeResources) {
TEST_P(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
// Create a downscaled image.
PaintImage first_image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage first_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage first_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -1535,10 +1504,8 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) {
// Create a larger version of |first_image|, this should immediately free the
// memory used by |first_image| for the smaller scale.
- DrawImage second_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage second_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(1.0f, 1.0f)));
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -1563,15 +1530,10 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) {
TEST_P(GpuImageDecodeCacheTest, OrphanedZeroRefImagesImmediatelyDeleted) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
// Create a downscaled image.
PaintImage first_image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage first_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage first_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -1587,10 +1549,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedZeroRefImagesImmediatelyDeleted) {
// Create a larger version of |first_image|, this should immediately free the
// memory used by |first_image| for the smaller scale.
- DrawImage second_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage second_draw_image = CreateDrawImageInternal(first_image);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -1610,14 +1569,11 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedZeroRefImagesImmediatelyDeleted) {
TEST_P(GpuImageDecodeCacheTest, QualityCappedAtMedium) {
auto cache = CreateCache();
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- bool is_decomposable = true;
- SkMatrix matrix = CreateMatrix(SkSize::Make(0.4f, 0.4f), is_decomposable);
+ SkMatrix matrix = CreateMatrix(SkSize::Make(0.4f, 0.4f));
// Create an image with kLow_FilterQuality.
- DrawImage low_draw_image(image,
- SkIRect::MakeWH(image.width(), image.height()),
- kLow_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage low_draw_image = CreateDrawImageInternal(
+ image, matrix, nullptr /* color_space */, kLow_SkFilterQuality);
ImageDecodeCache::TaskResult low_result = cache->GetTaskForImageAndRef(
low_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(low_result.need_unref);
@@ -1625,21 +1581,16 @@ TEST_P(GpuImageDecodeCacheTest, QualityCappedAtMedium) {
// Get the same image at kMedium_SkFilterQuality. We can't re-use low, so we
// should get a new task/ref.
- DrawImage medium_draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()),
- kMedium_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ DrawImage medium_draw_image = CreateDrawImageInternal(image);
ImageDecodeCache::TaskResult medium_result = cache->GetTaskForImageAndRef(
medium_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(medium_result.need_unref);
EXPECT_TRUE(medium_result.task.get());
EXPECT_FALSE(low_result.task.get() == medium_result.task.get());
- // Get the same image at kHigh_FilterQuality. We should re-use medium.
- DrawImage high_quality_draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()),
- kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex,
- DefaultColorSpace());
+ // Get the same image at kHigh_SkFilterQuality. We should re-use medium.
+ DrawImage high_quality_draw_image = CreateDrawImageInternal(
+ image, matrix, nullptr /* color_space */, kHigh_SkFilterQuality);
ImageDecodeCache::TaskResult high_quality_result =
cache->GetTaskForImageAndRef(high_quality_draw_image,
ImageDecodeCache::TracingInfo());
@@ -1660,15 +1611,9 @@ TEST_P(GpuImageDecodeCacheTest, QualityCappedAtMedium) {
// cache entry creation doesn't cause a buffer overflow/crash.
TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawMipUsageChange) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
// Create an image decode task and cache entry that does not need mips.
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1687,10 +1632,8 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawMipUsageChange) {
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
// Do an at-raster decode of the above image that *does* require mips.
- DrawImage draw_image_mips(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(0.6f, 0.6f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image_mips =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.6f, 0.6f)));
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image_mips));
cache->DrawWithImageFinished(draw_image_mips, decoded_draw_image);
@@ -1698,13 +1641,10 @@ TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawMipUsageChange) {
TEST_P(GpuImageDecodeCacheTest, OutOfRasterDecodeTask) {
auto cache = CreateCache();
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- bool is_decomposable = true;
- SkMatrix matrix = CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable);
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- kLow_SkFilterQuality, matrix,
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ SkMatrix matrix = CreateMatrix(SkSize::Make(1.0f, 1.0f));
+ DrawImage draw_image = CreateDrawImageInternal(
+ image, matrix, nullptr /* color_space */, kLow_SkFilterQuality);
ImageDecodeCache::TaskResult result =
cache->GetOutOfRasterDecodeTaskForImageAndRef(draw_image);
@@ -1723,16 +1663,10 @@ TEST_P(GpuImageDecodeCacheTest, OutOfRasterDecodeTask) {
TEST_P(GpuImageDecodeCacheTest, ZeroCacheNormalWorkingSet) {
SetCachedTexturesLimit(0);
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
// Add an image to the cache-> Due to normal working set, this should produce
// a task and a ref.
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1776,19 +1710,13 @@ TEST_P(GpuImageDecodeCacheTest, SmallCacheNormalWorkingSet) {
// Cache will fit one image.
SetCachedTexturesLimit(1);
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
PaintImage image2 = CreatePaintImageInternal(GetNormalImageSize());
DrawImage draw_image2(
- image2, SkIRect::MakeWH(image2.width(), image2.height()), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
+ image2, SkIRect::MakeWH(image2.width(), image2.height()),
+ kMedium_SkFilterQuality, CreateMatrix(SkSize::Make(1.0f, 1.0f)),
PaintImage::kDefaultFrameIndex, DefaultColorSpace());
// Add an image to the cache and un-ref it.
@@ -1858,15 +1786,9 @@ TEST_P(GpuImageDecodeCacheTest, SmallCacheNormalWorkingSet) {
TEST_P(GpuImageDecodeCacheTest, ClearCache) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
for (int i = 0; i < 10; ++i) {
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1888,15 +1810,9 @@ TEST_P(GpuImageDecodeCacheTest, ClearCache) {
TEST_P(GpuImageDecodeCacheTest, ClearCacheInUse) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
// Create an image but keep it reffed so it can't be immediately freed.
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1923,36 +1839,27 @@ TEST_P(GpuImageDecodeCacheTest, ClearCacheInUse) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentColorSpace) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
gfx::ColorSpace color_space_a = gfx::ColorSpace::CreateSRGB();
gfx::ColorSpace color_space_b = gfx::ColorSpace::CreateXYZD50();
PaintImage first_image = CreatePaintImageInternal(gfx::Size(100, 100));
- DrawImage first_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space_a);
+ DrawImage first_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(1.0f, 1.0f)), &color_space_a);
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
EXPECT_TRUE(first_result.task);
- DrawImage second_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space_b);
+ DrawImage second_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(1.0f, 1.0f)), &color_space_b);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
EXPECT_TRUE(second_result.task);
EXPECT_TRUE(first_result.task.get() != second_result.task.get());
- DrawImage third_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space_a);
+ DrawImage third_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(1.0f, 1.0f)), &color_space_a);
ImageDecodeCache::TaskResult third_result = cache->GetTaskForImageAndRef(
third_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(third_result.need_unref);
@@ -1970,15 +1877,10 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentColorSpace) {
TEST_P(GpuImageDecodeCacheTest, GetTaskForLargeImageNonSRGBColorSpace) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
gfx::ColorSpace color_space = gfx::ColorSpace::CreateXYZD50();
-
PaintImage image = CreateLargePaintImageForSoftwareFallback();
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space);
+ DrawImage draw_image = CreateDrawImageInternal(
+ image, CreateMatrix(SkSize::Make(1.0f, 1.0f)), &color_space);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -1992,7 +1894,6 @@ TEST_P(GpuImageDecodeCacheTest, GetTaskForLargeImageNonSRGBColorSpace) {
TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
auto cache = CreateCache();
-
std::vector<FrameMetadata> frames = {
FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
@@ -2014,12 +1915,10 @@ TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
+ SkFilterQuality quality = kMedium_SkFilterQuality;
DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- 1u, DefaultColorSpace());
+ quality, CreateMatrix(SkSize::Make(1.0f, 1.0f)), 1u,
+ DefaultColorSpace());
auto decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -2046,8 +1945,7 @@ TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
ASSERT_LT(subset_height, test_image_size.height());
DrawImage subset_draw_image(
image, SkIRect::MakeWH(subset_width, subset_height), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u,
- DefaultColorSpace());
+ CreateMatrix(SkSize::Make(1.0f, 1.0f)), 3u, DefaultColorSpace());
decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(subset_draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -2059,15 +1957,10 @@ TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {
TEST_P(GpuImageDecodeCacheTest, OrphanedDataCancelledWhileReplaced) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
// Create a downscaled image.
PaintImage first_image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage first_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage first_draw_image = CreateDrawImageInternal(
+ first_image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
ImageDecodeCache::TaskResult first_result = cache->GetTaskForImageAndRef(
first_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(first_result.need_unref);
@@ -2078,10 +1971,7 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedDataCancelledWhileReplaced) {
// Create a larger version of |first_image|, this should immediately free
// the memory used by |first_image| for the smaller scale.
- DrawImage second_draw_image(
- first_image, SkIRect::MakeWH(first_image.width(), first_image.height()),
- quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage second_draw_image = CreateDrawImageInternal(first_image);
ImageDecodeCache::TaskResult second_result = cache->GetTaskForImageAndRef(
second_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(second_result.need_unref);
@@ -2114,15 +2004,10 @@ TEST_P(GpuImageDecodeCacheTest, OrphanedDataCancelledWhileReplaced) {
TEST_P(GpuImageDecodeCacheTest, AlreadyBudgetedImagesAreNotAtRaster) {
auto cache = CreateCache();
- bool is_decomposable = true;
- const SkFilterQuality quality = kHigh_SkFilterQuality;
const gfx::Size test_image_size = GetNormalImageSize();
PaintImage image = CreatePaintImageInternal(test_image_size);
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
const size_t bytes_for_test_image =
GetBytesNeededForSingleImage(test_image_size);
@@ -2155,8 +2040,6 @@ TEST_P(GpuImageDecodeCacheTest, AlreadyBudgetedImagesAreNotAtRaster) {
TEST_P(GpuImageDecodeCacheTest, ImageBudgetingByCount) {
auto cache = CreateCache();
- bool is_decomposable = true;
- const SkFilterQuality quality = kHigh_SkFilterQuality;
const gfx::Size test_image_size = GetNormalImageSize();
// Allow a single image by count. Use a high byte limit as we want to test the
@@ -2166,10 +2049,7 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingByCount) {
cache->SetWorkingSetLimitsForTesting(
bytes_for_test_image * 100 /* max_bytes */, 1u /* max_items */);
PaintImage image = CreatePaintImageInternal(test_image_size);
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
// The image counts against our budget.
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
@@ -2179,11 +2059,9 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingByCount) {
EXPECT_TRUE(decoded_draw_image.is_budgeted());
// Try another image, it shouldn't be budgeted and should be at-raster.
- DrawImage second_draw_image(
- CreatePaintImageInternal(GetNormalImageSize()),
- SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage second_paint_image =
+ CreatePaintImageInternal(GetNormalImageSize());
+ DrawImage second_draw_image = CreateDrawImageInternal(second_paint_image);
// Should be at raster.
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
@@ -2202,15 +2080,10 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingByCount) {
TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {
auto cache = CreateCache();
- bool is_decomposable = true;
- const SkFilterQuality quality = kHigh_SkFilterQuality;
const gfx::Size test_image_size = GetNormalImageSize();
PaintImage image = CreatePaintImageInternal(test_image_size);
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
const size_t bytes_for_test_image =
GetBytesNeededForSingleImage(test_image_size);
@@ -2228,11 +2101,8 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {
EXPECT_TRUE(decoded_draw_image.is_budgeted());
// Try another image, it shouldn't be budgeted and should be at-raster.
- DrawImage second_draw_image(
- CreatePaintImageInternal(test_image_size),
- SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ PaintImage test_paint_image = CreatePaintImageInternal(test_image_size);
+ DrawImage second_draw_image = CreateDrawImageInternal(test_paint_image);
// Should be at raster.
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
@@ -2252,15 +2122,11 @@ TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {
TEST_P(GpuImageDecodeCacheTest,
ColorConversionDuringDecodeForLargeImageNonSRGBColorSpace) {
auto cache = CreateCache();
- bool is_decomposable = true;
- const SkFilterQuality quality = kHigh_SkFilterQuality;
gfx::ColorSpace color_space = gfx::ColorSpace::CreateXYZD50();
PaintImage image = CreateLargePaintImageForSoftwareFallback();
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space);
+ DrawImage draw_image = CreateDrawImageInternal(
+ image, CreateMatrix(SkSize::Make(1.0f, 1.0f)), &color_space);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2307,15 +2173,11 @@ TEST_P(GpuImageDecodeCacheTest,
TEST_P(GpuImageDecodeCacheTest,
ColorConversionDuringUploadForSmallImageNonSRGBColorSpace) {
auto cache = CreateCache();
- bool is_decomposable = true;
- const SkFilterQuality quality = kHigh_SkFilterQuality;
gfx::ColorSpace color_space = gfx::ColorSpace::CreateDisplayP3D65();
PaintImage image = CreatePaintImageInternal(gfx::Size(11, 12));
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space);
+ DrawImage draw_image = CreateDrawImageInternal(
+ image, CreateMatrix(SkSize::Make(1.0f, 1.0f)), &color_space);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2341,9 +2203,11 @@ TEST_P(GpuImageDecodeCacheTest,
EXPECT_EQ(image.width(), service_image->width());
EXPECT_EQ(image.height(), service_image->height());
- // Color space should be logically equal to the original color space.
- EXPECT_TRUE(SkColorSpace::Equals(service_image->colorSpace(),
- target_color_space.get()));
+ if (!do_yuv_decode_) {
+ // Color space should be logically equal to the original color space.
+ EXPECT_TRUE(SkColorSpace::Equals(service_image->colorSpace(),
+ target_color_space.get()));
+ }
} else {
// Ensure that the HW uploaded image had color space conversion applied.
EXPECT_TRUE(SkColorSpace::Equals(decoded_draw_image.image()->colorSpace(),
@@ -2360,14 +2224,9 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadNoScale) {
return;
}
auto cache = CreateCache();
- bool is_decomposable = true;
- const SkFilterQuality quality = kHigh_SkFilterQuality;
PaintImage image = CreateBitmapImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2385,14 +2244,9 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadTaskHasNoDeps) {
return;
}
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
PaintImage image = CreateBitmapImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
auto result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2409,14 +2263,9 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadTaskCancelled) {
return;
}
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
PaintImage image = CreateBitmapImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
auto result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2437,14 +2286,10 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
const bool should_cache_sw_image =
cache->SupportsColorSpaceConversion() && !use_transfer_cache_;
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
-
PaintImage image = CreateBitmapImageInternal(GetLargeImageSize());
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, gfx::ColorSpace::CreateDisplayP3D65());
+ gfx::ColorSpace color_space = gfx::ColorSpace::CreateDisplayP3D65();
+ DrawImage draw_image = CreateDrawImageInternal(
+ image, CreateMatrix(SkSize::Make(1.0f, 1.0f)), &color_space);
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2456,9 +2301,8 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageColorConverted) {
auto sw_image = cache->GetSWImageDecodeForTesting(draw_image);
ASSERT_EQ(!!sw_image, should_cache_sw_image);
if (should_cache_sw_image) {
- EXPECT_TRUE(SkColorSpace::Equals(
- sw_image->colorSpace(),
- gfx::ColorSpace::CreateDisplayP3D65().ToSkColorSpace().get()));
+ EXPECT_TRUE(SkColorSpace::Equals(sw_image->colorSpace(),
+ color_space.ToSkColorSpace().get()));
}
}
@@ -2468,14 +2312,10 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadDownscaled) {
return;
}
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
PaintImage image = CreateBitmapImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2486,8 +2326,6 @@ TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadDownscaled) {
TEST_P(GpuImageDecodeCacheTest, KeepOnlyLast2ContentIds) {
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
const PaintImage::Id paint_image_id = PaintImage::GetNextId();
@@ -2497,10 +2335,8 @@ TEST_P(GpuImageDecodeCacheTest, KeepOnlyLast2ContentIds) {
for (int i = 0; i < 10; ++i) {
PaintImage image = CreatePaintImageInternal(
GetNormalImageSize(), SkColorSpace::MakeSRGB(), paint_image_id);
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), quality,
- CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.5f, 0.5f)));
DecodedDrawImage decoded_draw_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
@@ -2536,8 +2372,6 @@ TEST_P(GpuImageDecodeCacheTest, DecodeToScale) {
return;
}
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kMedium_SkFilterQuality;
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
const SkISize full_size = SkISize::Make(100, 100);
@@ -2554,10 +2388,8 @@ TEST_P(GpuImageDecodeCacheTest, DecodeToScale) {
.set_paint_image_generator(generator)
.TakePaintImage();
- DrawImage draw_image(
- paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
- quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(
+ paint_image, CreateMatrix(SkSize::Make(0.5, 0.5)));
DecodedDrawImage decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
const int expected_width =
@@ -2583,8 +2415,6 @@ TEST_P(GpuImageDecodeCacheTest, DecodeToScaleNoneQuality) {
return;
}
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kNone_SkFilterQuality;
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
SkISize full_size = SkISize::Make(100, 100);
@@ -2601,10 +2431,9 @@ TEST_P(GpuImageDecodeCacheTest, DecodeToScaleNoneQuality) {
.set_paint_image_generator(generator)
.TakePaintImage();
- DrawImage draw_image(
- paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
- quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(paint_image, CreateMatrix(SkSize::Make(0.5, 0.5)),
+ nullptr /* color_space */, kNone_SkFilterQuality);
DecodedDrawImage decoded_image =
EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
ASSERT_TRUE(decoded_image.image());
@@ -2627,12 +2456,10 @@ TEST_P(GpuImageDecodeCacheTest, BasicMips) {
SkSize scale, gfx::ColorSpace color_space,
bool should_have_mips) {
auto cache = CreateCache();
- bool is_decomposable = true;
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
- DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
- filter_quality, CreateMatrix(scale, is_decomposable),
- PaintImage::kDefaultFrameIndex, color_space);
+ DrawImage draw_image = CreateDrawImageInternal(
+ image, CreateMatrix(scale), &color_space, filter_quality);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2644,23 +2471,23 @@ TEST_P(GpuImageDecodeCacheTest, BasicMips) {
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ // Pull out transfer cache ID from the DecodedDrawImage while it still has
+ // it attached.
+ DecodedDrawImage serialized_decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ const base::Optional<uint32_t> transfer_cache_entry_id =
+ serialized_decoded_draw_image.transfer_cache_entry_id();
DecodedDrawImage decoded_draw_image =
- EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
+ EnsureImageBacked(std::move(serialized_decoded_draw_image));
EXPECT_TRUE(decoded_draw_image.image());
EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
if (do_yuv_decode_) {
- // As of M74, Skia will flatten a YUV SkImage upon calling
- // makeTextureImage. Thus, we must separately request mips for each
- // plane and compare to the original uploaded planes.
- CompareAllPlanesToMippedVersions(cache.get(), draw_image,
- should_have_mips);
- EXPECT_TRUE(
- SkColorSpace::Equals(cache->SupportsColorSpaceConversion()
- ? color_space.ToSkColorSpace().get()
- : nullptr,
- decoded_draw_image.image()->colorSpace()));
-
+ // Skia will flatten a YUV SkImage upon calling makeTextureImage. Thus,
+ // we must separately request mips for each plane and compare to the
+ // original uploaded planes.
+ CompareAllPlanesToMippedVersions(
+ cache.get(), draw_image, transfer_cache_entry_id, should_have_mips);
} else {
sk_sp<SkImage> image_with_mips =
decoded_draw_image.image()->makeTextureImage(
@@ -2688,9 +2515,6 @@ TEST_P(GpuImageDecodeCacheTest, BasicMips) {
// Medium filter quality == mips
decode_and_check_mips(kMedium_SkFilterQuality, SkSize::Make(0.6f, 0.6f),
DefaultColorSpace(), true);
- // High filter quality == mips
- decode_and_check_mips(kHigh_SkFilterQuality, SkSize::Make(0.6f, 0.6f),
- DefaultColorSpace(), true);
// Color conversion preserves mips
decode_and_check_mips(kMedium_SkFilterQuality, SkSize::Make(0.6f, 0.6f),
gfx::ColorSpace::CreateXYZD50(), true);
@@ -2698,17 +2522,12 @@ TEST_P(GpuImageDecodeCacheTest, BasicMips) {
TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
auto cache = CreateCache();
- bool is_decomposable = true;
- auto filter_quality = kMedium_SkFilterQuality;
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
// Create an image with no scaling. It will not have mips.
{
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2720,17 +2539,24 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ // Pull out transfer cache ID from the DecodedDrawImage while it still has
+ // it attached.
+ DecodedDrawImage serialized_decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ const base::Optional<uint32_t> transfer_cache_entry_id =
+ serialized_decoded_draw_image.transfer_cache_entry_id();
DecodedDrawImage decoded_draw_image =
- EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
+ EnsureImageBacked(std::move(serialized_decoded_draw_image));
EXPECT_TRUE(decoded_draw_image.image());
EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
// No mips should be generated.
if (do_yuv_decode_) {
- // As of M74, Skia will flatten a YUV SkImage upon calling
- // makeTextureImage. Thus, we must separately request mips for each
- // plane and compare to the original uploaded planes.
+ // Skia will flatten a YUV SkImage upon calling makeTextureImage. Thus,
+ // we must separately request mips for each plane and compare to the
+ // original uploaded planes.
CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+ transfer_cache_entry_id,
false /* should_have_mips */);
} else {
sk_sp<SkImage> image_with_mips =
@@ -2750,10 +2576,8 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
// no new task (re-uses the existing image), but mips should have been
// added.
{
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
- CreateMatrix(SkSize::Make(0.6f, 0.6f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.6f, 0.6f)));
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2762,21 +2586,26 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ // Pull out transfer cache ID from the DecodedDrawImage while it still has
+ // it attached.
+ DecodedDrawImage serialized_decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ const base::Optional<uint32_t> transfer_cache_entry_id =
+ serialized_decoded_draw_image.transfer_cache_entry_id();
DecodedDrawImage decoded_draw_image =
- EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
+ EnsureImageBacked(std::move(serialized_decoded_draw_image));
EXPECT_TRUE(decoded_draw_image.image());
EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
// Mips should be generated
if (do_yuv_decode_) {
+ // Skia will flatten a YUV SkImage upon calling makeTextureImage. Thus,
+ // we must separately request mips for each plane and compare to the
+ // original uploaded planes.
CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+ transfer_cache_entry_id,
true /* should_have_mips */);
- EXPECT_TRUE(
- SkColorSpace::Equals(cache->SupportsColorSpaceConversion()
- ? DefaultColorSpace().ToSkColorSpace().get()
- : nullptr,
- decoded_draw_image.image()->colorSpace()));
} else {
sk_sp<SkImage> image_with_mips =
decoded_draw_image.image()->makeTextureImage(
@@ -2790,9 +2619,6 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
auto cache = CreateCache();
- bool is_decomposable = true;
- auto filter_quality = kMedium_SkFilterQuality;
-
PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
struct Decode {
@@ -2803,10 +2629,7 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
// Create an image with no scaling. It will not have mips.
{
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(image);
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2818,17 +2641,24 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ // Pull out transfer cache ID from the DecodedDrawImage while it still has
+ // it attached.
+ DecodedDrawImage serialized_decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ const base::Optional<uint32_t> transfer_cache_entry_id =
+ serialized_decoded_draw_image.transfer_cache_entry_id();
DecodedDrawImage decoded_draw_image =
- EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
+ EnsureImageBacked(std::move(serialized_decoded_draw_image));
ASSERT_TRUE(decoded_draw_image.image());
ASSERT_TRUE(decoded_draw_image.image()->isTextureBacked());
// No mips should be generated.
if (do_yuv_decode_) {
- // As of M74, Skia will flatten a YUV SkImage upon calling
- // makeTextureImage. Thus, we must separately request mips for each
- // plane and compare to the original uploaded planes.
+ // Skia will flatten a YUV SkImage upon calling makeTextureImage. Thus,
+ // we must separately request mips for each plane and compare to the
+ // original uploaded planes.
CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+ transfer_cache_entry_id,
false /* should_have_mips */);
} else {
sk_sp<SkImage> image_with_mips =
@@ -2841,10 +2671,8 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
// Second decode with mips.
{
- DrawImage draw_image(
- image, SkIRect::MakeWH(image.width(), image.height()), filter_quality,
- CreateMatrix(SkSize::Make(0.6f, 0.6f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image =
+ CreateDrawImageInternal(image, CreateMatrix(SkSize::Make(0.6f, 0.6f)));
ImageDecodeCache::TaskResult result = cache->GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
@@ -2853,21 +2681,26 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ // Pull out transfer cache ID from the DecodedDrawImage while it still has
+ // it attached.
+ DecodedDrawImage serialized_decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ const base::Optional<uint32_t> transfer_cache_entry_id =
+ serialized_decoded_draw_image.transfer_cache_entry_id();
DecodedDrawImage decoded_draw_image =
- EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
+ EnsureImageBacked(std::move(serialized_decoded_draw_image));
ASSERT_TRUE(decoded_draw_image.image());
ASSERT_TRUE(decoded_draw_image.image()->isTextureBacked());
// Mips should be generated.
if (do_yuv_decode_) {
+ // Skia will flatten a YUV SkImage upon calling makeTextureImage. Thus,
+ // we must separately request mips for each plane and compare to the
+ // original uploaded planes.
CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+ transfer_cache_entry_id,
true /* should_have_mips */);
- EXPECT_TRUE(
- SkColorSpace::Equals(cache->SupportsColorSpaceConversion()
- ? DefaultColorSpace().ToSkColorSpace().get()
- : nullptr,
- decoded_draw_image.image()->colorSpace()));
} else {
sk_sp<SkImage> image_with_mips =
decoded_draw_image.image()->makeTextureImage(
@@ -2911,21 +2744,139 @@ TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
}
}
+TEST_P(GpuImageDecodeCacheTest,
+ OriginalYUVDecodeScaledDrawCorrectlyMipsPlanes) {
+ // This test creates an image that will be YUV decoded and drawn at 80% scale.
+ // Because the final size is between mip levels, we expect the image to be
+ // decoded and uploaded at original size (mip level 0 for all planes) but to
+ // have mips attached since kMedium_SkFilterQuality uses bilinear filtering
+ // between mip levels.
+ if (!do_yuv_decode_) {
+ // The YUV case may choose different mip levels between chroma and luma
+ // planes.
+ return;
+ }
+ auto cache = CreateCache();
+ SkFilterQuality filter_quality = kMedium_SkFilterQuality;
+ SkSize requires_decode_at_original_scale = SkSize::Make(0.8f, 0.8f);
+
+ PaintImage image = CreatePaintImageInternal(GetNormalImageSize());
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ filter_quality,
+ CreateMatrix(requires_decode_at_original_scale),
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ ImageDecodeCache::TaskResult result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ EXPECT_TRUE(result.task);
+
+ TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(result.task.get());
+
+ // Must hold context lock before calling GetDecodedImageForDraw /
+ // DrawWithImageFinished.
+ viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ // Pull out transfer cache ID from the DecodedDrawImage while it still has
+ // it attached.
+ DecodedDrawImage serialized_decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ const base::Optional<uint32_t> transfer_cache_entry_id =
+ serialized_decoded_draw_image.transfer_cache_entry_id();
+ DecodedDrawImage decoded_draw_image =
+ EnsureImageBacked(std::move(serialized_decoded_draw_image));
+ EXPECT_TRUE(decoded_draw_image.image());
+ EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
+
+ // Skia will flatten a YUV SkImage upon calling makeTextureImage. Thus, we
+ // must separately request mips for each plane and compare to the original
+ // uploaded planes.
+ CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+ transfer_cache_entry_id,
+ true /* should_have_mips */);
+ SkYUVASizeInfo yuv_size_info = GetYUV420SizeInfo(GetNormalImageSize());
+ VerifyUploadedPlaneSizes(cache.get(), draw_image, transfer_cache_entry_id,
+ yuv_size_info.fSizes);
+
+ cache->DrawWithImageFinished(draw_image, decoded_draw_image);
+ cache->UnrefImage(draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheTest, ScaledYUVDecodeScaledDrawCorrectlyMipsPlanes) {
+ // This test creates an image that will be YUV decoded and drawn at 45% scale.
+ // Because the final size is between mip levels, we expect the image to be
+ // decoded and uploaded at half its original size (mip level 1 for Y plane but
+ // level 0 for chroma planes) and to have mips attached since
+ // kMedium_SkFilterQuality uses bilinear filtering between mip levels.
+ if (!do_yuv_decode_) {
+ // The YUV case may choose different mip levels between chroma and luma
+ // planes.
+ return;
+ }
+ auto cache = CreateCache();
+ SkFilterQuality filter_quality = kMedium_SkFilterQuality;
+ SkSize less_than_half_scale = SkSize::Make(0.45f, 0.45f);
+
+ gfx::Size image_size = GetNormalImageSize();
+ PaintImage image = CreatePaintImageInternal(image_size);
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ filter_quality, CreateMatrix(less_than_half_scale),
+ PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ ImageDecodeCache::TaskResult result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ EXPECT_TRUE(result.task);
+
+ TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(result.task.get());
+
+ // Must hold context lock before calling GetDecodedImageForDraw /
+ // DrawWithImageFinished.
+ viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ // Pull out transfer cache ID from the DecodedDrawImage while it still has
+ // it attached.
+ DecodedDrawImage serialized_decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ const base::Optional<uint32_t> transfer_cache_entry_id =
+ serialized_decoded_draw_image.transfer_cache_entry_id();
+ DecodedDrawImage decoded_draw_image =
+ EnsureImageBacked(std::move(serialized_decoded_draw_image));
+ EXPECT_TRUE(decoded_draw_image.image());
+ EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
+
+ // Skia will flatten a YUV SkImage upon calling makeTextureImage. Thus, we
+ // must separately request mips for each plane and compare to the original
+ // uploaded planes.
+ CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+ transfer_cache_entry_id,
+ true /* should_have_mips */);
+
+ // Because we intend to draw this image at 0.45 x 0.45 scale, we will upload
+ // the Y plane at mip level 1 (corresponding to half the original size). The
+ // chroma planes (U and V) should be uploaded at the same size as the Y plane,
+ // corresponding to mip level 0, because the largest dimensions greater than
+ // or equal to target dimensions for them is their original size.
+ SkISize mipped_plane_sizes[SkYUVASizeInfo::kMaxCount];
+ mipped_plane_sizes[SkYUVAIndex::kY_Index] = SkISize::Make(
+ (image_size.width() + 1) / 2, (image_size.height() + 1) / 2);
+ mipped_plane_sizes[SkYUVAIndex::kU_Index] =
+ mipped_plane_sizes[SkYUVAIndex::kY_Index];
+ mipped_plane_sizes[SkYUVAIndex::kV_Index] =
+ mipped_plane_sizes[SkYUVAIndex::kY_Index];
+ VerifyUploadedPlaneSizes(cache.get(), draw_image, transfer_cache_entry_id,
+ mipped_plane_sizes);
+
+ cache->DrawWithImageFinished(draw_image, decoded_draw_image);
+ cache->UnrefImage(draw_image);
+}
+
TEST_P(GpuImageDecodeCacheTest, GetBorderlineLargeDecodedImageForDraw) {
// We will create a texture that's at the maximum size the GPU says it can
// support for uploads.
auto cache = CreateCache();
- bool is_decomposable = true;
- SkFilterQuality quality = kHigh_SkFilterQuality;
PaintImage almost_too_large_image =
CreatePaintImageInternal(gfx::Size(max_texture_size_, max_texture_size_));
- DrawImage draw_image(almost_too_large_image,
- SkIRect::MakeWH(almost_too_large_image.width(),
- almost_too_large_image.height()),
- quality,
- CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
- PaintImage::kDefaultFrameIndex, DefaultColorSpace());
+ DrawImage draw_image = CreateDrawImageInternal(almost_too_large_image);
ImageDecodeCache::TaskResult result =
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
@@ -2959,16 +2910,326 @@ bool true_array[] = {true};
INSTANTIATE_TEST_SUITE_P(
GpuImageDecodeCacheTestsInProcessRaster,
GpuImageDecodeCacheTest,
- testing::Combine(testing::ValuesIn(test_color_types),
- testing::ValuesIn(false_array) /* use_transfer_cache */,
- testing::Bool() /* do_yuv_decode */));
+ testing::Combine(
+ testing::ValuesIn(test_color_types),
+ testing::ValuesIn(false_array) /* use_transfer_cache */,
+ testing::Bool() /* do_yuv_decode */,
+ testing::ValuesIn(false_array) /* advertise_accelerated_decoding */));
INSTANTIATE_TEST_SUITE_P(
GpuImageDecodeCacheTestsOOPR,
GpuImageDecodeCacheTest,
- testing::Combine(testing::ValuesIn(test_color_types),
- testing::ValuesIn(true_array) /* use_transfer_cache */,
- testing::ValuesIn(false_array) /* do_yuv_decode */));
+ testing::Combine(
+ testing::ValuesIn(test_color_types),
+ testing::ValuesIn(true_array) /* use_transfer_cache */,
+ testing::Bool() /* do_yuv_decode */,
+ testing::ValuesIn(false_array) /* advertise_accelerated_decoding */));
+
+class GpuImageDecodeCacheWithAcceleratedDecodesTest
+ : public GpuImageDecodeCacheTest {
+ public:
+ PaintImage CreatePaintImageForDecodeAcceleration(
+ const gfx::Size& size,
+ sk_sp<SkColorSpace> color_space = nullptr,
+ bool is_eligible_for_accelerated_decoding = true) {
+ SkImageInfo info =
+ SkImageInfo::Make(size.width(), size.height(), color_type_,
+ kPremul_SkAlphaType, color_space);
+ sk_sp<FakePaintImageGenerator> generator;
+ if (do_yuv_decode_) {
+ generator =
+ sk_make_sp<FakePaintImageGenerator>(info, GetYUV420SizeInfo(size));
+ } else {
+ generator = sk_make_sp<FakePaintImageGenerator>(info);
+ }
+ if (is_eligible_for_accelerated_decoding)
+ generator->SetEligibleForAcceleratedDecoding();
+ PaintImage image = PaintImageBuilder::WithDefault()
+ .set_id(PaintImage::GetNextId())
+ .set_paint_image_generator(generator)
+ .TakePaintImage();
+ return image;
+ }
+
+ StrictMock<MockRasterImplementation>* raster_implementation() const {
+ return static_cast<StrictMock<MockRasterImplementation>*>(
+ context_provider_->RasterInterface());
+ }
+};
+
+TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
+ RequestAcceleratedDecodeSuccessfully) {
+ auto cache = CreateCache();
+ const gfx::Size image_size = GetNormalImageSize();
+ const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB();
+ const gfx::ColorSpace target_color_space(*image_color_space);
+ ASSERT_TRUE(target_color_space.IsValid());
+ const PaintImage image =
+ CreatePaintImageForDecodeAcceleration(image_size, image_color_space);
+ const SkFilterQuality quality = kHigh_SkFilterQuality;
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)),
+ PaintImage::kDefaultFrameIndex, target_color_space);
+ ImageDecodeCache::TaskResult result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ ASSERT_TRUE(result.task);
+
+ // Accelerated decodes should not produce decode tasks.
+ ASSERT_TRUE(result.task->dependencies().empty());
+ EXPECT_CALL(*raster_implementation(),
+ DoScheduleImageDecode(image_size, _, gfx::ColorSpace(), _))
+ .Times(1);
+ TestTileTaskRunner::ProcessTask(result.task.get());
+
+ // Must hold context lock before calling GetDecodedImageForDraw /
+ // DrawWithImageFinished.
+ viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ const DecodedDrawImage decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ EXPECT_TRUE(decoded_draw_image.transfer_cache_entry_id().has_value());
+ cache->DrawWithImageFinished(draw_image, decoded_draw_image);
+ cache->UnrefImage(draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
+ RequestAcceleratedDecodeSuccessfullyWithColorSpaceConversion) {
+ auto cache = CreateCache();
+ const gfx::Size image_size = GetNormalImageSize();
+ const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB();
+ const gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateXYZD50();
+ ASSERT_TRUE(target_color_space.IsValid());
+ const PaintImage image =
+ CreatePaintImageForDecodeAcceleration(image_size, image_color_space);
+ const SkFilterQuality quality = kHigh_SkFilterQuality;
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)),
+ PaintImage::kDefaultFrameIndex, target_color_space);
+ ImageDecodeCache::TaskResult result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ ASSERT_TRUE(result.task);
+
+ // Accelerated decodes should not produce decode tasks.
+ ASSERT_TRUE(result.task->dependencies().empty());
+ EXPECT_CALL(*raster_implementation(),
+ DoScheduleImageDecode(image_size, _,
+ cache->SupportsColorSpaceConversion()
+ ? target_color_space
+ : gfx::ColorSpace(),
+ _))
+ .Times(1);
+ TestTileTaskRunner::ProcessTask(result.task.get());
+
+ // Must hold context lock before calling GetDecodedImageForDraw /
+ // DrawWithImageFinished.
+ viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ const DecodedDrawImage decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ EXPECT_TRUE(decoded_draw_image.transfer_cache_entry_id().has_value());
+ cache->DrawWithImageFinished(draw_image, decoded_draw_image);
+ cache->UnrefImage(draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
+ AcceleratedDecodeRequestFails) {
+ auto cache = CreateCache();
+ const gfx::Size image_size = GetNormalImageSize();
+ const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB();
+ const gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateXYZD50();
+ ASSERT_TRUE(target_color_space.IsValid());
+ const PaintImage image =
+ CreatePaintImageForDecodeAcceleration(image_size, image_color_space);
+ const SkFilterQuality quality = kHigh_SkFilterQuality;
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)),
+ PaintImage::kDefaultFrameIndex, target_color_space);
+ ImageDecodeCache::TaskResult result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ ASSERT_TRUE(result.task);
+
+ // Accelerated decodes should not produce decode tasks.
+ ASSERT_TRUE(result.task->dependencies().empty());
+ raster_implementation()->SetAcceleratedDecodingFailed();
+ EXPECT_CALL(*raster_implementation(),
+ DoScheduleImageDecode(image_size, _,
+ cache->SupportsColorSpaceConversion()
+ ? target_color_space
+ : gfx::ColorSpace(),
+ _))
+ .Times(1);
+ TestTileTaskRunner::ProcessTask(result.task.get());
+
+ // Must hold context lock before calling GetDecodedImageForDraw /
+ // DrawWithImageFinished.
+ viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ const DecodedDrawImage decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ EXPECT_FALSE(decoded_draw_image.transfer_cache_entry_id().has_value());
+ cache->DrawWithImageFinished(draw_image, decoded_draw_image);
+ cache->UnrefImage(draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
+ CannotRequestAcceleratedDecodeBecauseOfStandAloneDecode) {
+ auto cache = CreateCache();
+ const gfx::Size image_size = GetNormalImageSize();
+ const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB();
+ const gfx::ColorSpace target_color_space(*image_color_space);
+ ASSERT_TRUE(target_color_space.IsValid());
+ const PaintImage image =
+ CreatePaintImageForDecodeAcceleration(image_size, image_color_space);
+ const SkFilterQuality quality = kHigh_SkFilterQuality;
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality, CreateMatrix(SkSize::Make(1.0f, 1.0f)),
+ PaintImage::kDefaultFrameIndex, target_color_space);
+ ImageDecodeCache::TaskResult result =
+ cache->GetOutOfRasterDecodeTaskForImageAndRef(draw_image);
+ EXPECT_TRUE(result.need_unref);
+ ASSERT_TRUE(result.task);
+
+ // A non-accelerated standalone decode should produce only a decode task.
+ ASSERT_TRUE(result.task->dependencies().empty());
+ TestTileTaskRunner::ProcessTask(result.task.get());
+ cache->UnrefImage(draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
+ CannotRequestAcceleratedDecodeBecauseOfNonZeroUploadMipLevel) {
+ auto cache = CreateCache();
+ const gfx::Size image_size = GetNormalImageSize();
+ const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB();
+ const gfx::ColorSpace target_color_space(*image_color_space);
+ ASSERT_TRUE(target_color_space.IsValid());
+ const PaintImage image =
+ CreatePaintImageForDecodeAcceleration(image_size, image_color_space);
+ const SkFilterQuality quality = kHigh_SkFilterQuality;
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality, CreateMatrix(SkSize::Make(0.5f, 0.5f)),
+ PaintImage::kDefaultFrameIndex, target_color_space);
+ ImageDecodeCache::TaskResult result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ ASSERT_TRUE(result.task);
+
+ // A non-accelerated normal decode should produce a decode dependency.
+ ASSERT_EQ(result.task->dependencies().size(), 1u);
+ ASSERT_TRUE(result.task->dependencies()[0]);
+ TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(result.task.get());
+ cache->UnrefImage(draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
+ CannotRequestAcceleratedDecodeBecauseOfIneligiblePaintImage) {
+ auto cache = CreateCache();
+ const gfx::Size image_size = GetNormalImageSize();
+ const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB();
+ const gfx::ColorSpace target_color_space(*image_color_space);
+ ASSERT_TRUE(target_color_space.IsValid());
+ const PaintImage image = CreatePaintImageForDecodeAcceleration(
+ image_size, image_color_space,
+ false /* is_eligible_for_accelerated_decoding */);
+ const SkFilterQuality quality = kHigh_SkFilterQuality;
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality, CreateMatrix(SkSize::Make(1.0f, 1.0f)),
+ PaintImage::kDefaultFrameIndex, target_color_space);
+ ImageDecodeCache::TaskResult result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ ASSERT_TRUE(result.task);
+
+ // A non-accelerated normal decode should produce a decode dependency.
+ ASSERT_EQ(result.task->dependencies().size(), 1u);
+ ASSERT_TRUE(result.task->dependencies()[0]);
+ TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(result.task.get());
+ cache->UnrefImage(draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
+ CannotRequestAcceleratedDecodeBecauseOfNonSRGBColorSpace) {
+ auto cache = CreateCache();
+ const gfx::Size image_size = GetNormalImageSize();
+ const sk_sp<SkColorSpace> image_color_space =
+ SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB);
+ const gfx::ColorSpace target_color_space(*image_color_space);
+ ASSERT_TRUE(target_color_space.IsValid());
+ const PaintImage image =
+ CreatePaintImageForDecodeAcceleration(image_size, image_color_space);
+ const SkFilterQuality quality = kHigh_SkFilterQuality;
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality, CreateMatrix(SkSize::Make(1.0f, 1.0f)),
+ PaintImage::kDefaultFrameIndex, target_color_space);
+ ImageDecodeCache::TaskResult result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ ASSERT_TRUE(result.task);
+
+ // A non-accelerated normal decode should produce a decode dependency.
+ ASSERT_EQ(result.task->dependencies().size(), 1u);
+ ASSERT_TRUE(result.task->dependencies()[0]);
+ TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(result.task.get());
+ cache->UnrefImage(draw_image);
+}
+
+TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
+ RequestAcceleratedDecodeSuccessfullyAfterCancellation) {
+ auto cache = CreateCache();
+ const gfx::Size image_size = GetNormalImageSize();
+ const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB();
+ const gfx::ColorSpace target_color_space(*image_color_space);
+ ASSERT_TRUE(target_color_space.IsValid());
+ const PaintImage image =
+ CreatePaintImageForDecodeAcceleration(image_size, image_color_space);
+ const SkFilterQuality quality = kHigh_SkFilterQuality;
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)),
+ PaintImage::kDefaultFrameIndex, target_color_space);
+ ImageDecodeCache::TaskResult result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(result.need_unref);
+ ASSERT_TRUE(result.task);
+
+ // Accelerated decodes should not produce decode tasks.
+ ASSERT_TRUE(result.task->dependencies().empty());
+
+ // Cancel the upload.
+ TestTileTaskRunner::CancelTask(result.task.get());
+ TestTileTaskRunner::CompleteTask(result.task.get());
+
+ // Get the image again - we should have an upload task.
+ ImageDecodeCache::TaskResult another_result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(another_result.need_unref);
+ ASSERT_TRUE(another_result.task);
+ EXPECT_EQ(another_result.task->dependencies().size(), 0u);
+ EXPECT_CALL(*raster_implementation(),
+ DoScheduleImageDecode(image_size, _, gfx::ColorSpace(), _))
+ .Times(1);
+ TestTileTaskRunner::ProcessTask(another_result.task.get());
+
+ // Must hold context lock before calling GetDecodedImageForDraw /
+ // DrawWithImageFinished.
+ viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ const DecodedDrawImage decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ EXPECT_TRUE(decoded_draw_image.transfer_cache_entry_id().has_value());
+ cache->DrawWithImageFinished(draw_image, decoded_draw_image);
+ cache->UnrefImage(draw_image);
+ cache->UnrefImage(draw_image);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ GpuImageDecodeCacheTestsOOPR,
+ GpuImageDecodeCacheWithAcceleratedDecodesTest,
+ testing::Combine(
+ testing::ValuesIn(test_color_types),
+ testing::ValuesIn(true_array) /* use_transfer_cache */,
+ testing::Bool() /* do_yuv_decode */,
+ testing::ValuesIn(true_array) /* advertise_accelerated_decoding */));
#undef EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE
#undef EXPECT_FALSE_IF_NOT_USING_TRANSFER_CACHE
diff --git a/chromium/cc/tiles/image_controller.cc b/chromium/cc/tiles/image_controller.cc
index 919be166e5f..9f600462eb8 100644
--- a/chromium/cc/tiles/image_controller.cc
+++ b/chromium/cc/tiles/image_controller.cc
@@ -21,8 +21,7 @@ ImageController::ImageController(
base::SequencedTaskRunner* origin_task_runner,
scoped_refptr<base::SequencedTaskRunner> worker_task_runner)
: worker_task_runner_(std::move(worker_task_runner)),
- origin_task_runner_(origin_task_runner),
- weak_ptr_factory_(this) {
+ origin_task_runner_(origin_task_runner) {
weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
}
@@ -129,11 +128,6 @@ void ImageController::StopWorkerTasks() {
image_decode_queue_.clear();
}
-void ImageController::SetPaintWorkletLayerPainter(
- std::unique_ptr<PaintWorkletLayerPainter> painter) {
- paint_worklet_image_cache_.SetPaintWorkletLayerPainter(std::move(painter));
-}
-
void ImageController::SetImageDecodeCache(ImageDecodeCache* cache) {
DCHECK(!cache_ || !cache);
@@ -152,27 +146,7 @@ void ImageController::SetImageDecodeCache(ImageDecodeCache* cache) {
}
}
-void ImageController::ConvertPaintWorkletImagesToTask(
- std::vector<DrawImage>* sync_decoded_images,
- std::vector<scoped_refptr<TileTask>>* tasks) {
- for (auto it = sync_decoded_images->begin();
- it != sync_decoded_images->end();) {
- if (!it->paint_image().IsPaintWorklet()) {
- ++it;
- continue;
- }
- scoped_refptr<TileTask> result =
- paint_worklet_image_cache_.GetTaskForPaintWorkletImage(*it);
- if (result)
- tasks->push_back(std::move(result));
- // Remove it so that there is no need to check whether an image is
- // PaintWorklet generated or not in TileManager's
- // work_to_schedule->extra_prepaint_images.insert.
- it = sync_decoded_images->erase(it);
- }
-}
-
-void ImageController::ConvertDataImagesToTasks(
+void ImageController::ConvertImagesToTasks(
std::vector<DrawImage>* sync_decoded_images,
std::vector<scoped_refptr<TileTask>>* tasks,
bool* has_at_raster_images,
@@ -181,10 +155,10 @@ void ImageController::ConvertDataImagesToTasks(
*has_at_raster_images = false;
for (auto it = sync_decoded_images->begin();
it != sync_decoded_images->end();) {
- if (it->paint_image().IsPaintWorklet()) {
- ++it;
- continue;
- }
+ // PaintWorklet images should not be included in this set; they have already
+ // been painted before raster and so do not need raster-time work.
+ DCHECK(!it->paint_image().IsPaintWorklet());
+
ImageDecodeCache::TaskResult result =
cache_->GetTaskForImageAndRef(*it, tracing_info);
*has_at_raster_images |= result.IsAtRaster();
@@ -212,8 +186,8 @@ std::vector<scoped_refptr<TileTask>> ImageController::SetPredecodeImages(
const ImageDecodeCache::TracingInfo& tracing_info) {
std::vector<scoped_refptr<TileTask>> new_tasks;
bool has_at_raster_images = false;
- ConvertDataImagesToTasks(&images, &new_tasks, &has_at_raster_images,
- tracing_info);
+ ConvertImagesToTasks(&images, &new_tasks, &has_at_raster_images,
+ tracing_info);
UnrefImages(predecode_locked_images_);
predecode_locked_images_ = std::move(images);
return new_tasks;
diff --git a/chromium/cc/tiles/image_controller.h b/chromium/cc/tiles/image_controller.h
index 2533b6e50f2..1ec832d13c1 100644
--- a/chromium/cc/tiles/image_controller.h
+++ b/chromium/cc/tiles/image_controller.h
@@ -19,7 +19,6 @@
#include "cc/paint/draw_image.h"
#include "cc/raster/tile_task.h"
#include "cc/tiles/image_decode_cache.h"
-#include "cc/tiles/paint_worklet_image_cache.h"
namespace cc {
@@ -39,32 +38,17 @@ class CC_EXPORT ImageController {
ImageController& operator=(const ImageController&) = delete;
void SetImageDecodeCache(ImageDecodeCache* cache);
- void SetPaintWorkletLayerPainter(
- std::unique_ptr<PaintWorkletLayerPainter> painter);
- // The name "Data images" are the images that are not generated by
- // PaintWorklet.
- // Build tile tasks for synchronously decoded images that are not generated by
- // PaintWorklet.
+ // Build tile tasks for synchronously decoded images.
// |sync_decoded_images| is the input. These are the images from a particular
// tile, retrieved by the DiscardableImageMap. Images can be removed from the
// vector under certain conditions.
// |tasks| is an output, which are the built tile tasks.
// |has_at_raster_images| is an output parameter.
// |tracing_info| is used in tracing or UMA only.
- void ConvertDataImagesToTasks(
- std::vector<DrawImage>* sync_decoded_images,
- std::vector<scoped_refptr<TileTask>>* tasks,
- bool* has_at_raster_images,
- const ImageDecodeCache::TracingInfo& tracing_info);
- // TODO(crbug.com/915566): bundle all tasks into a big TaskBag.
- // Build tile tasks for images that are generated by PaintWorklet.
- // |sync_decoded_images| is the input, which are the images from a particular
- // tile, retrieved by DiscardableImageMap. Images are removed from the vector
- // once the tile task is built.
- // |tasks| is an output, which are the built tile tasks.
- void ConvertPaintWorkletImagesToTask(
- std::vector<DrawImage>* sync_decoded_images,
- std::vector<scoped_refptr<TileTask>>* tasks);
+ void ConvertImagesToTasks(std::vector<DrawImage>* sync_decoded_images,
+ std::vector<scoped_refptr<TileTask>>* tasks,
+ bool* has_at_raster_images,
+ const ImageDecodeCache::TracingInfo& tracing_info);
void UnrefImages(const std::vector<DrawImage>& images);
void ReduceMemoryUsage();
std::vector<scoped_refptr<TileTask>> SetPredecodeImages(
@@ -90,9 +74,6 @@ class CC_EXPORT ImageController {
}
ImageDecodeCache* cache() const { return cache_; }
- PaintWorkletImageCache* paint_worklet_image_cache() {
- return &paint_worklet_image_cache_;
- }
protected:
scoped_refptr<base::SequencedTaskRunner> worker_task_runner_;
@@ -128,7 +109,6 @@ class CC_EXPORT ImageController {
base::WeakPtr<ImageController> weak_ptr_;
ImageDecodeCache* cache_ = nullptr;
- PaintWorkletImageCache paint_worklet_image_cache_;
std::vector<DrawImage> predecode_locked_images_;
static ImageDecodeRequestId s_next_image_decode_queue_id_;
@@ -151,7 +131,7 @@ class CC_EXPORT ImageController {
// from generating new tasks, this vector should be empty.
std::vector<ImageDecodeRequest> orphaned_decode_requests_;
- base::WeakPtrFactory<ImageController> weak_ptr_factory_;
+ base::WeakPtrFactory<ImageController> weak_ptr_factory_{this};
};
} // namespace cc
diff --git a/chromium/cc/tiles/image_controller_unittest.cc b/chromium/cc/tiles/image_controller_unittest.cc
index 1c3e0d3b215..17b20018fb2 100644
--- a/chromium/cc/tiles/image_controller_unittest.cc
+++ b/chromium/cc/tiles/image_controller_unittest.cc
@@ -244,9 +244,7 @@ DrawImage CreateBitmapDrawImage(gfx::Size size) {
class ImageControllerTest : public testing::Test {
public:
- ImageControllerTest()
- : task_runner_(base::SequencedTaskRunnerHandle::Get()),
- weak_ptr_factory_(this) {
+ ImageControllerTest() : task_runner_(base::SequencedTaskRunnerHandle::Get()) {
image_ = CreateDiscardableDrawImage(gfx::Size(1, 1));
}
~ImageControllerTest() override = default;
@@ -314,31 +312,9 @@ class ImageControllerTest : public testing::Test {
std::unique_ptr<ImageController> controller_;
DrawImage image_;
- base::WeakPtrFactory<ImageControllerTest> weak_ptr_factory_;
+ base::WeakPtrFactory<ImageControllerTest> weak_ptr_factory_{this};
};
-// Test that GetTasksForImagesAndRef does not generate task for PaintWorklet
-// images.
-TEST_F(ImageControllerTest, GetTasksForImagesAndRefForPaintWorkletImages) {
- std::vector<DrawImage> images(1);
- ImageDecodeCache::TracingInfo tracing_info;
-
- PaintImage paint_image = CreatePaintImage(100, 100);
- DrawImage draw_image(
- paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
- kNone_SkFilterQuality, CreateMatrix(SkSize::Make(1.f, 1.f), true),
- PaintImage::kDefaultFrameIndex);
- images[0] = draw_image;
-
- ASSERT_EQ(1u, images.size());
-
- std::vector<scoped_refptr<TileTask>> tasks;
- bool has_at_raster_images = false;
- controller()->ConvertDataImagesToTasks(&images, &tasks, &has_at_raster_images,
- tracing_info);
- EXPECT_EQ(tasks.size(), 0u);
-}
-
TEST_F(ImageControllerTest, NullControllerUnrefsImages) {
std::vector<DrawImage> images(10);
ImageDecodeCache::TracingInfo tracing_info;
diff --git a/chromium/cc/tiles/image_decode_cache.cc b/chromium/cc/tiles/image_decode_cache.cc
index 7c83ee45a15..9c68e3cc26c 100644
--- a/chromium/cc/tiles/image_decode_cache.cc
+++ b/chromium/cc/tiles/image_decode_cache.cc
@@ -4,7 +4,6 @@
#include "cc/tiles/image_decode_cache.h"
-#include "base/metrics/histogram_macros.h"
#include "cc/raster/tile_task.h"
namespace cc {
@@ -19,11 +18,4 @@ ImageDecodeCache::TaskResult::TaskResult(const TaskResult& result) = default;
ImageDecodeCache::TaskResult::~TaskResult() = default;
-void ImageDecodeCache::RecordImageMipLevelUMA(int mip_level) {
- DCHECK_GE(mip_level, 0);
- DCHECK_LT(mip_level, 32);
- UMA_HISTOGRAM_EXACT_LINEAR("Renderer4.ImageDecodeMipLevel", mip_level + 1,
- 33);
-}
-
} // namespace cc
diff --git a/chromium/cc/tiles/image_decode_cache.h b/chromium/cc/tiles/image_decode_cache.h
index 6d7d339ee28..241f5772b02 100644
--- a/chromium/cc/tiles/image_decode_cache.h
+++ b/chromium/cc/tiles/image_decode_cache.h
@@ -143,9 +143,6 @@ class CC_EXPORT ImageDecodeCache {
// image can directly be used for raster (for instance bitmaps in a software
// draw).
virtual bool UseCacheForDrawImage(const DrawImage& image) const = 0;
-
- protected:
- void RecordImageMipLevelUMA(int mip_level);
};
} // namespace cc
diff --git a/chromium/cc/tiles/paint_worklet_image_cache.cc b/chromium/cc/tiles/paint_worklet_image_cache.cc
deleted file mode 100644
index d0bd702cae7..00000000000
--- a/chromium/cc/tiles/paint_worklet_image_cache.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/tiles/paint_worklet_image_cache.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "cc/paint/paint_worklet_layer_painter.h"
-
-namespace cc {
-
-class PaintWorkletTaskImpl : public TileTask {
- public:
- PaintWorkletTaskImpl(PaintWorkletImageCache* cache,
- const PaintImage& paint_image)
- : TileTask(true), cache_(cache), paint_image_(paint_image) {}
- PaintWorkletTaskImpl(const PaintWorkletTaskImpl&) = delete;
-
- PaintWorkletTaskImpl& operator=(const PaintWorkletTaskImpl&) = delete;
-
- // Overridden from Task:
- void RunOnWorkerThread() override { cache_->PaintImageInTask(paint_image_); }
-
- // Overridden from TileTask:
- void OnTaskCompleted() override {}
-
- protected:
- ~PaintWorkletTaskImpl() override = default;
-
- private:
- PaintWorkletImageCache* cache_;
- PaintImage paint_image_;
-};
-
-PaintWorkletImageCache::PaintWorkletImageCache() {}
-
-PaintWorkletImageCache::~PaintWorkletImageCache() {
- for (const auto& pair : records_)
- DCHECK_EQ(pair.second.used_ref_count, 0u);
-}
-
-void PaintWorkletImageCache::SetPaintWorkletLayerPainter(
- std::unique_ptr<PaintWorkletLayerPainter> painter) {
- DCHECK(!painter_);
- painter_ = std::move(painter);
-}
-
-scoped_refptr<TileTask> PaintWorkletImageCache::GetTaskForPaintWorkletImage(
- const DrawImage& image) {
- DCHECK(painter_);
- DCHECK(image.paint_image().IsPaintWorklet());
- return base::MakeRefCounted<PaintWorkletTaskImpl>(this, image.paint_image());
-}
-
-// TODO(xidachen): we might need to consider the animated property value and the
-// PaintWorkletInput to decide whether we need to call Paint() function or not.
-void PaintWorkletImageCache::PaintImageInTask(const PaintImage& paint_image) {
- // TODO(crbug.com/939009): When creating a TileTask for a given PaintImage at
- // GetTaskForPaintWorkletImage, we should not create a new TileTask if there
- // is already a TileTask for this PaintImage.
- {
- base::AutoLock hold(records_lock_);
- if (records_.find(paint_image.paint_worklet_input()) != records_.end())
- return;
- }
- // Because the compositor could be waiting on the lock in NotifyPrepareTiles,
- // we unlock here such that the compositor won't be blocked on potentially
- // slow Paint function.
- // TODO(xidachen): ensure that the canvas operations in the PaintRecord
- // matches the PaintGeneratedImage::Draw.
- sk_sp<PaintRecord> record =
- painter_->Paint(paint_image.paint_worklet_input());
- if (!record)
- return;
- {
- base::AutoLock hold(records_lock_);
- // It is possible for two or more threads to both pass through the first
- // lock and arrive here. To avoid ref-count issues caused by potential
- // racing among threads, we use insert such that if an entry already exists
- // for a particular key, the value won't be overridden.
- records_.insert(
- std::make_pair(paint_image.paint_worklet_input(),
- PaintWorkletImageCacheValue(std::move(record), 0)));
- }
-}
-
-std::pair<sk_sp<PaintRecord>, base::OnceCallback<void()>>
-PaintWorkletImageCache::GetPaintRecordAndRef(PaintWorkletInput* input) {
- base::AutoLock hold(records_lock_);
- DCHECK(records_.find(input) != records_.end());
- records_[input].used_ref_count++;
- records_[input].num_of_frames_not_accessed = 0u;
- // The PaintWorkletImageCache object lives as long as the LayerTreeHostImpl,
- // and that ensures that this pointer and the input will be alive when this
- // callback is executed.
- auto callback =
- base::BindOnce(&PaintWorkletImageCache::DecrementCacheRefCount,
- base::Unretained(this), base::Unretained(input));
- return std::make_pair(records_[input].record, std::move(callback));
-}
-
-void PaintWorkletImageCache::SetNumOfFramesToPurgeCacheEntryForTest(
- size_t num) {
- num_of_frames_to_purge_cache_entry_ = num;
-}
-
-void PaintWorkletImageCache::DecrementCacheRefCount(PaintWorkletInput* input) {
- base::AutoLock hold(records_lock_);
- auto it = records_.find(input);
- DCHECK(it != records_.end());
-
- auto& pair = it->second;
- DCHECK_GT(pair.used_ref_count, 0u);
- pair.used_ref_count--;
-}
-
-void PaintWorkletImageCache::NotifyDidPrepareTiles() {
- base::AutoLock hold(records_lock_);
- base::EraseIf(
- records_,
- [this](
- const std::pair<PaintWorkletInput*, PaintWorkletImageCacheValue>& t) {
- return t.second.num_of_frames_not_accessed >=
- num_of_frames_to_purge_cache_entry_ &&
- t.second.used_ref_count == 0;
- });
- for (auto& pair : records_)
- pair.second.num_of_frames_not_accessed++;
-}
-
-PaintWorkletImageCache::PaintWorkletImageCacheValue::
- PaintWorkletImageCacheValue() = default;
-
-PaintWorkletImageCache::PaintWorkletImageCacheValue::
- PaintWorkletImageCacheValue(sk_sp<PaintRecord> record, size_t ref_count)
- : record(std::move(record)), used_ref_count(ref_count) {}
-
-PaintWorkletImageCache::PaintWorkletImageCacheValue::
- PaintWorkletImageCacheValue(const PaintWorkletImageCacheValue& other)
- : record(other.record), used_ref_count(other.used_ref_count) {}
-
-PaintWorkletImageCache::PaintWorkletImageCacheValue::
- ~PaintWorkletImageCacheValue() = default;
-
-} // namespace cc
diff --git a/chromium/cc/tiles/paint_worklet_image_cache.h b/chromium/cc/tiles/paint_worklet_image_cache.h
deleted file mode 100644
index f9b976f357b..00000000000
--- a/chromium/cc/tiles/paint_worklet_image_cache.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_TILES_PAINT_WORKLET_IMAGE_CACHE_H_
-#define CC_TILES_PAINT_WORKLET_IMAGE_CACHE_H_
-
-#include <utility>
-
-#include "base/containers/flat_map.h"
-#include "base/synchronization/lock.h"
-#include "cc/cc_export.h"
-#include "cc/paint/draw_image.h"
-#include "cc/paint/paint_record.h"
-#include "cc/paint/paint_worklet_layer_painter.h"
-#include "cc/raster/tile_task.h"
-#include "cc/tiles/image_decode_cache.h"
-
-namespace cc {
-
-// PaintWorkletImageCache is responsible for generating tasks of executing
-// PaintWorklet JS paint callbacks, and being able to return the generated
-// results when requested.
-class CC_EXPORT PaintWorkletImageCache {
- public:
- struct CC_EXPORT PaintWorkletImageCacheValue {
- PaintWorkletImageCacheValue();
- PaintWorkletImageCacheValue(sk_sp<PaintRecord> record, size_t ref_count);
- PaintWorkletImageCacheValue(const PaintWorkletImageCacheValue&);
- ~PaintWorkletImageCacheValue();
-
- sk_sp<PaintRecord> record;
- size_t used_ref_count;
- // Indicates how many continuous frames that this cache is never accessed or
- // updated. A cache entry should be purged if this number is larger than
- // |num_of_frames_to_purge_cache_entry_|.
- size_t num_of_frames_not_accessed = 0u;
- };
-
- PaintWorkletImageCache();
-
- ~PaintWorkletImageCache();
-
- void SetPaintWorkletLayerPainter(
- std::unique_ptr<PaintWorkletLayerPainter> painter);
-
- scoped_refptr<TileTask> GetTaskForPaintWorkletImage(const DrawImage& image);
-
- void PaintImageInTask(const PaintImage& paint_image);
-
- void NotifyDidPrepareTiles();
-
- // Returns a callback to decrement the ref count for the corresponding entry.
- std::pair<sk_sp<PaintRecord>, base::OnceCallback<void()>>
- GetPaintRecordAndRef(PaintWorkletInput* input);
-
- const base::flat_map<PaintWorkletInput*, PaintWorkletImageCacheValue>&
- GetRecordsForTest() {
- return records_;
- }
-
- void SetNumOfFramesToPurgeCacheEntryForTest(size_t);
-
- private:
- void DecrementCacheRefCount(PaintWorkletInput* input);
-
- // This is a map of paint worklet inputs to a pair of paint record and a
- // reference count. The paint record is the representation of the worklet
- // output based on the input, and the reference count is the number of times
- // that it is used for tile rasterization.
- base::flat_map<PaintWorkletInput*, PaintWorkletImageCacheValue> records_;
-
- // The |records_| can be accessed from compositor and raster worker threads at
- // the same time. To prevent race, we need to lock on it.
- base::Lock records_lock_;
-
- // The PaintWorkletImageCache is owned by ImageController, which has the same
- // life time as the LayerTreeHostImpl, that guarantees that the painter will
- // live as long as the LayerTreeHostImpl.
- std::unique_ptr<PaintWorkletLayerPainter> painter_;
-
- size_t num_of_frames_to_purge_cache_entry_ = 5u;
-};
-
-} // namespace cc
-
-#endif // CC_TILES_PAINT_WORKLET_IMAGE_CACHE_H_
diff --git a/chromium/cc/tiles/paint_worklet_image_cache_unittest.cc b/chromium/cc/tiles/paint_worklet_image_cache_unittest.cc
deleted file mode 100644
index 7af4b9340c6..00000000000
--- a/chromium/cc/tiles/paint_worklet_image_cache_unittest.cc
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <utility>
-
-#include "cc/tiles/paint_worklet_image_cache.h"
-
-#include "cc/paint/draw_image.h"
-#include "cc/raster/paint_worklet_image_provider.h"
-#include "cc/test/skia_common.h"
-#include "cc/test/test_paint_worklet_input.h"
-#include "cc/test/test_paint_worklet_layer_painter.h"
-#include "cc/test/test_tile_task_runner.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-class TestPaintWorkletImageCache : public PaintWorkletImageCache {
- public:
- TestPaintWorkletImageCache() {}
-};
-
-SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) {
- SkMatrix matrix;
- matrix.setScale(scale.width(), scale.height());
-
- if (!is_decomposable) {
- // Perspective is not decomposable, add it.
- matrix[SkMatrix::kMPersp0] = 0.1f;
- }
-
- return matrix;
-}
-
-PaintImage CreatePaintImage(int width, int height) {
- scoped_refptr<TestPaintWorkletInput> input =
- base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(width, height));
- return CreatePaintWorkletPaintImage(input);
-}
-
-scoped_refptr<TileTask> GetTaskForPaintWorkletImage(
- const PaintImage& paint_image,
- TestPaintWorkletImageCache* cache) {
- DrawImage draw_image(
- paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()),
- kNone_SkFilterQuality, CreateMatrix(SkSize::Make(1.f, 1.f), true),
- PaintImage::kDefaultFrameIndex);
- return cache->GetTaskForPaintWorkletImage(draw_image);
-}
-
-void TestPaintRecord(const PaintRecord* record) {
- EXPECT_EQ(record->total_op_count(), 1u);
-
- // GetOpAtForTesting check whether the type is the same as DrawImageOp or not.
- // If not, it returns a nullptr.
- auto* paint_op = record->GetOpAtForTesting<DrawImageOp>(0);
- EXPECT_TRUE(paint_op);
-}
-
-TEST(PaintWorkletImageCacheTest, GetTaskForImage) {
- TestPaintWorkletImageCache cache;
- std::unique_ptr<TestPaintWorkletLayerPainter> painter =
- std::make_unique<TestPaintWorkletLayerPainter>();
- cache.SetPaintWorkletLayerPainter(std::move(painter));
- PaintImage paint_image = CreatePaintImage(100, 100);
- scoped_refptr<TileTask> task =
- GetTaskForPaintWorkletImage(paint_image, &cache);
- EXPECT_TRUE(task);
- PaintWorkletImageProvider provider(&cache);
-
- TestTileTaskRunner::ProcessTask(task.get());
-
- {
- ImageProvider::ScopedResult result =
- provider.GetPaintRecordResult(paint_image.paint_worklet_input());
- EXPECT_TRUE(result.paint_record());
- TestPaintRecord(result.paint_record());
-
- base::flat_map<PaintWorkletInput*,
- PaintWorkletImageCache::PaintWorkletImageCacheValue>
- records = cache.GetRecordsForTest();
- // Test the ref count.
- EXPECT_EQ(records[paint_image.paint_worklet_input()].used_ref_count, 1u);
- }
- base::flat_map<PaintWorkletInput*,
- PaintWorkletImageCache::PaintWorkletImageCacheValue>
- records = cache.GetRecordsForTest();
- // Test the ref count, which should have been decremented when the result
- // goes out of the scope.
- EXPECT_EQ(records[paint_image.paint_worklet_input()].used_ref_count, 0u);
-
- {
- ImageProvider::ScopedResult result =
- provider.GetPaintRecordResult(paint_image.paint_worklet_input());
-
- base::flat_map<PaintWorkletInput*,
- PaintWorkletImageCache::PaintWorkletImageCacheValue>
- records = cache.GetRecordsForTest();
- // Test the ref count.
- EXPECT_EQ(records[paint_image.paint_worklet_input()].used_ref_count, 1u);
-
- ImageProvider::ScopedResult moved_result = std::move(result);
-
- EXPECT_FALSE(result);
-
- EXPECT_TRUE(moved_result.paint_record());
- TestPaintRecord(moved_result.paint_record());
-
- // Once moved, the ref count from |result| should have been transferred to
- // |moved_result|, so there should be only one un-ref when they both go out
- // of scope.
- EXPECT_EQ(records[paint_image.paint_worklet_input()].used_ref_count, 1u);
- }
- EXPECT_EQ(records[paint_image.paint_worklet_input()].used_ref_count, 0u);
-}
-
-TEST(PaintWorkletImageCacheTest, EntryWithNonZeroRefCountNotPurged) {
- TestPaintWorkletImageCache cache;
- std::unique_ptr<TestPaintWorkletLayerPainter> painter =
- std::make_unique<TestPaintWorkletLayerPainter>();
- cache.SetPaintWorkletLayerPainter(std::move(painter));
- PaintImage paint_image = CreatePaintImage(100, 100);
- scoped_refptr<TileTask> task =
- GetTaskForPaintWorkletImage(paint_image, &cache);
- EXPECT_TRUE(task);
-
- TestTileTaskRunner::ProcessTask(task.get());
-
- PaintWorkletImageProvider provider(&cache);
- ImageProvider::ScopedResult result =
- provider.GetPaintRecordResult(paint_image.paint_worklet_input());
- base::flat_map<PaintWorkletInput*,
- PaintWorkletImageCache::PaintWorkletImageCacheValue>
- records = cache.GetRecordsForTest();
- EXPECT_EQ(records[paint_image.paint_worklet_input()].used_ref_count, 1u);
-
- cache.NotifyDidPrepareTiles();
- cache.NotifyDidPrepareTiles();
- cache.NotifyDidPrepareTiles();
-
- records = cache.GetRecordsForTest();
- EXPECT_EQ(records.size(), 1u);
-}
-
-TEST(PaintWorkletImageCacheTest, MultipleRecordsInCache) {
- TestPaintWorkletImageCache cache;
- std::unique_ptr<TestPaintWorkletLayerPainter> painter =
- std::make_unique<TestPaintWorkletLayerPainter>();
- cache.SetPaintWorkletLayerPainter(std::move(painter));
- PaintImage paint_image1 = CreatePaintImage(100, 100);
- scoped_refptr<TileTask> task1 =
- GetTaskForPaintWorkletImage(paint_image1, &cache);
- EXPECT_TRUE(task1);
- PaintImage paint_image2 = CreatePaintImage(200, 200);
- scoped_refptr<TileTask> task2 =
- GetTaskForPaintWorkletImage(paint_image2, &cache);
- EXPECT_TRUE(task2);
-
- TestTileTaskRunner::ProcessTask(task1.get());
- TestTileTaskRunner::ProcessTask(task2.get());
-
- base::flat_map<PaintWorkletInput*,
- PaintWorkletImageCache::PaintWorkletImageCacheValue>
- records = cache.GetRecordsForTest();
- EXPECT_EQ(records.size(), 2u);
-
- cache.SetNumOfFramesToPurgeCacheEntryForTest(2u);
- PaintRecord* record1 =
- records[paint_image1.paint_worklet_input()].record.get();
- EXPECT_TRUE(record1);
- // Test the |num_of_frames_not_accessed| for this cache entry.
- EXPECT_EQ(
- records[paint_image1.paint_worklet_input()].num_of_frames_not_accessed,
- 0u);
- TestPaintRecord(record1);
-
- PaintRecord* record2 =
- records[paint_image2.paint_worklet_input()].record.get();
- EXPECT_TRUE(record2);
- // Test the |num_of_frames_not_accessed| for this cache entry.
- EXPECT_EQ(
- records[paint_image2.paint_worklet_input()].num_of_frames_not_accessed,
- 0u);
- TestPaintRecord(record2);
-
- // NotifyDidPrepareTiles is called by TileManager::PrepareTiles() which is
- // called at each new impl frame. Here we test that a paint record with
- // |num_of_frames_not_accessed| >= 2 is purged from the cache.
- cache.NotifyDidPrepareTiles();
- records = cache.GetRecordsForTest();
- EXPECT_EQ(
- records[paint_image1.paint_worklet_input()].num_of_frames_not_accessed,
- 1u);
- EXPECT_EQ(
- records[paint_image2.paint_worklet_input()].num_of_frames_not_accessed,
- 1u);
-
- std::pair<sk_sp<PaintRecord>, base::OnceCallback<void()>> pair =
- cache.GetPaintRecordAndRef(paint_image1.paint_worklet_input());
- // Run the callback to decrement the ref count.
- std::move(pair.second).Run();
- records = cache.GetRecordsForTest();
- EXPECT_EQ(
- records[paint_image1.paint_worklet_input()].num_of_frames_not_accessed,
- 0u);
-
- cache.NotifyDidPrepareTiles();
- cache.NotifyDidPrepareTiles();
- records = cache.GetRecordsForTest();
- // The cache entry for paint_image2 should have been purged because it was
- // never accessed/updated in the last 2 frames.
- EXPECT_EQ(records.size(), 1u);
- EXPECT_EQ(
- records[paint_image1.paint_worklet_input()].num_of_frames_not_accessed,
- 2u);
-}
-
-// This test ensures that if an entry already exist, then the PaintImageInTask
-// will not replace it with a new entry and reset its ref count.
-TEST(PaintWorkletImageCacheTest, CacheEntryLookup) {
- TestPaintWorkletImageCache cache;
- std::unique_ptr<TestPaintWorkletLayerPainter> painter =
- std::make_unique<TestPaintWorkletLayerPainter>();
- cache.SetPaintWorkletLayerPainter(std::move(painter));
- PaintImage paint_image = CreatePaintImage(100, 100);
- scoped_refptr<TileTask> task =
- GetTaskForPaintWorkletImage(paint_image, &cache);
- EXPECT_TRUE(task);
- PaintWorkletImageProvider provider(&cache);
-
- TestTileTaskRunner::ProcessTask(task.get());
-
- {
- ImageProvider::ScopedResult result =
- provider.GetPaintRecordResult(paint_image.paint_worklet_input());
- EXPECT_TRUE(result.paint_record());
- TestPaintRecord(result.paint_record());
-
- base::flat_map<PaintWorkletInput*,
- PaintWorkletImageCache::PaintWorkletImageCacheValue>
- records = cache.GetRecordsForTest();
- // Test the ref count.
- EXPECT_EQ(records[paint_image.paint_worklet_input()].used_ref_count, 1u);
-
- // Create a new task with the same PaintWorkletInput as the previous task.
- // Then ProcessTask will invoke PaintWorkletImageCache::PaintImageInTask,
- // and it should early exit, without replacing the existing PaintRecord and
- // resetting the ref count.
- scoped_refptr<TileTask> task_with_the_same_input =
- GetTaskForPaintWorkletImage(paint_image, &cache);
- EXPECT_TRUE(task);
- TestTileTaskRunner::ProcessTask(task_with_the_same_input.get());
- EXPECT_EQ(records[paint_image.paint_worklet_input()].used_ref_count, 1u);
- }
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/tiles/picture_layer_tiling.h b/chromium/cc/tiles/picture_layer_tiling.h
index 4f66d992b35..253fdea09ac 100644
--- a/chromium/cc/tiles/picture_layer_tiling.h
+++ b/chromium/cc/tiles/picture_layer_tiling.h
@@ -17,6 +17,7 @@
#include "cc/base/region.h"
#include "cc/base/tiling_data.h"
#include "cc/cc_export.h"
+#include "cc/paint/paint_worklet_input.h"
#include "cc/tiles/tile.h"
#include "cc/tiles/tile_priority.h"
#include "cc/trees/occlusion.h"
@@ -40,8 +41,7 @@ class CC_EXPORT PictureLayerTilingClient {
// Create a tile at the given content_rect (in the contents scale of the
// tiling) This might return null if the client cannot create such a tile.
virtual std::unique_ptr<Tile> CreateTile(const Tile::CreateInfo& info) = 0;
- virtual gfx::Size CalculateTileSize(
- const gfx::Size& content_bounds) const = 0;
+ virtual gfx::Size CalculateTileSize(const gfx::Size& content_bounds) = 0;
// This invalidation region defines the area (if any, it can by null) that
// tiles can not be shared between pending and active trees.
virtual const Region* GetPendingInvalidation() = 0;
@@ -49,6 +49,7 @@ class CC_EXPORT PictureLayerTilingClient {
const PictureLayerTiling* tiling) const = 0;
virtual bool HasValidTilePriorities() const = 0;
virtual bool RequiresHighResToDraw() const = 0;
+ virtual const PaintWorkletRecordMap& GetPaintWorkletRecords() const = 0;
protected:
virtual ~PictureLayerTilingClient() {}
@@ -135,6 +136,9 @@ class CC_EXPORT PictureLayerTiling {
const scoped_refptr<RasterSource>& raster_source() const {
return raster_source_;
}
+ const PaintWorkletRecordMap& GetPaintWorkletRecords() const {
+ return client_->GetPaintWorkletRecords();
+ }
gfx::Size tiling_size() const { return tiling_data_.tiling_size(); }
gfx::Rect live_tiles_rect() const { return live_tiles_rect_; }
gfx::Size tile_size() const { return tiling_data_.max_texture_size(); }
diff --git a/chromium/cc/tiles/picture_layer_tiling_set.cc b/chromium/cc/tiles/picture_layer_tiling_set.cc
index 38d7ad0e9fa..5a2bcb740a0 100644
--- a/chromium/cc/tiles/picture_layer_tiling_set.cc
+++ b/chromium/cc/tiles/picture_layer_tiling_set.cc
@@ -242,7 +242,7 @@ void PictureLayerTilingSet::CleanUpTilings(
continue;
// Don't remove tilings that are required.
- if (base::ContainsValue(needed_tilings, tiling.get())) {
+ if (base::Contains(needed_tilings, tiling.get())) {
continue;
}
diff --git a/chromium/cc/tiles/prioritized_tile.h b/chromium/cc/tiles/prioritized_tile.h
index a2996602c7f..54538898271 100644
--- a/chromium/cc/tiles/prioritized_tile.h
+++ b/chromium/cc/tiles/prioritized_tile.h
@@ -6,6 +6,7 @@
#define CC_TILES_PRIORITIZED_TILE_H_
#include "cc/cc_export.h"
+#include "cc/paint/paint_worklet_input.h"
#include "cc/raster/raster_source.h"
#include "cc/tiles/picture_layer_tiling.h"
#include "cc/tiles/tile.h"
@@ -32,6 +33,9 @@ class CC_EXPORT PrioritizedTile {
const scoped_refptr<RasterSource>& raster_source() const {
return source_tiling_->raster_source();
}
+ const PaintWorkletRecordMap& GetPaintWorkletRecords() const {
+ return source_tiling_->GetPaintWorkletRecords();
+ }
const TilePriority& priority() const { return priority_; }
bool is_occluded() const { return is_occluded_; }
bool is_process_for_images_only() const {
diff --git a/chromium/cc/tiles/software_image_decode_cache.cc b/chromium/cc/tiles/software_image_decode_cache.cc
index f858a180756..6aa420ce0b5 100644
--- a/chromium/cc/tiles/software_image_decode_cache.cc
+++ b/chromium/cc/tiles/software_image_decode_cache.cc
@@ -76,7 +76,12 @@ class SoftwareImageDecodeTaskImpl : public TileTask {
paint_image_.GetSkImage().get(),
devtools_instrumentation::ScopedImageDecodeTask::kSoftware,
ImageDecodeCache::ToScopedTaskType(tracing_info_.task_type));
- cache_->DecodeImageInTask(image_key_, paint_image_, task_type_);
+ SoftwareImageDecodeCache::TaskProcessingResult result =
+ cache_->DecodeImageInTask(image_key_, paint_image_, task_type_);
+
+ // Do not log timing UMAs if we did not perform a full decode.
+ if (result != SoftwareImageDecodeCache::TaskProcessingResult::kFullDecode)
+ image_decode_task.SuppressMetrics();
}
// Overridden from TileTask:
@@ -300,9 +305,10 @@ void SoftwareImageDecodeCache::UnrefImage(const CacheKey& key) {
}
}
-void SoftwareImageDecodeCache::DecodeImageInTask(const CacheKey& key,
- const PaintImage& paint_image,
- DecodeTaskType task_type) {
+SoftwareImageDecodeCache::TaskProcessingResult
+SoftwareImageDecodeCache::DecodeImageInTask(const CacheKey& key,
+ const PaintImage& paint_image,
+ DecodeTaskType task_type) {
TRACE_EVENT1("cc,benchmark", "SoftwareImageDecodeCache::DecodeImageInTask",
"key", key.ToString());
base::AutoLock lock(lock_);
@@ -316,16 +322,16 @@ void SoftwareImageDecodeCache::DecodeImageInTask(const CacheKey& key,
DCHECK_GT(cache_entry->ref_count, 0);
DCHECK(cache_entry->is_budgeted);
- DecodeImageIfNecessary(key, paint_image, cache_entry);
+ TaskProcessingResult result =
+ DecodeImageIfNecessary(key, paint_image, cache_entry);
DCHECK(cache_entry->decode_failed || cache_entry->is_locked);
- RecordImageMipLevelUMA(
- MipMapUtil::GetLevelForSize(key.src_rect().size(), key.target_size()));
+ return result;
}
-void SoftwareImageDecodeCache::DecodeImageIfNecessary(
- const CacheKey& key,
- const PaintImage& paint_image,
- CacheEntry* entry) {
+SoftwareImageDecodeCache::TaskProcessingResult
+SoftwareImageDecodeCache::DecodeImageIfNecessary(const CacheKey& key,
+ const PaintImage& paint_image,
+ CacheEntry* entry) {
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"SoftwareImageDecodeCache::DecodeImageIfNecessary", "key",
key.ToString());
@@ -336,18 +342,18 @@ void SoftwareImageDecodeCache::DecodeImageIfNecessary(
entry->decode_failed = true;
if (entry->decode_failed)
- return;
+ return TaskProcessingResult::kCancelled;
if (entry->memory) {
if (entry->is_locked)
- return;
+ return TaskProcessingResult::kLockOnly;
bool lock_succeeded = entry->Lock();
// TODO(vmpstr): Deprecate the prepaint split, since it doesn't matter.
RecordLockExistingCachedImageHistogram(TilePriority::NOW, lock_succeeded);
if (lock_succeeded)
- return;
+ return TaskProcessingResult::kLockOnly;
}
std::unique_ptr<CacheEntry> local_cache_entry;
@@ -439,7 +445,7 @@ void SoftwareImageDecodeCache::DecodeImageIfNecessary(
if (!local_cache_entry) {
entry->decode_failed = true;
- return;
+ return TaskProcessingResult::kCancelled;
}
// Just in case someone else did this already, just unlock our work.
@@ -457,6 +463,8 @@ void SoftwareImageDecodeCache::DecodeImageIfNecessary(
local_cache_entry->MoveImageMemoryTo(entry);
DCHECK(entry->is_locked);
}
+
+ return TaskProcessingResult::kFullDecode;
}
base::Optional<SoftwareImageDecodeCache::CacheKey>
diff --git a/chromium/cc/tiles/software_image_decode_cache.h b/chromium/cc/tiles/software_image_decode_cache.h
index c3b7c03303d..176adeec8ed 100644
--- a/chromium/cc/tiles/software_image_decode_cache.h
+++ b/chromium/cc/tiles/software_image_decode_cache.h
@@ -32,6 +32,10 @@ class CC_EXPORT SoftwareImageDecodeCache
enum class DecodeTaskType { USE_IN_RASTER_TASKS, USE_OUT_OF_RASTER_TASKS };
+ // Identifies whether a decode task performed decode work, or was fulfilled /
+ // failed trivially.
+ enum class TaskProcessingResult { kFullDecode, kLockOnly, kCancelled };
+
SoftwareImageDecodeCache(SkColorType color_type,
size_t locked_memory_limit_bytes,
PaintImage::GeneratorClientId generator_client_id);
@@ -56,9 +60,9 @@ class CC_EXPORT SoftwareImageDecodeCache
// Decode the given image and store it in the cache. This is only called by an
// image decode task from a worker thread.
- void DecodeImageInTask(const CacheKey& key,
- const PaintImage& paint_image,
- DecodeTaskType task_type);
+ TaskProcessingResult DecodeImageInTask(const CacheKey& key,
+ const PaintImage& paint_image,
+ DecodeTaskType task_type);
void OnImageDecodeTaskCompleted(const CacheKey& key,
DecodeTaskType task_type);
@@ -123,9 +127,9 @@ class CC_EXPORT SoftwareImageDecodeCache
CacheEntry* AddCacheEntry(const CacheKey& key);
- void DecodeImageIfNecessary(const CacheKey& key,
- const PaintImage& paint_image,
- CacheEntry* cache_entry);
+ TaskProcessingResult DecodeImageIfNecessary(const CacheKey& key,
+ const PaintImage& paint_image,
+ CacheEntry* cache_entry);
void AddBudgetForImage(const CacheKey& key, CacheEntry* entry);
void RemoveBudgetForImage(const CacheKey& key, CacheEntry* entry);
base::Optional<CacheKey> FindCachedCandidate(const CacheKey& key);
diff --git a/chromium/cc/tiles/software_image_decode_cache_utils.h b/chromium/cc/tiles/software_image_decode_cache_utils.h
index 835d68c8492..3293d8b4cc9 100644
--- a/chromium/cc/tiles/software_image_decode_cache_utils.h
+++ b/chromium/cc/tiles/software_image_decode_cache_utils.h
@@ -50,12 +50,11 @@ class SoftwareImageDecodeCacheUtils {
bool operator==(const CacheKey& other) const {
// The frame_key always has to be the same. However, after that all
// original decodes are the same, so if we can use the original decode,
- // return true. If not, then we have to compare every field. Note we don't
- // compare |nearest_neighbor_| because we would only use kOriginal type in
- // that case (dchecked below), which implies no scale. The returned scale
- // to Skia would respect the nearest neighbor value of the requested
- // image.
- DCHECK(!is_nearest_neighbor_ || type_ == kOriginal);
+ // return true. If not, then we have to compare every field.
+ // |nearest_neighbor_| is not compared below since it is not used for
+ // scaled decodes and does not affect the contents of the cache entry
+ // (just passed to skia for the filtering to be done at raster time).
+ DCHECK(!is_nearest_neighbor_ || type_ != kSubrectAndScale);
return frame_key_ == other.frame_key_ && type_ == other.type_ &&
target_color_space_ == other.target_color_space_ &&
(type_ == kOriginal || (src_rect_ == other.src_rect_ &&
diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc
index 165bb015145..032b487ef5e 100644
--- a/chromium/cc/tiles/tile_manager.cc
+++ b/chromium/cc/tiles/tile_manager.cc
@@ -402,9 +402,7 @@ TileManager::TileManager(
base::Unretained(this))),
has_scheduled_tile_tasks_(false),
prepare_tiles_count_(0u),
- next_tile_id_(0u),
- task_set_finished_weak_ptr_factory_(this),
- ready_to_draw_callback_weak_ptr_factory_(this) {}
+ next_tile_id_(0u) {}
TileManager::~TileManager() {
FinishTasksAndCleanUp();
@@ -550,8 +548,6 @@ bool TileManager::PrepareTiles(
// Schedule tile tasks.
ScheduleTasks(std::move(prioritized_work));
- image_controller_.paint_worklet_image_cache()->NotifyDidPrepareTiles();
-
TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD,
"state", BasicStateAsValue());
return true;
@@ -779,8 +775,12 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
// If we couldn't fit the tile into our current memory limit, then we're
// done.
if (!memory_usage_is_within_limit) {
- if (tile_is_needed_now)
+ if (tile_is_needed_now) {
+ LOG(ERROR) << "WARNING: tile memory limits exceeded, some content may "
+ "not draw";
+
had_enough_memory_to_schedule_tiles_needed_now = false;
+ }
all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
break;
}
@@ -1190,10 +1190,8 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
prepare_tiles_count_, prioritized_tile.priority().priority_bin,
ImageDecodeCache::TaskType::kInRaster);
bool has_at_raster_images = false;
- image_controller_.ConvertDataImagesToTasks(
- &sync_decoded_images, &decode_tasks, &has_at_raster_images, tracing_info);
- image_controller_.ConvertPaintWorkletImagesToTask(&sync_decoded_images,
- &decode_tasks);
+ image_controller_.ConvertImagesToTasks(&sync_decoded_images, &decode_tasks,
+ &has_at_raster_images, tracing_info);
// Notify |decoded_image_tracker_| after |image_controller_| to ensure we've
// taken new refs on the images before releasing the predecode API refs.
decoded_image_tracker_.OnImagesUsedInDraw(sync_decoded_images);
@@ -1246,8 +1244,13 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
PlaybackImageProvider image_provider(image_controller_.cache(),
raster_color_space, std::move(settings));
+ // We make a deliberate copy of the PaintWorklet map here, as the
+ // PictureLayerImpl's map could be mutated or destroyed whilst raster from an
+ // earlier snapshot is still ongoing on the raster worker threads.
+ PaintWorkletRecordMap paint_worklet_records =
+ prioritized_tile.GetPaintWorkletRecords();
PaintWorkletImageProvider paint_worklet_image_provider(
- image_controller_.paint_worklet_image_cache());
+ std::move(paint_worklet_records));
DispatchingImageProvider dispatching_image_provider(
std::move(image_provider), std::move(paint_worklet_image_provider));
@@ -1711,11 +1714,6 @@ TileManager::ActivationStateAsValue() {
return std::move(state);
}
-void TileManager::SetPaintWorkletLayerPainter(
- std::unique_ptr<PaintWorkletLayerPainter> painter) {
- image_controller_.SetPaintWorkletLayerPainter(std::move(painter));
-}
-
void TileManager::ActivationStateAsValueInto(
base::trace_event::TracedValue* state) {
state->SetString("tree_priority",
diff --git a/chromium/cc/tiles/tile_manager.h b/chromium/cc/tiles/tile_manager.h
index 015ce53e837..afa7d42ef37 100644
--- a/chromium/cc/tiles/tile_manager.h
+++ b/chromium/cc/tiles/tile_manager.h
@@ -294,9 +294,6 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
void set_active_url(const GURL& url) { active_url_ = url; }
- void SetPaintWorkletLayerPainter(
- std::unique_ptr<PaintWorkletLayerPainter> painter);
-
protected:
friend class Tile;
// Must be called by tile during destruction.
@@ -473,9 +470,10 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
// different. The |task_set_finished_weak_ptr_factory_| is invalidated any
// time new tasks are scheduled, preventing a race when the callback has
// been scheduled but not yet executed.
- base::WeakPtrFactory<TileManager> task_set_finished_weak_ptr_factory_;
+ base::WeakPtrFactory<TileManager> task_set_finished_weak_ptr_factory_{this};
// The |ready_to_draw_callback_weak_ptr_factory_| is never invalidated.
- base::WeakPtrFactory<TileManager> ready_to_draw_callback_weak_ptr_factory_;
+ base::WeakPtrFactory<TileManager> ready_to_draw_callback_weak_ptr_factory_{
+ this};
};
} // namespace cc
diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc
index 9c6d1e0516b..7b4e57f2e2c 100644
--- a/chromium/cc/tiles/tile_manager_unittest.cc
+++ b/chromium/cc/tiles/tile_manager_unittest.cc
@@ -2583,7 +2583,7 @@ TEST_F(TileManagerReadyToDrawTest, TilePrioritiesUpdated) {
final_num_prepaint++;
} else {
final_num_required++;
- if (base::ContainsValue(prepaint_tiles, tile)) {
+ if (base::Contains(prepaint_tiles, tile)) {
found_one_prepaint_to_required_transition = true;
}
}
diff --git a/chromium/cc/tiles/tile_task_manager.cc b/chromium/cc/tiles/tile_task_manager.cc
index 2bfdd9e88ef..476a7d7a965 100644
--- a/chromium/cc/tiles/tile_task_manager.cc
+++ b/chromium/cc/tiles/tile_task_manager.cc
@@ -5,6 +5,7 @@
#include "cc/tiles/tile_task_manager.h"
#include "base/memory/ptr_util.h"
+#include "base/threading/thread_restrictions.h"
#include "base/trace_event/trace_event.h"
namespace cc {
@@ -50,7 +51,10 @@ void TileTaskManagerImpl::Shutdown() {
// Cancel non-scheduled tasks and wait for running tasks to finish.
TaskGraph empty;
task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
- task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
+ {
+ base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
+ task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
+ }
}
} // namespace cc