#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include <cmath>
#include <memory>
#include <tuple>
#include <vector>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/path_service.h"
#include "base/test/test_switches.h"
#include "build/build_config.h"
#include "cc/base/completion_event.h"
#include "cc/paint/display_item_list.h"
#include "cc/paint/paint_filter.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_image_builder.h"
#include "cc/raster/playback_image_provider.h"
#include "cc/test/fake_paint_image_generator.h"
#include "cc/test/pixel_comparator.h"
#include "cc/test/pixel_test_utils.h"
#include "cc/tiles/gpu_image_decode_cache.h"
#include "components/viz/common/resources/shared_image_format.h"
#include "components/viz/service/gl/gpu_service_impl.h"
#include "components/viz/test/buildflags.h"
#include "components/viz/test/paths.h"
#include "components/viz/test/test_gpu_service_holder.h"
#include "components/viz/test/test_in_process_context_provider.h"
#include "gpu/command_buffer/client/client_shared_image.h"
#include "gpu/command_buffer/client/raster_implementation.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/gr_shader_cache.h"
#include "gpu/command_buffer/service/graphite_utils.h"
#include "gpu/config/gpu_finch_features.h"
#include "ipc/common/gpu_client_ids.h"
#include "skia/ext/font_utils.h"
#include "skia/ext/legacy_display_globals.h"
#include "skia/ext/skcolorspace_trfn.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkAlphaType.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkColorType.h"
#include "third_party/skia/include/core/SkGraphics.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkTextBlob.h"
#include "third_party/skia/include/core/SkYUVAInfo.h"
#include "third_party/skia/include/gpu/GpuTypes.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/GrTypes.h"
#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
#include "third_party/skia/include/gpu/graphite/Context.h"
#include "third_party/skia/include/gpu/graphite/GraphiteTypes.h"
#include "third_party/skia/include/gpu/graphite/Surface.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "ui/gl/gl_implementation.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#endif
namespace cc {
namespace {
scoped_refptr<DisplayItemList> MakeNoopDisplayItemList() { … }
SkBitmap MakeSolidColorBitmap(gfx::Size size, SkColor4f color) { … }
sk_sp<SkImage> MakeSkImage(const gfx::Size& size,
sk_sp<SkColorSpace> color_space = nullptr) { … }
constexpr size_t kCacheLimitBytes = …;
constexpr PaintFlags::FilterQuality kDefaultFilterQuality = …;
class OopPixelTest : public testing::Test,
public gpu::raster::GrShaderCache::Client { … };
class OopClearPixelTest : public OopPixelTest,
public ::testing::WithParamInterface<bool> { … };
TEST_F(OopPixelTest, DrawColor) { … }
TEST_F(OopPixelTest, DrawColorWithTargetColorSpace) { … }
TEST_F(OopPixelTest, DrawRect) { … }
TEST_F(OopPixelTest, DrawRecordPaintFilterTranslatedBounds) { … }
TEST_F(OopPixelTest, DrawImage) { … }
TEST_F(OopPixelTest, DrawImageScaled) { … }
TEST_F(OopPixelTest, DrawImageShaderScaled) { … }
TEST_F(OopPixelTest, DrawRecordShaderWithImageScaled) { … }
TEST_F(OopPixelTest, DrawRecordShaderTranslatedTileRect) { … }
TEST_F(OopPixelTest, DrawImageWithTargetColorSpace) { … }
TEST_F(OopPixelTest, DrawGainmapImage) { … }
TEST_F(OopPixelTest, DrawGainmapImageFiltering) { … }
TEST_F(OopPixelTest, DrawHdrImageWithMetadata) { … }
TEST_F(OopPixelTest, DrawImageWithSourceColorSpace) { … }
TEST_F(OopPixelTest, DrawImageWithSourceAndTargetColorSpace) { … }
TEST_F(OopPixelTest, DrawImageWithSetMatrix) { … }
namespace {
class TestMailboxBacking : public TextureBacking { … };
}
TEST_F(OopPixelTest, DrawMailboxBackedImage) { … }
TEST_F(OopPixelTest, Preclear) { … }
TEST_P(OopClearPixelTest, ClearingOpaqueCorner) { … }
TEST_F(OopPixelTest, ClearingOpaqueCornerExactEdge) { … }
TEST_F(OopPixelTest, ClearingOpaqueCornerPartialRaster) { … }
TEST_P(OopClearPixelTest, ClearingOpaqueLeftEdge) { … }
TEST_P(OopClearPixelTest, ClearingOpaqueRightEdge) { … }
TEST_P(OopClearPixelTest, ClearingOpaqueTopEdge) { … }
TEST_P(OopClearPixelTest, ClearingOpaqueBottomEdge) { … }
TEST_F(OopPixelTest, ClearingOpaqueInternal) { … }
TEST_F(OopPixelTest, ClearingTransparentCorner) { … }
TEST_F(OopPixelTest, ClearingTransparentInternalTile) { … }
TEST_F(OopPixelTest, ClearingTransparentCornerPartialRaster) { … }
TEST_F(OopPixelTest, DrawRectPlaybackRect) { … }
TEST_F(OopPixelTest, DrawRectScaleTransformOptions) { … }
TEST_F(OopPixelTest, DrawRectTransformOptionsFullRaster) { … }
TEST_F(OopPixelTest, DrawRectQueryMiddleOfDisplayList) { … }
TEST_F(OopPixelTest, DrawRectColorSpace) { … }
sk_sp<SkTextBlob> BuildTextBlob(
sk_sp<SkTypeface> typeface = skia::DefaultTypeface(),
bool use_lcd_text = false) { … }
static constexpr SkScalar kTextBlobY = …;
enum class TextBlobStrategy { … };
enum class FilterStrategy { … };
enum class MatrixStrategy { … };
enum class LCDStrategy { … };
TextBlobTestConfig;
class OopTextBlobPixelTest
: public OopPixelTest,
public ::testing::WithParamInterface<TextBlobTestConfig> { … };
TEST_P(OopTextBlobPixelTest, Config) { … }
INSTANTIATE_TEST_SUITE_P(…);
void ClearFontCache(CompletionEvent* event) { … }
TEST_F(OopPixelTest, DrawTextMultipleRasterCHROMIUM) { … }
TEST_F(OopPixelTest, DrawTextBlobPersistentShaderCache) { … }
TEST_F(OopPixelTest, WritePixels) { … }
TEST_F(OopPixelTest, CopySharedImage) { … }
#if !BUILDFLAG(IS_ANDROID_EMULATOR)
using OopYUVToRGBConfig = ::testing::tuple<gfx::ColorSpace, bool>;
class OopYUVToRGBPixelTest
: public OopPixelTest,
public ::testing::WithParamInterface<OopYUVToRGBConfig> {
public:
bool TestColorSpaceConversion() const {
return ::testing::get<1>(GetParam());
}
gfx::ColorSpace DestinationColorSpace() const {
return ::testing::get<0>(GetParam());
}
};
TEST_P(OopYUVToRGBPixelTest, ConvertYUVToRGB) {
const gfx::ColorSpace source_color_space(gfx::ColorSpace::PrimaryID::P3,
gfx::ColorSpace::TransferID::SRGB);
const gfx::ColorSpace dest_color_space = DestinationColorSpace();
RasterOptions options(gfx::Size(16, 16));
RasterOptions uv_options(gfx::Size(options.resource_size.width() / 2,
options.resource_size.height() / 2));
auto* ri = raster_context_provider_->RasterInterface();
auto* sii = raster_context_provider_->SharedImageInterface();
auto dest_client_si = CreateClientSharedImage(
ri, sii, options, viz::SinglePlaneFormat::kRGBA_8888, dest_color_space);
constexpr viz::SharedImageFormat format = viz::SinglePlaneFormat::kR_8;
scoped_refptr<gpu::ClientSharedImage> yuv_client_si[3]{
CreateClientSharedImage(ri, sii, options, format),
CreateClientSharedImage(ri, sii, uv_options, format),
CreateClientSharedImage(ri, sii, uv_options, format)};
gpu::Mailbox yuv_mailboxes[3]{
yuv_client_si[0]->mailbox(),
yuv_client_si[1]->mailbox(),
yuv_client_si[2]->mailbox(),
};
SkImageInfo y_info = SkImageInfo::Make(
options.resource_size.width(), options.resource_size.height(),
kGray_8_SkColorType, kPremul_SkAlphaType,
options.target_color_params.color_space.ToSkColorSpace());
SkImageInfo uv_info = SkImageInfo::Make(
uv_options.resource_size.width(), uv_options.resource_size.height(),
kGray_8_SkColorType, kPremul_SkAlphaType,
uv_options.target_color_params.color_space.ToSkColorSpace());
SkBitmap y_bitmap;
y_bitmap.allocPixels(y_info);
memset(y_bitmap.getPixels(), 0x1d, y_bitmap.computeByteSize());
SkBitmap u_bitmap;
u_bitmap.allocPixels(uv_info);
memset(u_bitmap.getPixels(), 0xff, u_bitmap.computeByteSize());
SkBitmap v_bitmap;
v_bitmap.allocPixels(uv_info);
memset(v_bitmap.getPixels(), 0x6b, v_bitmap.computeByteSize());
UploadPixels(ri, yuv_client_si[0]->mailbox(), y_info, y_bitmap);
UploadPixels(ri, yuv_client_si[1]->mailbox(), uv_info, u_bitmap);
UploadPixels(ri, yuv_client_si[2]->mailbox(), uv_info, v_bitmap);
ri->ConvertYUVAMailboxesToRGB(
dest_client_si->mailbox(), 0, 0, options.resource_size.width(),
options.resource_size.height(), kJPEG_SkYUVColorSpace,
TestColorSpaceConversion() ? source_color_space.ToSkColorSpace().get()
: nullptr,
SkYUVAInfo::PlaneConfig::kY_U_V, SkYUVAInfo::Subsampling::k420,
yuv_mailboxes);
SkBitmap actual_bitmap =
ReadbackMailbox(ri, dest_client_si->mailbox(), options.resource_size,
dest_color_space.ToSkColorSpace());
SkColor expected_color =
(TestColorSpaceConversion() && dest_color_space.IsValid())
? SkColorSetARGB(255, 61, 29, 252)
: SkColorSetARGB(255, 0, 0, 254);
SkBitmap expected_bitmap = MakeSolidColorBitmap(
options.resource_size, SkColor4f::FromColor(expected_color));
auto comparator = FuzzyPixelComparator()
.SetErrorPixelsPercentageLimit(100.0f)
.SetAbsErrorLimit(2);
ExpectEquals(actual_bitmap, expected_bitmap, comparator);
gpu::SyncToken sync_token;
sii->DestroySharedImage(sync_token, std::move(dest_client_si));
sii->DestroySharedImage(sync_token, std::move(yuv_client_si[0]));
sii->DestroySharedImage(sync_token, std::move(yuv_client_si[1]));
sii->DestroySharedImage(sync_token, std::move(yuv_client_si[2]));
}
INSTANTIATE_TEST_SUITE_P(
P,
OopYUVToRGBPixelTest,
::testing::Combine(
::testing::Values(gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020,
gfx::ColorSpace::TransferID::SRGB),
gfx::ColorSpace()),
::testing::Bool()));
TEST_F(OopPixelTest, ConvertNV12ToRGB) {
RasterOptions options(gfx::Size(16, 16));
RasterOptions uv_options(gfx::Size(options.resource_size.width() / 2,
options.resource_size.height() / 2));
auto* ri = raster_context_provider_->RasterInterface();
auto* sii = raster_context_provider_->SharedImageInterface();
scoped_refptr<gpu::ClientSharedImage> dest_client_si =
CreateClientSharedImage(ri, sii, options,
viz::SinglePlaneFormat::kRGBA_8888);
scoped_refptr<gpu::ClientSharedImage> y_uv_client_si[2]{
CreateClientSharedImage(ri, sii, options, viz::SinglePlaneFormat::kR_8),
CreateClientSharedImage(ri, sii, uv_options,
viz::SinglePlaneFormat::kRG_88),
};
gpu::Mailbox y_uv_mailboxes[2]{
y_uv_client_si[0]->mailbox(),
y_uv_client_si[1]->mailbox(),
};
SkImageInfo y_info = SkImageInfo::Make(
options.resource_size.width(), options.resource_size.height(),
kGray_8_SkColorType, kPremul_SkAlphaType,
options.target_color_params.color_space.ToSkColorSpace());
SkImageInfo uv_info = SkImageInfo::Make(
uv_options.resource_size.width(), uv_options.resource_size.height(),
kR8G8_unorm_SkColorType, kPremul_SkAlphaType,
uv_options.target_color_params.color_space.ToSkColorSpace());
SkBitmap y_bitmap;
y_bitmap.allocPixels(y_info);
memset(y_bitmap.getPixels(), 0x1d, y_bitmap.computeByteSize());
SkBitmap uv_bitmap;
uv_bitmap.allocPixels(uv_info);
uint8_t* uv_pix = static_cast<uint8_t*>(uv_bitmap.getPixels());
for (size_t i = 0; i < uv_bitmap.computeByteSize(); i += 2) {
uv_pix[i] = 0xff;
uv_pix[i + 1] = 0x6d;
}
UploadPixels(ri, y_uv_client_si[0]->mailbox(), y_info, y_bitmap);
UploadPixels(ri, y_uv_client_si[1]->mailbox(), uv_info, uv_bitmap);
ri->ConvertYUVAMailboxesToRGB(
dest_client_si->mailbox(), 0, 0, options.resource_size.width(),
options.resource_size.height(), kJPEG_SkYUVColorSpace,
SkColorSpace::MakeSRGB().get(), SkYUVAInfo::PlaneConfig::kY_UV,
SkYUVAInfo::Subsampling::k420, y_uv_mailboxes);
SkBitmap actual_bitmap =
ReadbackMailbox(ri, dest_client_si->mailbox(), options.resource_size);
SkBitmap expected_bitmap = MakeSolidColorBitmap(
options.resource_size,
SkColor4f::FromColor(SkColorSetARGB(255, 2, 0, 254)));
ExpectEquals(actual_bitmap, expected_bitmap);
gpu::SyncToken sync_token;
sii->DestroySharedImage(sync_token, std::move(dest_client_si));
sii->DestroySharedImage(sync_token, std::move(y_uv_client_si[0]));
sii->DestroySharedImage(sync_token, std::move(y_uv_client_si[1]));
}
#endif
class OopPathPixelTest : public OopPixelTest,
public ::testing::WithParamInterface<bool> { … };
TEST_P(OopPathPixelTest, Basic) { … }
TEST_F(OopPixelTest, RecordShaderExceedsMaxTextureSize) { … }
INSTANTIATE_TEST_SUITE_P(…) …;
INSTANTIATE_TEST_SUITE_P(…) …;
}
}