| Index: cc/tiles/image_decode_controller_unittest.cc
|
| diff --git a/cc/tiles/image_decode_controller_unittest.cc b/cc/tiles/image_decode_controller_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..668de9bd0b02d99afa1ef2c70fd4b018642483aa
|
| --- /dev/null
|
| +++ b/cc/tiles/image_decode_controller_unittest.cc
|
| @@ -0,0 +1,822 @@
|
| +// Copyright 2015 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/image_decode_controller.h"
|
| +
|
| +#include "cc/playback/draw_image.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace cc {
|
| +namespace {
|
| +
|
| +skia::RefPtr<SkImage> CreateImage(int width, int height) {
|
| + SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
|
| + SkBitmap bitmap;
|
| + bitmap.allocPixels(info);
|
| + return skia::AdoptRef(SkImage::NewFromBitmap(bitmap));
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyLowQuality) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality qualities[] = {kNone_SkFilterQuality, kLow_SkFilterQuality};
|
| + for (auto quality : qualities) {
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 1.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(quality, key.filter_quality());
|
| + EXPECT_EQ(50, key.target_size().width());
|
| + EXPECT_EQ(150, key.target_size().height());
|
| + EXPECT_EQ(50u * 150u * 4u, key.target_bytes());
|
| + }
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyMediumQuality) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kMedium_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 1.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(quality, key.filter_quality());
|
| + EXPECT_EQ(50, key.target_size().width());
|
| + EXPECT_EQ(150, key.target_size().height());
|
| + EXPECT_EQ(50u * 150u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyMediumQualityEvenWithPerspective) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = true;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kMedium_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 1.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(quality, key.filter_quality());
|
| + EXPECT_EQ(50, key.target_size().width());
|
| + EXPECT_EQ(150, key.target_size().height());
|
| + EXPECT_EQ(50u * 150u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyMediumQualityDropToLowIfEnlarging) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kMedium_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(1.5f, 1.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(150, key.target_size().width());
|
| + EXPECT_EQ(150, key.target_size().height());
|
| + EXPECT_EQ(150u * 150u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyMediumQualityDropToLowIfIdentity) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kMedium_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(1.f, 1.f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(100, key.target_size().width());
|
| + EXPECT_EQ(100, key.target_size().height());
|
| + EXPECT_EQ(100u * 100u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest,
|
| + ImageKeyMediumQualityDropToLowIfNearlyIdentity) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kMedium_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(1.001f, 1.001f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(100, key.target_size().width());
|
| + EXPECT_EQ(100, key.target_size().height());
|
| + EXPECT_EQ(100u * 100u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest,
|
| + ImageKeyMediumQualityDropToLowIfNearlyIdentity2) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kMedium_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.999f, 0.999f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(100, key.target_size().width());
|
| + EXPECT_EQ(100, key.target_size().height());
|
| + EXPECT_EQ(100u * 100u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest,
|
| + ImageKeyMediumQualityDropToLowIfNotDecomposable) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = false;
|
| + SkFilterQuality quality = kMedium_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 1.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(50, key.target_size().width());
|
| + EXPECT_EQ(150, key.target_size().height());
|
| + EXPECT_EQ(50u * 150u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyHighQuality) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 1.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(quality, key.filter_quality());
|
| + EXPECT_EQ(50, key.target_size().width());
|
| + EXPECT_EQ(150, key.target_size().height());
|
| + EXPECT_EQ(50u * 150u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest,
|
| + ImageKeyHighQualityDropToMediumWithPerspective) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = true;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 1.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kMedium_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(50, key.target_size().width());
|
| + EXPECT_EQ(150, key.target_size().height());
|
| + EXPECT_EQ(50u * 150u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyHighQualityDropToMediumIfTooLarge) {
|
| + // Just over 64MB when scaled.
|
| + skia::RefPtr<SkImage> image = CreateImage(4555, 2048);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + // At least one dimension should scale down, so that medium quality doesn't
|
| + // become low.
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.9f, 2.f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kMedium_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(4100, key.target_size().width());
|
| + EXPECT_EQ(4096, key.target_size().height());
|
| + EXPECT_EQ(4100u * 4096u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyHighQualityDropToLowIfNotDecomposable) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = false;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 1.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(50, key.target_size().width());
|
| + EXPECT_EQ(150, key.target_size().height());
|
| + EXPECT_EQ(50u * 150u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyHighQualityDropToLowIfIdentity) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(1.f, 1.f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(100, key.target_size().width());
|
| + EXPECT_EQ(100, key.target_size().height());
|
| + EXPECT_EQ(100u * 100u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyHighQualityDropToLowIfNearlyIdentity) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(1.001f, 1.001f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(100, key.target_size().width());
|
| + EXPECT_EQ(100, key.target_size().height());
|
| + EXPECT_EQ(100u * 100u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, ImageKeyHighQualityDropToLowIfNearlyIdentity2) {
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.999f, 0.999f), quality, has_perspective, is_decomposable);
|
| +
|
| + auto key = ImageDecodeControllerKey::FromDrawImage(draw_image);
|
| + EXPECT_EQ(image->uniqueID(), key.image_id());
|
| + EXPECT_EQ(kLow_SkFilterQuality, key.filter_quality());
|
| + EXPECT_EQ(100, key.target_size().width());
|
| + EXPECT_EQ(100, key.target_size().height());
|
| + EXPECT_EQ(100u * 100u * 4u, key.target_bytes());
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, GetTaskForImageSameImage) {
|
| + ImageDecodeController controller;
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| + uint64_t prepare_tiles_id = 1;
|
| +
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> task;
|
| + bool need_unref =
|
| + controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(task);
|
| +
|
| + DrawImage another_draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> another_task;
|
| + need_unref = controller.GetTaskForImageAndRef(
|
| + another_draw_image, prepare_tiles_id, &another_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(task.get() == another_task.get());
|
| +
|
| + controller.UnrefImage(draw_image);
|
| + controller.UnrefImage(draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, GetTaskForImageSameImageDifferentQuality) {
|
| + ImageDecodeController controller;
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + uint64_t prepare_tiles_id = 1;
|
| +
|
| + DrawImage high_quality_draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), kHigh_SkFilterQuality, has_perspective,
|
| + is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> high_quality_task;
|
| + bool need_unref = controller.GetTaskForImageAndRef(
|
| + high_quality_draw_image, prepare_tiles_id, &high_quality_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(high_quality_task);
|
| +
|
| + DrawImage medium_quality_draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), kMedium_SkFilterQuality, has_perspective,
|
| + is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> medium_quality_task;
|
| + need_unref = controller.GetTaskForImageAndRef(
|
| + medium_quality_draw_image, prepare_tiles_id, &medium_quality_task);
|
| + // Medium quality isn't handled by the controller, so it won't ref it. Note
|
| + // that this will change when medium quality is handled and will need to be
|
| + // updated.
|
| + EXPECT_FALSE(need_unref);
|
| + EXPECT_TRUE(medium_quality_task);
|
| + EXPECT_TRUE(high_quality_task.get() != medium_quality_task.get());
|
| +
|
| + DrawImage low_quality_draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), kLow_SkFilterQuality, has_perspective,
|
| + is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> low_quality_task;
|
| + need_unref = controller.GetTaskForImageAndRef(
|
| + low_quality_draw_image, prepare_tiles_id, &low_quality_task);
|
| + // Note that when we pin the original decode, we might ref low quality images
|
| + // too, but we don't support that right now.
|
| + EXPECT_FALSE(need_unref);
|
| + EXPECT_TRUE(low_quality_task);
|
| + EXPECT_TRUE(high_quality_task.get() != low_quality_task.get());
|
| + EXPECT_TRUE(medium_quality_task.get() != low_quality_task.get());
|
| +
|
| + controller.UnrefImage(high_quality_draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, GetTaskForImageSameImageDifferentSize) {
|
| + ImageDecodeController controller;
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + uint64_t prepare_tiles_id = 1;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + DrawImage half_size_draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> half_size_task;
|
| + bool need_unref = controller.GetTaskForImageAndRef(
|
| + half_size_draw_image, prepare_tiles_id, &half_size_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(half_size_task);
|
| +
|
| + DrawImage quarter_size_draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.25f, 0.25f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> quarter_size_task;
|
| + need_unref = controller.GetTaskForImageAndRef(
|
| + quarter_size_draw_image, prepare_tiles_id, &quarter_size_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(quarter_size_task);
|
| + EXPECT_TRUE(half_size_task.get() != quarter_size_task.get());
|
| +
|
| + controller.UnrefImage(half_size_draw_image);
|
| + controller.UnrefImage(quarter_size_draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, GetTaskForImageDifferentImage) {
|
| + ImageDecodeController controller;
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + uint64_t prepare_tiles_id = 1;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + skia::RefPtr<SkImage> first_image = CreateImage(100, 100);
|
| + DrawImage first_draw_image(
|
| + first_image.get(),
|
| + SkIRect::MakeWH(first_image->width(), first_image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> first_task;
|
| + bool need_unref = controller.GetTaskForImageAndRef(
|
| + first_draw_image, prepare_tiles_id, &first_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(first_task);
|
| +
|
| + skia::RefPtr<SkImage> second_image = CreateImage(100, 100);
|
| + DrawImage second_draw_image(
|
| + second_image.get(),
|
| + SkIRect::MakeWH(second_image->width(), second_image->height()),
|
| + SkSize::Make(0.25f, 0.25f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> second_task;
|
| + need_unref = controller.GetTaskForImageAndRef(second_draw_image,
|
| + prepare_tiles_id, &second_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(second_task);
|
| + EXPECT_TRUE(first_task.get() != second_task.get());
|
| +
|
| + controller.UnrefImage(first_draw_image);
|
| + controller.UnrefImage(second_draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, GetTaskForImageAlreadyDecoded) {
|
| + ImageDecodeController controller;
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + uint64_t prepare_tiles_id = 1;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> task;
|
| + bool need_unref =
|
| + controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(task);
|
| +
|
| + task->WillSchedule();
|
| + task->ScheduleOnOriginThread(nullptr);
|
| + task->DidSchedule();
|
| + task->RunOnWorkerThread();
|
| +
|
| + scoped_refptr<ImageDecodeTask> another_task;
|
| + need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
|
| + &another_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_FALSE(another_task);
|
| +
|
| + task->WillComplete();
|
| + task->CompleteOnOriginThread(nullptr);
|
| + task->DidComplete();
|
| +
|
| + controller.UnrefImage(draw_image);
|
| + controller.UnrefImage(draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, GetTaskForImageAlreadyPrerolled) {
|
| + ImageDecodeController controller;
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + uint64_t prepare_tiles_id = 1;
|
| + SkFilterQuality quality = kLow_SkFilterQuality;
|
| +
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(1.f, 1.f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> task;
|
| + bool need_unref =
|
| + controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
|
| + // We're not currently locking original scale or low quality images.
|
| + EXPECT_FALSE(need_unref);
|
| + EXPECT_TRUE(task);
|
| +
|
| + task->WillSchedule();
|
| + task->ScheduleOnOriginThread(nullptr);
|
| + task->DidSchedule();
|
| + task->RunOnWorkerThread();
|
| +
|
| + scoped_refptr<ImageDecodeTask> another_task;
|
| + need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
|
| + &another_task);
|
| + EXPECT_FALSE(need_unref);
|
| + EXPECT_FALSE(another_task);
|
| +
|
| + task->WillComplete();
|
| + task->CompleteOnOriginThread(nullptr);
|
| + task->DidComplete();
|
| +
|
| + scoped_refptr<ImageDecodeTask> third_task;
|
| + need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
|
| + &third_task);
|
| + EXPECT_FALSE(need_unref);
|
| + EXPECT_FALSE(third_task);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, GetTaskForImageCanceledGetsNewTask) {
|
| + ImageDecodeController controller;
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + uint64_t prepare_tiles_id = 1;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> task;
|
| + bool need_unref =
|
| + controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(task);
|
| +
|
| + task->WillSchedule();
|
| + task->ScheduleOnOriginThread(nullptr);
|
| + task->DidSchedule();
|
| +
|
| + scoped_refptr<ImageDecodeTask> another_task;
|
| + need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
|
| + &another_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(another_task.get() == task.get());
|
| +
|
| + // Didn't run the task, complete it (it was canceled).
|
| + task->WillComplete();
|
| + task->CompleteOnOriginThread(nullptr);
|
| + task->DidComplete();
|
| +
|
| + // Fully cancel everything (so the raster would unref things).
|
| + controller.UnrefImage(draw_image);
|
| + controller.UnrefImage(draw_image);
|
| +
|
| + // Here a new task is created.
|
| + scoped_refptr<ImageDecodeTask> third_task;
|
| + need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
|
| + &third_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(third_task);
|
| + EXPECT_FALSE(third_task.get() == task.get());
|
| +
|
| + controller.UnrefImage(draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, GetTaskForImageCanceledWhileReffedGetsNewTask) {
|
| + ImageDecodeController controller;
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + uint64_t prepare_tiles_id = 1;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> task;
|
| + bool need_unref =
|
| + controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(task);
|
| +
|
| + task->WillSchedule();
|
| + task->ScheduleOnOriginThread(nullptr);
|
| + task->DidSchedule();
|
| +
|
| + scoped_refptr<ImageDecodeTask> another_task;
|
| + need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
|
| + &another_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(another_task.get() == task.get());
|
| +
|
| + // Didn't run the task, complete it (it was canceled).
|
| + task->WillComplete();
|
| + task->CompleteOnOriginThread(nullptr);
|
| + task->DidComplete();
|
| +
|
| + // Note that here, everything is reffed, but a new task is created. This is
|
| + // possible with repeated schedule/cancel operations.
|
| + scoped_refptr<ImageDecodeTask> third_task;
|
| + need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
|
| + &third_task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(third_task);
|
| + EXPECT_FALSE(third_task.get() == task.get());
|
| +
|
| + // 3 Unrefs!
|
| + controller.UnrefImage(draw_image);
|
| + controller.UnrefImage(draw_image);
|
| + controller.UnrefImage(draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, GetDecodedImageForDraw) {
|
| + ImageDecodeController controller;
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + uint64_t prepare_tiles_id = 1;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| + scoped_refptr<ImageDecodeTask> task;
|
| + bool need_unref =
|
| + controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(task);
|
| +
|
| + task->WillSchedule();
|
| + task->ScheduleOnOriginThread(nullptr);
|
| + task->DidSchedule();
|
| +
|
| + task->RunOnWorkerThread();
|
| +
|
| + task->WillComplete();
|
| + task->CompleteOnOriginThread(nullptr);
|
| + task->DidComplete();
|
| +
|
| + DecodedDrawImage decoded_draw_image =
|
| + controller.GetDecodedImageForDraw(draw_image);
|
| + EXPECT_TRUE(decoded_draw_image.image());
|
| + EXPECT_EQ(50, decoded_draw_image.image()->width());
|
| + EXPECT_EQ(50, decoded_draw_image.image()->height());
|
| + EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().width());
|
| + EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
|
| + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality());
|
| + EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
|
| + EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
|
| +
|
| + controller.DrawWithImageFinished(draw_image, decoded_draw_image);
|
| + controller.UnrefImage(draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest, GetDecodedImageForDrawAtRasterDecode) {
|
| + ImageDecodeController controller;
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + DecodedDrawImage decoded_draw_image =
|
| + controller.GetDecodedImageForDraw(draw_image);
|
| + EXPECT_TRUE(decoded_draw_image.image());
|
| + EXPECT_EQ(50, decoded_draw_image.image()->width());
|
| + EXPECT_EQ(50, decoded_draw_image.image()->height());
|
| + EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().width());
|
| + EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
|
| + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality());
|
| + EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
|
| + EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
|
| +
|
| + controller.DrawWithImageFinished(draw_image, decoded_draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest,
|
| + GetDecodedImageForDrawAtRasterDecodeMultipleTimes) {
|
| + ImageDecodeController controller;
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + DecodedDrawImage decoded_draw_image =
|
| + controller.GetDecodedImageForDraw(draw_image);
|
| + EXPECT_TRUE(decoded_draw_image.image());
|
| + EXPECT_EQ(50, decoded_draw_image.image()->width());
|
| + EXPECT_EQ(50, decoded_draw_image.image()->height());
|
| + EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().width());
|
| + EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
|
| + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality());
|
| + EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
|
| + EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
|
| +
|
| + DecodedDrawImage another_decoded_draw_image =
|
| + controller.GetDecodedImageForDraw(draw_image);
|
| + EXPECT_EQ(decoded_draw_image.image()->uniqueID(),
|
| + another_decoded_draw_image.image()->uniqueID());
|
| +
|
| + controller.DrawWithImageFinished(draw_image, decoded_draw_image);
|
| + controller.DrawWithImageFinished(draw_image, another_decoded_draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest,
|
| + GetDecodedImageForDrawAtRasterDecodeDoesNotPreventTasks) {
|
| + ImageDecodeController controller;
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + uint64_t prepare_tiles_id = 1;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + DecodedDrawImage decoded_draw_image =
|
| + controller.GetDecodedImageForDraw(draw_image);
|
| + EXPECT_TRUE(decoded_draw_image.image());
|
| + EXPECT_EQ(50, decoded_draw_image.image()->width());
|
| + EXPECT_EQ(50, decoded_draw_image.image()->height());
|
| + EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().width());
|
| + EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
|
| + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality());
|
| + EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
|
| + EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
|
| +
|
| + scoped_refptr<ImageDecodeTask> task;
|
| + bool need_unref =
|
| + controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(task);
|
| +
|
| + task->WillSchedule();
|
| + task->ScheduleOnOriginThread(nullptr);
|
| + task->DidSchedule();
|
| +
|
| + task->RunOnWorkerThread();
|
| +
|
| + task->WillComplete();
|
| + task->CompleteOnOriginThread(nullptr);
|
| + task->DidComplete();
|
| +
|
| + DecodedDrawImage another_decoded_draw_image =
|
| + controller.GetDecodedImageForDraw(draw_image);
|
| + // This should get the new decoded/locked image, not the one we're using at
|
| + // raster.
|
| + // TODO(vmpstr): We can possibly optimize this so that the decode simply moves
|
| + // the image to the right spot.
|
| + EXPECT_NE(decoded_draw_image.image()->uniqueID(),
|
| + another_decoded_draw_image.image()->uniqueID());
|
| + EXPECT_FALSE(another_decoded_draw_image.is_at_raster_decode());
|
| +
|
| + controller.DrawWithImageFinished(draw_image, decoded_draw_image);
|
| + controller.DrawWithImageFinished(draw_image, another_decoded_draw_image);
|
| + controller.UnrefImage(draw_image);
|
| +}
|
| +
|
| +TEST(ImageDecodeControllerTest,
|
| + GetDecodedImageForDrawAtRasterDecodeIsUsedForLockedCache) {
|
| + ImageDecodeController controller;
|
| + bool has_perspective = false;
|
| + bool is_decomposable = true;
|
| + uint64_t prepare_tiles_id = 1;
|
| + SkFilterQuality quality = kHigh_SkFilterQuality;
|
| +
|
| + skia::RefPtr<SkImage> image = CreateImage(100, 100);
|
| + DrawImage draw_image(
|
| + image.get(), SkIRect::MakeWH(image->width(), image->height()),
|
| + SkSize::Make(0.5f, 0.5f), quality, has_perspective, is_decomposable);
|
| +
|
| + DecodedDrawImage decoded_draw_image =
|
| + controller.GetDecodedImageForDraw(draw_image);
|
| + EXPECT_TRUE(decoded_draw_image.image());
|
| + EXPECT_EQ(50, decoded_draw_image.image()->width());
|
| + EXPECT_EQ(50, decoded_draw_image.image()->height());
|
| + EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().width());
|
| + EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
|
| + EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality());
|
| + EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
|
| + EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
|
| +
|
| + scoped_refptr<ImageDecodeTask> task;
|
| + bool need_unref =
|
| + controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
|
| + EXPECT_TRUE(need_unref);
|
| + EXPECT_TRUE(task);
|
| +
|
| + task->WillSchedule();
|
| + task->ScheduleOnOriginThread(nullptr);
|
| + task->DidSchedule();
|
| +
|
| + // If we finish the draw here, then we will use it for the locked decode
|
| + // instead of decoding again.
|
| + controller.DrawWithImageFinished(draw_image, decoded_draw_image);
|
| +
|
| + task->RunOnWorkerThread();
|
| +
|
| + task->WillComplete();
|
| + task->CompleteOnOriginThread(nullptr);
|
| + task->DidComplete();
|
| +
|
| + DecodedDrawImage another_decoded_draw_image =
|
| + controller.GetDecodedImageForDraw(draw_image);
|
| + // This should get the decoded/locked image which we originally decoded at
|
| + // raster time, since it's now in the locked cache.
|
| + EXPECT_EQ(decoded_draw_image.image()->uniqueID(),
|
| + another_decoded_draw_image.image()->uniqueID());
|
| + EXPECT_FALSE(another_decoded_draw_image.is_at_raster_decode());
|
| +
|
| + controller.DrawWithImageFinished(draw_image, another_decoded_draw_image);
|
| + controller.UnrefImage(draw_image);
|
| +}
|
| +
|
| +} // namespace
|
| +} // namespace cc
|
|
|