1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
6
7 #include "components/viz/common/resources/single_release_callback.h"
8 #include "components/viz/test/test_context_provider.h"
9 #include "components/viz/test/test_gles2_interface.h"
10 #include "components/viz/test/test_gpu_memory_buffer_manager.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
14 #include "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h"
15 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
16 #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
17 #include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h"
18 #include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h"
19 #include "third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h"
20 #include "third_party/blink/renderer/platform/graphics/test/gpu_test_utils.h"
21 #include "third_party/blink/renderer/platform/wtf/functional.h"
22 #include "third_party/skia/include/core/SkFilterQuality.h"
23 #include "ui/gfx/buffer_types.h"
24
25 using testing::_;
26 using testing::InSequence;
27 using testing::Return;
28 using testing::Test;
29
30 namespace blink {
31
32 namespace {
33
34 constexpr int kMaxTextureSize = 1024;
35
36 class MockCanvasResourceDispatcherClient
37 : public CanvasResourceDispatcherClient {
38 public:
39 MockCanvasResourceDispatcherClient() = default;
40
41 MOCK_METHOD0(BeginFrame, bool());
42 MOCK_METHOD1(SetFilterQualityInResource, void(SkFilterQuality));
43 };
44
45 } // anonymous namespace
46
47 class CanvasResourceProviderTest : public Test {
48 public:
SetUp()49 void SetUp() override {
50 test_context_provider_ = viz::TestContextProvider::Create();
51 auto* test_gl = test_context_provider_->UnboundTestContextGL();
52 test_gl->set_max_texture_size(kMaxTextureSize);
53 test_gl->set_support_texture_storage_image(true);
54 test_gl->set_supports_shared_image_swap_chain(true);
55 test_gl->set_supports_gpu_memory_buffer_format(gfx::BufferFormat::RGBA_8888,
56 true);
57 test_gl->set_supports_gpu_memory_buffer_format(gfx::BufferFormat::BGRA_8888,
58 true);
59 test_gl->set_supports_gpu_memory_buffer_format(gfx::BufferFormat::RGBA_F16,
60 true);
61 InitializeSharedGpuContext(test_context_provider_.get(),
62 &image_decode_cache_);
63 context_provider_wrapper_ = SharedGpuContext::ContextProviderWrapper();
64 }
65
TearDown()66 void TearDown() override { SharedGpuContext::ResetForTesting(); }
67
68 protected:
69 cc::StubDecodeCache image_decode_cache_;
70 scoped_refptr<viz::TestContextProvider> test_context_provider_;
71 base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
72 ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform_;
73 };
74
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderAcceleratedOverlay)75 TEST_F(CanvasResourceProviderTest, CanvasResourceProviderAcceleratedOverlay) {
76 const IntSize kSize(10, 10);
77 const CanvasColorParams kColorParams(
78 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
79 kNonOpaque);
80
81 auto provider = CanvasResourceProvider::Create(
82 kSize,
83 CanvasResourceProvider::ResourceUsage::kAcceleratedDirect2DResourceUsage,
84 context_provider_wrapper_, 0 /* msaa_sample_count */,
85 kMedium_SkFilterQuality, kColorParams,
86 CanvasResourceProvider::kAllowImageChromiumPresentationMode,
87 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
88
89 EXPECT_EQ(provider->Size(), kSize);
90 EXPECT_TRUE(provider->IsValid());
91 EXPECT_TRUE(provider->IsAccelerated());
92 EXPECT_TRUE(provider->SupportsDirectCompositing());
93 EXPECT_TRUE(provider->SupportsSingleBuffering());
94 EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
95 // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it
96 // will internally force it to kRGBA8
97 EXPECT_EQ(provider->ColorParams().PixelFormat(), CanvasPixelFormat::kRGBA8);
98 EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
99 kColorParams.GetOpacityMode());
100
101 EXPECT_FALSE(provider->IsSingleBuffered());
102 provider->TryEnableSingleBuffering();
103 EXPECT_TRUE(provider->IsSingleBuffered());
104 }
105
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderTexture)106 TEST_F(CanvasResourceProviderTest, CanvasResourceProviderTexture) {
107 const IntSize kSize(10, 10);
108 const CanvasColorParams kColorParams(
109 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
110 kNonOpaque);
111
112 auto provider = CanvasResourceProvider::CreateSharedImageProvider(
113 kSize, context_provider_wrapper_, kLow_SkFilterQuality, kColorParams,
114 true /*is_origin_top_left*/, CanvasResourceProvider::RasterMode::kGPU,
115 0u /*shared_image_usage_flags*/);
116
117 EXPECT_EQ(provider->Size(), kSize);
118 EXPECT_TRUE(provider->IsValid());
119 EXPECT_TRUE(provider->IsAccelerated());
120 EXPECT_TRUE(provider->SupportsDirectCompositing());
121 EXPECT_FALSE(provider->SupportsSingleBuffering());
122 EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
123 // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it
124 // will internally force it to kRGBA8
125 EXPECT_EQ(provider->ColorParams().PixelFormat(), CanvasPixelFormat::kRGBA8);
126 EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
127 kColorParams.GetOpacityMode());
128
129 EXPECT_FALSE(provider->IsSingleBuffered());
130 }
131
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderUnacceleratedOverlay)132 TEST_F(CanvasResourceProviderTest, CanvasResourceProviderUnacceleratedOverlay) {
133 const IntSize kSize(10, 10);
134 const CanvasColorParams kColorParams(
135 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
136 kNonOpaque);
137
138 auto provider = CanvasResourceProvider::Create(
139 kSize,
140 CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage,
141 context_provider_wrapper_, 0 /* msaa_sample_count */,
142 kLow_SkFilterQuality, kColorParams,
143 CanvasResourceProvider::kAllowImageChromiumPresentationMode,
144 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
145
146 EXPECT_EQ(provider->Size(), kSize);
147 EXPECT_TRUE(provider->IsValid());
148 EXPECT_FALSE(provider->IsAccelerated());
149 EXPECT_TRUE(provider->SupportsDirectCompositing());
150
151 // We do not support single buffering for unaccelerated low latency canvas.
152 EXPECT_FALSE(provider->SupportsSingleBuffering());
153
154 EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
155 EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
156 EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
157 kColorParams.GetOpacityMode());
158
159 EXPECT_FALSE(provider->IsSingleBuffered());
160 }
161
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderSharedImageResourceRecycling)162 TEST_F(CanvasResourceProviderTest,
163 CanvasResourceProviderSharedImageResourceRecycling) {
164 const IntSize kSize(10, 10);
165 const CanvasColorParams kColorParams(
166 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
167 kNonOpaque);
168
169 auto provider = CanvasResourceProvider::Create(
170 kSize,
171 CanvasResourceProvider::ResourceUsage::
172 kAcceleratedCompositedResourceUsage,
173 context_provider_wrapper_, 0 /* msaa_sample_count */,
174 kMedium_SkFilterQuality, kColorParams,
175 CanvasResourceProvider::kAllowImageChromiumPresentationMode,
176 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
177
178 EXPECT_EQ(provider->Size(), kSize);
179 EXPECT_TRUE(provider->IsValid());
180 EXPECT_TRUE(provider->IsAccelerated());
181 EXPECT_FALSE(provider->IsSingleBuffered());
182 EXPECT_FALSE(provider->SupportsSingleBuffering());
183 EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
184 // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it
185 // will internally force it to kRGBA8
186 EXPECT_EQ(provider->ColorParams().PixelFormat(), CanvasPixelFormat::kRGBA8);
187 EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
188 kColorParams.GetOpacityMode());
189
190 // Same resource and sync token if we query again without updating.
191 auto resource = provider->ProduceCanvasResource();
192 auto sync_token = resource->GetSyncToken();
193 ASSERT_TRUE(resource);
194 EXPECT_EQ(resource, provider->ProduceCanvasResource());
195 EXPECT_EQ(sync_token, resource->GetSyncToken());
196
197 // Resource updated after draw.
198 provider->Canvas()->clear(SK_ColorWHITE);
199 auto new_resource = provider->ProduceCanvasResource();
200 EXPECT_NE(resource, new_resource);
201 EXPECT_NE(sync_token, new_resource->GetSyncToken());
202
203 // Resource recycled.
204 viz::TransferableResource transferable_resource;
205 std::unique_ptr<viz::SingleReleaseCallback> release_callback;
206 ASSERT_TRUE(resource->PrepareTransferableResource(
207 &transferable_resource, &release_callback, kUnverifiedSyncToken));
208 auto* resource_ptr = resource.get();
209 resource = nullptr;
210 release_callback->Run(sync_token, false);
211
212 provider->Canvas()->clear(SK_ColorBLACK);
213 auto resource_again = provider->ProduceCanvasResource();
214 EXPECT_EQ(resource_ptr, resource_again);
215 EXPECT_NE(sync_token, resource_again->GetSyncToken());
216 }
217
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderSharedImageStaticBitmapImage)218 TEST_F(CanvasResourceProviderTest,
219 CanvasResourceProviderSharedImageStaticBitmapImage) {
220 const IntSize kSize(10, 10);
221 const CanvasColorParams kColorParams(
222 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
223 kNonOpaque);
224
225 auto provider = CanvasResourceProvider::Create(
226 kSize,
227 CanvasResourceProvider::ResourceUsage::
228 kAcceleratedCompositedResourceUsage,
229 context_provider_wrapper_, 0 /* msaa_sample_count */,
230 kMedium_SkFilterQuality, kColorParams,
231 CanvasResourceProvider::kAllowImageChromiumPresentationMode,
232 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
233 ASSERT_TRUE(provider->IsValid());
234
235 // Same resource returned until the canvas is updated.
236 auto image = provider->Snapshot();
237 ASSERT_TRUE(image);
238 auto new_image = provider->Snapshot();
239 EXPECT_EQ(image->GetMailboxHolder().mailbox,
240 new_image->GetMailboxHolder().mailbox);
241 EXPECT_EQ(provider->ProduceCanvasResource()->GetOrCreateGpuMailbox(
242 kOrderingBarrier),
243 image->GetMailboxHolder().mailbox);
244
245 // Resource updated after draw.
246 provider->Canvas()->clear(SK_ColorWHITE);
247 provider->FlushCanvas();
248 new_image = provider->Snapshot();
249 EXPECT_NE(new_image->GetMailboxHolder().mailbox,
250 image->GetMailboxHolder().mailbox);
251
252 // Resource recycled.
253 auto original_mailbox = image->GetMailboxHolder().mailbox;
254 image.reset();
255 provider->Canvas()->clear(SK_ColorBLACK);
256 provider->FlushCanvas();
257 EXPECT_EQ(original_mailbox, provider->Snapshot()->GetMailboxHolder().mailbox);
258 }
259
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderSharedImageCopyOnWriteDisabled)260 TEST_F(CanvasResourceProviderTest,
261 CanvasResourceProviderSharedImageCopyOnWriteDisabled) {
262 auto* fake_context = static_cast<FakeWebGraphicsContext3DProvider*>(
263 context_provider_wrapper_->ContextProvider());
264 auto caps = fake_context->GetCapabilities();
265 caps.disable_2d_canvas_copy_on_write = true;
266 fake_context->SetCapabilities(caps);
267
268 const IntSize kSize(10, 10);
269 const CanvasColorParams kColorParams(
270 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
271 kNonOpaque);
272
273 auto provider = CanvasResourceProvider::Create(
274 kSize,
275 CanvasResourceProvider::ResourceUsage::
276 kAcceleratedCompositedResourceUsage,
277 context_provider_wrapper_, 0 /* msaa_sample_count */,
278 kMedium_SkFilterQuality, kColorParams,
279 CanvasResourceProvider::kAllowImageChromiumPresentationMode,
280 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
281 ASSERT_TRUE(provider->IsValid());
282
283 // Disabling copy-on-write forces a copy each time the resource is queried.
284 auto resource = provider->ProduceCanvasResource();
285 EXPECT_NE(resource->GetOrCreateGpuMailbox(kOrderingBarrier),
286 provider->ProduceCanvasResource()->GetOrCreateGpuMailbox(
287 kOrderingBarrier));
288 }
289
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderBitmap)290 TEST_F(CanvasResourceProviderTest, CanvasResourceProviderBitmap) {
291 const IntSize kSize(10, 10);
292 const CanvasColorParams kColorParams(
293 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
294 kNonOpaque);
295
296 auto provider = CanvasResourceProvider::CreateBitmapProvider(
297 kSize, kLow_SkFilterQuality, kColorParams);
298
299 EXPECT_EQ(provider->Size(), kSize);
300 EXPECT_TRUE(provider->IsValid());
301 EXPECT_FALSE(provider->IsAccelerated());
302 EXPECT_FALSE(provider->SupportsDirectCompositing());
303 EXPECT_FALSE(provider->SupportsSingleBuffering());
304 EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
305 EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
306 EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
307 kColorParams.GetOpacityMode());
308
309 EXPECT_FALSE(provider->IsSingleBuffered());
310 }
311
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderSharedBitmap)312 TEST_F(CanvasResourceProviderTest, CanvasResourceProviderSharedBitmap) {
313 const IntSize kSize(10, 10);
314 const CanvasColorParams kColorParams(
315 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
316 kNonOpaque);
317
318 MockCanvasResourceDispatcherClient client;
319 CanvasResourceDispatcher resource_dispatcher(
320 &client, 1 /* client_id */, 1 /* sink_id */,
321 1 /* placeholder_canvas_id */, kSize);
322
323 auto provider = CanvasResourceProvider::Create(
324 kSize,
325 CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage,
326 context_provider_wrapper_, 0 /* msaa_sample_count */,
327 kLow_SkFilterQuality, kColorParams,
328 CanvasResourceProvider::kDefaultPresentationMode,
329 resource_dispatcher.GetWeakPtr(), true /* is_origin_top_left */);
330
331 EXPECT_EQ(provider->Size(), kSize);
332 EXPECT_TRUE(provider->IsValid());
333 EXPECT_FALSE(provider->IsAccelerated());
334 EXPECT_TRUE(provider->SupportsDirectCompositing());
335 EXPECT_FALSE(provider->SupportsSingleBuffering());
336 EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
337 EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
338 EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
339 kColorParams.GetOpacityMode());
340
341 EXPECT_FALSE(provider->IsSingleBuffered());
342 provider->TryEnableSingleBuffering();
343 EXPECT_FALSE(provider->IsSingleBuffered());
344 }
345
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderDirect2DGpuMemoryBuffer)346 TEST_F(CanvasResourceProviderTest,
347 CanvasResourceProviderDirect2DGpuMemoryBuffer) {
348 const IntSize kSize(10, 10);
349 const CanvasColorParams kColorParams(
350 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
351 kNonOpaque);
352
353 auto provider = CanvasResourceProvider::Create(
354 kSize,
355 CanvasResourceProvider::ResourceUsage::kAcceleratedDirect2DResourceUsage,
356 context_provider_wrapper_, 0 /* msaa_sample_count */,
357 kLow_SkFilterQuality, kColorParams,
358 CanvasResourceProvider::kAllowImageChromiumPresentationMode,
359 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
360
361 EXPECT_EQ(provider->Size(), kSize);
362 EXPECT_TRUE(provider->IsValid());
363 EXPECT_TRUE(provider->IsAccelerated());
364 EXPECT_TRUE(provider->SupportsDirectCompositing());
365 EXPECT_TRUE(provider->SupportsSingleBuffering());
366 EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
367 // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it
368 // will internally force it to kRGBA8
369 EXPECT_EQ(provider->ColorParams().PixelFormat(), CanvasPixelFormat::kRGBA8);
370 EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
371 kColorParams.GetOpacityMode());
372
373 EXPECT_FALSE(provider->IsSingleBuffered());
374 provider->TryEnableSingleBuffering();
375 EXPECT_TRUE(provider->IsSingleBuffered());
376 }
377
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderDirect3DGpuMemoryBuffer)378 TEST_F(CanvasResourceProviderTest,
379 CanvasResourceProviderDirect3DGpuMemoryBuffer) {
380 const IntSize kSize(10, 10);
381 const CanvasColorParams kColorParams(
382 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
383 kNonOpaque);
384
385 auto provider = CanvasResourceProvider::Create(
386 kSize,
387 CanvasResourceProvider::ResourceUsage::kAcceleratedDirect3DResourceUsage,
388 context_provider_wrapper_, 0 /* msaa_sample_count */,
389 kLow_SkFilterQuality, kColorParams,
390 CanvasResourceProvider::kAllowImageChromiumPresentationMode,
391 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
392
393 EXPECT_EQ(provider->Size(), kSize);
394 EXPECT_TRUE(provider->IsValid());
395 EXPECT_TRUE(provider->IsAccelerated());
396 EXPECT_TRUE(provider->SupportsDirectCompositing());
397 EXPECT_TRUE(provider->SupportsSingleBuffering());
398 EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
399 EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
400 EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
401 kColorParams.GetOpacityMode());
402
403 EXPECT_FALSE(provider->IsSingleBuffered());
404 provider->TryEnableSingleBuffering();
405 EXPECT_TRUE(provider->IsSingleBuffered());
406
407 gpu::Mailbox mailbox = gpu::Mailbox::Generate();
408 scoped_refptr<ExternalCanvasResource> resource =
409 ExternalCanvasResource::Create(
410 mailbox, kSize, GL_TEXTURE_2D, kColorParams,
411 SharedGpuContext::ContextProviderWrapper(), provider->CreateWeakPtr(),
412 kMedium_SkFilterQuality, true /*is_origin_top_left*/);
413
414 // NewOrRecycledResource() would return nullptr before an ImportResource().
415 EXPECT_TRUE(provider->ImportResource(resource));
416 EXPECT_EQ(provider->NewOrRecycledResource(), resource);
417 // NewOrRecycledResource() will always return the same |resource|.
418 EXPECT_EQ(provider->NewOrRecycledResource(), resource);
419 }
420
421 // Verifies that Accelerated Direct 3D resources are backed by SharedImages.
422 // https://crbug.com/985366
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderDirect3DTexture)423 TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect3DTexture) {
424 const IntSize kSize(10, 10);
425 const CanvasColorParams kColorParams(
426 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
427 kNonOpaque);
428
429 auto provider = CanvasResourceProvider::Create(
430 kSize,
431 CanvasResourceProvider::ResourceUsage::kAcceleratedDirect3DResourceUsage,
432 context_provider_wrapper_, 0 /* msaa_sample_count */,
433 kLow_SkFilterQuality, kColorParams,
434 CanvasResourceProvider::kDefaultPresentationMode,
435 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
436
437 EXPECT_EQ(provider->Size(), kSize);
438 EXPECT_TRUE(provider->IsValid());
439 EXPECT_TRUE(provider->IsAccelerated());
440 EXPECT_TRUE(provider->SupportsDirectCompositing());
441 EXPECT_FALSE(provider->SupportsSingleBuffering());
442 EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
443 // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it
444 // will internally force it to kRGBA8
445 EXPECT_EQ(provider->ColorParams().PixelFormat(), CanvasPixelFormat::kRGBA8);
446 EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
447 kColorParams.GetOpacityMode());
448
449 EXPECT_FALSE(provider->IsSingleBuffered());
450 provider->TryEnableSingleBuffering();
451 EXPECT_FALSE(provider->IsSingleBuffered());
452
453 auto resource = provider->ProduceCanvasResource();
454 viz::TransferableResource transferable_resource;
455 std::unique_ptr<viz::SingleReleaseCallback> callback;
456 resource->PrepareTransferableResource(&transferable_resource, &callback,
457 kOrderingBarrier);
458 EXPECT_TRUE(transferable_resource.mailbox_holder.mailbox.IsSharedImage());
459 EXPECT_FALSE(transferable_resource.is_overlay_candidate);
460 callback->Run(gpu::SyncToken(), true /* is_lost */);
461 }
462
TEST_F(CanvasResourceProviderTest,DimensionsExceedMaxTextureSize_Bitmap)463 TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize_Bitmap) {
464 const CanvasColorParams kColorParams(
465 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
466 kNonOpaque);
467
468 auto provider = CanvasResourceProvider::CreateBitmapProvider(
469 IntSize(kMaxTextureSize - 1, kMaxTextureSize), kLow_SkFilterQuality,
470 kColorParams);
471 EXPECT_FALSE(provider->SupportsDirectCompositing());
472 provider = CanvasResourceProvider::CreateBitmapProvider(
473 IntSize(kMaxTextureSize, kMaxTextureSize), kLow_SkFilterQuality,
474 kColorParams);
475 EXPECT_FALSE(provider->SupportsDirectCompositing());
476 provider = CanvasResourceProvider::CreateBitmapProvider(
477 IntSize(kMaxTextureSize + 1, kMaxTextureSize), kLow_SkFilterQuality,
478 kColorParams);
479 EXPECT_FALSE(provider->SupportsDirectCompositing());
480 }
481
TEST_F(CanvasResourceProviderTest,DimensionsExceedMaxTextureSize_SharedImage)482 TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize_SharedImage) {
483 const CanvasColorParams kColorParams(
484 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
485 kNonOpaque);
486
487 auto provider = CanvasResourceProvider::CreateSharedImageProvider(
488 IntSize(kMaxTextureSize - 1, kMaxTextureSize), context_provider_wrapper_,
489 kLow_SkFilterQuality, kColorParams, true /*is_origin_top_left*/,
490 CanvasResourceProvider::RasterMode::kGPU,
491 0u /*shared_image_usage_flags*/);
492 EXPECT_TRUE(provider->SupportsDirectCompositing());
493 provider = CanvasResourceProvider::CreateSharedImageProvider(
494 IntSize(kMaxTextureSize, kMaxTextureSize), context_provider_wrapper_,
495 kLow_SkFilterQuality, kColorParams, true /*is_origin_top_left*/,
496 CanvasResourceProvider::RasterMode::kGPU,
497 0u /*shared_image_usage_flags*/);
498 EXPECT_TRUE(provider->SupportsDirectCompositing());
499 provider = CanvasResourceProvider::CreateSharedImageProvider(
500 IntSize(kMaxTextureSize + 1, kMaxTextureSize), context_provider_wrapper_,
501 kLow_SkFilterQuality, kColorParams, true /*is_origin_top_left*/,
502 CanvasResourceProvider::RasterMode::kGPU,
503 0u /*shared_image_usage_flags*/);
504 // The CanvasResourceProvider for SharedImage should not be created or valid
505 // if the texture size is greater than the maximum value
506 EXPECT_TRUE(!provider || !provider->IsValid());
507 }
508
TEST_F(CanvasResourceProviderTest,DimensionsExceedMaxTextureSize)509 TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
510 const CanvasColorParams kColorParams(
511 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
512 kNonOpaque);
513
514 for (int i = 0;
515 i < static_cast<int>(CanvasResourceProvider::ResourceUsage::kMaxValue);
516 ++i) {
517 SCOPED_TRACE(i);
518 auto usage = static_cast<CanvasResourceProvider::ResourceUsage>(i);
519 bool should_support_compositing = false;
520 std::unique_ptr<CanvasResourceProvider> provider;
521 switch (usage) {
522 // Skipping ResourceUsages that will be removed after this refactor
523 // bug(1035589)
524 case CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage:
525 continue;
526 case CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage:
527 continue;
528 case CanvasResourceProvider::ResourceUsage::
529 kSoftwareCompositedResourceUsage:
530 FALLTHROUGH;
531 case CanvasResourceProvider::ResourceUsage::
532 kSoftwareCompositedDirect2DResourceUsage:
533 FALLTHROUGH;
534 case CanvasResourceProvider::ResourceUsage::
535 kAcceleratedCompositedResourceUsage:
536 FALLTHROUGH;
537 case CanvasResourceProvider::ResourceUsage::
538 kAcceleratedDirect2DResourceUsage:
539 FALLTHROUGH;
540 case CanvasResourceProvider::ResourceUsage::
541 kAcceleratedDirect3DResourceUsage:
542 should_support_compositing = true;
543 break;
544 }
545
546 provider = CanvasResourceProvider::Create(
547 IntSize(kMaxTextureSize - 1, kMaxTextureSize), usage,
548 context_provider_wrapper_, 0 /* msaa_sample_count */,
549 kLow_SkFilterQuality, kColorParams,
550 CanvasResourceProvider::kAllowImageChromiumPresentationMode,
551 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
552
553 EXPECT_EQ(provider->SupportsDirectCompositing(),
554 should_support_compositing);
555
556 provider = CanvasResourceProvider::Create(
557 IntSize(kMaxTextureSize, kMaxTextureSize), usage,
558 context_provider_wrapper_, 0 /* msaa_sample_count */,
559 kLow_SkFilterQuality, kColorParams,
560 CanvasResourceProvider::kAllowImageChromiumPresentationMode,
561 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
562
563 EXPECT_EQ(provider->SupportsDirectCompositing(),
564 should_support_compositing);
565
566 provider = CanvasResourceProvider::Create(
567 IntSize(kMaxTextureSize + 1, kMaxTextureSize), usage,
568 context_provider_wrapper_, 0 /* msaa_sample_count */,
569 kLow_SkFilterQuality, kColorParams,
570 CanvasResourceProvider::kAllowImageChromiumPresentationMode,
571 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
572
573 EXPECT_FALSE(provider->SupportsDirectCompositing());
574 }
575 }
576
TEST_F(CanvasResourceProviderTest,CanvasResourceProviderDirect2DSwapChain)577 TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect2DSwapChain) {
578 const IntSize kSize(10, 10);
579 const CanvasColorParams kColorParams(
580 CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
581 kNonOpaque);
582
583 auto provider = CanvasResourceProvider::Create(
584 kSize,
585 CanvasResourceProvider::ResourceUsage::kAcceleratedDirect2DResourceUsage,
586 context_provider_wrapper_, 0 /* msaa_sample_count */,
587 kLow_SkFilterQuality, kColorParams,
588 CanvasResourceProvider::kAllowSwapChainPresentationMode,
589 nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
590
591 EXPECT_EQ(provider->Size(), kSize);
592 EXPECT_TRUE(provider->IsValid());
593 EXPECT_TRUE(provider->IsAccelerated());
594 EXPECT_TRUE(provider->SupportsDirectCompositing());
595 EXPECT_TRUE(provider->SupportsSingleBuffering());
596 EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
597 EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
598 EXPECT_EQ(provider->ColorParams().GetOpacityMode(),
599 kColorParams.GetOpacityMode());
600
601 EXPECT_FALSE(provider->IsSingleBuffered());
602 provider->TryEnableSingleBuffering();
603 EXPECT_TRUE(provider->IsSingleBuffered());
604 }
605
606 } // namespace blink
607