Flutter Impeller
impeller::testing Namespace Reference

Classes

struct  Foo
 
struct  RWFoo
 
struct  CVTest
 
struct  BlendModeSelection
 
struct  MaskBlurTestConfig
 
struct  TextRenderOptions
 
class  BlendFilterContentsTest
 
class  GaussianBlurFilterContentsTest
 
class  MatrixFilterContentsTest
 
class  MockIdleWaiter
 
class  FailingAllocator
 
class  FlushTestDeviceBuffer
 
class  FlushTestAllocator
 
class  FlushTestContentContext
 
class  TestAllocator
 
struct  ColorBlendTestData
 
class  GoldenDigest
 Manages a global variable for tracking instances of golden images. More...
 
class  GoldenTests
 
class  MetalScreenshot
 A screenshot that was produced from MetalScreenshotter. More...
 
class  MetalScreenshotter
 
class  Screenshot
 
class  Screenshotter
 
class  VulkanScreenshotter
 
class  WorkingDirectory
 
class  TestReactorGLES
 
class  MockWorker
 
class  RendererDartTest
 
class  CompareFunctionUIData
 
class  MockPathVertexWriter
 
class  MockSegmentReceiver
 

Typedefs

using AiksTest = AiksPlayground
 
using DisplayListTest = DlPlayground
 
using HostBufferTest = EntityPlayground
 
using TextContentsTest = PlaygroundTest
 
using EntityTest = EntityPlayground
 
using EntityPassTargetTest = EntityPlayground
 
using RenderTargetCacheTest = EntityPlayground
 
using SaveLayerUtilsTest = ::testing::Test
 
using DlPathReceiverMock = flutter::testing::DlPathReceiverMock
 
using AllocatorMTLTest = PlaygroundTest
 
using ContextMTLTest = PlaygroundTest
 
using SwapchainTransientsMTLTest = PlaygroundTest
 
using DriverInfoVKTest = PlaygroundTest
 
using PipelineCacheDataVKPlaygroundTest = PlaygroundTest
 
using RendererTest = PlaygroundTest
 
using BlitPassTest = AiksTest
 
using ComputeTest = ComputePlaygroundTest
 
using DeviceBufferTest = Playground
 
using RuntimeStageTest = RuntimeStagePlayground
 
using TypographerTest = PlaygroundTest
 

Functions

 TEST (AllocationSizeTest, CanCreateTypedAllocations)
 
 TEST (AllocationSizeTest, CanCreateTypedAllocationsWithLiterals)
 
 TEST (AllocationSizeTest, CanConvert)
 
 TEST (AllocationSizeTest, ConversionsAreNonTruncating)
 
 TEST (AllocationSizeTest, CanGetFloatValues)
 
 TEST (AllocationSizeTest, RelationalOperatorsAreFunctional)
 
 TEST (AllocationSizeTest, CanCast)
 
 TEST (AllocationSizeTest, CanPerformSimpleArithmetic)
 
 TEST (AllocationSizeTest, CanConstructWithArith)
 
 TEST (ThreadTest, CanCreateMutex)
 
 TEST (ThreadTest, CanCreateMutexLock)
 
 TEST (ThreadTest, CanCreateRWMutex)
 
 TEST (ThreadTest, CanCreateRWMutexLock)
 
 TEST (ConditionVariableTest, WaitUntil)
 
 TEST (ConditionVariableTest, WaitFor)
 
 TEST (ConditionVariableTest, WaitForever)
 
 TEST (ConditionVariableTest, TestsCriticalSectionAfterWaitForUntil)
 
 TEST (ConditionVariableTest, TestsCriticalSectionAfterWait)
 
 TEST (BaseTest, NoExceptionPromiseValue)
 
 TEST (BaseTest, NoExceptionPromiseEmpty)
 
 TEST (BaseTest, CanUseTypedMasks)
 
 TEST (AllocatorTest, TextureDescriptorCompatibility)
 
 TEST (AllocatorTest, RangeTest)
 
 TEST (BufferViewTest, Empty)
 
 TEST (BufferViewTest, TakeRaw)
 
 TEST_P (AiksTest, DrawAtlasNoColor)
 
 TEST_P (AiksTest, DrawAtlasWithColorAdvanced)
 
 TEST_P (AiksTest, DrawAtlasWithColorSimple)
 
 TEST_P (AiksTest, DrawAtlasWithOpacity)
 
 TEST_P (AiksTest, DrawAtlasNoColorFullSize)
 
 TEST_P (AiksTest, DrawAtlasAdvancedAndTransform)
 
 TEST_P (AiksTest, DrawAtlasWithColorAdvancedAndTransform)
 
 TEST_P (AiksTest, DrawAtlasPlusWideGamut)
 
 TEST_P (AiksTest, DlAtlasGeometryNoBlendRenamed)
 
 TEST_P (AiksTest, DlAtlasGeometryBlend)
 
 TEST_P (AiksTest, DlAtlasGeometryColorButNoBlend)
 
 TEST_P (AiksTest, DlAtlasGeometrySkip)
 
 TEST_P (AiksTest, DrawImageRectWithBlendColorFilter)
 
 TEST_P (AiksTest, DrawImageRectWithMatrixColorFilter)
 
 TEST_P (AiksTest, DrawAtlasWithColorBurn)
 
 TEST_P (AiksTest, CanRenderColoredRect)
 
 TEST_P (AiksTest, CanRenderWideStrokedRectWithoutOverlap)
 
 TEST_P (AiksTest, CanRenderWideStrokedRectPathWithoutOverlap)
 
 TEST_P (AiksTest, CanRenderImage)
 
 TEST_P (AiksTest, CanRenderInvertedImageWithColorFilter)
 
 TEST_P (AiksTest, CanRenderColorFilterWithInvertColors)
 
 TEST_P (AiksTest, CanRenderColorFilterWithInvertColorsDrawPaint)
 
 TEST_P (AiksTest, CanRenderTiledTextureClamp)
 
 TEST_P (AiksTest, CanRenderTiledTextureRepeat)
 
 TEST_P (AiksTest, CanRenderTiledTextureMirror)
 
 TEST_P (AiksTest, CanRenderTiledTextureDecal)
 
 TEST_P (AiksTest, CanRenderTiledTextureClampWithTranslate)
 
 TEST_P (AiksTest, CanRenderImageRect)
 
 TEST_P (AiksTest, DrawImageRectSrcOutsideBounds)
 
 TEST_P (AiksTest, CanRenderSimpleClips)
 
 TEST_P (AiksTest, CanSaveLayerStandalone)
 
 TEST_P (AiksTest, CanRenderDifferentShapesWithSameColorSource)
 
 TEST_P (AiksTest, CanRenderRoundedRectWithNonUniformRadii)
 
 TEST_P (AiksTest, CanDrawPaint)
 
 TEST_P (AiksTest, CanDrawPaintMultipleTimes)
 
 TEST_P (AiksTest, StrokedRectsRenderCorrectly)
 
 TEST_P (AiksTest, FilledCirclesRenderCorrectly)
 
 TEST_P (AiksTest, StrokedCirclesRenderCorrectly)
 
 TEST_P (AiksTest, FilledEllipsesRenderCorrectly)
 
 TEST_P (AiksTest, FilledArcsRenderCorrectly)
 
 TEST_P (AiksTest, FilledArcsRenderCorrectlyWithCenter)
 
 TEST_P (AiksTest, NonSquareFilledArcsRenderCorrectly)
 
 TEST_P (AiksTest, NonSquareFilledArcsRenderCorrectlyWithCenter)
 
 TEST_P (AiksTest, StrokedArcsRenderCorrectlyWithButtEnds)
 
 TEST_P (AiksTest, StrokedArcsRenderCorrectlyWithSquareEnds)
 
 TEST_P (AiksTest, StrokedArcsRenderCorrectlyWithRoundEnds)
 
 TEST_P (AiksTest, StrokedArcsRenderCorrectlyWithBevelJoinsAndCenter)
 
 TEST_P (AiksTest, StrokedArcsRenderCorrectlyWithMiterJoinsAndCenter)
 
 TEST_P (AiksTest, StrokedArcsRenderCorrectlyWithRoundJoinsAndCenter)
 
 TEST_P (AiksTest, StrokedArcsRenderCorrectlyWithSquareAndButtEnds)
 
 TEST_P (AiksTest, StrokedArcsRenderCorrectlyWithSquareAndButtAndRoundEnds)
 
 TEST_P (AiksTest, StrokedArcsCoverFullArcWithButtEnds)
 
 TEST_P (AiksTest, FilledRoundRectsRenderCorrectly)
 
 TEST_P (AiksTest, SolidColorCirclesOvalsRRectsMaskBlurCorrectly)
 
 TEST_P (AiksTest, CanRenderClippedBackdropFilter)
 
 TEST_P (AiksTest, CanDrawPerspectiveTransformWithClips)
 
 TEST_P (AiksTest, ImageColorSourceEffectTransform)
 
 TEST_P (AiksTest, SubpassWithClearColorOptimization)
 
 TEST_P (AiksTest, MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen)
 
 TEST_P (AiksTest, MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen)
 
 TEST_P (AiksTest, ClearColorOptimizationWhenSubpassIsBiggerThanParentPass)
 
 TEST_P (AiksTest, EmptySaveLayerIgnoresPaint)
 
 TEST_P (AiksTest, EmptySaveLayerRendersWithClear)
 
 TEST_P (AiksTest, CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated)
 
 TEST_P (AiksTest, FormatWideGamut)
 
 TEST_P (AiksTest, FormatSRGB)
 
 TEST_P (AiksTest, CoordinateConversionsAreCorrect)
 
 TEST_P (AiksTest, CanPerformFullScreenMSAA)
 
 TEST_P (AiksTest, CanPerformSkew)
 
 TEST_P (AiksTest, CanPerformSaveLayerWithBounds)
 
 TEST_P (AiksTest, FilledRoundRectPathsRenderCorrectly)
 
 TEST_P (AiksTest, CoverageOriginShouldBeAccountedForInSubpasses)
 
 TEST_P (AiksTest, SaveLayerDrawsBehindSubsequentEntities)
 
 TEST_P (AiksTest, SiblingSaveLayerBoundsAreRespected)
 
 TEST_P (AiksTest, CanRenderClippedLayers)
 
 TEST_P (AiksTest, SaveLayerFiltersScaleWithTransform)
 
 TEST_P (AiksTest, FastEllipticalRRectMaskBlursRenderCorrectly)
 
 TEST_P (AiksTest, PipelineBlendSingleParameter)
 
 TEST_P (AiksTest, MassiveScalingMatrixImageFilter)
 
 TEST_P (AiksTest, NoDimplesInRRectPath)
 
 TEST_P (AiksTest, BackdropFilterOverUnclosedClip)
 
static BlendModeSelection GetBlendModeSelection ()
 
 TEST_P (AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer)
 
 TEST_P (AiksTest, BlendModeShouldCoverWholeScreen)
 
 TEST_P (AiksTest, CanDrawPaintWithAdvancedBlend)
 
 TEST_P (AiksTest, DrawPaintWithAdvancedBlendOverFilter)
 
 TEST_P (AiksTest, DrawAdvancedBlendPartlyOffscreen)
 
 TEST_P (AiksTest, PaintBlendModeIsRespected)
 
 TEST_P (AiksTest, ColorFilterBlend)
 
 TEST_P (AiksTest, ColorFilterAdvancedBlend)
 
 TEST_P (AiksTest, ColorFilterAdvancedBlendNoFbFetch)
 
 TEST_P (AiksTest, BlendModePlusAlphaWideGamut)
 
 TEST_P (AiksTest, BlendModePlusAlphaColorFilterWideGamut)
 
 TEST_P (AiksTest, ForegroundBlendSubpassCollapseOptimization)
 
 TEST_P (AiksTest, ClearBlend)
 
static sk_sp< DisplayList > BlendModeTest (Vector2 content_scale, BlendMode blend_mode, const sk_sp< DlImageImpeller > &src_image, const sk_sp< DlImageImpeller > &dst_image, Scalar src_alpha)
 
 TEST_P (AiksTest, CanDrawPaintMultipleTimesInteractive)
 
 TEST_P (AiksTest, ForegroundPipelineBlendAppliesTransformCorrectly)
 
 TEST_P (AiksTest, ForegroundAdvancedBlendAppliesTransformCorrectly)
 
 TEST_P (AiksTest, FramebufferAdvancedBlendCoverage)
 
 TEST_P (AiksTest, ColorWheel)
 
 TEST_P (AiksTest, DestructiveBlendColorFilterFloodsClip)
 
 TEST_P (AiksTest, AdvancedBlendColorFilterWithDestinationOpacity)
 
 TEST_P (AiksTest, EmulatedAdvancedBlendRestore)
 
 TEST_P (AiksTest, SolidColorOvalsMaskBlurTinySigma)
 
sk_sp< flutter::DisplayList > DoGradientOvalStrokeMaskBlur (Vector2 content_Scale, Scalar sigma, DlBlurStyle style)
 
 TEST_P (AiksTest, GradientOvalStrokeMaskBlur)
 
 TEST_P (AiksTest, GradientOvalStrokeMaskBlurSigmaZero)
 
 TEST_P (AiksTest, GradientOvalStrokeMaskBlurOuter)
 
 TEST_P (AiksTest, GradientOvalStrokeMaskBlurInner)
 
 TEST_P (AiksTest, GradientOvalStrokeMaskBlurSolid)
 
 TEST_P (AiksTest, SolidColorCircleMaskBlurTinySigma)
 
 TEST_P (AiksTest, CanRenderMaskBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderForegroundBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderBackdropBlurInteractive)
 
 TEST_P (AiksTest, CanRenderBackdropBlur)
 
 TEST_P (AiksTest, CanRenderBackdropBlurWithSingleBackdropId)
 
 TEST_P (AiksTest, CanRenderMultipleBackdropBlurWithSingleBackdropId)
 
 TEST_P (AiksTest, CanRenderMultipleBackdropBlurWithSingleBackdropIdAndDistinctFilters)
 
 TEST_P (AiksTest, CanRenderBackdropBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderClippedBlur)
 
 TEST_P (AiksTest, ClippedBlurFilterRendersCorrectlyInteractive)
 
 TEST_P (AiksTest, ClippedBlurFilterRendersCorrectly)
 
 TEST_P (AiksTest, ClearBlendWithBlur)
 
 TEST_P (AiksTest, BlurHasNoEdge)
 
 TEST_P (AiksTest, MaskBlurWithZeroSigmaIsSkipped)
 
 TEST_P (AiksTest, MaskBlurOnZeroDimensionIsSkippedWideGamut)
 
static sk_sp< DisplayList > MaskBlurVariantTest (const AiksTest &test_context, const MaskBlurTestConfig &config)
 
 TEST_P (AiksTest, GaussianBlurStyleInner)
 
 TEST_P (AiksTest, GaussianBlurStyleOuter)
 
 TEST_P (AiksTest, GaussianBlurStyleSolid)
 
 TEST_P (AiksTest, MaskBlurTexture)
 
 TEST_P (AiksTest, MaskBlurDoesntStretchContents)
 
 TEST_P (AiksTest, GaussianBlurAtPeripheryVertical)
 
 TEST_P (AiksTest, GaussianBlurAtPeripheryHorizontal)
 
 TEST_P (AiksTest, GaussianBlurAnimatedBackdrop)
 
 TEST_P (AiksTest, GaussianBlurStyleInnerGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleSolidGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleOuterGradient)
 
 TEST_P (AiksTest, GaussianBlurScaledAndClipped)
 
 TEST_P (AiksTest, GaussianBlurRotatedAndClippedInteractive)
 
 TEST_P (AiksTest, GaussianBlurOneDimension)
 
 TEST_P (AiksTest, GaussianBlurRotatedAndClipped)
 
 TEST_P (AiksTest, GaussianBlurRotatedNonUniform)
 
 TEST_P (AiksTest, BlurredRectangleWithShader)
 
 TEST_P (AiksTest, GaussianBlurSolidColorTinyMipMap)
 
 TEST_P (AiksTest, GaussianBlurBackdropTinyMipMap)
 
 TEST_P (AiksTest, CanRenderMultipleBackdropBlurWithSingleBackdropIdDifferentLayers)
 
 TEST_P (AiksTest, BlurGradientWithOpacity)
 
 TEST_P (AiksTest, CanRenderNestedBackdropBlur)
 
 TEST_P (AiksTest, CanRenderNestedClips)
 
 TEST_P (AiksTest, CanRenderDifferenceClips)
 
 TEST_P (AiksTest, CanRenderWithContiguousClipRestores)
 
 TEST_P (AiksTest, ClipsUseCurrentTransform)
 
 TEST_P (AiksTest, FramebufferBlendsRespectClips)
 
 TEST_P (AiksTest, CanRenderLinearGradientClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientRepeat)
 
 TEST_P (AiksTest, CanRenderLinearGradientMirror)
 
 TEST_P (AiksTest, CanRenderLinearGradientDecal)
 
 TEST_P (AiksTest, CanRenderLinearGradientDecalWithColorFilter)
 
static void CanRenderLinearGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderLinearGradientWithDitheringEnabled)
 
static void CanRenderRadialGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderRadialGradientWithDitheringEnabled)
 
static void CanRenderSweepGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderSweepGradientWithDitheringEnabled)
 
static void CanRenderConicalGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderConicalGradientWithDitheringEnabled)
 
 TEST_P (AiksTest, CanRenderLinearGradientWithOverlappingStopsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientWithIncompleteStops)
 
 TEST_P (AiksTest, CanRenderRadialGradientWithIncompleteStops)
 
 TEST_P (AiksTest, CanRenderConicalGradientWithIncompleteStops)
 
 TEST_P (AiksTest, CanRenderSweepGradientWithIncompleteStops)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsRepeat)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsMirror)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsDecal)
 
 TEST_P (AiksTest, CanRenderLinearGradientWayManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsUnevenStops)
 
 TEST_P (AiksTest, CanRenderLinearGradientMaskBlur)
 
 TEST_P (AiksTest, CanRenderRadialGradient)
 
 TEST_P (AiksTest, CanRenderRadialGradientManyColors)
 
 TEST_P (AiksTest, CanRenderSweepGradientClamp)
 
 TEST_P (AiksTest, CanRenderSweepGradientRepeat)
 
 TEST_P (AiksTest, CanRenderSweepGradientMirror)
 
 TEST_P (AiksTest, CanRenderSweepGradientDecal)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsRepeat)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsMirror)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsDecal)
 
 TEST_P (AiksTest, CanRenderConicalGradient)
 
 TEST_P (AiksTest, CanRenderGradientDecalWithBackground)
 
 TEST_P (AiksTest, GradientStrokesRenderCorrectly)
 
 TEST_P (AiksTest, FastGradientTestHorizontal)
 
 TEST_P (AiksTest, FastGradientTestVertical)
 
 TEST_P (AiksTest, FastGradientTestHorizontalReversed)
 
 TEST_P (AiksTest, FastGradientTestVerticalReversed)
 
 TEST_P (AiksTest, VerifyNonOptimizedGradient)
 
 TEST_P (AiksTest, DrawOpacityPeephole)
 
 TEST_P (AiksTest, CanRenderGroupOpacity)
 
 TEST_P (AiksTest, CanRenderGroupOpacityToSavelayer)
 
 TEST_P (AiksTest, RotateColorFilteredPath)
 
 TEST_P (AiksTest, CanRenderStrokes)
 
 TEST_P (AiksTest, CanRenderCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderThickCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderThinCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderStrokePathThatEndsAtSharpTurn)
 
 TEST_P (AiksTest, CanRenderStrokePathWithCubicLine)
 
 TEST_P (AiksTest, CanRenderQuadraticStrokeWithInstantTurn)
 
 TEST_P (AiksTest, CanRenderFilledConicPaths)
 
 TEST_P (AiksTest, CanRenderStrokedConicPaths)
 
 TEST_P (AiksTest, HairlinePath)
 
 TEST_P (AiksTest, HairlineDrawLine)
 
 TEST_P (AiksTest, CanRenderTightConicPath)
 
 TEST_P (AiksTest, CanRenderDifferencePaths)
 
 TEST_P (AiksTest, CanDrawAnOpenPath)
 
 TEST_P (AiksTest, CanDrawAnOpenPathThatIsntARect)
 
 TEST_P (AiksTest, SolidStrokesRenderCorrectly)
 
 TEST_P (AiksTest, DrawLinesRenderCorrectly)
 
 TEST_P (AiksTest, ScaleExperimentAntialiasLines)
 
 TEST_P (AiksTest, HexagonExperimentAntialiasLines)
 
 TEST_P (AiksTest, SimpleExperimentAntialiasLines)
 
 TEST_P (AiksTest, DrawRectStrokesRenderCorrectly)
 
 TEST_P (AiksTest, DrawRectStrokesWithBevelJoinRenderCorrectly)
 
 TEST_P (AiksTest, CanDrawMultiContourConvexPath)
 
 TEST_P (AiksTest, ArcWithZeroSweepAndBlur)
 
 TEST_P (AiksTest, CanRenderClips)
 
 TEST_P (AiksTest, FatStrokeArc)
 
 TEST_P (AiksTest, CanRenderOverlappingMultiContourPath)
 
 TEST_P (AiksTest, TwoContourPathWithSinglePointContour)
 
 TEST_P (AiksTest, StrokeCapsAndJoins)
 
 TEST_P (AiksTest, BlurredCircleWithStrokeWidth)
 
 TEST_P (AiksTest, CanRenderClippedRuntimeEffects)
 
 TEST_P (AiksTest, DrawPaintTransformsBounds)
 
 TEST_P (AiksTest, CanRenderRuntimeEffectFilter)
 
 TEST_P (AiksTest, RuntimeEffectWithInvalidSamplerDoesNotCrash)
 
bool RenderTextInCanvasSkia (const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string_view &font_fixture, const TextRenderOptions &options={}, const std::optional< SkFont > &font=std::nullopt)
 
 TEST_P (AiksTest, CanRenderTextFrame)
 
 TEST_P (AiksTest, CanRenderTextFrameWithInvertedTransform)
 
 TEST_P (AiksTest, CanRenderStrokedTextFrame)
 
 TEST_P (AiksTest, CanRenderTextStrokeWidth)
 
 TEST_P (AiksTest, CanRenderTextFrameWithHalfScaling)
 
 TEST_P (AiksTest, ScaledK)
 
 TEST_P (AiksTest, MassiveScaleConvertToPath)
 
 TEST_P (AiksTest, CanRenderTextFrameWithScalingOverflow)
 
 TEST_P (AiksTest, CanRenderTextFrameWithFractionScaling)
 
 TEST_P (AiksTest, TextRotated180Degrees)
 
 TEST_P (AiksTest, TextFrameSubpixelAlignment)
 
 TEST_P (AiksTest, CanRenderItalicizedText)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrame)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrameWithBlur)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrameWithAlpha)
 
 TEST_P (AiksTest, CanRenderTextInSaveLayer)
 
 TEST_P (AiksTest, CanRenderTextOutsideBoundaries)
 
 TEST_P (AiksTest, TextRotated)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveSaveLayer)
 
 TEST_P (AiksTest, CanRenderTextWithLargePerspectiveTransform)
 
 TEST_P (AiksTest, CanRenderTextWithPerspectiveTransformInSublist)
 
 TEST_P (AiksTest, TextForegroundShaderWithTransform)
 
 TEST_P (AiksTest, DifferenceClipsMustRenderIdenticallyAcrossBackends)
 
 TEST_P (AiksTest, TextContentsMismatchedTransformTest)
 
 TEST_P (AiksTest, TextWithShadowCache)
 
 TEST_P (AiksTest, MultipleTextWithShadowCache)
 
 TEST_P (AiksTest, SingleIconShadowTest)
 
 TEST_P (AiksTest, VarietyOfTextScalesShowingRasterAndPath)
 
 TEST_P (AiksTest, CollapsedDrawPaintInSubpass)
 
 TEST_P (AiksTest, CollapsedDrawPaintInSubpassBackdropFilter)
 
 TEST_P (AiksTest, ColorMatrixFilterSubpassCollapseOptimization)
 
 TEST_P (AiksTest, LinearToSrgbFilterSubpassCollapseOptimization)
 
 TEST_P (AiksTest, SrgbToLinearFilterSubpassCollapseOptimization)
 
 TEST_P (AiksTest, TranslucentSaveLayerDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, ImageFilteredUnboundedSaveLayerWithUnboundedContents)
 
 TEST_P (AiksTest, TranslucentSaveLayerImageDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly)
 
 TEST_P (AiksTest, CanRenderTinyOverlappingSubpasses)
 
 TEST_P (AiksTest, CanRenderDestructiveSaveLayer)
 
 TEST_P (AiksTest, CanDrawPoints)
 
 TEST_P (AiksTest, CanDrawPointsWithTextureMap)
 
 TEST_P (AiksTest, MipmapGenerationWorksCorrectly)
 
 TEST_P (AiksTest, StrokedPathWithMoveToThenCloseDrawnCorrectly)
 
 TEST_P (AiksTest, SetContentsWithRegion)
 
 TEST_P (AiksTest, ReleasesTextureOnTeardown)
 
 TEST_P (AiksTest, MatrixImageFilterMagnify)
 
 TEST_P (AiksTest, ImageFilteredSaveLayerWithUnboundedContents)
 
 TEST_P (AiksTest, MatrixBackdropFilter)
 
 TEST_P (AiksTest, MatrixSaveLayerFilter)
 
 TEST_P (AiksTest, CanDrawScaledPointsSmallScaleLargeRadius)
 
 TEST_P (AiksTest, CanDrawScaledPointsLargeScaleSmallRadius)
 
 TEST_P (AiksTest, TransparentShadowProducesCorrectColor)
 
 TEST_P (AiksTest, DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists)
 
 TEST_P (AiksTest, BackdropRestoreUsesCorrectCoverageForFirstRestoredClip)
 
 TEST_P (AiksTest, CanPictureConvertToImage)
 
 TEST_P (AiksTest, CanEmptyPictureConvertToImage)
 
 TEST_P (AiksTest, DepthValuesForLineMode)
 
 TEST_P (AiksTest, DepthValuesForPolygonMode)
 
 TEST_P (AiksTest, ToImageFromImage)
 
 TEST_P (AiksTest, DisplayListToTextureAllocationFailure)
 
 TEST_P (AiksTest, DisplayListToTextureWithMipGeneration)
 
 TEST_P (AiksTest, VerticesGeometryUVPositionData)
 
 TEST_P (AiksTest, VerticesGeometryUVPositionDataWithTranslate)
 
 TEST_P (AiksTest, VerticesGeometryColorUVPositionData)
 
 TEST_P (AiksTest, VerticesGeometryColorUVPositionDataAdvancedBlend)
 
 TEST_P (AiksTest, CanConvertTriangleFanToTriangles)
 
 TEST_P (AiksTest, DrawVerticesSolidColorTrianglesWithoutIndices)
 
 TEST_P (AiksTest, DrawVerticesLinearGradientWithoutIndices)
 
 TEST_P (AiksTest, DrawVerticesLinearGradientWithTextureCoordinates)
 
 TEST_P (AiksTest, DrawVerticesImageSourceWithTextureCoordinates)
 
 TEST_P (AiksTest, DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending)
 
 TEST_P (AiksTest, DrawVerticesSolidColorTrianglesWithIndices)
 
 TEST_P (AiksTest, DrawVerticesPremultipliesColors)
 
 TEST_P (AiksTest, DrawVerticesWithInvalidIndices)
 
 TEST_P (AiksTest, DrawVerticesTextureCoordinatesWithFragmentShader)
 
 TEST_P (AiksTest, DrawVerticesTextureCoordinatesWithFragmentShaderNonZeroOrigin)
 
 TEST_P (AiksTest, VerticesGeometryWithMaskFilter)
 
 INSTANTIATE_PLAYGROUND_SUITE (AiksTest)
 
std::unique_ptr< CanvasCreateTestCanvas (ContentContext &context, std::optional< Rect > cull_rect=std::nullopt, bool requires_readback=false)
 
 TEST_P (AiksTest, TransformMultipliesCorrectly)
 
 TEST_P (AiksTest, CanvasCanPushPopCTM)
 
 TEST_P (AiksTest, CanvasCTMCanBeUpdated)
 
 TEST_P (AiksTest, BackdropCountDownNormal)
 
 TEST_P (AiksTest, BackdropCountDownBackdropId)
 
 TEST_P (AiksTest, BackdropCountDownBackdropIdMixed)
 
 TEST_P (AiksTest, BackdropCountDownWithNestedSaveLayers)
 
 TEST_P (AiksTest, DrawVerticesLinearGradientWithEmptySize)
 
 TEST_P (AiksTest, DrawVerticesWithEmptyTextureCoordinates)
 
 TEST_P (AiksTest, SupportsBlitToOnscreen)
 
 TEST_P (AiksTest, RoundSuperellipseShadowComparison)
 
flutter::DlColor toColor (const float *components)
 
 INSTANTIATE_PLAYGROUND_SUITE (DisplayListTest)
 
 TEST_P (DisplayListTest, CanDrawRect)
 
 TEST_P (DisplayListTest, CanDrawTextBlob)
 
 TEST_P (DisplayListTest, CanDrawTextBlobWithGradient)
 
 TEST_P (DisplayListTest, CanDrawTextWithSaveLayer)
 
 TEST_P (DisplayListTest, CanDrawImage)
 
 TEST_P (DisplayListTest, CanDrawCapsAndJoins)
 
 TEST_P (DisplayListTest, CanDrawArc)
 
 TEST_P (DisplayListTest, StrokedPathsDrawCorrectly)
 
 TEST_P (DisplayListTest, CanDrawWithOddPathWinding)
 
 TEST_P (DisplayListTest, CanDrawAnOpenPath)
 
 TEST_P (DisplayListTest, CanDrawWithMaskBlur)
 
 TEST_P (DisplayListTest, CanDrawStrokedText)
 
 TEST_P (DisplayListTest, StrokedTextNotOffsetFromNormalText)
 
 TEST_P (DisplayListTest, IgnoreMaskFilterWhenSavingLayer)
 
 TEST_P (DisplayListTest, CanDrawWithBlendColorFilter)
 
 TEST_P (DisplayListTest, CanDrawWithColorFilterImageFilter)
 
 TEST_P (DisplayListTest, CanDrawWithImageBlurFilter)
 
 TEST_P (DisplayListTest, CanDrawWithComposeImageFilter)
 
 TEST_P (DisplayListTest, CanClampTheResultingColorOfColorMatrixFilter)
 
 TEST_P (DisplayListTest, CanDrawBackdropFilter)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImage)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterWidthBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterHeightBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCornersScaledDown)
 
 TEST_P (DisplayListTest, NinePatchImagePrecision)
 
 TEST_P (DisplayListTest, CanDrawPoints)
 
 TEST_P (DisplayListTest, CanDrawZeroLengthLine)
 
 TEST_P (DisplayListTest, CanDrawShadow)
 
 TEST_P (DisplayListTest, CanDrawZeroWidthLine)
 
 TEST_P (DisplayListTest, CanDrawWithMatrixFilter)
 
 TEST_P (DisplayListTest, CanDrawWithMatrixFilterWhenSavingLayer)
 
 TEST_P (DisplayListTest, CanDrawRectWithLinearToSrgbColorFilter)
 
 TEST_P (DisplayListTest, CanDrawPaintWithColorSource)
 
 TEST_P (DisplayListTest, CanBlendDstOverAndDstCorrectly)
 
 TEST_P (DisplayListTest, CanDrawCorrectlyWithColorFilterAndImageFilter)
 
 TEST_P (DisplayListTest, MaskBlursApplyCorrectlyToColorSources)
 
 TEST_P (DisplayListTest, DrawShapes)
 
 TEST_P (DisplayListTest, ClipDrawRRectWithNonCircularRadii)
 
 TEST_P (DisplayListTest, DrawVerticesBlendModes)
 
 TEST_P (DisplayListTest, DrawPaintIgnoresMaskFilter)
 
 TEST_P (DisplayListTest, DrawMaskBlursThatMightUseSaveLayers)
 
 TEST (PaintTest, GradientStopConversion)
 
 TEST (PaintTest, GradientMissing0)
 
 TEST (PaintTest, GradientMissingLastValue)
 
 TEST (PaintTest, GradientStopGreaterThan1)
 
 TEST (PaintTest, GradientConversionNonMonotonic)
 
 TEST (SkiaConversionTest, ToSamplerDescriptor)
 
 TEST (SkiaConversionsTest, ToColor)
 
 TEST (EntityPassClipStackTest, CanPushAndPopEntities)
 
 TEST (EntityPassClipStackTest, CanPopEntitiesSafely)
 
 TEST (EntityPassClipStackTest, AppendAndRestoreClipCoverage)
 
 TEST (EntityPassClipStackTest, AppendAndRestoreClipCoverageNonAA)
 
 TEST (EntityPassClipStackTest, AppendLargerClipCoverage)
 
 TEST (EntityPassClipStackTest, AppendLargerClipCoverageWithDifferenceOrNonSquare)
 
 TEST (EntityPassClipStackTest, AppendDecreasingSizeClipCoverage)
 
 TEST (EntityPassClipStackTest, AppendIncreasingSizeClipCoverage)
 
 TEST (EntityPassClipStackTest, UnbalancedRestore)
 
 TEST (EntityPassClipStackTest, ClipAndRestoreWithSubpasses)
 
 TEST (EntityPassClipStackTest, ClipAndRestoreWithSubpassesNonAA)
 
 INSTANTIATE_PLAYGROUND_SUITE (BlendFilterContentsTest)
 
 TEST_P (BlendFilterContentsTest, AdvancedBlendColorAlignsColorTo4)
 
 INSTANTIATE_PLAYGROUND_SUITE (GaussianBlurFilterContentsTest)
 
 TEST (GaussianBlurFilterContentsTest, Create)
 
 TEST (GaussianBlurFilterContentsTest, CoverageEmpty)
 
 TEST (GaussianBlurFilterContentsTest, CoverageSimple)
 
 TEST (GaussianBlurFilterContentsTest, CoverageWithSigma)
 
 TEST_P (GaussianBlurFilterContentsTest, CoverageWithTexture)
 
 TEST_P (GaussianBlurFilterContentsTest, CoverageWithEffectTransform)
 
 TEST (GaussianBlurFilterContentsTest, FilterSourceCoverage)
 
 TEST (GaussianBlurFilterContentsTest, CalculateSigmaValues)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverage)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverageTranslate)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverageRotated)
 
 TEST_P (GaussianBlurFilterContentsTest, CalculateUVsSimple)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithDestinationRect)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithDestinationRectScaled)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithEffectTransform)
 
 TEST (GaussianBlurFilterContentsTest, CalculateSigmaForBlurRadius)
 
 TEST (GaussianBlurFilterContentsTest, Coefficients)
 
 TEST (GaussianBlurFilterContentsTest, LerpHackKernelSamplesSimple)
 
 TEST (GaussianBlurFilterContentsTest, LerpHackKernelSamplesComplex)
 
 TEST (GaussianBlurFilterContentsTest, ChopHugeBlurs)
 
 TEST (FilterInputTest, CanSetLocalTransformForTexture)
 
 INSTANTIATE_PLAYGROUND_SUITE (MatrixFilterContentsTest)
 
 TEST (MatrixFilterContentsTest, CoverageEmpty)
 
 TEST (MatrixFilterContentsTest, CoverageSimple)
 
 TEST (MatrixFilterContentsTest, Coverage2x)
 
 TEST (MatrixFilterContentsTest, Coverage2xEffect)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageIdentity)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageTranslate)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageClippedSubpassTranslate)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageScale)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageClippedSubpassScale)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageSubpassScale)
 
 INSTANTIATE_PLAYGROUND_SUITE (HostBufferTest)
 
 TEST_P (HostBufferTest, IdleWaiter)
 
 TEST_P (HostBufferTest, CanEmplace)
 
 TEST_P (HostBufferTest, CanEmplaceWithAlignment)
 
 TEST_P (HostBufferTest, HostBufferInitialState)
 
 TEST_P (HostBufferTest, ResetIncrementsFrameCounter)
 
 TEST_P (HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback)
 
 TEST_P (HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBuffer)
 
 TEST_P (HostBufferTest, UnusedBuffersAreDiscardedWhenResetting)
 
 TEST_P (HostBufferTest, EmplaceWithProcIsAligned)
 
 TEST_P (HostBufferTest, EmplaceWithFailingAllocationDoesntCrash)
 
 TEST (LineContents, Create)
 
 TEST (LineContents, CalculatePerVertex)
 
 TEST (LineContents, CreateCurveData)
 
 TEST (LineContents, CreateCurveDataScaled)
 
 TEST (LineContents, CalculatePerVertexLimit)
 
 INSTANTIATE_PLAYGROUND_SUITE (TextContentsTest)
 
 TEST_P (TextContentsTest, SimpleComputeVertexData)
 
 TEST_P (TextContentsTest, SimpleComputeVertexData2x)
 
 TEST_P (TextContentsTest, MaintainsShape)
 
 TEST_P (TextContentsTest, SimpleSubpixel)
 
 TEST_P (TextContentsTest, SimpleSubpixel3x)
 
 TEST_P (TextContentsTest, SimpleSubpixel26)
 
 TEST_P (TextContentsTest, SimpleSubpixel80)
 
 TEST_P (EntityTest, TiledTextureContentsRendersWithCorrectPipeline)
 
 TEST_P (EntityTest, TiledTextureContentsRendersWithCorrectPipelineExternalOES)
 
 TEST (DrawOrderResolverTest, GetSortedDrawsReturnsCorrectOrderWithNoClips)
 
 TEST (DrawOrderResolverTest, GetSortedDrawsReturnsCorrectOrderWithClips)
 
 TEST (DrawOrderResolverTest, GetSortedDrawsRespectsSkipCounts)
 
 TEST (DrawOrderResolverTest, GetSortedDrawsReturnsCorrectOrderWithFlush)
 
 TEST_P (EntityPassTargetTest, SwapWithMSAATexture)
 
 TEST_P (EntityPassTargetTest, SwapWithMSAAImplicitResolve)
 
Rect RectMakeCenterSize (Point center, Size size)
 
 TEST_P (EntityTest, CanCreateEntity)
 
 TEST_P (EntityTest, FilterCoverageRespectsCropRect)
 
 TEST_P (EntityTest, GeometryBoundsAreTransformed)
 
 TEST_P (EntityTest, ThreeStrokesInOnePath)
 
 TEST_P (EntityTest, StrokeWithTextureContents)
 
 TEST_P (EntityTest, TriangleInsideASquare)
 
 TEST_P (EntityTest, StrokeCapAndJoinTest)
 
 TEST_P (EntityTest, CubicCurveTest)
 
 TEST_P (EntityTest, CanDrawCorrectlyWithRotatedTransform)
 
 TEST_P (EntityTest, CubicCurveAndOverlapTest)
 
 TEST_P (EntityTest, SolidColorContentsStrokeSetStrokeCapsAndJoins)
 
 TEST_P (EntityTest, SolidColorContentsStrokeSetMiterLimit)
 
 TEST_P (EntityTest, BlendingModeOptions)
 
 TEST_P (EntityTest, BezierCircleScaled)
 
 TEST_P (EntityTest, Filters)
 
 TEST_P (EntityTest, GaussianBlurFilter)
 
 TEST_P (EntityTest, MorphologyFilter)
 
 TEST_P (EntityTest, SetBlendMode)
 
 TEST_P (EntityTest, ContentsGetBoundsForEmptyPathReturnsNullopt)
 
 TEST_P (EntityTest, SolidStrokeCoverageIsCorrect)
 
 TEST_P (EntityTest, BorderMaskBlurCoverageIsCorrect)
 
 TEST_P (EntityTest, SolidFillCoverageIsCorrect)
 
 TEST_P (EntityTest, RRectShadowTest)
 
 TEST_P (EntityTest, ColorMatrixFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, ColorMatrixFilterEditable)
 
 TEST_P (EntityTest, LinearToSrgbFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, LinearToSrgbFilter)
 
 TEST_P (EntityTest, SrgbToLinearFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, SrgbToLinearFilter)
 
static Vector3 RGBToYUV (Vector3 rgb, YUVColorSpace yuv_color_space)
 
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures (Context *context, YUVColorSpace yuv_color_space)
 
 TEST_P (EntityTest, YUVToRGBFilter)
 
 TEST_P (EntityTest, RuntimeEffect)
 
 TEST_P (EntityTest, RuntimeEffectCanSuccessfullyRender)
 
 TEST_P (EntityTest, RuntimeEffectCanPrecache)
 
 TEST_P (EntityTest, RuntimeEffectSetsRightSizeWhenUniformIsStruct)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorAdvancedBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorClearBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorSrcBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorDstBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorSrcInBlend)
 
 TEST_P (EntityTest, CoverageForStrokePathWithNegativeValuesInTransform)
 
 TEST_P (EntityTest, SolidColorContentsIsOpaque)
 
 TEST_P (EntityTest, ConicalGradientContentsIsOpaque)
 
 TEST_P (EntityTest, LinearGradientContentsIsOpaque)
 
 TEST_P (EntityTest, RadialGradientContentsIsOpaque)
 
 TEST_P (EntityTest, SweepGradientContentsIsOpaque)
 
 TEST_P (EntityTest, TiledTextureContentsIsOpaque)
 
 TEST_P (EntityTest, PointFieldGeometryCoverage)
 
 TEST_P (EntityTest, ColorFilterContentsWithLargeGeometry)
 
 TEST_P (EntityTest, TextContentsCeilsGlyphScaleToDecimal)
 
 TEST_P (EntityTest, SpecializationConstantsAreAppliedToVariants)
 
 TEST_P (EntityTest, DecalSpecializationAppliedToMorphologyFilter)
 
 TEST_P (EntityTest, ContentContextOptionsHasReasonableHashFunctions)
 
 TEST_P (EntityTest, FillPathGeometryGetPositionBufferReturnsExpectedMode)
 
 TEST_P (EntityTest, FailOnValidationError)
 
 TEST_P (EntityTest, CanComputeGeometryForEmptyPathsWithoutCrashing)
 
 TEST_P (EntityTest, CanRenderEmptyPathsWithoutCrashing)
 
 TEST_P (EntityTest, DrawSuperEllipse)
 
 TEST_P (EntityTest, DrawRoundSuperEllipse)
 
 TEST_P (EntityTest, SolidColorApplyColorFilter)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Linear)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Radial)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Conical)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Sweep)
 
 TEST_P (EntityTest, GiantStrokePathAllocation)
 
 TEST_P (EntityTest, RoundSuperellipseGetPositionBufferFlushes)
 
 TEST (EntityGeometryTest, RectGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversAreaNoInnerRect)
 
 TEST (EntityGeometryTest, FillArcGeometryCoverage)
 
 TEST (EntityGeometryTest, StrokeArcGeometryCoverage)
 
 TEST (EntityGeometryTest, FillRoundRectGeometryCoversArea)
 
 TEST (EntityGeometryTest, LineGeometryCoverage)
 
 TEST (EntityGeometryTest, RoundRectGeometryCoversArea)
 
 TEST (EntityGeometryTest, GeometryResultHasReasonableDefaults)
 
 TEST (EntityGeometryTest, AlphaCoverageStrokePaths)
 
 TEST (EntityGeometryTest, SimpleTwoLineStrokeVerticesButtCap)
 
 TEST (EntityGeometryTest, SimpleTwoLineStrokeVerticesRoundCap)
 
 TEST (EntityGeometryTest, SimpleTwoLineStrokeVerticesSquareCap)
 
 TEST (EntityGeometryTest, TwoLineSegmentsRightTurnStrokeVerticesBevelJoin)
 
 TEST (EntityGeometryTest, TwoLineSegmentsLeftTurnStrokeVerticesBevelJoin)
 
 TEST (EntityGeometryTest, TwoLineSegmentsRightTurnStrokeVerticesMiterJoin)
 
 TEST (EntityGeometryTest, TwoLineSegmentsLeftTurnStrokeVerticesMiterJoin)
 
 TEST (EntityGeometryTest, TinyQuadGeneratesCaps)
 
 TEST (EntityGeometryTest, TinyConicGeneratesCaps)
 
 TEST (EntityGeometryTest, TinyCubicGeneratesCaps)
 
 TEST (EntityGeometryTest, TwoLineSegmentsMiterLimit)
 
 TEST (EntityGeometryTest, TwoLineSegments180DegreeJoins)
 
 TEST (EntityGeometryTest, TightQuadratic180DegreeJoins)
 
 TEST (EntityGeometryTest, TightConic180DegreeJoins)
 
 TEST (EntityGeometryTest, TightCubic180DegreeJoins)
 
 TEST (EntityGeometryTest, RotatedFilledCircleGeometryCoverage)
 
 TEST (EntityGeometryTest, RotatedStrokedCircleGeometryCoverage)
 
 TEST_P (RenderTargetCacheTest, CachesUsedTexturesAcrossFrames)
 
 TEST_P (RenderTargetCacheTest, CachesUsedTexturesAcrossFramesWithKeepAlive)
 
 TEST_P (RenderTargetCacheTest, DoesNotPersistFailedAllocations)
 
 TEST_P (RenderTargetCacheTest, CachedTextureGetsNewAttachmentConfig)
 
 TEST_P (RenderTargetCacheTest, CreateWithEmptySize)
 
 TEST (SaveLayerUtilsTest, SimplePaintComputedCoverage)
 
 TEST (SaveLayerUtilsTest, BackdropFiterComputedCoverage)
 
 TEST (SaveLayerUtilsTest, ImageFiterComputedCoverage)
 
 TEST (SaveLayerUtilsTest, ImageFiterSmallScaleComputedCoverageLargerThanBoundsLimit)
 
 TEST (SaveLayerUtilsTest, ImageFiterLargeScaleComputedCoverageLargerThanBoundsLimit)
 
 TEST (SaveLayerUtilsTest, DisjointCoverage)
 
 TEST (SaveLayerUtilsTest, DisjointCoverageTransformedByImageFilter)
 
 TEST (SaveLayerUtilsTest, DisjointCoveragTransformedByCTM)
 
 TEST (SaveLayerUtilsTest, BasicEmptyCoverage)
 
 TEST (SaveLayerUtilsTest, ImageFilterEmptyCoverage)
 
 TEST (SaveLayerUtilsTest, BackdropFilterEmptyCoverage)
 
 TEST (SaveLayerUtilsTest, FloodInputCoverage)
 
 TEST (SaveLayerUtilsTest, FloodInputCoverageWithImageFilter)
 
 TEST (SaveLayerUtilsTest, FloodInputCoverageWithImageFilterWithNoCoverageProducesNoCoverage)
 
 TEST (SaveLayerUtilsTest, CoverageLimitIgnoredIfIntersectedValueIsCloseToActualCoverageSmallerWithImageFilter)
 
 TEST (SaveLayerUtilsTest, CoverageLimitIgnoredIfIntersectedValueIsCloseToActualCoverageLargerWithImageFilter)
 
 TEST (SaveLayerUtilsTest, CoverageLimitRespectedIfSubstantiallyDifferentFromContentCoverage)
 
 TEST (SaveLayerUtilsTest, RoundUpCoverageWhenCloseToCoverageLimit)
 
 TEST (SaveLayerUtilsTest, DontRoundUpCoverageWhenNotCloseToCoverageLimitWidth)
 
 TEST (SaveLayerUtilsTest, DontRoundUpCoverageWhenNotCloseToCoverageLimitHeight)
 
 TEST (SaveLayerUtilsTest, DontRoundUpCoverageWhenNotCloseToCoverageLimitWidthHeight)
 
 TEST (ArcTest, ArcIterationsFullCircle)
 
 TEST (ArcTest, ArcIterationsVariousStartAnglesNearQuadrantAxis)
 
 TEST (ArcTest, ArcIterationsVariousEndAnglesNearQuadrantAxis)
 
 TEST (ArcTest, ArcIterationsVariousTinyArcsNearQuadrantAxis)
 
 TEST (ArcTest, ArcIterationsOnlyFirstQuadrant)
 
 TEST (ArcTest, ArcIterationsOnlySecondQuadrant)
 
 TEST (ArcTest, ArcIterationsOnlyThirdQuadrant)
 
 TEST (ArcTest, ArcIterationsOnlyFourthQuadrant)
 
 TEST (ArcTest, ArcIterationsAllQuadrantsFromFirst)
 
 TEST (ArcTest, ArcIterationsAllQuadrantsFromSecond)
 
 TEST (ArcTest, ArcIterationsAllQuadrantsFromThird)
 
 TEST (ArcTest, ArcIterationsAllQuadrantsFromFourth)
 
 TEST (GeometryTest, ScalarNearlyEqual)
 
 TEST (GeometryTest, MakeColumn)
 
 TEST (GeometryTest, MakeRow)
 
 TEST (GeometryTest, RotationMatrix)
 
 TEST (GeometryTest, InvertMultMatrix)
 
 TEST (GeometryTest, MatrixBasis)
 
 TEST (GeometryTest, MutliplicationMatrix)
 
 TEST (GeometryTest, DeterminantTest)
 
 TEST (GeometryTest, InvertMatrix)
 
 TEST (GeometryTest, TestDecomposition)
 
 TEST (GeometryTest, TestDecomposition2)
 
 TEST (GeometryTest, TestRecomposition)
 
 TEST (GeometryTest, TestRecomposition2)
 
 TEST (GeometryTest, MatrixVectorMultiplication)
 
 TEST (GeometryTest, MatrixMakeRotationFromQuaternion)
 
 TEST (GeometryTest, MatrixTransformDirection)
 
 TEST (GeometryTest, MatrixGetMaxBasisLengthXY)
 
 TEST (GeometryTest, MatrixMakeOrthographic)
 
 TEST (GeometryTest, MatrixMakePerspective)
 
 TEST (GeometryTest, MatrixGetBasisVectors)
 
 TEST (GeometryTest, MatrixGetDirectionScale)
 
 TEST (GeometryTest, MatrixTranslationScaleOnly)
 
 TEST (GeometryTest, MatrixLookAt)
 
 TEST (GeometryTest, QuaternionLerp)
 
 TEST (GeometryTest, QuaternionVectorMultiply)
 
 TEST (GeometryTest, CanGenerateMipCounts)
 
 TEST (GeometryTest, CanConvertTTypesExplicitly)
 
 TEST (GeometryTest, CanPerformAlgebraicPointOps)
 
 TEST (GeometryTest, CanPerformAlgebraicPointOpsWithArithmeticTypes)
 
 TEST (GeometryTest, PointIntegerCoercesToFloat)
 
 TEST (GeometryTest, SizeCoercesToPoint)
 
 TEST (GeometryTest, CanUsePointAssignmentOperators)
 
 TEST (GeometryTest, PointDotProduct)
 
 TEST (GeometryTest, PointCrossProduct)
 
 TEST (GeometryTest, PointReflect)
 
 TEST (GeometryTest, PointAbs)
 
 TEST (GeometryTest, PointRotate)
 
 TEST (GeometryTest, PointAngleTo)
 
 TEST (GeometryTest, PointMin)
 
 TEST (GeometryTest, Vector4IsFinite)
 
 TEST (GeometryTest, Vector3Min)
 
 TEST (GeometryTest, Vector4Min)
 
 TEST (GeometryTest, PointMax)
 
 TEST (GeometryTest, Vector3Max)
 
 TEST (GeometryTest, Vector4Max)
 
 TEST (GeometryTest, PointFloor)
 
 TEST (GeometryTest, Vector3Floor)
 
 TEST (GeometryTest, Vector4Floor)
 
 TEST (GeometryTest, PointCeil)
 
 TEST (GeometryTest, Vector3Ceil)
 
 TEST (GeometryTest, Vector4Ceil)
 
 TEST (GeometryTest, PointRound)
 
 TEST (GeometryTest, Vector3Round)
 
 TEST (GeometryTest, Vector4Round)
 
 TEST (GeometryTest, PointLerp)
 
 TEST (GeometryTest, Vector3Lerp)
 
 TEST (GeometryTest, Vector4Lerp)
 
 TEST (GeometryTest, SeparatedVector2NormalizesWithConstructor)
 
 TEST (GeometryTest, SeparatedVector2GetVector)
 
 TEST (GeometryTest, SeparatedVector2GetAlignment)
 
 TEST (GeometryTest, SeparatedVector2AngleTo)
 
 TEST (GeometryTest, CanUseVector3AssignmentOperators)
 
 TEST (GeometryTest, CanPerformAlgebraicVector3Ops)
 
 TEST (GeometryTest, CanPerformAlgebraicVector3OpsWithArithmeticTypes)
 
 TEST (GeometryTest, ColorPremultiply)
 
 TEST (GeometryTest, ColorR8G8B8A8)
 
 TEST (GeometryTest, ColorLerp)
 
 TEST (GeometryTest, ColorClamp01)
 
 TEST (GeometryTest, ColorMakeRGBA8)
 
 TEST (GeometryTest, ColorApplyColorMatrix)
 
 TEST (GeometryTest, ColorLinearToSRGB)
 
 TEST (GeometryTest, ColorSRGBToLinear)
 
 TEST (GeometryTest, ColorBlendReturnsExpectedResults)
 
 TEST (GeometryTest, BlendModeToString)
 
 TEST (GeometryTest, CanConvertBetweenDegressAndRadians)
 
 TEST (GeometryTest, MatrixPrinting)
 
 TEST (GeometryTest, PointPrinting)
 
 TEST (GeometryTest, Vector3Printing)
 
 TEST (GeometryTest, Vector4Printing)
 
 TEST (GeometryTest, ColorPrinting)
 
 TEST (GeometryTest, ToIColor)
 
 TEST (GeometryTest, Gradient)
 
 TEST (GeometryTest, HalfConversions)
 
 TEST (MatrixTest, Multiply)
 
 TEST (MatrixTest, Equals)
 
 TEST (MatrixTest, NotEquals)
 
 TEST (MatrixTest, HasPerspective2D)
 
 TEST (MatrixTest, HasPerspective)
 
 TEST (MatrixTest, HasTranslation)
 
 TEST (MatrixTest, IsTranslationOnly)
 
 TEST (MatrixTest, IsTranslationScaleOnly)
 
 TEST (MatrixTest, IsInvertibleGetDeterminant)
 
 TEST (MatrixTest, IsFinite)
 
 TEST (MatrixTest, IsAligned2D)
 
 TEST (MatrixTest, IsAligned)
 
 TEST (MatrixTest, TransformHomogenous)
 
 TEST (MatrixTest, GetMaxBasisXYNegativeScale)
 
 TEST (MatrixTest, GetMaxBasisXYWithLargeAndSmallScalingFactor)
 
 TEST (MatrixTest, GetMaxBasisXYWithLargeAndSmallScalingFactorNonScaleTranslate)
 
 TEST (MatrixTest, TranslateWithPerspective)
 
 TEST (MatrixTest, MakeScaleTranslate)
 
 TEST (MatrixTest, To3x3)
 
 TEST (MatrixTest, MinMaxScales2D)
 
 TEST (PathSourceTest, RectSourceTest)
 
 TEST (PathSourceTest, EllipseSourceTest)
 
 TEST (PathSourceTest, RoundRectSourceTest)
 
 TEST (PathSourceTest, DiffRoundRectSourceTest)
 
 TEST (PathSourceTest, DashedLinePathSource)
 
 TEST (PathSourceTest, EmptyDashedLinePathSource)
 
 TEST (PathSourceTest, DashedLinePathSourceZeroOffGaps)
 
 TEST (PathSourceTest, DashedLinePathSourceInvalidOffGaps)
 
 TEST (PathSourceTest, DashedLinePathSourceInvalidOnRegion)
 
 TEST (RectTest, RectEmptyDeclaration)
 
 TEST (RectTest, IRectEmptyDeclaration)
 
 TEST (RectTest, RectDefaultConstructor)
 
 TEST (RectTest, IRectDefaultConstructor)
 
 TEST (RectTest, RectSimpleLTRB)
 
 TEST (RectTest, IRectSimpleLTRB)
 
 TEST (RectTest, RectSimpleXYWH)
 
 TEST (RectTest, IRectSimpleXYWH)
 
 TEST (RectTest, RectSimpleWH)
 
 TEST (RectTest, IRectSimpleWH)
 
 TEST (RectTest, RectFromIRect)
 
 TEST (RectTest, RectOverflowXYWH)
 
 TEST (RectTest, IRectOverflowXYWH)
 
 TEST (RectTest, RectOverflowLTRB)
 
 TEST (RectTest, IRectOverflowLTRB)
 
 TEST (RectTest, RectMakeSize)
 
 TEST (RectTest, RectMakeMaximum)
 
 TEST (RectTest, IRectMakeMaximum)
 
 TEST (RectTest, RectFromRect)
 
 TEST (RectTest, IRectFromIRect)
 
 TEST (RectTest, RectCopy)
 
 TEST (RectTest, IRectCopy)
 
 TEST (RectTest, RectOriginSizeXYWHGetters)
 
 TEST (RectTest, IRectOriginSizeXYWHGetters)
 
 TEST (RectTest, RectRoundOutEmpty)
 
 TEST (RectTest, RectRoundOutSimple)
 
 TEST (RectTest, RectRoundOutToIRectHuge)
 
 TEST (RectTest, RectDoesNotIntersectEmpty)
 
 TEST (RectTest, IRectDoesNotIntersectEmpty)
 
 TEST (RectTest, EmptyRectDoesNotIntersect)
 
 TEST (RectTest, EmptyIRectDoesNotIntersect)
 
 TEST (RectTest, RectScale)
 
 TEST (RectTest, IRectScale)
 
 TEST (RectTest, RectArea)
 
 TEST (RectTest, IRectArea)
 
 TEST (RectTest, RectGetNormalizingTransform)
 
 TEST (RectTest, IRectGetNormalizingTransform)
 
 TEST (RectTest, RectXYWHIsEmpty)
 
 TEST (RectTest, IRectXYWHIsEmpty)
 
 TEST (RectTest, MakePointBoundsQuad)
 
 TEST (RectTest, IsSquare)
 
 TEST (RectTest, GetCenter)
 
 TEST (RectTest, RectExpand)
 
 TEST (RectTest, IRectExpand)
 
 TEST (RectTest, ContainsFloatingPoint)
 
template<typename R >
static constexpr R flip_lr (R rect)
 
template<typename R >
static constexpr R flip_tb (R rect)
 
template<typename R >
static constexpr R flip_lrtb (R rect)
 
static constexpr Rect swap_nan (const Rect &rect, int index)
 
static constexpr Point swap_nan (const Point &point, int index)
 
 TEST (RectTest, RectUnion)
 
 TEST (RectTest, OptRectUnion)
 
 TEST (RectTest, IRectUnion)
 
 TEST (RectTest, OptIRectUnion)
 
 TEST (RectTest, RectIntersection)
 
 TEST (RectTest, OptRectIntersection)
 
 TEST (RectTest, IRectIntersection)
 
 TEST (RectTest, OptIRectIntersection)
 
 TEST (RectTest, RectIntersectsWithRect)
 
 TEST (RectTest, IRectIntersectsWithRect)
 
 TEST (RectTest, RectContainsPoint)
 
 TEST (RectTest, IRectContainsIPoint)
 
 TEST (RectTest, RectContainsInclusivePoint)
 
 TEST (RectTest, IRectContainsInclusiveIPoint)
 
 TEST (RectTest, RectContainsRect)
 
 TEST (RectTest, IRectContainsIRect)
 
 TEST (RectTest, RectCutOut)
 
 TEST (RectTest, IRectCutOut)
 
 TEST (RectTest, RectGetPoints)
 
 TEST (RectTest, RectShift)
 
 TEST (RectTest, RectGetTransformedPoints)
 
 TEST (RectTest, RectMakePointBounds)
 
 TEST (RectTest, RectGetPositive)
 
 TEST (RectTest, RectDirections)
 
 TEST (RectTest, RectProject)
 
 TEST (RectTest, RectRoundOut)
 
 TEST (RectTest, IRectRoundOut)
 
 TEST (RectTest, RectRound)
 
 TEST (RectTest, IRectRound)
 
 TEST (RectTest, TransformAndClipBounds)
 
 TEST (RoundRectTest, EmptyDeclaration)
 
 TEST (RoundRectTest, DefaultConstructor)
 
 TEST (RoundRectTest, EmptyRectConstruction)
 
 TEST (RoundRectTest, RectConstructor)
 
 TEST (RoundRectTest, InvertedRectConstruction)
 
 TEST (RoundRectTest, EmptyOvalConstruction)
 
 TEST (RoundRectTest, OvalConstructor)
 
 TEST (RoundRectTest, InvertedOvalConstruction)
 
 TEST (RoundRectTest, RectRadiusConstructor)
 
 TEST (RoundRectTest, RectXYConstructor)
 
 TEST (RoundRectTest, RectSizeConstructor)
 
 TEST (RoundRectTest, RectRadiiConstructor)
 
 TEST (RoundRectTest, RectRadiiOverflowWidthConstructor)
 
 TEST (RoundRectTest, RectRadiiOverflowHeightConstructor)
 
 TEST (RoundRectTest, Shift)
 
 TEST (RoundRectTest, ExpandScalar)
 
 TEST (RoundRectTest, ExpandTwoScalars)
 
 TEST (RoundRectTest, ExpandFourScalars)
 
 TEST (RoundRectTest, ContractScalar)
 
 TEST (RoundRectTest, ContractTwoScalars)
 
 TEST (RoundRectTest, ContractFourScalars)
 
 TEST (RoundRectTest, ContractAndRequireRadiiAdjustment)
 
 TEST (RoundRectTest, NoCornerRoundRectContains)
 
 TEST (RoundRectTest, TinyCornerRoundRectContains)
 
 TEST (RoundRectTest, UniformCircularRoundRectContains)
 
 TEST (RoundRectTest, UniformEllipticalRoundRectContains)
 
 TEST (RoundRectTest, DifferingCornersRoundRectContains)
 
 TEST (RoundSuperellipseTest, EmptyDeclaration)
 
 TEST (RoundSuperellipseTest, DefaultConstructor)
 
 TEST (RoundSuperellipseTest, EmptyRectConstruction)
 
 TEST (RoundSuperellipseTest, RectConstructor)
 
 TEST (RoundSuperellipseTest, InvertedRectConstruction)
 
 TEST (RoundSuperellipseTest, EmptyOvalConstruction)
 
 TEST (RoundSuperellipseTest, OvalConstructor)
 
 TEST (RoundSuperellipseTest, InvertedOvalConstruction)
 
 TEST (RoundSuperellipseTest, RectRadiusConstructor)
 
 TEST (RoundSuperellipseTest, RectXYConstructor)
 
 TEST (RoundSuperellipseTest, RectSizeConstructor)
 
 TEST (RoundSuperellipseTest, RectRadiiConstructor)
 
 TEST (RoundSuperellipseTest, RectRadiiOverflowWidthConstructor)
 
 TEST (RoundSuperellipseTest, RectRadiiOverflowHeightConstructor)
 
 TEST (RoundSuperellipseTest, Shift)
 
 TEST (RoundSuperellipseTest, ExpandScalar)
 
 TEST (RoundSuperellipseTest, ExpandTwoScalars)
 
 TEST (RoundSuperellipseTest, ExpandFourScalars)
 
 TEST (RoundSuperellipseTest, ContractScalar)
 
 TEST (RoundSuperellipseTest, ContractTwoScalars)
 
 TEST (RoundSuperellipseTest, ContractFourScalars)
 
 TEST (RoundSuperellipseTest, ContractAndRequireRadiiAdjustment)
 
 TEST (RoundSuperellipseTest, NoCornerRoundSuperellipseContains)
 
 TEST (RoundSuperellipseTest, TinyCornerContains)
 
 TEST (RoundSuperellipseTest, UniformSquareContains)
 
 TEST (RoundSuperellipseTest, UniformEllipticalContains)
 
 TEST (RoundSuperellipseTest, UniformRectangularContains)
 
 TEST (RoundSuperellipseTest, SlimDiagonalContains)
 
 TEST (RoundSuperellipseTest, PointsOutsideOfSharpCorner)
 
 TEST (RoundSuperellipseTest, PathForRectangularRseWithShapeCornersShouldBeWithinBounds)
 
 TEST (RoudingRadiiTest, RoundingRadiiEmptyDeclaration)
 
 TEST (RoudingRadiiTest, RoundingRadiiDefaultConstructor)
 
 TEST (RoudingRadiiTest, RoundingRadiiScalarConstructor)
 
 TEST (RoudingRadiiTest, RoundingRadiiEmptyScalarConstructor)
 
 TEST (RoudingRadiiTest, RoundingRadiiSizeConstructor)
 
 TEST (RoudingRadiiTest, RoundingRadiiEmptySizeConstructor)
 
 TEST (RoudingRadiiTest, RoundingRadiiNamedSizesConstructor)
 
 TEST (RoudingRadiiTest, RoundingRadiiPartialNamedSizesConstructor)
 
 TEST (RoudingRadiiTest, RoundingRadiiMultiply)
 
 TEST (RoudingRadiiTest, RoundingRadiiEquals)
 
 TEST (RoudingRadiiTest, RoundingRadiiNotEquals)
 
 TEST (RoudingRadiiTest, RoundingRadiiCornersSameTolerance)
 
 TEST (RSTransformTest, Construction)
 
 TEST (RSTransformTest, CompareToMatrix)
 
 TEST (SaturatedMath, ExplicitAddOfSignedInts)
 
 TEST (SaturatedMath, ImplicitAddOfSignedInts)
 
 TEST (SaturatedMath, ExplicitAddOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitAddOfFloatingPoint)
 
 TEST (SaturatedMath, ExplicitSubOfSignedInts)
 
 TEST (SaturatedMath, ImplicitSubOfSignedInts)
 
 TEST (SaturatedMath, ExplicitSubOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitSubOfFloatingPoint)
 
 TEST (SaturatedMath, ExplicitAverageScalarOfSignedInts)
 
 TEST (SaturatedMath, ImplicitAverageScalarOfSignedInts)
 
 TEST (SaturatedMath, ExplicitAverageScalarOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitAverageScalarOfFloatingPoint)
 
 TEST (SaturatedMath, CastingFiniteDoubleToFloatStaysFinite)
 
 TEST (SaturatedMath, CastingInfiniteDoubleToFloatStaysInfinite)
 
 TEST (SaturatedMath, CastingNaNDoubleToFloatStaysNaN)
 
 TEST (SaturatedMath, CastingLargeScalarToSignedIntProducesLimit)
 
 TEST (SaturatedMath, CastingInfiniteScalarToSignedIntProducesLimit)
 
 TEST (SaturatedMath, CastingNaNScalarToSignedIntProducesZero)
 
 TEST (SizeTest, SizeIsEmpty)
 
 TEST (SizeTest, ISizeIsEmpty)
 
 TEST (SizeTest, IsSquare)
 
 TEST (SizeTest, MaxDimension)
 
 TEST (SizeTest, NegationOperator)
 
 TEST (TrigTest, TrigAngles)
 
 TEST (TrigTest, MultiplyByScalarRadius)
 
 TEST_F (GoldenTests, ConicalGradient)
 
 TEST (BlitCommandGLESTest, BlitCopyTextureToBufferCommandGLESBindsFramebuffer)
 
 FML_TEST_CLASS (BufferBindingsGLESTest, BindUniformData)
 
 FML_TEST_CLASS (BufferBindingsGLESTest, BindArrayData)
 
 TEST (BufferBindingsGLESTest, BindUniformData)
 
 TEST (BufferBindingsGLESTest, BindArrayData)
 
 TEST (DeviceBufferGLESTest, BindUniformData)
 
 TEST (UniqueHandleGLES, MakeUntracked)
 
 INSTANTIATE_METAL_PLAYGROUND_SUITE (AllocatorMTLTest)
 
 TEST_P (AllocatorMTLTest, DebugTraceMemoryStatistics)
 
 TEST_P (AllocatorMTLTest, ManagedMemory)
 
 TEST_P (ContextMTLTest, FlushTask)
 
 TEST_P (ContextMTLTest, FlushTaskWithGPULoss)
 
 TEST_P (SwapchainTransientsMTLTest, CanAllocateSwapchainTextures)
 
 TEST (AllocatorVKTest, ToVKImageUsageFlags)
 
 TEST (AllocatorVKTest, MemoryTypeSelectionSingleHeap)
 
 TEST (AllocatorVKTest, MemoryTypeSelectionTwoHeap)
 
 TEST (AllocatorVKTest, ImageResourceKeepsVulkanDeviceAlive)
 
 TEST (CommandEncoderVKTest, DeleteEncoderAfterThreadDies)
 
 TEST (CommandEncoderVKTest, CleanupAfterSubmit)
 
 TEST (CommandPoolRecyclerVKTest, GetsACommandPoolPerThread)
 
 TEST (CommandPoolRecyclerVKTest, GetsTheSameCommandPoolOnSameThread)
 
 TEST (CommandPoolRecyclerVKTest, ReclaimMakesCommandPoolAvailable)
 
 TEST (CommandPoolRecyclerVKTest, CommandBuffersAreRecycled)
 
 TEST (CommandPoolRecyclerVKTest, ExtraCommandBufferAllocationsTriggerTrim)
 
 TEST (CommandPoolRecyclerVKTest, RecyclerGlobalPoolMapSize)
 
 TEST (ContextVKTest, CommonHardwareConcurrencyConfigurations)
 
 TEST (ContextVKTest, DeletesCommandPools)
 
 TEST (ContextVKTest, DeletesCommandPoolsOnAllThreads)
 
 TEST (ContextVKTest, ThreadLocalCleanupDeletesCommandPool)
 
 TEST (ContextVKTest, DeletePipelineAfterContext)
 
 TEST (ContextVKTest, DeleteShaderFunctionAfterContext)
 
 TEST (ContextVKTest, DeletePipelineLibraryAfterContext)
 
 TEST (ContextVKTest, CanCreateContextInAbsenceOfValidationLayers)
 
 TEST (ContextVKTest, CanCreateContextWithValidationLayers)
 
 TEST (CapabilitiesVKTest, ContextInitializesWithNoStencilFormat)
 
 TEST (CapabilitiesVKTest, ContextFailsInitializationForNoCombinedDepthStencilFormat)
 
 TEST (ContextVKTest, WarmUpFunctionCreatesRenderPass)
 
 TEST (ContextVKTest, FatalMissingValidations)
 
 TEST (ContextVKTest, HasDefaultColorFormat)
 
 TEST (ContextVKTest, EmbedderOverridesUsesInstanceExtensions)
 
 TEST (ContextVKTest, EmbedderOverrides)
 
 TEST (ContextVKTest, BatchSubmitCommandBuffersOnArm)
 
 TEST (ContextVKTest, BatchSubmitCommandBuffersOnNonArm)
 
 TEST (ContextVKTest, AHBSwapchainCapabilitiesCanBeMissing)
 
 TEST (ContextVKTest, HashIsUniqueAcrossThreads)
 
 TEST (DescriptorPoolRecyclerVKTest, GetDescriptorPoolRecyclerCreatesNewPools)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimMakesDescriptorPoolAvailable)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimDropsDescriptorPoolIfSizeIsExceeded)
 
 TEST (DescriptorPoolRecyclerVKTest, MultipleCommandBuffersShareDescriptorPool)
 
 TEST (DescriptorPoolRecyclerVKTest, DescriptorsAreRecycled)
 
 INSTANTIATE_VULKAN_PLAYGROUND_SUITE (DriverInfoVKTest)
 
 TEST_P (DriverInfoVKTest, CanQueryDriverInfo)
 
 TEST_P (DriverInfoVKTest, CanDumpToLog)
 
 TEST (DriverInfoVKTest, CanIdentifyBadMaleoonDriver)
 
bool IsBadVersionTest (std::string_view driver_name, bool qc=true)
 
bool CanBatchSubmitTest (std::string_view driver_name, bool qc=true)
 
 TEST (DriverInfoVKTest, CanBatchSubmitCommandBuffers)
 
bool CanUsePrimitiveRestartSubmitTest (std::string_view driver_name, bool qc=true)
 
 TEST (DriverInfoVKTest, CanUsePrimitiveRestart)
 
bool CanUseMipgeneration (std::string_view driver_name, bool qc=true)
 
 TEST (DriverInfoVKTest, CanGenerateMipMaps)
 
 TEST (DriverInfoVKTest, DriverParsingMali)
 
 TEST (DriverInfoVKTest, DriverParsingAdreno)
 
 TEST (DriverInfoVKTest, DisabledDevices)
 
 TEST (DriverInfoVKTest, EnabledDevicesMali)
 
 TEST (DriverInfoVKTest, EnabledDevicesAdreno)
 
bool CanUseFramebufferFetch (std::string_view driver_name, bool qc=true)
 
 TEST (DriverInfoVKTest, CanUseFramebufferFetch)
 
 TEST (DriverInfoVKTest, DisableOldXclipseDriver)
 
 TEST (DriverInfoVKTest, OldPowerVRDisabled)
 
 TEST (DriverInfoVKTest, NewPowerVREnabled)
 
 TEST (DriverInfoVKTest, PowerVRBSeries)
 
 TEST (FenceWaiterVKTest, IgnoresNullFence)
 
 TEST (FenceWaiterVKTest, IgnoresNullCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallbackX2)
 
 TEST (FenceWaiterVKTest, ExecutesNewFenceThenOldFence)
 
 TEST (FenceWaiterVKTest, AddFenceDoesNothingIfTerminating)
 
 TEST (FenceWaiterVKTest, InProgressFencesStillWaitIfTerminated)
 
 TEST (FormatsVKTest, DescriptorMapping)
 
 TEST (PipelineCacheDataVKTest, CanTestHeaderCompatibility)
 
 TEST (PipelineCacheDataVKTest, CanCreateFromDeviceProperties)
 
 TEST (PipelineCacheDataVKTest, WritesIncompleteCacheData)
 
 TEST_P (PipelineCacheDataVKPlaygroundTest, CanPersistAndRetrievePipelineCache)
 
 TEST_P (PipelineCacheDataVKPlaygroundTest, IntegrityChecksArePerformedOnPersistedData)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithNoDepthStencil)
 
 TEST (RenderPassBuilder, RenderPassWithLoadOpUsesCurrentLayout)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithCombinedDepthStencil)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithOnlyStencil)
 
 TEST (RenderPassBuilder, CreatesMSAAResolveWithCorrectStore)
 
 TEST_P (RendererTest, CachesRenderPassAndFramebuffer)
 
 TEST_P (RendererTest, CachesRenderPassAndFramebufferNonMSAA)
 
 TEST_P (RendererTest, CachesRenderPassAndFramebufferMixed)
 
 TEST (RenderPassVK, DoesNotRedundantlySetStencil)
 
 TEST (ResourceManagerVKTest, CreatesANewInstance)
 
 TEST (ResourceManagerVKTest, ReclaimMovesAResourceAndDestroysIt)
 
 TEST (ResourceManagerVKTest, TerminatesWhenOutOfScope)
 
 TEST (ResourceManagerVKTest, IsThreadSafe)
 
 TEST (SurfaceContextVK, TearsDownSwapchain)
 
 TEST_P (BlitPassTest, BlitAcrossDifferentPixelFormatsFails)
 
 TEST_P (BlitPassTest, BlitAcrossDifferentSampleCountsFails)
 
 TEST_P (BlitPassTest, BlitPassesForMatchingFormats)
 
 TEST_P (BlitPassTest, ChecksInvalidSliceParameters)
 
 TEST_P (BlitPassTest, CanBlitSmallRegionToUninitializedTexture)
 
 TEST_P (BlitPassTest, ChecksInvalidMipLevelParameter)
 
 TEST_P (BlitPassTest, CanBlitToHigherTextureMipLevels)
 
 TEST_P (BlitPassTest, CanResizeTextures)
 
 TEST_P (BlitPassTest, CanResizeTexturesPlayground)
 
 CAPABILITY_TEST (SupportsOffscreenMSAA, false)
 
 CAPABILITY_TEST (SupportsSSBO, false)
 
 CAPABILITY_TEST (SupportsTextureToTextureBlits, false)
 
 CAPABILITY_TEST (SupportsFramebufferFetch, false)
 
 CAPABILITY_TEST (SupportsCompute, false)
 
 CAPABILITY_TEST (SupportsComputeSubgroups, false)
 
 CAPABILITY_TEST (SupportsReadFromResolve, false)
 
 CAPABILITY_TEST (SupportsDecalSamplerAddressMode, false)
 
 CAPABILITY_TEST (SupportsDeviceTransientTextures, false)
 
 CAPABILITY_TEST (SupportsTriangleFan, false)
 
 CAPABILITY_TEST (SupportsExtendedRangeFormats, false)
 
 CAPABILITY_TEST (NeedsPartitionedHostBuffer, false)
 
 TEST (CapabilitiesTest, DefaultColorFormat)
 
 TEST (CapabilitiesTest, DefaultStencilFormat)
 
 TEST (CapabilitiesTest, DefaultDepthStencilFormat)
 
 TEST (CapabilitiesTest, DefaultGlyphAtlasFormat)
 
 TEST (CapabilitiesTest, MaxRenderPassAttachmentSize)
 
 TEST (CapabilitiesTest, MinUniformAlignment)
 
 INSTANTIATE_COMPUTE_SUITE (ComputeTest)
 
 TEST_P (ComputeTest, CapabilitiesReportSupport)
 
 TEST_P (ComputeTest, CanCreateComputePass)
 
 TEST_P (ComputeTest, CanComputePrefixSum)
 
 TEST_P (ComputeTest, 1DThreadgroupSizingIsCorrect)
 
 TEST_P (ComputeTest, CanComputePrefixSumLargeInteractive)
 
 TEST_P (ComputeTest, MultiStageInputAndOutput)
 
 TEST_P (ComputeTest, CanCompute1DimensionalData)
 
 TEST_P (ComputeTest, ReturnsEarlyWhenAnyGridDimensionIsZero)
 
 TEST (PipelineDescriptorTest, PrimitiveTypeHashEquality)
 
 TEST (PoolTest, Simple)
 
 TEST (PoolTest, Overload)
 
static void InstantiateTestShaderLibrary (Context::BackendType backend_type)
 
 INSTANTIATE_PLAYGROUND_SUITE (RendererDartTest)
 
 TEST_P (RendererDartTest, CanRunDartInPlaygroundFrame)
 
 TEST_P (RendererDartTest, CanInstantiateFlutterGPUContext)
 
 TEST_P (RendererDartTest, CanCreateShaderLibrary)
 
 TEST_P (RendererDartTest, CanReflectUniformStructs)
 
 TEST_P (RendererDartTest, CanCreateRenderPassAndSubmit)
 
 TEST_P (RendererTest, CanCreateBoxPrimitive)
 
 TEST_P (RendererTest, BabysFirstTriangle)
 
 TEST_P (RendererTest, CanRenderPerspectiveCube)
 
 TEST_P (RendererTest, CanRenderMultiplePrimitives)
 
 TEST_P (RendererTest, CanRenderToTexture)
 
 TEST_P (RendererTest, CanRenderInstanced)
 
 TEST_P (RendererTest, CanBlitTextureToTexture)
 
 TEST_P (RendererTest, CanBlitTextureToBuffer)
 
 TEST_P (RendererTest, CanGenerateMipmaps)
 
 TEST_P (RendererTest, TheImpeller)
 
 TEST_P (RendererTest, Planet)
 
 TEST_P (RendererTest, ArrayUniforms)
 
 TEST_P (RendererTest, InactiveUniforms)
 
 TEST_P (RendererTest, DefaultIndexSize)
 
 TEST_P (RendererTest, DefaultIndexBehavior)
 
 TEST_P (RendererTest, VertexBufferBuilder)
 
static const CompareFunctionUIDataCompareFunctionUI ()
 
 TEST_P (RendererTest, StencilMask)
 
 TEST_P (RendererTest, CanLookupRenderTargetProperties)
 
 TEST_P (RendererTest, RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat)
 
template<class VertexShader , class FragmentShader >
std::shared_ptr< Pipeline< PipelineDescriptor > > CreateDefaultPipeline (const std::shared_ptr< Context > &context)
 
 TEST_P (RendererTest, CanSepiaToneWithSubpasses)
 
 TEST_P (RendererTest, CanSepiaToneThenSwizzleWithSubpasses)
 
 TEST_P (RendererTest, BindingNullTexturesDoesNotCrash)
 
 INSTANTIATE_PLAYGROUND_SUITE (RuntimeStageTest)
 
 TEST_P (RuntimeStageTest, CanReadValidBlob)
 
 TEST_P (RuntimeStageTest, CanRejectInvalidBlob)
 
 TEST_P (RuntimeStageTest, CanReadUniforms)
 
 TEST_P (RuntimeStageTest, CanReadUniformsSamplerBeforeUBO)
 
 TEST_P (RuntimeStageTest, CanReadUniformsSamplerAfterUBO)
 
 TEST_P (RuntimeStageTest, CanRegisterStage)
 
 TEST_P (RuntimeStageTest, CanCreatePipelineFromRuntimeStage)
 
 TEST_P (RuntimeStageTest, ContainsExpectedShaderTypes)
 
static std::shared_ptr< fml::Mapping > CreateMappingFromString (std::string p_string)
 
const std::string CreateStringFromMapping (const fml::Mapping &mapping)
 
 TEST (ShaderArchiveTest, CanReadAndWriteBlobs)
 
 TEST (PathTessellatorTest, EmptyPath)
 
 TEST (PathTessellatorTest, EmptyPathMultipleMoveTo)
 
 TEST (PathTessellatorTest, SimpleClosedPath)
 
 TEST (PathTessellatorTest, SimpleUnclosedPath)
 
 TEST (PathTessellatorTest, SimplePathTrailingMoveTo)
 
 TEST (PathTessellatorTest, DegenerateSegmentsPath)
 
 TEST (PathTessellatorTest, QuadToLineToOptimization)
 
 TEST (PathTessellatorTest, ConicToLineToOptimization)
 
 TEST (PathTessellatorTest, ConicToQuadToOptimization)
 
 TEST (PathTessellatorTest, SimplePathMultipleMoveTo)
 
 TEST (PathTessellatorTest, ComplexPath)
 
 TEST (PathTessellatorTest, ComplexPathTrailingMoveTo)
 
 TEST (PathTessellatorTest, LinearQuadToPointCount)
 
 TEST (PathTessellatorTest, LinearConicToPointCount)
 
 TEST (PathTessellatorTest, LinearCubicToPointCount)
 
 TEST (TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus)
 
 TEST (TessellatorTest, TessellateConvex)
 
 TEST (TessellatorTest, TessellateConvexUnclosedPath)
 
 TEST (TessellatorTest, CircleVertexCounts)
 
 TEST (TessellatorTest, FilledCircleTessellationVertices)
 
 TEST (TessellatorTest, StrokedCircleTessellationVertices)
 
 TEST (TessellatorTest, RoundCapLineTessellationVertices)
 
 TEST (TessellatorTest, FilledEllipseTessellationVertices)
 
 TEST (TessellatorTest, FilledRoundRectTessellationVertices)
 
 TEST (TessellatorTest, EarlyReturnEmptyConvexShape)
 
static std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, const TypographerContext *typographer_context, HostBuffer &data_host_buffer, GlyphAtlas::Type type, Rational scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::shared_ptr< TextFrame > &frame)
 
static std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, const TypographerContext *typographer_context, HostBuffer &data_host_buffer, GlyphAtlas::Type type, Rational scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::vector< std::shared_ptr< TextFrame >> &frames, const std::vector< std::optional< GlyphProperties >> &properties)
 
 TEST_P (TypographerTest, CanConvertTextBlob)
 
 TEST_P (TypographerTest, CanCreateRenderContext)
 
 TEST_P (TypographerTest, CanCreateGlyphAtlas)
 
 TEST_P (TypographerTest, LazyAtlasTracksColor)
 
 TEST_P (TypographerTest, GlyphAtlasWithOddUniqueGlyphSize)
 
 TEST_P (TypographerTest, GlyphAtlasIsRecycledIfUnchanged)
 
 TEST_P (TypographerTest, GlyphAtlasWithLotsOfdUniqueGlyphSize)
 
 TEST_P (TypographerTest, GlyphAtlasTextureIsRecycledIfUnchanged)
 
 TEST_P (TypographerTest, GlyphColorIsPartOfCacheKey)
 
 TEST_P (TypographerTest, GlyphColorIsIgnoredForNonEmojiFonts)
 
 TEST_P (TypographerTest, RectanglePackerAddsNonoverlapingRectangles)
 
 TEST (TypographerTest, RectanglePackerFillsRows)
 
 TEST_P (TypographerTest, GlyphAtlasTextureWillGrowTilMaxTextureSize)
 
 TEST_P (TypographerTest, TextFrameInitialBoundsArePlaceholder)
 
 TEST_P (TypographerTest, TextFrameInvalidationWithScale)
 
 TEST_P (TypographerTest, TextFrameAtlasGenerationTracksState)
 
 TEST_P (TypographerTest, InvalidAtlasForcesRepopulation)
 

Variables

static const std::map< std::string, MaskBlurTestConfigkPaintVariations
 
static constexpr std::string_view kFontFixture
 
static constexpr const size_t kMagicFailingAllocation = 1024000 * 2
 
std::vector< Pointgolden_cubic_and_quad_points
 

Typedef Documentation

◆ AiksTest

Definition at line 17 of file aiks_unittests.h.

◆ AllocatorMTLTest

◆ BlitPassTest

Definition at line 27 of file blit_pass_unittests.cc.

◆ ComputeTest

Definition at line 21 of file compute_unittests.cc.

◆ ContextMTLTest

Definition at line 25 of file context_mtl_unittests.mm.

◆ DeviceBufferTest

Definition at line 12 of file device_buffer_unittests.cc.

◆ DisplayListTest

Definition at line 44 of file dl_unittests.cc.

◆ DlPathReceiverMock

using impeller::testing::DlPathReceiverMock = typedef flutter::testing::DlPathReceiverMock

Definition at line 19 of file path_source_unittests.cc.

◆ DriverInfoVKTest

◆ EntityPassTargetTest

◆ EntityTest

◆ HostBufferTest

◆ PipelineCacheDataVKPlaygroundTest

◆ RendererTest

◆ RenderTargetCacheTest

◆ RuntimeStageTest

◆ SaveLayerUtilsTest

using impeller::testing::SaveLayerUtilsTest = typedef ::testing::Test

Definition at line 15 of file save_layer_utils_unittests.cc.

◆ SwapchainTransientsMTLTest

◆ TextContentsTest

◆ TypographerTest

Function Documentation

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [1/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Conical  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [2/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Linear  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [3/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Radial  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [4/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Sweep  )

◆ BlendModeTest()

static sk_sp<DisplayList> impeller::testing::BlendModeTest ( Vector2  content_scale,
BlendMode  blend_mode,
const sk_sp< DlImageImpeller > &  src_image,
const sk_sp< DlImageImpeller > &  dst_image,
Scalar  src_alpha 
)
static
  1. Save layer blending (top squares).
  2. CPU blend modes (bottom squares).
  3. Image blending (bottom images).

Compare these results with the images in the Flutter blend mode documentation: https://api.flutter.dev/flutter/dart-ui/BlendMode.html

Definition at line 500 of file aiks_dl_blend_unittests.cc.

504  {
505  if (AiksTest::ImGuiBegin("Controls", nullptr,
506  ImGuiWindowFlags_AlwaysAutoResize)) {
507  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
508  ImGui::End();
509  }
510 
511  Color destination_color = Color::CornflowerBlue().WithAlpha(0.75);
512  auto source_colors = std::vector<Color>({Color::White().WithAlpha(0.75),
513  Color::LimeGreen().WithAlpha(0.75),
514  Color::Black().WithAlpha(0.75)});
515 
516  DisplayListBuilder builder;
517  {
518  DlPaint paint;
519  paint.setColor(DlColor::kBlack());
520  builder.DrawPaint(paint);
521  }
522  // TODO(bdero): Why does this cause the left image to double scale on high DPI
523  // displays.
524  // builder.Scale(content_scale);
525 
526  //----------------------------------------------------------------------------
527  /// 1. Save layer blending (top squares).
528  ///
529 
530  builder.Save();
531  for (const auto& color : source_colors) {
532  builder.Save();
533  {
534  builder.ClipRect(DlRect::MakeXYWH(25, 25, 100, 100));
535  // Perform the blend in a SaveLayer so that the initial backdrop color is
536  // fully transparent black. SourceOver blend the result onto the parent
537  // pass.
538  builder.SaveLayer(std::nullopt);
539  {
540  DlPaint draw_paint;
541  draw_paint.setColor(
542  DlColor::RGBA(destination_color.red, destination_color.green,
543  destination_color.blue, destination_color.alpha));
544  builder.DrawPaint(draw_paint);
545 
546  // Draw the source color in an offscreen pass and blend it to the parent
547  // pass.
548  DlPaint save_paint;
549  save_paint.setBlendMode(static_cast<DlBlendMode>(blend_mode));
550  builder.SaveLayer(std::nullopt, &save_paint);
551  { //
552  DlPaint paint;
553  paint.setColor(
554  DlColor::RGBA(color.red, color.green, color.blue, color.alpha));
555  builder.DrawRect(DlRect::MakeXYWH(25, 25, 100, 100), paint);
556  }
557  builder.Restore();
558  }
559  builder.Restore();
560  }
561  builder.Restore();
562  builder.Translate(100, 0);
563  }
564  builder.RestoreToCount(0);
565 
566  //----------------------------------------------------------------------------
567  /// 2. CPU blend modes (bottom squares).
568  ///
569 
570  builder.Save();
571  builder.Translate(0, 100);
572  // Perform the blend in a SaveLayer so that the initial backdrop color is
573  // fully transparent black. SourceOver blend the result onto the parent pass.
574  builder.SaveLayer(std::nullopt);
575  for (const auto& color : source_colors) {
576  // Simply write the CPU blended color to the pass.
577  DlPaint paint;
578  auto dest = destination_color.Blend(color, blend_mode);
579  paint.setColor(DlColor::RGBA(dest.red, dest.green, dest.blue, dest.alpha));
580  paint.setBlendMode(DlBlendMode::kSrcOver);
581  builder.DrawRect(DlRect::MakeXYWH(25, 25, 100, 100), paint);
582  builder.Translate(100, 0);
583  }
584  builder.Restore();
585  builder.Restore();
586 
587  //----------------------------------------------------------------------------
588  /// 3. Image blending (bottom images).
589  ///
590  /// Compare these results with the images in the Flutter blend mode
591  /// documentation: https://api.flutter.dev/flutter/dart-ui/BlendMode.html
592  ///
593 
594  builder.Translate(0, 250);
595 
596  // Draw grid behind the images.
597  {
598  DlPaint paint;
599  paint.setColor(DlColor::RGBA(41 / 255.0, 41 / 255.0, 41 / 255.0, 1));
600  builder.DrawRect(DlRect::MakeLTRB(0, 0, 800, 400), paint);
601  }
602 
603  DlPaint square_paint;
604  square_paint.setColor(DlColor::RGBA(15 / 255.0, 15 / 255.0, 15 / 255.0, 1));
605  for (int y = 0; y < 400 / 8; y++) {
606  for (int x = 0; x < 800 / 16; x++) {
607  builder.DrawRect(DlRect::MakeXYWH(x * 16 + (y % 2) * 8, y * 8, 8, 8),
608  square_paint);
609  }
610  }
611 
612  // Uploaded image source (left image).
613  DlPaint paint;
614  paint.setBlendMode(DlBlendMode::kSrcOver);
615  builder.Save();
616  builder.SaveLayer(std::nullopt, &paint);
617  {
618  builder.DrawImage(dst_image, DlPoint(0, 0), DlImageSampling::kMipmapLinear,
619  &paint);
620 
621  paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
622  paint.setBlendMode(static_cast<DlBlendMode>(blend_mode));
623  builder.DrawImage(src_image, DlPoint(0, 0), DlImageSampling::kMipmapLinear,
624  &paint);
625  }
626  builder.Restore();
627  builder.Restore();
628 
629  // Rendered image source (right image).
630  builder.Save();
631 
632  DlPaint save_paint;
633  builder.SaveLayer(std::nullopt, &save_paint);
634  {
635  builder.DrawImage(dst_image, DlPoint(400, 0),
636  DlImageSampling::kMipmapLinear, nullptr);
637 
638  DlPaint save_paint;
639  save_paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
640  save_paint.setBlendMode(static_cast<DlBlendMode>(blend_mode));
641  builder.SaveLayer(std::nullopt, &save_paint);
642  {
643  builder.DrawImage(src_image, DlPoint(400, 0),
644  DlImageSampling::kMipmapLinear, nullptr);
645  }
646  builder.Restore();
647  }
648  builder.Restore();
649  builder.Restore();
650 
651  return builder.Build();
652 }
int32_t x
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:24

References impeller::Color::alpha, impeller::Color::Black(), impeller::Color::Blend(), impeller::Color::blue, impeller::Color::CornflowerBlue(), impeller::Color::green, impeller::AiksPlayground::ImGuiBegin(), impeller::Color::LimeGreen(), impeller::Color::red, impeller::Color::White(), impeller::Color::WithAlpha(), and x.

◆ CanBatchSubmitTest()

bool impeller::testing::CanBatchSubmitTest ( std::string_view  driver_name,
bool  qc = true 
)

Definition at line 71 of file driver_info_vk_unittests.cc.

71  {
72  auto const context =
73  MockVulkanContextBuilder()
74  .SetPhysicalPropertiesCallback(
75  [&driver_name, qc](VkPhysicalDevice device,
76  VkPhysicalDeviceProperties* prop) {
77  if (qc) {
78  prop->vendorID = 0x168C; // Qualcomm
79  } else {
80  prop->vendorID = 0x13B5; // ARM
81  }
82  driver_name.copy(prop->deviceName, driver_name.size());
83  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
84  })
85  .Build();
86  return !GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
88 }
WorkaroundsVK GetWorkaroundsFromDriverInfo(DriverInfoVK &driver_info)

References impeller::WorkaroundsVK::batch_submit_command_buffer_timeout, and impeller::GetWorkaroundsFromDriverInfo().

Referenced by TEST().

◆ CanRenderConicalGradientWithDithering()

static void impeller::testing::CanRenderConicalGradientWithDithering ( AiksTest aiks_test)
static

Definition at line 155 of file aiks_dl_gradient_unittests.cc.

155  {
156  DisplayListBuilder builder;
157  builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
158  DlPaint paint;
159  builder.Translate(100.0, 100.0);
160 
161  // #FFF -> #000
162  std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
163  DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
164  std::vector<Scalar> stops = {0.0, 1.0};
165 
166  paint.setColorSource(DlColorSource::MakeConical({0, 1}, 0, {100, 100}, 100, 2,
167  colors.data(), stops.data(),
168  DlTileMode::kMirror));
169 
170  builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
171  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
172 }

References impeller::Playground::GetContentScale(), impeller::AiksPlayground::OpenPlaygroundHere(), impeller::Color::ToARGB(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by TEST_P().

◆ CanRenderLinearGradientWithDithering()

static void impeller::testing::CanRenderLinearGradientWithDithering ( AiksTest aiks_test)
static

Definition at line 92 of file aiks_dl_gradient_unittests.cc.

92  {
93  DisplayListBuilder builder;
94  DlPaint paint;
95  builder.Translate(100.0, 100.0);
96 
97  // 0xffcccccc --> 0xff333333, taken from
98  // https://github.com/flutter/flutter/issues/118073#issue-1521699748
99  std::vector<DlColor> colors = {DlColor(0xFFCCCCCC), DlColor(0xFF333333)};
100  std::vector<Scalar> stops = {0.0, 1.0};
101 
102  paint.setColorSource(DlColorSource::MakeLinear(
103  {0, 0}, {800, 500}, 2, colors.data(), stops.data(), DlTileMode::kClamp));
104  builder.DrawRect(DlRect::MakeXYWH(0, 0, 800, 500), paint);
105  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
106 }

References impeller::AiksPlayground::OpenPlaygroundHere().

Referenced by TEST_P().

◆ CanRenderRadialGradientWithDithering()

static void impeller::testing::CanRenderRadialGradientWithDithering ( AiksTest aiks_test)
static

Definition at line 112 of file aiks_dl_gradient_unittests.cc.

112  {
113  DisplayListBuilder builder;
114  DlPaint paint;
115  builder.Translate(100.0, 100.0);
116 
117  // #FFF -> #000
118  std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
119  DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
120  std::vector<Scalar> stops = {0.0, 1.0};
121 
122  paint.setColorSource(DlColorSource::MakeRadial(
123  {600, 600}, 600, 2, colors.data(), stops.data(), DlTileMode::kClamp));
124  builder.DrawRect(DlRect::MakeXYWH(0, 0, 1200, 1200), paint);
125  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
126 }

References impeller::AiksPlayground::OpenPlaygroundHere(), and impeller::Color::ToARGB().

Referenced by TEST_P().

◆ CanRenderSweepGradientWithDithering()

static void impeller::testing::CanRenderSweepGradientWithDithering ( AiksTest aiks_test)
static

Definition at line 132 of file aiks_dl_gradient_unittests.cc.

132  {
133  DisplayListBuilder builder;
134  builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
135  DlPaint paint;
136  builder.Translate(100.0, 100.0);
137 
138  // #FFF -> #000
139  std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
140  DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
141  std::vector<Scalar> stops = {0.0, 1.0};
142 
143  paint.setColorSource(DlColorSource::MakeSweep(
144  {100, 100}, /*start=*/45, /*end=*/135, 2, colors.data(), stops.data(),
145  DlTileMode::kMirror));
146 
147  builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
148  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
149 }

References impeller::Playground::GetContentScale(), impeller::AiksPlayground::OpenPlaygroundHere(), impeller::Color::ToARGB(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by TEST_P().

◆ CanUseFramebufferFetch()

bool impeller::testing::CanUseFramebufferFetch ( std::string_view  driver_name,
bool  qc = true 
)

Definition at line 197 of file driver_info_vk_unittests.cc.

197  {
198  auto const context =
199  MockVulkanContextBuilder()
200  .SetPhysicalPropertiesCallback(
201  [&driver_name, qc](VkPhysicalDevice device,
202  VkPhysicalDeviceProperties* prop) {
203  if (qc) {
204  prop->vendorID = 0x168C; // Qualcomm
205  } else {
206  prop->vendorID = 0x13B5; // ARM
207  }
208  driver_name.copy(prop->deviceName, driver_name.size());
209  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
210  })
211  .Build();
212  return !GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
214 }
bool input_attachment_self_dependency_broken

References impeller::GetWorkaroundsFromDriverInfo(), and impeller::WorkaroundsVK::input_attachment_self_dependency_broken.

Referenced by TEST().

◆ CanUseMipgeneration()

bool impeller::testing::CanUseMipgeneration ( std::string_view  driver_name,
bool  qc = true 
)

Definition at line 127 of file driver_info_vk_unittests.cc.

127  {
128  auto const context =
129  MockVulkanContextBuilder()
130  .SetPhysicalPropertiesCallback(
131  [&driver_name, qc](VkPhysicalDevice device,
132  VkPhysicalDeviceProperties* prop) {
133  if (qc) {
134  prop->vendorID = 0x168C; // Qualcomm
135  } else {
136  prop->vendorID = 0x13B5; // ARM
137  }
138  driver_name.copy(prop->deviceName, driver_name.size());
139  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
140  })
141  .Build();
142  return !GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
144 }

References impeller::WorkaroundsVK::broken_mipmap_generation, and impeller::GetWorkaroundsFromDriverInfo().

Referenced by TEST().

◆ CanUsePrimitiveRestartSubmitTest()

bool impeller::testing::CanUsePrimitiveRestartSubmitTest ( std::string_view  driver_name,
bool  qc = true 
)

Definition at line 98 of file driver_info_vk_unittests.cc.

99  {
100  auto const context =
101  MockVulkanContextBuilder()
102  .SetPhysicalPropertiesCallback(
103  [&driver_name, qc](VkPhysicalDevice device,
104  VkPhysicalDeviceProperties* prop) {
105  if (qc) {
106  prop->vendorID = 0x168C; // Qualcomm
107  } else {
108  prop->vendorID = 0x13B5; // ARM
109  }
110  driver_name.copy(prop->deviceName, driver_name.size());
111  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
112  })
113  .Build();
114  return !GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
116 }

References impeller::GetWorkaroundsFromDriverInfo(), and impeller::WorkaroundsVK::slow_primitive_restart_performance.

Referenced by TEST().

◆ CAPABILITY_TEST() [1/12]

impeller::testing::CAPABILITY_TEST ( NeedsPartitionedHostBuffer  ,
false   
)

◆ CAPABILITY_TEST() [2/12]

impeller::testing::CAPABILITY_TEST ( SupportsCompute  ,
false   
)

◆ CAPABILITY_TEST() [3/12]

impeller::testing::CAPABILITY_TEST ( SupportsComputeSubgroups  ,
false   
)

◆ CAPABILITY_TEST() [4/12]

impeller::testing::CAPABILITY_TEST ( SupportsDecalSamplerAddressMode  ,
false   
)

◆ CAPABILITY_TEST() [5/12]

impeller::testing::CAPABILITY_TEST ( SupportsDeviceTransientTextures  ,
false   
)

◆ CAPABILITY_TEST() [6/12]

impeller::testing::CAPABILITY_TEST ( SupportsExtendedRangeFormats  ,
false   
)

◆ CAPABILITY_TEST() [7/12]

impeller::testing::CAPABILITY_TEST ( SupportsFramebufferFetch  ,
false   
)

◆ CAPABILITY_TEST() [8/12]

impeller::testing::CAPABILITY_TEST ( SupportsOffscreenMSAA  ,
false   
)

◆ CAPABILITY_TEST() [9/12]

impeller::testing::CAPABILITY_TEST ( SupportsReadFromResolve  ,
false   
)

◆ CAPABILITY_TEST() [10/12]

impeller::testing::CAPABILITY_TEST ( SupportsSSBO  ,
false   
)

◆ CAPABILITY_TEST() [11/12]

impeller::testing::CAPABILITY_TEST ( SupportsTextureToTextureBlits  ,
false   
)

◆ CAPABILITY_TEST() [12/12]

impeller::testing::CAPABILITY_TEST ( SupportsTriangleFan  ,
false   
)

◆ CompareFunctionUI()

static const CompareFunctionUIData& impeller::testing::CompareFunctionUI ( )
static

Definition at line 1212 of file renderer_unittests.cc.

1212  {
1213  static CompareFunctionUIData data;
1214  return data;
1215 }
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:68

References data.

Referenced by TEST_P().

◆ CreateDefaultPipeline()

template<class VertexShader , class FragmentShader >
std::shared_ptr<Pipeline<PipelineDescriptor> > impeller::testing::CreateDefaultPipeline ( const std::shared_ptr< Context > &  context)

Definition at line 1403 of file renderer_unittests.cc.

1404  {
1405  using TexturePipelineBuilder = PipelineBuilder<VertexShader, FragmentShader>;
1406  auto pipeline_desc =
1407  TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1408  if (!pipeline_desc.has_value()) {
1409  return nullptr;
1410  }
1411  pipeline_desc->SetSampleCount(SampleCount::kCount4);
1412  pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
1413  auto pipeline =
1414  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
1415  if (!pipeline || !pipeline->IsValid()) {
1416  return nullptr;
1417  }
1418  return pipeline;
1419 }

References impeller::kCount4.

◆ CreateGlyphAtlas() [1/2]

static std::shared_ptr<GlyphAtlas> impeller::testing::CreateGlyphAtlas ( Context context,
const TypographerContext typographer_context,
HostBuffer data_host_buffer,
GlyphAtlas::Type  type,
Rational  scale,
const std::shared_ptr< GlyphAtlasContext > &  atlas_context,
const std::shared_ptr< TextFrame > &  frame 
)
static

Definition at line 32 of file typographer_unittests.cc.

39  {
40  frame->SetPerFrameData(scale, {0, 0}, Matrix(), std::nullopt);
41  return typographer_context->CreateGlyphAtlas(context, type, data_host_buffer,
42  atlas_context, {frame});
43 }
GLenum type

References impeller::TypographerContext::CreateGlyphAtlas(), and type.

Referenced by TEST_P().

◆ CreateGlyphAtlas() [2/2]

static std::shared_ptr<GlyphAtlas> impeller::testing::CreateGlyphAtlas ( Context context,
const TypographerContext typographer_context,
HostBuffer data_host_buffer,
GlyphAtlas::Type  type,
Rational  scale,
const std::shared_ptr< GlyphAtlasContext > &  atlas_context,
const std::vector< std::shared_ptr< TextFrame >> &  frames,
const std::vector< std::optional< GlyphProperties >> &  properties 
)
static

Definition at line 45 of file typographer_unittests.cc.

53  {
54  size_t offset = 0;
55  for (auto& frame : frames) {
56  frame->SetPerFrameData(scale, {0, 0}, Matrix(), properties[offset++]);
57  }
58  return typographer_context->CreateGlyphAtlas(context, type, data_host_buffer,
59  atlas_context, frames);
60 }

References impeller::TypographerContext::CreateGlyphAtlas(), and type.

◆ CreateMappingFromString()

static std::shared_ptr<fml::Mapping> impeller::testing::CreateMappingFromString ( std::string  p_string)
static

Definition at line 15 of file shader_archive_unittests.cc.

16  {
17  auto string = std::make_shared<std::string>(std::move(p_string));
18  return std::make_shared<fml::NonOwnedMapping>(
19  reinterpret_cast<const uint8_t*>(string->data()), string->size(),
20  [string](auto, auto) {});
21 }

Referenced by TEST().

◆ CreateStringFromMapping()

const std::string impeller::testing::CreateStringFromMapping ( const fml::Mapping &  mapping)

Definition at line 23 of file shader_archive_unittests.cc.

23  {
24  return std::string{reinterpret_cast<const char*>(mapping.GetMapping()),
25  mapping.GetSize()};
26 }

Referenced by TEST().

◆ CreateTestCanvas()

std::unique_ptr<Canvas> impeller::testing::CreateTestCanvas ( ContentContext context,
std::optional< Rect cull_rect = std::nullopt,
bool  requires_readback = false 
)

Definition at line 26 of file canvas_unittests.cc.

29  {
30  TextureDescriptor onscreen_desc;
31  onscreen_desc.size = {100, 100};
32  onscreen_desc.format =
33  context.GetDeviceCapabilities().GetDefaultColorFormat();
34  onscreen_desc.usage = TextureUsage::kRenderTarget;
35  onscreen_desc.storage_mode = StorageMode::kDevicePrivate;
36  onscreen_desc.sample_count = SampleCount::kCount1;
37  std::shared_ptr<Texture> onscreen =
38  context.GetContext()->GetResourceAllocator()->CreateTexture(
39  onscreen_desc);
40 
41  ColorAttachment color0;
42  color0.load_action = LoadAction::kClear;
43  if (context.GetContext()->GetCapabilities()->SupportsOffscreenMSAA()) {
44  TextureDescriptor onscreen_msaa_desc = onscreen_desc;
45  onscreen_msaa_desc.sample_count = SampleCount::kCount4;
46  onscreen_msaa_desc.storage_mode = StorageMode::kDeviceTransient;
47  onscreen_msaa_desc.type = TextureType::kTexture2DMultisample;
48 
49  std::shared_ptr<Texture> onscreen_msaa =
50  context.GetContext()->GetResourceAllocator()->CreateTexture(
51  onscreen_msaa_desc);
52  color0.resolve_texture = onscreen;
53  color0.texture = onscreen_msaa;
54  color0.store_action = StoreAction::kMultisampleResolve;
55  } else {
56  color0.texture = onscreen;
57  }
58 
59  RenderTarget render_target;
60  render_target.SetColorAttachment(color0, 0);
61 
62  if (cull_rect.has_value()) {
63  return std::make_unique<Canvas>(
64  context, render_target, /*is_onscreen=*/false,
65  /*requires_readback=*/requires_readback, cull_rect.value());
66  }
67  return std::make_unique<Canvas>(context, render_target, /*is_onscreen=*/false,
68  /*requires_readback=*/requires_readback);
69 }

References impeller::TextureDescriptor::format, impeller::ContentContext::GetContext(), impeller::Capabilities::GetDefaultColorFormat(), impeller::ContentContext::GetDeviceCapabilities(), impeller::kClear, impeller::kCount1, impeller::kCount4, impeller::kDevicePrivate, impeller::kDeviceTransient, impeller::kMultisampleResolve, impeller::kRenderTarget, impeller::kTexture2DMultisample, impeller::Attachment::load_action, impeller::Attachment::resolve_texture, impeller::TextureDescriptor::sample_count, impeller::RenderTarget::SetColorAttachment(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, impeller::Attachment::texture, impeller::TextureDescriptor::type, and impeller::TextureDescriptor::usage.

Referenced by TEST_P().

◆ CreateTestYUVTextures()

static std::vector<std::shared_ptr<Texture> > impeller::testing::CreateTestYUVTextures ( Context context,
YUVColorSpace  yuv_color_space 
)
static

Definition at line 1658 of file entity_unittests.cc.

1660  {
1661  Vector3 red = {244.0 / 255.0, 67.0 / 255.0, 54.0 / 255.0};
1662  Vector3 green = {76.0 / 255.0, 175.0 / 255.0, 80.0 / 255.0};
1663  Vector3 blue = {33.0 / 255.0, 150.0 / 255.0, 243.0 / 255.0};
1664  Vector3 white = {1.0, 1.0, 1.0};
1665  Vector3 red_yuv = RGBToYUV(red, yuv_color_space);
1666  Vector3 green_yuv = RGBToYUV(green, yuv_color_space);
1667  Vector3 blue_yuv = RGBToYUV(blue, yuv_color_space);
1668  Vector3 white_yuv = RGBToYUV(white, yuv_color_space);
1669  std::vector<Vector3> yuvs{red_yuv, green_yuv, blue_yuv, white_yuv};
1670  std::vector<uint8_t> y_data;
1671  std::vector<uint8_t> uv_data;
1672  for (int i = 0; i < 4; i++) {
1673  auto yuv = yuvs[i];
1674  uint8_t y = std::round(yuv.x * 255.0);
1675  uint8_t u = std::round(yuv.y * 255.0);
1676  uint8_t v = std::round(yuv.z * 255.0);
1677  for (int j = 0; j < 16; j++) {
1678  y_data.push_back(y);
1679  }
1680  for (int j = 0; j < 8; j++) {
1681  uv_data.push_back(j % 2 == 0 ? u : v);
1682  }
1683  }
1684  auto cmd_buffer = context->CreateCommandBuffer();
1685  auto blit_pass = cmd_buffer->CreateBlitPass();
1686 
1687  impeller::TextureDescriptor y_texture_descriptor;
1688  y_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
1689  y_texture_descriptor.format = PixelFormat::kR8UNormInt;
1690  y_texture_descriptor.size = {8, 8};
1691  auto y_texture =
1692  context->GetResourceAllocator()->CreateTexture(y_texture_descriptor);
1693  auto y_mapping = std::make_shared<fml::DataMapping>(y_data);
1694  auto y_mapping_buffer =
1695  context->GetResourceAllocator()->CreateBufferWithCopy(*y_mapping);
1696 
1697  blit_pass->AddCopy(DeviceBuffer::AsBufferView(y_mapping_buffer), y_texture);
1698 
1699  impeller::TextureDescriptor uv_texture_descriptor;
1700  uv_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
1701  uv_texture_descriptor.format = PixelFormat::kR8G8UNormInt;
1702  uv_texture_descriptor.size = {4, 4};
1703  auto uv_texture =
1704  context->GetResourceAllocator()->CreateTexture(uv_texture_descriptor);
1705  auto uv_mapping = std::make_shared<fml::DataMapping>(uv_data);
1706  auto uv_mapping_buffer =
1707  context->GetResourceAllocator()->CreateBufferWithCopy(*uv_mapping);
1708 
1709  blit_pass->AddCopy(DeviceBuffer::AsBufferView(uv_mapping_buffer), uv_texture);
1710 
1711  if (!blit_pass->EncodeCommands() ||
1712  !context->GetCommandQueue()->Submit({cmd_buffer}).ok()) {
1713  FML_DLOG(ERROR) << "Could not copy contents into Y/UV texture.";
1714  }
1715 
1716  return {y_texture, uv_texture};
1717 }
static Vector3 RGBToYUV(Vector3 rgb, YUVColorSpace yuv_color_space)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...

References impeller::DeviceBuffer::AsBufferView(), impeller::Context::CreateCommandBuffer(), impeller::TextureDescriptor::format, impeller::Context::GetCommandQueue(), impeller::Context::GetResourceAllocator(), impeller::kHostVisible, impeller::kR8G8UNormInt, impeller::kR8UNormInt, RGBToYUV(), impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

Referenced by TEST_P().

◆ DoGradientOvalStrokeMaskBlur()

sk_sp<flutter::DisplayList> impeller::testing::DoGradientOvalStrokeMaskBlur ( Vector2  content_Scale,
Scalar  sigma,
DlBlurStyle  style 
)

Definition at line 62 of file aiks_dl_blur_unittests.cc.

64  {
65  DisplayListBuilder builder;
66  builder.Scale(content_Scale.x, content_Scale.y);
67 
68  DlPaint background_paint;
69  background_paint.setColor(DlColor(1, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
70  builder.DrawPaint(background_paint);
71 
72  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue()};
73  std::vector<Scalar> stops = {0.0, 1.0};
74 
75  DlPaint paint;
76  paint.setMaskFilter(DlBlurMaskFilter::Make(style, sigma));
77  auto gradient = DlColorSource::MakeLinear(
78  {0, 0}, {200, 200}, 2, colors.data(), stops.data(), DlTileMode::kClamp);
79  paint.setColorSource(gradient);
80  paint.setColor(DlColor::kWhite());
81  paint.setDrawStyle(DlDrawStyle::kStroke);
82  paint.setStrokeWidth(20);
83 
84  builder.Save();
85  builder.Translate(100, 100);
86 
87  {
88  DlPaint line_paint;
89  line_paint.setColor(DlColor::kWhite());
90  builder.DrawLine(DlPoint(100, 0), DlPoint(100, 60), line_paint);
91  builder.DrawLine(DlPoint(0, 30), DlPoint(200, 30), line_paint);
92  }
93 
94  DlRoundRect rrect =
95  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 200.0f, 60.0f), 50, 100);
96  builder.DrawRoundRect(rrect, paint);
97  builder.Restore();
98 
99  return builder.Build();
100 }
flutter::DlRoundRect DlRoundRect
Definition: dl_dispatcher.h:27

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by TEST_P().

◆ flip_lr()

template<typename R >
static constexpr R impeller::testing::flip_lr ( rect)
inlinestaticconstexpr

Definition at line 1324 of file rect_unittests.cc.

1324  {
1325  return R::MakeLTRB(rect.GetRight(), rect.GetTop(), //
1326  rect.GetLeft(), rect.GetBottom());
1327 }

Referenced by flip_lrtb(), and TEST().

◆ flip_lrtb()

template<typename R >
static constexpr R impeller::testing::flip_lrtb ( rect)
inlinestaticconstexpr

Definition at line 1336 of file rect_unittests.cc.

1336  {
1337  return flip_lr(flip_tb(rect));
1338 }
static constexpr R flip_tb(R rect)
static constexpr R flip_lr(R rect)

References flip_lr(), and flip_tb().

Referenced by TEST().

◆ flip_tb()

template<typename R >
static constexpr R impeller::testing::flip_tb ( rect)
inlinestaticconstexpr

Definition at line 1330 of file rect_unittests.cc.

1330  {
1331  return R::MakeLTRB(rect.GetLeft(), rect.GetBottom(), //
1332  rect.GetRight(), rect.GetTop());
1333 }

Referenced by flip_lrtb(), and TEST().

◆ FML_TEST_CLASS() [1/2]

impeller::testing::FML_TEST_CLASS ( BufferBindingsGLESTest  ,
BindArrayData   
)

◆ FML_TEST_CLASS() [2/2]

impeller::testing::FML_TEST_CLASS ( BufferBindingsGLESTest  ,
BindUniformData   
)

◆ GetBlendModeSelection()

static BlendModeSelection impeller::testing::GetBlendModeSelection ( )
static

Definition at line 44 of file aiks_dl_blend_unittests.cc.

44  {
45  std::vector<const char*> blend_mode_names;
46  std::vector<BlendMode> blend_mode_values;
47  {
48  const std::vector<std::tuple<const char*, BlendMode>> blends = {
50  assert(blends.size() ==
51  static_cast<size_t>(Entity::kLastAdvancedBlendMode) + 1);
52  for (const auto& [name, mode] : blends) {
53  blend_mode_names.push_back(name);
54  blend_mode_values.push_back(mode);
55  }
56  }
57 
58  return {blend_mode_names, blend_mode_values};
59 }
#define BLEND_MODE_TUPLE(blend_mode)
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
Definition: color.h:19

References BLEND_MODE_TUPLE, IMPELLER_FOR_EACH_BLEND_MODE, and impeller::Entity::kLastAdvancedBlendMode.

Referenced by TEST_P().

◆ INSTANTIATE_COMPUTE_SUITE()

impeller::testing::INSTANTIATE_COMPUTE_SUITE ( ComputeTest  )

◆ INSTANTIATE_METAL_PLAYGROUND_SUITE()

impeller::testing::INSTANTIATE_METAL_PLAYGROUND_SUITE ( AllocatorMTLTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [1/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( AiksTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [2/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( BlendFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [3/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( DisplayListTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [4/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( GaussianBlurFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [5/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( HostBufferTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [6/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( MatrixFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [7/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RendererDartTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [8/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RuntimeStageTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [9/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( TextContentsTest  )

◆ INSTANTIATE_VULKAN_PLAYGROUND_SUITE()

impeller::testing::INSTANTIATE_VULKAN_PLAYGROUND_SUITE ( DriverInfoVKTest  )

◆ InstantiateTestShaderLibrary()

static void impeller::testing::InstantiateTestShaderLibrary ( Context::BackendType  backend_type)
static

Definition at line 34 of file renderer_dart_unittests.cc.

34  {
35  auto fixture =
36  flutter::testing::OpenFixtureAsMapping("playground.shaderbundle");
37  auto library = flutter::gpu::ShaderLibrary::MakeFromFlatbuffer(
38  backend_type, std::move(fixture));
39  flutter::gpu::ShaderLibrary::SetOverride(library);
40 }

Referenced by impeller::testing::RendererDartTest::GetIsolate().

◆ IsBadVersionTest()

bool impeller::testing::IsBadVersionTest ( std::string_view  driver_name,
bool  qc = true 
)

Definition at line 53 of file driver_info_vk_unittests.cc.

53  {
54  auto const context =
55  MockVulkanContextBuilder()
56  .SetPhysicalPropertiesCallback(
57  [&driver_name, qc](VkPhysicalDevice device,
58  VkPhysicalDeviceProperties* prop) {
59  if (qc) {
60  prop->vendorID = 0x168C; // Qualcomm
61  } else {
62  prop->vendorID = 0x13B5; // ARM
63  }
64  driver_name.copy(prop->deviceName, driver_name.size());
65  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
66  })
67  .Build();
68  return context->GetDriverInfo()->IsKnownBadDriver();
69 }

Referenced by TEST().

◆ MaskBlurVariantTest()

static sk_sp<DisplayList> impeller::testing::MaskBlurVariantTest ( const AiksTest test_context,
const MaskBlurTestConfig config 
)
static

Definition at line 505 of file aiks_dl_blur_unittests.cc.

507  {
508  DisplayListBuilder builder;
509  builder.Scale(test_context.GetContentScale().x,
510  test_context.GetContentScale().y);
511  builder.Scale(0.8f, 0.8f);
512  builder.Translate(50.f, 50.f);
513 
514  DlPaint draw_paint;
515  draw_paint.setColor(
516  DlColor::RGBA(Color::AntiqueWhite().red, Color::AntiqueWhite().green,
517  Color::AntiqueWhite().blue, Color::AntiqueWhite().alpha));
518  builder.DrawPaint(draw_paint);
519 
520  DlPaint paint;
521  paint.setMaskFilter(DlBlurMaskFilter::Make(config.style, config.sigma));
522  paint.setInvertColors(config.invert_colors);
523  paint.setImageFilter(config.image_filter);
524  paint.setBlendMode(config.blend_mode);
525 
526  const Scalar x = 50;
527  const Scalar radius = 20.0f;
528  const Scalar y_spacing = 100.0f;
529  Scalar alpha = config.alpha * 255;
530 
531  Scalar y = 50;
532  paint.setColor(DlColor::kCrimson().withAlpha(alpha));
533  builder.DrawRect(DlRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
534  radius, 60.0f - radius),
535  paint);
536 
537  y += y_spacing;
538  paint.setColor(DlColor::kBlue().withAlpha(alpha));
539  builder.DrawCircle(DlPoint{x + 25, y + 25}, radius, paint);
540 
541  y += y_spacing;
542  paint.setColor(DlColor::kGreen().withAlpha(alpha));
543  builder.DrawOval(DlRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
544  radius, 60.0f - radius),
545  paint);
546 
547  y += y_spacing;
548  paint.setColor(DlColor::kPurple().withAlpha(alpha));
549  DlRoundRect rrect = DlRoundRect::MakeRectXY(
550  DlRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, radius);
551  builder.DrawRoundRect(rrect, paint);
552 
553  y += y_spacing;
554  paint.setColor(DlColor::kOrange().withAlpha(alpha));
555 
556  rrect = DlRoundRect::MakeRectXY(DlRect::MakeXYWH(x, y, 60.0f, 60.0f), //
557  radius, 5.0);
558  builder.DrawRoundRect(rrect, paint);
559 
560  y += y_spacing;
561  paint.setColor(DlColor::kMaroon().withAlpha(alpha));
562 
563  {
564  DlPathBuilder path_builder;
565  path_builder.MoveTo(DlPoint(x + 0, y + 60));
566  path_builder.LineTo(DlPoint(x + 30, y + 0));
567  path_builder.LineTo(DlPoint(x + 60, y + 60));
568  path_builder.Close();
569 
570  builder.DrawPath(path_builder.TakePath(), paint);
571  }
572 
573  y += y_spacing;
574  paint.setColor(DlColor::kMaroon().withAlpha(alpha));
575  {
576  DlPath path = DlPath::MakeArc(Rect::MakeXYWH(x + 5, y, 50, 50), //
577  Degrees(90), Degrees(180), false) +
578  DlPath::MakeArc(Rect::MakeXYWH(x + 25, y, 50, 50), //
579  Degrees(90), Degrees(180), false);
580  builder.DrawPath(path, paint);
581  }
582 
583  return builder.Build();
584 }
float Scalar
Definition: scalar.h:19
flutter::DlPath DlPath
Definition: dl_dispatcher.h:29

References impeller::testing::MaskBlurTestConfig::alpha, impeller::Color::AntiqueWhite(), impeller::testing::MaskBlurTestConfig::blend_mode, impeller::Playground::GetContentScale(), impeller::testing::MaskBlurTestConfig::image_filter, impeller::testing::MaskBlurTestConfig::invert_colors, impeller::TRect< Scalar >::MakeXYWH(), impeller::testing::MaskBlurTestConfig::sigma, impeller::testing::MaskBlurTestConfig::style, x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ RectMakeCenterSize()

Rect impeller::testing::RectMakeCenterSize ( Point  center,
Size  size 
)

Definition at line 68 of file entity_unittests.cc.

68  {
69  return Rect::MakeSize(size).Shift(center - size / 2);
70 }

References impeller::TRect< Scalar >::MakeSize(), and impeller::TRect< T >::Shift().

Referenced by TEST_P().

◆ RenderTextInCanvasSkia()

bool impeller::testing::RenderTextInCanvasSkia ( const std::shared_ptr< Context > &  context,
DisplayListBuilder &  canvas,
const std::string &  text,
const std::string_view &  font_fixture,
const TextRenderOptions options = {},
const std::optional< SkFont > &  font = std::nullopt 
)

Definition at line 45 of file aiks_dl_text_unittests.cc.

49  {},
50  const std::optional<SkFont>& font = std::nullopt) {
51  // Draw the baseline.
52  DlPaint paint;
53  paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25));
54  canvas.DrawRect(
55  DlRect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
56  paint);
57 
58  // Mark the point at which the text is drawn.
59  paint.setColor(DlColor::kRed().withAlpha(255 * 0.25));
60  canvas.DrawCircle(options.position, 5.0, paint);
61 
62  // Construct the text blob.
63  SkFont selected_font;
64  if (!font.has_value()) {
65  auto c_font_fixture = std::string(font_fixture);
66  auto mapping =
67  flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
68  if (!mapping) {
69  return false;
70  }
71  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
72  selected_font = SkFont(font_mgr->makeFromData(mapping), options.font_size);
73  if (options.is_subpixel) {
74  selected_font.setSubpixel(true);
75  }
76  } else {
77  selected_font = font.value();
78  }
79  auto blob = SkTextBlob::MakeFromString(text.c_str(), selected_font);
80  if (!blob) {
81  return false;
82  }
83 
84  // Create the Impeller text frame and draw it at the designated baseline.
85  auto frame = MakeTextFrameFromTextBlobSkia(blob);
86 
87  DlPaint text_paint;
88  text_paint.setColor(options.color);
89  text_paint.setMaskFilter(options.filter);
90  text_paint.setStrokeWidth(options.stroke_width);
91  text_paint.setDrawStyle(options.stroke ? DlDrawStyle::kStroke
92  : DlDrawStyle::kFill);
93  canvas.DrawText(DlTextImpeller::Make(frame), options.position.x,
94  options.position.y, text_paint);
95  return true;
96 }
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)

Referenced by TEST_P(), and flutter::testing::TEST_P().

◆ RGBToYUV()

static Vector3 impeller::testing::RGBToYUV ( Vector3  rgb,
YUVColorSpace  yuv_color_space 
)
static

Definition at line 1641 of file entity_unittests.cc.

1641  {
1642  Vector3 yuv;
1643  switch (yuv_color_space) {
1644  case YUVColorSpace::kBT601FullRange:
1645  yuv.x = rgb.x * 0.299 + rgb.y * 0.587 + rgb.z * 0.114;
1646  yuv.y = rgb.x * -0.169 + rgb.y * -0.331 + rgb.z * 0.5 + 0.5;
1647  yuv.z = rgb.x * 0.5 + rgb.y * -0.419 + rgb.z * -0.081 + 0.5;
1648  break;
1649  case YUVColorSpace::kBT601LimitedRange:
1650  yuv.x = rgb.x * 0.257 + rgb.y * 0.516 + rgb.z * 0.100 + 0.063;
1651  yuv.y = rgb.x * -0.145 + rgb.y * -0.291 + rgb.z * 0.439 + 0.5;
1652  yuv.z = rgb.x * 0.429 + rgb.y * -0.368 + rgb.z * -0.071 + 0.5;
1653  break;
1654  }
1655  return yuv;
1656 }

References impeller::kBT601FullRange, impeller::kBT601LimitedRange, impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

Referenced by CreateTestYUVTextures().

◆ swap_nan() [1/2]

static constexpr Point impeller::testing::swap_nan ( const Point point,
int  index 
)
inlinestaticconstexpr

Definition at line 1350 of file rect_unittests.cc.

1350  {
1351  Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1352  FML_DCHECK(index >= 0 && index <= 3);
1353  Scalar x = ((index & (1 << 0)) != 0) ? nan : point.x;
1354  Scalar y = ((index & (1 << 1)) != 0) ? nan : point.y;
1355  return Point(x, y);
1356 }
TPoint< Scalar > Point
Definition: point.h:327

References x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ swap_nan() [2/2]

static constexpr Rect impeller::testing::swap_nan ( const Rect rect,
int  index 
)
inlinestaticconstexpr

Definition at line 1340 of file rect_unittests.cc.

1340  {
1341  Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1342  FML_DCHECK(index >= 0 && index <= 15);
1343  Scalar l = ((index & (1 << 0)) != 0) ? nan : rect.GetLeft();
1344  Scalar t = ((index & (1 << 1)) != 0) ? nan : rect.GetTop();
1345  Scalar r = ((index & (1 << 2)) != 0) ? nan : rect.GetRight();
1346  Scalar b = ((index & (1 << 3)) != 0) ? nan : rect.GetBottom();
1347  return Rect::MakeLTRB(l, t, r, b);
1348 }

References impeller::saturated::b, impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), and impeller::TRect< Scalar >::MakeLTRB().

Referenced by TEST().

◆ TEST() [1/525]

impeller::testing::TEST ( AllocationSizeTest  ,
CanCast   
)

Definition at line 77 of file allocation_size_unittests.cc.

77  {
78  using namespace allocation_size_literals;
79  {
80  auto a = KiloBytes{1500_bytes};
81  ASSERT_DOUBLE_EQ(a.GetSize(), 1.5);
82  }
83  {
84  auto a = KiloBytes{Bytes{1500}};
85  ASSERT_DOUBLE_EQ(a.GetSize(), 1.5);
86  }
87 
88  ASSERT_DOUBLE_EQ(MebiBytes{Bytes{4194304}}.GetSize(), 4);
89 }
constexpr double GetSize() const
AllocationSize< 1 '024u *1 '024u > MebiBytes
AllocationSize< 1u > Bytes
AllocationSize< 1 '000u > KiloBytes

References impeller::AllocationSize< Period >::GetSize().

◆ TEST() [2/525]

impeller::testing::TEST ( AllocationSizeTest  ,
CanConstructWithArith   
)

Definition at line 110 of file allocation_size_unittests.cc.

110  {
111  {
112  Bytes a(1u);
113  ASSERT_EQ(a.GetByteSize(), 1u);
114  }
115  {
116  Bytes a(1.5);
117  ASSERT_EQ(a.GetByteSize(), 2u);
118  }
119  {
120  Bytes a(1.5f);
121  ASSERT_EQ(a.GetByteSize(), 2u);
122  }
123 }

References impeller::AllocationSize< Period >::GetByteSize().

◆ TEST() [3/525]

impeller::testing::TEST ( AllocationSizeTest  ,
CanConvert   
)

Definition at line 44 of file allocation_size_unittests.cc.

44  {
45  using namespace allocation_size_literals;
46  ASSERT_EQ((5_gb).ConvertTo<MegaBytes>().GetSize(), 5000u);
47 }

◆ TEST() [4/525]

impeller::testing::TEST ( AllocationSizeTest  ,
CanCreateTypedAllocations   
)

Definition at line 10 of file allocation_size_unittests.cc.

10  {
11  auto bytes = Bytes{1024};
12  ASSERT_EQ(bytes.GetByteSize(), 1024u);
13 
14  auto kilobytes = KiloBytes{5};
15  ASSERT_EQ(kilobytes.GetByteSize(), 5u * 1e3);
16 
17  auto megabytes = MegaBytes{5};
18  ASSERT_EQ(megabytes.GetByteSize(), 5u * 1e6);
19 
20  auto gigabytes = GigaBytes{5};
21  ASSERT_EQ(gigabytes.GetByteSize(), 5u * 1e9);
22 
23  auto kibibytes = KibiBytes{1};
24  ASSERT_EQ(kibibytes.GetByteSize(), 1024u);
25 
26  auto mebibytes = MebiBytes{1};
27  ASSERT_EQ(mebibytes.GetByteSize(), 1048576u);
28 
29  auto gigibytes = GibiBytes{1};
30  ASSERT_EQ(gigibytes.GetByteSize(), 1073741824u);
31 }
Vector3 e3
AllocationSize< 1 '024u *1 '024u *1 '024u > GibiBytes
AllocationSize< 1 '000u *1 '000u *1 '000u > GigaBytes
AllocationSize< 1 '024u > KibiBytes
AllocationSize< 1 '000u *1 '000u > MegaBytes

References e3.

◆ TEST() [5/525]

impeller::testing::TEST ( AllocationSizeTest  ,
CanCreateTypedAllocationsWithLiterals   
)

Definition at line 33 of file allocation_size_unittests.cc.

33  {
34  using namespace allocation_size_literals;
35  ASSERT_EQ((1024_bytes).GetByteSize(), 1024u);
36  ASSERT_EQ((5_kb).GetByteSize(), 5u * 1e3);
37  ASSERT_EQ((5_mb).GetByteSize(), 5u * 1e6);
38  ASSERT_EQ((5_gb).GetByteSize(), 5u * 1e9);
39  ASSERT_EQ((1_kib).GetByteSize(), 1024u);
40  ASSERT_EQ((1_mib).GetByteSize(), 1048576u);
41  ASSERT_EQ((1_gib).GetByteSize(), 1073741824u);
42 }

References e3.

◆ TEST() [6/525]

impeller::testing::TEST ( AllocationSizeTest  ,
CanGetFloatValues   
)

Definition at line 55 of file allocation_size_unittests.cc.

55  {
56  using namespace allocation_size_literals;
57  ASSERT_DOUBLE_EQ((1500_bytes).ConvertTo<KiloBytes>().GetSize(), 1.5);
58 }

◆ TEST() [7/525]

impeller::testing::TEST ( AllocationSizeTest  ,
CanPerformSimpleArithmetic   
)

Definition at line 91 of file allocation_size_unittests.cc.

91  {
92  using namespace allocation_size_literals;
93  {
94  auto a = 100_bytes;
95  auto b = 200_bytes;
96  ASSERT_EQ((a + b).GetByteSize(), 300u);
97  }
98  {
99  auto a = 100_bytes;
100  a += 200_bytes;
101  ASSERT_EQ(a.GetByteSize(), 300u);
102  }
103  {
104  auto a = 100_bytes;
105  a -= 50_bytes;
106  ASSERT_EQ(a.GetByteSize(), 50u);
107  }
108 }

References impeller::saturated::b.

◆ TEST() [8/525]

impeller::testing::TEST ( AllocationSizeTest  ,
ConversionsAreNonTruncating   
)

Definition at line 49 of file allocation_size_unittests.cc.

49  {
50  using namespace allocation_size_literals;
51  ASSERT_DOUBLE_EQ((1500_bytes).ConvertTo<KiloBytes>().GetSize(), 1.5);
52  ASSERT_EQ((1500_bytes).ConvertTo<KiloBytes>().GetByteSize(), 1500u);
53 }

◆ TEST() [9/525]

impeller::testing::TEST ( AllocationSizeTest  ,
RelationalOperatorsAreFunctional   
)

Definition at line 60 of file allocation_size_unittests.cc.

60  {
61  using namespace allocation_size_literals;
62 
63  auto a = 1500_bytes;
64  auto b = 2500_bytes;
65  auto c = 0_bytes;
66 
67  ASSERT_TRUE(a != b);
68  ASSERT_FALSE(a == b);
69  ASSERT_TRUE(b > a);
70  ASSERT_TRUE(b >= a);
71  ASSERT_TRUE(a < b);
72  ASSERT_TRUE(a <= b);
73  ASSERT_TRUE(a);
74  ASSERT_FALSE(c);
75 }

References impeller::saturated::b.

◆ TEST() [10/525]

impeller::testing::TEST ( AllocatorTest  ,
RangeTest   
)

Definition at line 82 of file allocator_unittests.cc.

82  {
83  {
84  Range a = Range{0, 10};
85  Range b = Range{10, 20};
86  auto merged = a.Merge(b);
87 
88  EXPECT_EQ(merged.offset, 0u);
89  EXPECT_EQ(merged.length, 30u);
90  }
91 
92  {
93  Range a = Range{0, 10};
94  Range b = Range{100, 20};
95  auto merged = a.Merge(b);
96 
97  EXPECT_EQ(merged.offset, 0u);
98  EXPECT_EQ(merged.length, 120u);
99  }
100 
101  {
102  Range a = Range{0, 10};
103  Range b = Range{100, 20};
104  auto merged = b.Merge(a);
105 
106  EXPECT_EQ(merged.offset, 0u);
107  EXPECT_EQ(merged.length, 120u);
108  }
109 
110  {
111  Range a = Range{0, 10};
112  Range b = Range{100, 0};
113  auto merged = b.Merge(a);
114 
115  EXPECT_EQ(merged.offset, 0u);
116  EXPECT_EQ(merged.length, 10u);
117  }
118 
119  {
120  Range a = Range{0, 10};
121  Range b = Range{0, 10};
122  auto merged = b.Merge(a);
123 
124  EXPECT_EQ(merged.offset, 0u);
125  EXPECT_EQ(merged.length, 10u);
126  }
127 }

References impeller::saturated::b, and impeller::Range::Merge().

◆ TEST() [11/525]

impeller::testing::TEST ( AllocatorTest  ,
TextureDescriptorCompatibility   
)

Definition at line 16 of file allocator_unittests.cc.

16  {
17  // Size.
18  {
19  TextureDescriptor desc_a = {.size = ISize(100, 100)};
20  TextureDescriptor desc_b = {.size = ISize(100, 100)};
21  TextureDescriptor desc_c = {.size = ISize(101, 100)};
22 
23  ASSERT_EQ(desc_a, desc_b);
24  ASSERT_NE(desc_a, desc_c);
25  }
26  // Storage Mode.
27  {
28  TextureDescriptor desc_a = {.storage_mode = StorageMode::kDevicePrivate};
29  TextureDescriptor desc_b = {.storage_mode = StorageMode::kDevicePrivate};
30  TextureDescriptor desc_c = {.storage_mode = StorageMode::kHostVisible};
31 
32  ASSERT_EQ(desc_a, desc_b);
33  ASSERT_NE(desc_a, desc_c);
34  }
35  // Format.
36  {
37  TextureDescriptor desc_a = {.format = PixelFormat::kR8G8B8A8UNormInt};
38  TextureDescriptor desc_b = {.format = PixelFormat::kR8G8B8A8UNormInt};
39  TextureDescriptor desc_c = {.format = PixelFormat::kB10G10R10A10XR};
40 
41  ASSERT_EQ(desc_a, desc_b);
42  ASSERT_NE(desc_a, desc_c);
43  }
44  // Sample Count.
45  {
46  TextureDescriptor desc_a = {.sample_count = SampleCount::kCount4};
47  TextureDescriptor desc_b = {.sample_count = SampleCount::kCount4};
48  TextureDescriptor desc_c = {.sample_count = SampleCount::kCount1};
49 
50  ASSERT_EQ(desc_a, desc_b);
51  ASSERT_NE(desc_a, desc_c);
52  }
53  // Sample Count.
54  {
55  TextureDescriptor desc_a = {.type = TextureType::kTexture2DMultisample};
56  TextureDescriptor desc_b = {.type = TextureType::kTexture2DMultisample};
57  TextureDescriptor desc_c = {.type = TextureType::kTexture2D};
58 
59  ASSERT_EQ(desc_a, desc_b);
60  ASSERT_NE(desc_a, desc_c);
61  }
62  // Compression.
63  {
64  TextureDescriptor desc_a = {.compression_type = CompressionType::kLossless};
65  TextureDescriptor desc_b = {.compression_type = CompressionType::kLossless};
66  TextureDescriptor desc_c = {.compression_type = CompressionType::kLossy};
67 
68  ASSERT_EQ(desc_a, desc_b);
69  ASSERT_NE(desc_a, desc_c);
70  }
71  // Mip Count.
72  {
73  TextureDescriptor desc_a = {.mip_count = 1};
74  TextureDescriptor desc_b = {.mip_count = 1};
75  TextureDescriptor desc_c = {.mip_count = 4};
76 
77  ASSERT_EQ(desc_a, desc_b);
78  ASSERT_NE(desc_a, desc_c);
79  }
80 }
ISize64 ISize
Definition: size.h:162

References impeller::TextureDescriptor::compression_type, impeller::TextureDescriptor::format, impeller::kB10G10R10A10XR, impeller::kCount1, impeller::kCount4, impeller::kDevicePrivate, impeller::kHostVisible, impeller::kLossless, impeller::kLossy, impeller::kR8G8B8A8UNormInt, impeller::kTexture2D, impeller::kTexture2DMultisample, impeller::TextureDescriptor::mip_count, impeller::TextureDescriptor::sample_count, impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::type.

◆ TEST() [12/525]

impeller::testing::TEST ( AllocatorVKTest  ,
ImageResourceKeepsVulkanDeviceAlive   
)

Definition at line 77 of file allocator_vk_unittests.cc.

77  {
78  std::shared_ptr<Texture> texture;
79  std::weak_ptr<Allocator> weak_allocator;
80  {
81  auto const context = MockVulkanContextBuilder().Build();
82  weak_allocator = context->GetResourceAllocator();
83  auto allocator = context->GetResourceAllocator();
84 
85  texture = allocator->CreateTexture(TextureDescriptor{
86  .storage_mode = StorageMode::kDevicePrivate,
87  .format = PixelFormat::kR8G8B8A8UNormInt,
88  .size = {1, 1},
89  });
90  context->Shutdown();
91  }
92 
93  ASSERT_TRUE(weak_allocator.lock());
94 }

References impeller::kDevicePrivate, impeller::kR8G8B8A8UNormInt, and impeller::TextureDescriptor::storage_mode.

◆ TEST() [13/525]

impeller::testing::TEST ( AllocatorVKTest  ,
MemoryTypeSelectionSingleHeap   
)

Definition at line 39 of file allocator_vk_unittests.cc.

39  {
40  vk::PhysicalDeviceMemoryProperties properties;
41  properties.memoryTypeCount = 1;
42  properties.memoryHeapCount = 1;
43  properties.memoryTypes[0].heapIndex = 0;
44  properties.memoryTypes[0].propertyFlags =
45  vk::MemoryPropertyFlagBits::eDeviceLocal;
46  properties.memoryHeaps[0].size = 1024 * 1024 * 1024;
47  properties.memoryHeaps[0].flags = vk::MemoryHeapFlagBits::eDeviceLocal;
48 
49  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(1, properties), 0);
50  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(2, properties), -1);
51  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(3, properties), 0);
52 }

References impeller::AllocatorVK::FindMemoryTypeIndex().

◆ TEST() [14/525]

impeller::testing::TEST ( AllocatorVKTest  ,
MemoryTypeSelectionTwoHeap   
)

Definition at line 54 of file allocator_vk_unittests.cc.

54  {
55  vk::PhysicalDeviceMemoryProperties properties;
56  properties.memoryTypeCount = 2;
57  properties.memoryHeapCount = 2;
58  properties.memoryTypes[0].heapIndex = 0;
59  properties.memoryTypes[0].propertyFlags =
60  vk::MemoryPropertyFlagBits::eHostVisible;
61  properties.memoryHeaps[0].size = 1024 * 1024 * 1024;
62  properties.memoryHeaps[0].flags = vk::MemoryHeapFlagBits::eDeviceLocal;
63 
64  properties.memoryTypes[1].heapIndex = 1;
65  properties.memoryTypes[1].propertyFlags =
66  vk::MemoryPropertyFlagBits::eDeviceLocal;
67  properties.memoryHeaps[1].size = 1024 * 1024 * 1024;
68  properties.memoryHeaps[1].flags = vk::MemoryHeapFlagBits::eDeviceLocal;
69 
70  // First fails because this only looks for eDeviceLocal.
71  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(1, properties), -1);
72  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(2, properties), 1);
73  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(3, properties), 1);
74  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(4, properties), -1);
75 }

References impeller::AllocatorVK::FindMemoryTypeIndex().

◆ TEST() [15/525]

impeller::testing::TEST ( AllocatorVKTest  ,
ToVKImageUsageFlags   
)

Definition at line 20 of file allocator_vk_unittests.cc.

20  {
21  EXPECT_EQ(AllocatorVK::ToVKImageUsageFlags(
22  PixelFormat::kR8G8B8A8UNormInt,
23  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget),
24  StorageMode::kDeviceTransient,
25  /*supports_memoryless_textures=*/true),
26  vk::ImageUsageFlagBits::eInputAttachment |
27  vk::ImageUsageFlagBits::eColorAttachment |
28  vk::ImageUsageFlagBits::eTransientAttachment);
29 
30  EXPECT_EQ(AllocatorVK::ToVKImageUsageFlags(
31  PixelFormat::kD24UnormS8Uint,
32  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget),
33  StorageMode::kDeviceTransient,
34  /*supports_memoryless_textures=*/true),
35  vk::ImageUsageFlagBits::eDepthStencilAttachment |
36  vk::ImageUsageFlagBits::eTransientAttachment);
37 }
Mask< TextureUsage > TextureUsageMask
Definition: formats.h:308

References impeller::kD24UnormS8Uint, impeller::kDeviceTransient, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, and impeller::AllocatorVK::ToVKImageUsageFlags().

◆ TEST() [16/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsAllQuadrantsFromFirst   
)

Definition at line 262 of file arc_unittests.cc.

262  {
263  CheckFiveQuadrants(Degrees(90 * 0 + 60), Degrees(330));
264 }

◆ TEST() [17/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsAllQuadrantsFromFourth   
)

Definition at line 274 of file arc_unittests.cc.

274  {
275  CheckFiveQuadrants(Degrees(90 * 3 + 60), Degrees(330));
276 }

◆ TEST() [18/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsAllQuadrantsFromSecond   
)

Definition at line 266 of file arc_unittests.cc.

266  {
267  CheckFiveQuadrants(Degrees(90 * 1 + 60), Degrees(330));
268 }

◆ TEST() [19/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsAllQuadrantsFromThird   
)

Definition at line 270 of file arc_unittests.cc.

270  {
271  CheckFiveQuadrants(Degrees(90 * 2 + 60), Degrees(330));
272 }

◆ TEST() [20/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsFullCircle   
)

Definition at line 125 of file arc_unittests.cc.

125  {
126  // Anything with a sweep <=-360 or >=360 is a full circle regardless of
127  // starting angle
128  for (int start = -720; start < 720; start += 30) {
129  for (int sweep = 360; sweep < 1080; sweep += 45) {
130  TestFullCircleArc(Degrees(start), Degrees(sweep));
131  TestFullCircleArc(Degrees(start), Degrees(-sweep));
132  }
133  }
134 }
const size_t start

References start.

◆ TEST() [21/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsOnlyFirstQuadrant   
)

Definition at line 210 of file arc_unittests.cc.

210  {
211  CheckOneQuadrant(Degrees(90 * 0 + 30), Degrees(30));
212 }

◆ TEST() [22/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsOnlyFourthQuadrant   
)

Definition at line 222 of file arc_unittests.cc.

222  {
223  CheckOneQuadrant(Degrees(90 * 3 + 30), Degrees(30));
224 }

◆ TEST() [23/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsOnlySecondQuadrant   
)

Definition at line 214 of file arc_unittests.cc.

214  {
215  CheckOneQuadrant(Degrees(90 * 1 + 30), Degrees(30));
216 }

◆ TEST() [24/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsOnlyThirdQuadrant   
)

Definition at line 218 of file arc_unittests.cc.

218  {
219  CheckOneQuadrant(Degrees(90 * 2 + 30), Degrees(30));
220 }

◆ TEST() [25/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsVariousEndAnglesNearQuadrantAxis   
)

Definition at line 172 of file arc_unittests.cc.

172  {
173  Tessellator tessellator;
174  const auto trigs = tessellator.GetTrigsForDeviceRadius(100);
175 
176  for (int sweep_i = 5; sweep_i < 20000; sweep_i += 5) {
177  const Degrees sweep(sweep_i * 0.01f);
178  for (int quadrant = -360; quadrant <= 360; quadrant += 90) {
179  const Degrees start(quadrant + 80);
180  Arc arc(Rect::MakeLTRB(10, 10, 20, 20), start, sweep, false);
181  const auto& arc_iteration = arc.ComputeIterations(trigs.GetSteps());
182 
183  TestArcIterator(arc_iteration, trigs, start, sweep,
184  "Various angles(" + std::to_string(start.degrees) +
185  " += " + std::to_string(sweep.degrees));
186  }
187  }
188 }

References impeller::Arc::ComputeIterations(), impeller::Degrees::degrees, impeller::Tessellator::Trigs::GetSteps(), impeller::Tessellator::GetTrigsForDeviceRadius(), impeller::TRect< Scalar >::MakeLTRB(), and start.

◆ TEST() [26/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsVariousStartAnglesNearQuadrantAxis   
)

Definition at line 153 of file arc_unittests.cc.

153  {
154  Tessellator tessellator;
155  const auto trigs = tessellator.GetTrigsForDeviceRadius(100);
156  const Degrees sweep(45);
157 
158  for (int start_i = -1000; start_i < 1000; start_i += 5) {
159  Scalar start_degrees = start_i * 0.01f;
160  for (int quadrant = -360; quadrant <= 360; quadrant += 90) {
161  const Degrees start(quadrant + start_degrees);
162  Arc arc(Rect::MakeLTRB(10, 10, 20, 20), start, sweep, false);
163  const auto& arc_iteration = arc.ComputeIterations(trigs.GetSteps());
164 
165  TestArcIterator(arc_iteration, trigs, start, sweep,
166  "Various angles(" + std::to_string(start.degrees) +
167  " += " + std::to_string(sweep.degrees));
168  }
169  }
170 }

References impeller::Arc::ComputeIterations(), impeller::Degrees::degrees, impeller::Tessellator::Trigs::GetSteps(), impeller::Tessellator::GetTrigsForDeviceRadius(), impeller::TRect< Scalar >::MakeLTRB(), and start.

◆ TEST() [27/525]

impeller::testing::TEST ( ArcTest  ,
ArcIterationsVariousTinyArcsNearQuadrantAxis   
)

Definition at line 190 of file arc_unittests.cc.

190  {
191  Tessellator tessellator;
192  const auto trigs = tessellator.GetTrigsForDeviceRadius(100);
193  const Degrees sweep(0.1f);
194 
195  for (int start_i = -1000; start_i < 1000; start_i += 5) {
196  Scalar start_degrees = start_i * 0.01f;
197  for (int quadrant = -360; quadrant <= 360; quadrant += 90) {
198  const Degrees start(quadrant + start_degrees);
199  Arc arc(Rect::MakeLTRB(10, 10, 20, 20), start, sweep, false);
200  const auto& arc_iteration = arc.ComputeIterations(trigs.GetSteps());
201  ASSERT_EQ(arc_iteration.quadrant_count, 0u);
202 
203  TestArcIterator(arc_iteration, trigs, start, sweep,
204  "Various angles(" + std::to_string(start.degrees) +
205  " += " + std::to_string(sweep.degrees));
206  }
207  }
208 }

References impeller::Arc::ComputeIterations(), impeller::Degrees::degrees, impeller::Tessellator::Trigs::GetSteps(), impeller::Tessellator::GetTrigsForDeviceRadius(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Arc::Iteration::quadrant_count, and start.

◆ TEST() [28/525]

impeller::testing::TEST ( BaseTest  ,
CanUseTypedMasks   
)

Definition at line 259 of file base_unittests.cc.

259  {
260  {
261  MyMask mask;
262  ASSERT_EQ(static_cast<uint32_t>(mask), 0u);
263  ASSERT_FALSE(mask);
264  }
265 
266  {
267  MyMask mask(MyMaskBits::kBar);
268  ASSERT_EQ(static_cast<uint32_t>(mask), 1u);
269  ASSERT_TRUE(mask);
270  }
271 
272  {
273  MyMask mask2(MyMaskBits::kBar);
274  MyMask mask(mask2);
275  ASSERT_EQ(static_cast<uint32_t>(mask), 1u);
276  ASSERT_TRUE(mask);
277  }
278 
279  {
280  MyMask mask2(MyMaskBits::kBar);
281  MyMask mask(std::move(mask2)); // NOLINT
282  ASSERT_EQ(static_cast<uint32_t>(mask), 1u);
283  ASSERT_TRUE(mask);
284  }
285 
286  ASSERT_LT(MyMaskBits::kBar, MyMaskBits::kBaz);
287  ASSERT_LE(MyMaskBits::kBar, MyMaskBits::kBaz);
288  ASSERT_GT(MyMaskBits::kBaz, MyMaskBits::kBar);
289  ASSERT_GE(MyMaskBits::kBaz, MyMaskBits::kBar);
290  ASSERT_EQ(MyMaskBits::kBaz, MyMaskBits::kBaz);
291  ASSERT_NE(MyMaskBits::kBaz, MyMaskBits::kBang);
292 
293  {
294  MyMask m1(MyMaskBits::kBar);
295  MyMask m2(MyMaskBits::kBaz);
296  ASSERT_EQ(static_cast<uint32_t>(m1 & m2), 0u);
297  ASSERT_FALSE(m1 & m2);
298  }
299 
300  {
301  MyMask m1(MyMaskBits::kBar);
302  MyMask m2(MyMaskBits::kBaz);
303  ASSERT_EQ(static_cast<uint32_t>(m1 | m2), ((1u << 0u) | (1u << 1u)));
304  ASSERT_TRUE(m1 | m2);
305  }
306 
307  {
308  MyMask m1(MyMaskBits::kBar);
309  MyMask m2(MyMaskBits::kBaz);
310  ASSERT_EQ(static_cast<uint32_t>(m1 ^ m2), ((1u << 0u) ^ (1u << 1u)));
311  ASSERT_TRUE(m1 ^ m2);
312  }
313 
314  {
315  MyMask m1(MyMaskBits::kBar);
316  ASSERT_EQ(static_cast<uint32_t>(~m1), (~(1u << 0u)));
317  ASSERT_TRUE(m1);
318  }
319 
320  {
321  MyMask m1 = MyMaskBits::kBar;
322  MyMask m2 = MyMaskBits::kBaz;
323  m2 = m1;
324  ASSERT_EQ(m2, MyMaskBits::kBar);
325  }
326 
327  {
328  MyMask m = MyMaskBits::kBar | MyMaskBits::kBaz;
329  ASSERT_TRUE(m);
330  }
331 
332  {
333  MyMask m = MyMaskBits::kBar & MyMaskBits::kBaz;
334  ASSERT_FALSE(m);
335  }
336 
337  {
338  MyMask m = MyMaskBits::kBar ^ MyMaskBits::kBaz;
339  ASSERT_TRUE(m);
340  }
341 
342  {
343  MyMask m = ~MyMaskBits::kBar;
344  ASSERT_TRUE(m);
345  }
346 
347  {
348  MyMask m1 = MyMaskBits::kBar;
349  MyMask m2 = MyMaskBits::kBaz;
350  m2 |= m1;
351  ASSERT_EQ(m1, MyMaskBits::kBar);
352  MyMask pred = MyMaskBits::kBar | MyMaskBits::kBaz;
353  ASSERT_EQ(m2, pred);
354  }
355 
356  {
357  MyMask m1 = MyMaskBits::kBar;
358  MyMask m2 = MyMaskBits::kBaz;
359  m2 &= m1;
360  ASSERT_EQ(m1, MyMaskBits::kBar);
361  MyMask pred = MyMaskBits::kBar & MyMaskBits::kBaz;
362  ASSERT_EQ(m2, pred);
363  }
364 
365  {
366  MyMask m1 = MyMaskBits::kBar;
367  MyMask m2 = MyMaskBits::kBaz;
368  m2 ^= m1;
369  ASSERT_EQ(m1, MyMaskBits::kBar);
370  MyMask pred = MyMaskBits::kBar ^ MyMaskBits::kBaz;
371  ASSERT_EQ(m2, pred);
372  }
373 
374  {
375  MyMask x = MyMaskBits::kBar;
376  MyMask m = x | MyMaskBits::kBaz;
377  ASSERT_TRUE(m);
378  }
379 
380  {
381  MyMask x = MyMaskBits::kBar;
382  MyMask m = MyMaskBits::kBaz | x;
383  ASSERT_TRUE(m);
384  }
385 
386  {
387  MyMask x = MyMaskBits::kBar;
388  MyMask m = x & MyMaskBits::kBaz;
389  ASSERT_FALSE(m);
390  }
391 
392  {
393  MyMask x = MyMaskBits::kBar;
394  MyMask m = MyMaskBits::kBaz & x;
395  ASSERT_FALSE(m);
396  }
397 
398  {
399  MyMask x = MyMaskBits::kBar;
400  MyMask m = x ^ MyMaskBits::kBaz;
401  ASSERT_TRUE(m);
402  }
403 
404  {
405  MyMask x = MyMaskBits::kBar;
406  MyMask m = MyMaskBits::kBaz ^ x;
407  ASSERT_TRUE(m);
408  }
409 
410  {
411  MyMask x = MyMaskBits::kBar;
412  MyMask m = ~x;
413  ASSERT_TRUE(m);
414  }
415 
416  {
417  MyMaskBits x = MyMaskBits::kBar;
418  MyMask m = MyMaskBits::kBaz;
419  ASSERT_TRUE(x < m);
420  ASSERT_TRUE(x <= m);
421  }
422 
423  {
424  MyMaskBits x = MyMaskBits::kBar;
425  MyMask m = MyMaskBits::kBaz;
426  ASSERT_FALSE(x == m);
427  }
428 
429  {
430  MyMaskBits x = MyMaskBits::kBar;
431  MyMask m = MyMaskBits::kBaz;
432  ASSERT_TRUE(x != m);
433  }
434 
435  {
436  MyMaskBits x = MyMaskBits::kBar;
437  MyMask m = MyMaskBits::kBaz;
438  ASSERT_FALSE(x > m);
439  ASSERT_FALSE(x >= m);
440  }
441 }
Mask< MyMaskBits > MyMask

References impeller::kBang, impeller::kBar, impeller::kBaz, and x.

◆ TEST() [29/525]

impeller::testing::TEST ( BaseTest  ,
NoExceptionPromiseEmpty   
)

Definition at line 250 of file base_unittests.cc.

250  {
251  auto wrapper = std::make_shared<NoExceptionPromise<int>>();
252  std::future future = wrapper->get_future();
253 
254  // Destroy the empty promise with the future still pending. Verify that the
255  // process does not abort while destructing the promise.
256  wrapper.reset();
257 }

◆ TEST() [30/525]

impeller::testing::TEST ( BaseTest  ,
NoExceptionPromiseValue   
)

Definition at line 243 of file base_unittests.cc.

243  {
244  NoExceptionPromise<int> wrapper;
245  std::future future = wrapper.get_future();
246  wrapper.set_value(123);
247  ASSERT_EQ(future.get(), 123);
248 }

References impeller::NoExceptionPromise< T >::get_future(), and impeller::NoExceptionPromise< T >::set_value().

◆ TEST() [31/525]

impeller::testing::TEST ( BlitCommandGLESTest  ,
BlitCopyTextureToBufferCommandGLESBindsFramebuffer   
)

Definition at line 39 of file blit_command_gles_unittests.cc.

39  {
40  auto mock_gles_impl = std::make_unique<MockGLESImpl>();
41  auto& mock_gles_impl_ref = *mock_gles_impl;
42 
43  EXPECT_CALL(mock_gles_impl_ref, GenFramebuffers(1, _))
44  .WillOnce(::testing::SetArgPointee<1>(3));
45  EXPECT_CALL(mock_gles_impl_ref, GenTextures(1, _))
46  .WillOnce(::testing::SetArgPointee<1>(1));
47  EXPECT_CALL(mock_gles_impl_ref, BindFramebuffer(GL_FRAMEBUFFER, 3)).Times(1);
48  EXPECT_CALL(mock_gles_impl_ref, CheckFramebufferStatus(GL_FRAMEBUFFER))
49  .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE));
50  EXPECT_CALL(mock_gles_impl_ref, ReadPixels(_, _, _, _, _, _, _)).Times(1);
51  EXPECT_CALL(mock_gles_impl_ref, BindFramebuffer(GL_FRAMEBUFFER, 0)).Times(1);
52 
53  std::shared_ptr<MockGLES> mock_gl = MockGLES::Init(std::move(mock_gles_impl));
54  auto reactor = std::make_shared<TestReactorGLES>();
55  auto worker = std::make_shared<MockWorker>();
56  reactor->AddWorker(worker);
57 
58  // Create source texture.
59  TextureDescriptor src_tex_desc;
60  src_tex_desc.format = PixelFormat::kR8G8B8A8UNormInt;
61  src_tex_desc.size = {10, 10};
62  src_tex_desc.usage =
63  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
64  auto source_texture = std::make_shared<TextureGLES>(reactor, src_tex_desc);
65  // Avoids the flip which would crash.
66  source_texture->SetCoordinateSystem(TextureCoordinateSystem::kUploadFromHost);
67 
68  // Create destination buffer.
69  DeviceBufferDescriptor dest_buffer_desc;
70  dest_buffer_desc.size = 10 * 10 * 4;
71  dest_buffer_desc.storage_mode = StorageMode::kHostVisible;
72  auto allocation = std::make_shared<Allocation>();
73  ASSERT_TRUE(allocation->Truncate(Bytes(dest_buffer_desc.size)));
74  auto dest_buffer =
75  std::make_shared<DeviceBufferGLES>(dest_buffer_desc, reactor, allocation);
76 
77  ASSERT_TRUE(reactor->React());
78 
79  BlitCopyTextureToBufferCommandGLES command;
80  command.source = source_texture;
81  command.destination = dest_buffer;
82  command.source_region =
83  IRect::MakeSize(source_texture->GetTextureDescriptor().size);
84  command.label = "TestBlit";
85 
86  EXPECT_TRUE(command.Encode(*reactor));
87 
88  source_texture.reset();
89  dest_buffer.reset();
90 
91  ASSERT_TRUE(reactor->React());
92 }

References impeller::BlitCopyTextureToBufferCommand::destination, impeller::BlitCopyTextureToBufferCommandGLES::Encode(), impeller::TextureDescriptor::format, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kUploadFromHost, impeller::BlitCommand::label, impeller::TRect< T >::MakeSize(), impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::BlitCopyTextureToBufferCommand::source, impeller::BlitCopyTextureToBufferCommand::source_region, impeller::DeviceBufferDescriptor::storage_mode, and impeller::TextureDescriptor::usage.

◆ TEST() [32/525]

impeller::testing::TEST ( BufferBindingsGLESTest  ,
BindArrayData   
)

Definition at line 51 of file buffer_bindings_gles_unittests.cc.

51  {
52  BufferBindingsGLES bindings;
53  absl::flat_hash_map<std::string, GLint> uniform_bindings;
54  uniform_bindings["SHADERMETADATA.FOOBAR[0]"] = 1;
55  bindings.SetUniformBindings(std::move(uniform_bindings));
56  auto mock_gles_impl = std::make_unique<MockGLESImpl>();
57 
58  EXPECT_CALL(*mock_gles_impl, Uniform1fv(_, _, _)).Times(1);
59 
60  std::shared_ptr<MockGLES> mock_gl = MockGLES::Init(std::move(mock_gles_impl));
61  std::vector<BufferResource> bound_buffers;
62  std::vector<TextureAndSampler> bound_textures;
63 
64  ShaderMetadata shader_metadata = {
65  .name = "shader_metadata",
66  .members = {ShaderStructMemberMetadata{.type = ShaderType::kFloat,
67  .name = "foobar",
68  .offset = 0,
69  .size = sizeof(float),
70  .byte_length = sizeof(float) * 4,
71  .array_elements = 4}}};
72  std::shared_ptr<ReactorGLES> reactor;
73  std::shared_ptr<Allocation> backing_store = std::make_shared<Allocation>();
74  ASSERT_TRUE(backing_store->Truncate(Bytes{sizeof(float) * 4}));
75  DeviceBufferGLES device_buffer(
76  DeviceBufferDescriptor{.size = sizeof(float) * 4}, reactor,
77  backing_store);
78  BufferView buffer_view(&device_buffer, Range(0, sizeof(float)));
79  bound_buffers.push_back(BufferResource(&shader_metadata, buffer_view));
80 
81  EXPECT_TRUE(bindings.BindUniformData(mock_gl->GetProcTable(), bound_textures,
82  bound_buffers, Range{0, 0},
83  Range{0, 1}));
84 }
BufferView buffer_view
Resource< BufferView > BufferResource
Definition: command.h:55

References impeller::BufferBindingsGLES::BindUniformData(), buffer_view, impeller::kFloat, impeller::ShaderMetadata::name, impeller::DeviceBufferDescriptor::size, and impeller::ShaderStructMemberMetadata::type.

◆ TEST() [33/525]

impeller::testing::TEST ( BufferBindingsGLESTest  ,
BindUniformData   
)

Definition at line 17 of file buffer_bindings_gles_unittests.cc.

17  {
18  BufferBindingsGLES bindings;
19  absl::flat_hash_map<std::string, GLint> uniform_bindings;
20  uniform_bindings["SHADERMETADATA.FOOBAR"] = 1;
21  bindings.SetUniformBindings(std::move(uniform_bindings));
22  auto mock_gles_impl = std::make_unique<MockGLESImpl>();
23 
24  EXPECT_CALL(*mock_gles_impl, Uniform1fv(_, _, _)).Times(1);
25 
26  std::shared_ptr<MockGLES> mock_gl = MockGLES::Init(std::move(mock_gles_impl));
27  std::vector<BufferResource> bound_buffers;
28  std::vector<TextureAndSampler> bound_textures;
29 
30  ShaderMetadata shader_metadata = {
31  .name = "shader_metadata",
32  .members = {ShaderStructMemberMetadata{.type = ShaderType::kFloat,
33  .name = "foobar",
34  .offset = 0,
35  .size = sizeof(float),
36  .byte_length = sizeof(float),
37  .array_elements = 0}}};
38  std::shared_ptr<ReactorGLES> reactor;
39  std::shared_ptr<Allocation> backing_store = std::make_shared<Allocation>();
40  ASSERT_TRUE(backing_store->Truncate(Bytes{sizeof(float)}));
41  DeviceBufferGLES device_buffer(DeviceBufferDescriptor{.size = sizeof(float)},
42  reactor, backing_store);
43  BufferView buffer_view(&device_buffer, Range(0, sizeof(float)));
44  bound_buffers.push_back(BufferResource(&shader_metadata, buffer_view));
45 
46  EXPECT_TRUE(bindings.BindUniformData(mock_gl->GetProcTable(), bound_textures,
47  bound_buffers, Range{0, 0},
48  Range{0, 1}));
49 }

References impeller::BufferBindingsGLES::BindUniformData(), buffer_view, impeller::kFloat, impeller::ShaderMetadata::name, impeller::DeviceBufferDescriptor::size, and impeller::ShaderStructMemberMetadata::type.

◆ TEST() [34/525]

impeller::testing::TEST ( BufferViewTest  ,
Empty   
)

Definition at line 11 of file buffer_view_unittests.cc.

11  {
12  BufferView buffer_view;
13  EXPECT_FALSE(buffer_view);
14 }

References buffer_view.

◆ TEST() [35/525]

impeller::testing::TEST ( BufferViewTest  ,
TakeRaw   
)

Definition at line 16 of file buffer_view_unittests.cc.

16  {
17  DeviceBuffer* buffer = reinterpret_cast<DeviceBuffer*>(0xcafebabe);
18  BufferView buffer_view(buffer, {0, 123});
19  EXPECT_TRUE(buffer_view);
20  std::shared_ptr<const DeviceBuffer> taken = buffer_view.TakeBuffer();
21  EXPECT_FALSE(taken);
22  EXPECT_EQ(buffer_view.GetBuffer(), buffer);
23 }

References buffer_view.

◆ TEST() [36/525]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultColorFormat   
)

Definition at line 34 of file capabilities_unittests.cc.

34  {
35  auto defaults = CapabilitiesBuilder().Build();
36  EXPECT_EQ(defaults->GetDefaultColorFormat(), PixelFormat::kUnknown);
37  auto mutated = CapabilitiesBuilder()
38  .SetDefaultColorFormat(PixelFormat::kB10G10R10A10XR)
39  .Build();
40  EXPECT_EQ(mutated->GetDefaultColorFormat(), PixelFormat::kB10G10R10A10XR);
41 }

References impeller::CapabilitiesBuilder::Build(), impeller::kB10G10R10A10XR, impeller::kUnknown, and impeller::CapabilitiesBuilder::SetDefaultColorFormat().

◆ TEST() [37/525]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultDepthStencilFormat   
)

Definition at line 52 of file capabilities_unittests.cc.

52  {
53  auto defaults = CapabilitiesBuilder().Build();
54  EXPECT_EQ(defaults->GetDefaultDepthStencilFormat(), PixelFormat::kUnknown);
55  auto mutated = CapabilitiesBuilder()
56  .SetDefaultDepthStencilFormat(PixelFormat::kD32FloatS8UInt)
57  .Build();
58  EXPECT_EQ(mutated->GetDefaultDepthStencilFormat(),
59  PixelFormat::kD32FloatS8UInt);
60 }

References impeller::CapabilitiesBuilder::Build(), impeller::kD32FloatS8UInt, impeller::kUnknown, and impeller::CapabilitiesBuilder::SetDefaultDepthStencilFormat().

◆ TEST() [38/525]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultGlyphAtlasFormat   
)

Definition at line 62 of file capabilities_unittests.cc.

62  {
63  auto defaults = CapabilitiesBuilder().Build();
64  EXPECT_EQ(defaults->GetDefaultGlyphAtlasFormat(), PixelFormat::kUnknown);
65  auto mutated = CapabilitiesBuilder()
66  .SetDefaultGlyphAtlasFormat(PixelFormat::kA8UNormInt)
67  .Build();
68  EXPECT_EQ(mutated->GetDefaultGlyphAtlasFormat(), PixelFormat::kA8UNormInt);
69 }

References impeller::CapabilitiesBuilder::Build(), impeller::kA8UNormInt, impeller::kUnknown, and impeller::CapabilitiesBuilder::SetDefaultGlyphAtlasFormat().

◆ TEST() [39/525]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultStencilFormat   
)

Definition at line 43 of file capabilities_unittests.cc.

43  {
44  auto defaults = CapabilitiesBuilder().Build();
45  EXPECT_EQ(defaults->GetDefaultStencilFormat(), PixelFormat::kUnknown);
46  auto mutated = CapabilitiesBuilder()
47  .SetDefaultStencilFormat(PixelFormat::kS8UInt)
48  .Build();
49  EXPECT_EQ(mutated->GetDefaultStencilFormat(), PixelFormat::kS8UInt);
50 }

References impeller::CapabilitiesBuilder::Build(), impeller::kS8UInt, impeller::kUnknown, and impeller::CapabilitiesBuilder::SetDefaultStencilFormat().

◆ TEST() [40/525]

impeller::testing::TEST ( CapabilitiesTest  ,
MaxRenderPassAttachmentSize   
)

Definition at line 71 of file capabilities_unittests.cc.

71  {
72  auto defaults = CapabilitiesBuilder().Build();
73  EXPECT_EQ(defaults->GetMaximumRenderPassAttachmentSize(), ISize(1, 1));
74  auto mutated = CapabilitiesBuilder()
75  .SetMaximumRenderPassAttachmentSize({100, 100})
76  .Build();
77  EXPECT_EQ(mutated->GetMaximumRenderPassAttachmentSize(), ISize(100, 100));
78 }

References impeller::CapabilitiesBuilder::Build(), and impeller::CapabilitiesBuilder::SetMaximumRenderPassAttachmentSize().

◆ TEST() [41/525]

impeller::testing::TEST ( CapabilitiesTest  ,
MinUniformAlignment   
)

Definition at line 80 of file capabilities_unittests.cc.

80  {
81  auto defaults = CapabilitiesBuilder().Build();
82  EXPECT_EQ(defaults->GetMinimumUniformAlignment(), 256u);
83  auto mutated = CapabilitiesBuilder().SetMinimumUniformAlignment(16).Build();
84  EXPECT_EQ(mutated->GetMinimumUniformAlignment(), 16u);
85 }

References impeller::CapabilitiesBuilder::Build(), and impeller::CapabilitiesBuilder::SetMinimumUniformAlignment().

◆ TEST() [42/525]

impeller::testing::TEST ( CapabilitiesVKTest  ,
ContextFailsInitializationForNoCombinedDepthStencilFormat   
)

Definition at line 215 of file context_vk_unittests.cc.

216  {
217  ScopedValidationDisable disable_validation;
218  const std::shared_ptr<ContextVK> context =
219  MockVulkanContextBuilder()
220  .SetPhysicalDeviceFormatPropertiesCallback(
221  [](VkPhysicalDevice physicalDevice, VkFormat format,
222  VkFormatProperties* pFormatProperties) {
223  if (format == VK_FORMAT_R8G8B8A8_UNORM) {
224  pFormatProperties->optimalTilingFeatures =
225  static_cast<VkFormatFeatureFlags>(
226  vk::FormatFeatureFlagBits::eColorAttachment);
227  }
228  // Ignore combined depth-stencil formats.
229  })
230  .Build();
231  ASSERT_EQ(context, nullptr);
232 }

◆ TEST() [43/525]

impeller::testing::TEST ( CapabilitiesVKTest  ,
ContextInitializesWithNoStencilFormat   
)

Definition at line 184 of file context_vk_unittests.cc.

184  {
185  const std::shared_ptr<ContextVK> context =
186  MockVulkanContextBuilder()
187  .SetPhysicalDeviceFormatPropertiesCallback(
188  [](VkPhysicalDevice physicalDevice, VkFormat format,
189  VkFormatProperties* pFormatProperties) {
190  if (format == VK_FORMAT_R8G8B8A8_UNORM) {
191  pFormatProperties->optimalTilingFeatures =
192  static_cast<VkFormatFeatureFlags>(
193  vk::FormatFeatureFlagBits::eColorAttachment);
194  } else if (format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
195  pFormatProperties->optimalTilingFeatures =
196  static_cast<VkFormatFeatureFlags>(
197  vk::FormatFeatureFlagBits::eDepthStencilAttachment);
198  }
199  // Ignore just the stencil format.
200  })
201  .Build();
202  ASSERT_NE(context, nullptr);
203  const CapabilitiesVK* capabilites_vk =
204  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
205  ASSERT_EQ(capabilites_vk->GetDefaultDepthStencilFormat(),
206  PixelFormat::kD32FloatS8UInt);
207  ASSERT_EQ(capabilites_vk->GetDefaultStencilFormat(),
208  PixelFormat::kD32FloatS8UInt);
209 }

References impeller::CapabilitiesVK::GetDefaultDepthStencilFormat(), impeller::CapabilitiesVK::GetDefaultStencilFormat(), and impeller::kD32FloatS8UInt.

◆ TEST() [44/525]

impeller::testing::TEST ( CommandEncoderVKTest  ,
CleanupAfterSubmit   
)

Definition at line 37 of file command_encoder_vk_unittests.cc.

37  {
38  // This tests deleting the TrackedObjects where the thread is killed before
39  // the fence waiter has disposed of them, making sure the command buffer and
40  // its pools are deleted in that order.
41  std::shared_ptr<std::vector<std::string>> called_functions;
42  {
43  fml::AutoResetWaitableEvent wait_for_submit;
44  fml::AutoResetWaitableEvent wait_for_thread_join;
45  auto context = MockVulkanContextBuilder().Build();
46  std::thread thread([&] {
47  auto buffer = context->CreateCommandBuffer();
48  context->GetCommandQueue()->Submit(
49  {buffer}, [&](CommandBuffer::Status status) {
50  ASSERT_EQ(status, CommandBuffer::Status::kCompleted);
51  wait_for_thread_join.Wait();
52  wait_for_submit.Signal();
53  });
54  });
55  thread.join();
56  wait_for_thread_join.Signal();
57  wait_for_submit.Wait();
58  called_functions = GetMockVulkanFunctions(context->GetDevice());
59  context->Shutdown();
60  }
61 
62  auto destroy_pool =
63  std::find(called_functions->begin(), called_functions->end(),
64  "vkDestroyCommandPool");
65  auto free_buffers =
66  std::find(called_functions->begin(), called_functions->end(),
67  "vkFreeCommandBuffers");
68  EXPECT_TRUE(destroy_pool != called_functions->end());
69  EXPECT_TRUE(free_buffers != called_functions->end());
70  EXPECT_TRUE(free_buffers < destroy_pool);
71 }

References impeller::CommandBuffer::kCompleted.

◆ TEST() [45/525]

impeller::testing::TEST ( CommandEncoderVKTest  ,
DeleteEncoderAfterThreadDies   
)

Definition at line 15 of file command_encoder_vk_unittests.cc.

15  {
16  // Tests that when a CommandEncoderVK is deleted that it will clean up its
17  // command buffers before it cleans up its command pool.
18  std::shared_ptr<std::vector<std::string>> called_functions;
19  {
20  auto context = MockVulkanContextBuilder().Build();
21  called_functions = GetMockVulkanFunctions(context->GetDevice());
22  std::thread thread([&] { context->CreateCommandBuffer(); });
23  thread.join();
24  context->Shutdown();
25  }
26  auto destroy_pool =
27  std::find(called_functions->begin(), called_functions->end(),
28  "vkDestroyCommandPool");
29  auto free_buffers =
30  std::find(called_functions->begin(), called_functions->end(),
31  "vkFreeCommandBuffers");
32  EXPECT_TRUE(destroy_pool != called_functions->end());
33  EXPECT_TRUE(free_buffers != called_functions->end());
34  EXPECT_TRUE(free_buffers < destroy_pool);
35 }

◆ TEST() [46/525]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
CommandBuffersAreRecycled   
)

Definition at line 137 of file command_pool_vk_unittests.cc.

137  {
138  auto const context = MockVulkanContextBuilder().Build();
139 
140  {
141  // Fetch a pool (which will be created).
142  auto const recycler = context->GetCommandPoolRecycler();
143  auto pool = recycler->Get();
144 
145  auto buffer = pool->CreateCommandBuffer();
146  pool->CollectCommandBuffer(std::move(buffer));
147 
148  // This normally is called at the end of a frame.
149  recycler->Dispose();
150  }
151 
152  WaitForReclaim(context);
153 
154  {
155  // Create a second pool and command buffer, which should reused the existing
156  // pool and cmd buffer.
157  auto const recycler = context->GetCommandPoolRecycler();
158  auto pool = recycler->Get();
159 
160  auto buffer = pool->CreateCommandBuffer();
161  pool->CollectCommandBuffer(std::move(buffer));
162 
163  // This normally is called at the end of a frame.
164  recycler->Dispose();
165  }
166 
167  // Now check that we only ever created one pool and one command buffer.
168  auto const called = ReclaimAndGetMockVulkanFunctions(context);
169  EXPECT_EQ(std::count(called->begin(), called->end(), "vkCreateCommandPool"),
170  1u);
171  EXPECT_EQ(
172  std::count(called->begin(), called->end(), "vkAllocateCommandBuffers"),
173  1u);
174 
175  context->Shutdown();
176 }

◆ TEST() [47/525]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
ExtraCommandBufferAllocationsTriggerTrim   
)

Definition at line 178 of file command_pool_vk_unittests.cc.

178  {
179  auto const context = MockVulkanContextBuilder().Build();
180 
181  {
182  // Fetch a pool (which will be created).
183  auto const recycler = context->GetCommandPoolRecycler();
184  auto pool = recycler->Get();
185 
186  // Allocate a large number of command buffers
187  for (auto i = 0; i < 64; i++) {
188  auto buffer = pool->CreateCommandBuffer();
189  pool->CollectCommandBuffer(std::move(buffer));
190  }
191 
192  // This normally is called at the end of a frame.
193  recycler->Dispose();
194  }
195 
196  // Command pool is reset but does not release resources.
197  auto called = ReclaimAndGetMockVulkanFunctions(context);
198  EXPECT_EQ(std::count(called->begin(), called->end(), "vkResetCommandPool"),
199  1u);
200 
201  // Create the pool a second time, but dont use any command buffers.
202  {
203  // Fetch a pool (which will be created).
204  auto const recycler = context->GetCommandPoolRecycler();
205  auto pool = recycler->Get();
206 
207  // This normally is called at the end of a frame.
208  recycler->Dispose();
209  }
210 
211  // Verify that the cmd pool was trimmed.
212 
213  // Now check that we only ever created one pool and one command buffer.
214  called = ReclaimAndGetMockVulkanFunctions(context);
215  EXPECT_EQ(std::count(called->begin(), called->end(),
216  "vkResetCommandPoolReleaseResources"),
217  1u);
218 
219  context->Shutdown();
220 }

◆ TEST() [48/525]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
GetsACommandPoolPerThread   
)

Definition at line 14 of file command_pool_vk_unittests.cc.

14  {
15  auto const context = MockVulkanContextBuilder().Build();
16 
17  {
18  // Record the memory location of each pointer to a command pool.
19  //
20  // These pools have to be held at this context, otherwise they will be
21  // dropped and recycled and potentially reused by another thread, causing
22  // flaky tests.
23  std::shared_ptr<CommandPoolVK> pool1;
24  std::shared_ptr<CommandPoolVK> pool2;
25 
26  // Create a command pool in two threads and record the memory location.
27  std::thread thread1(
28  [&]() { pool1 = context->GetCommandPoolRecycler()->Get(); });
29 
30  std::thread thread2(
31  [&]() { pool2 = context->GetCommandPoolRecycler()->Get(); });
32 
33  thread1.join();
34  thread2.join();
35 
36  // The two command pools should be different.
37  EXPECT_NE(pool1, pool2);
38  }
39 
40  context->Shutdown();
41 }

◆ TEST() [49/525]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
GetsTheSameCommandPoolOnSameThread   
)

Definition at line 43 of file command_pool_vk_unittests.cc.

43  {
44  auto const context = MockVulkanContextBuilder().Build();
45 
46  auto const pool1 = context->GetCommandPoolRecycler()->Get();
47  auto const pool2 = context->GetCommandPoolRecycler()->Get();
48 
49  // The two command pools should be the same.
50  EXPECT_EQ(pool1.get(), pool2.get());
51 
52  context->Shutdown();
53 }

◆ TEST() [50/525]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
ReclaimMakesCommandPoolAvailable   
)

Definition at line 107 of file command_pool_vk_unittests.cc.

107  {
108  auto const context = MockVulkanContextBuilder().Build();
109 
110  {
111  // Fetch a pool (which will be created).
112  auto const recycler = context->GetCommandPoolRecycler();
113  auto const pool = recycler->Get();
114 
115  // This normally is called at the end of a frame.
116  recycler->Dispose();
117  }
118 
119  WaitForReclaim(context);
120 
121  // On another thread explicitly, request a new pool.
122  std::thread thread([&]() {
123  auto const pool = context->GetCommandPoolRecycler()->Get();
124  EXPECT_NE(pool.get(), nullptr);
125  });
126 
127  thread.join();
128 
129  // Now check that we only ever created one pool.
130  auto const called = ReclaimAndGetMockVulkanFunctions(context);
131  EXPECT_EQ(std::count(called->begin(), called->end(), "vkCreateCommandPool"),
132  1u);
133 
134  context->Shutdown();
135 }

◆ TEST() [51/525]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
RecyclerGlobalPoolMapSize   
)

Definition at line 222 of file command_pool_vk_unittests.cc.

222  {
223  auto context = MockVulkanContextBuilder().Build();
224  auto const recycler = context->GetCommandPoolRecycler();
225 
226  // The global pool list for this context should initially be empty.
227  EXPECT_EQ(CommandPoolRecyclerVK::GetGlobalPoolCount(*context), 0);
228 
229  // Creating a pool for this thread should insert the pool into the global map.
230  auto pool = recycler->Get();
231  EXPECT_EQ(CommandPoolRecyclerVK::GetGlobalPoolCount(*context), 1);
232 
233  // Disposing this thread's pool should remove it from the global map.
234  pool.reset();
235  recycler->Dispose();
236  EXPECT_EQ(CommandPoolRecyclerVK::GetGlobalPoolCount(*context), 0);
237 
238  context->Shutdown();
239 }

References impeller::CommandPoolRecyclerVK::GetGlobalPoolCount().

◆ TEST() [52/525]

impeller::testing::TEST ( ConditionVariableTest  ,
TestsCriticalSectionAfterWait   
)

Definition at line 197 of file base_unittests.cc.

197  {
198  std::vector<std::thread> threads;
199  const auto kThreadCount = 10u;
200 
201  Mutex mtx;
202  ConditionVariable cv;
203  size_t sum = 0u;
204 
205  std::condition_variable start_cv;
206  std::mutex start_mtx;
207  bool start = false;
208  auto start_predicate = [&start]() { return start; };
209  auto thread_main = [&]() {
210  {
211  std::unique_lock start_lock(start_mtx);
212  start_cv.wait(start_lock, start_predicate);
213  }
214 
215  mtx.Lock();
216  cv.Wait(mtx, []() { return true; });
217  auto old_val = sum;
218  std::this_thread::sleep_for(std::chrono::milliseconds{100u});
219  sum = old_val + 1u;
220  mtx.Unlock();
221  };
222  // Launch all threads. They will wait for the start CV to be signaled.
223  threads.reserve(kThreadCount);
224  for (size_t i = 0; i < kThreadCount; i++) {
225  threads.emplace_back(thread_main);
226  }
227  // Notify all threads that the test may start.
228  {
229  {
230  std::scoped_lock start_lock(start_mtx);
231  start = true;
232  }
233  start_cv.notify_all();
234  }
235  // Join all threads.
236  ASSERT_EQ(threads.size(), kThreadCount);
237  for (size_t i = 0; i < kThreadCount; i++) {
238  threads[i].join();
239  }
240  ASSERT_EQ(sum, kThreadCount);
241 }

References start, and impeller::ConditionVariable::Wait().

◆ TEST() [53/525]

impeller::testing::TEST ( ConditionVariableTest  ,
TestsCriticalSectionAfterWaitForUntil   
)

Definition at line 151 of file base_unittests.cc.

151  {
152  std::vector<std::thread> threads;
153  const auto kThreadCount = 10u;
154 
155  Mutex mtx;
156  ConditionVariable cv;
157  size_t sum = 0u;
158 
159  std::condition_variable start_cv;
160  std::mutex start_mtx;
161  bool start = false;
162  auto start_predicate = [&start]() { return start; };
163  auto thread_main = [&]() {
164  {
165  std::unique_lock start_lock(start_mtx);
166  start_cv.wait(start_lock, start_predicate);
167  }
168 
169  mtx.Lock();
170  cv.WaitFor(mtx, std::chrono::milliseconds{0u}, []() { return true; });
171  auto old_val = sum;
172  std::this_thread::sleep_for(std::chrono::milliseconds{100u});
173  sum = old_val + 1u;
174  mtx.Unlock();
175  };
176  // Launch all threads. They will wait for the start CV to be signaled.
177  threads.reserve(kThreadCount);
178  for (size_t i = 0; i < kThreadCount; i++) {
179  threads.emplace_back(thread_main);
180  }
181  // Notify all threads that the test may start.
182  {
183  {
184  std::scoped_lock start_lock(start_mtx);
185  start = true;
186  }
187  start_cv.notify_all();
188  }
189  // Join all threads.
190  ASSERT_EQ(threads.size(), kThreadCount);
191  for (size_t i = 0; i < kThreadCount; i++) {
192  threads[i].join();
193  }
194  ASSERT_EQ(sum, kThreadCount);
195 }

References start, and impeller::ConditionVariable::WaitFor().

◆ TEST() [54/525]

impeller::testing::TEST ( ConditionVariableTest  ,
WaitFor   
)

Definition at line 113 of file base_unittests.cc.

113  {
114  CVTest test;
115  // test.rando_ivar = 12; // <--- Static analysis error
116  for (size_t i = 0; i < 2; ++i) {
117  test.mutex.Lock(); // <--- Static analysis error without this.
118  auto result = test.cv.WaitFor(
119  test.mutex, std::chrono::milliseconds{10},
120  [&]() IPLR_REQUIRES(test.mutex) {
121  test.rando_ivar = 12; // <-- Static analysics error without the
122  // IPLR_REQUIRES on the pred.
123  return false;
124  });
125  test.mutex.Unlock();
126  ASSERT_FALSE(result);
127  }
128  Lock lock(test.mutex); // <--- Static analysis error without this.
129  // The predicate never returns true. So return has to be due to a non-spurious
130  // wake.
131  ASSERT_EQ(test.rando_ivar, 12u);
132 }
#define IPLR_REQUIRES(...)
Definition: thread_safety.h:30

References impeller::testing::CVTest::cv, IPLR_REQUIRES, impeller::testing::CVTest::mutex, and impeller::ConditionVariable::WaitFor().

◆ TEST() [55/525]

impeller::testing::TEST ( ConditionVariableTest  ,
WaitForever   
)

Definition at line 134 of file base_unittests.cc.

134  {
135  CVTest test;
136  // test.rando_ivar = 12; // <--- Static analysis error
137  for (size_t i = 0; i < 2; ++i) {
138  test.mutex.Lock(); // <--- Static analysis error without this.
139  test.cv.Wait(test.mutex, [&]() IPLR_REQUIRES(test.mutex) {
140  test.rando_ivar = 12; // <-- Static analysics error without
141  // the IPLR_REQUIRES on the pred.
142  return true;
143  });
144  test.mutex.Unlock();
145  }
146  Lock lock(test.mutex); // <--- Static analysis error without this.
147  // The wake only happens when the predicate returns true.
148  ASSERT_EQ(test.rando_ivar, 12u);
149 }

References impeller::testing::CVTest::cv, IPLR_REQUIRES, impeller::testing::CVTest::mutex, and impeller::ConditionVariable::Wait().

◆ TEST() [56/525]

impeller::testing::TEST ( ConditionVariableTest  ,
WaitUntil   
)

Definition at line 90 of file base_unittests.cc.

90  {
91  CVTest test;
92  // test.rando_ivar = 12; // <--- Static analysis error
93  for (size_t i = 0; i < 2; ++i) {
94  test.mutex.Lock(); // <--- Static analysis error without this.
95  auto result = test.cv.WaitUntil(
96  test.mutex,
97  std::chrono::high_resolution_clock::now() +
98  std::chrono::milliseconds{10},
99  [&]() IPLR_REQUIRES(test.mutex) {
100  test.rando_ivar = 12; // <-- Static analysics error without the
101  // IPLR_REQUIRES on the pred.
102  return false;
103  });
104  test.mutex.Unlock();
105  ASSERT_FALSE(result);
106  }
107  Lock lock(test.mutex); // <--- Static analysis error without this.
108  // The predicate never returns true. So return has to be due to a non-spurious
109  // wake.
110  ASSERT_EQ(test.rando_ivar, 12u);
111 }

References impeller::testing::CVTest::cv, IPLR_REQUIRES, impeller::testing::CVTest::mutex, and impeller::ConditionVariable::WaitUntil().

◆ TEST() [57/525]

impeller::testing::TEST ( ContextVKTest  ,
AHBSwapchainCapabilitiesCanBeMissing   
)

Definition at line 357 of file context_vk_unittests.cc.

357  {
358  {
359  std::shared_ptr<ContextVK> context =
360  MockVulkanContextBuilder()
361  .SetSettingsCallback([](ContextVK::Settings& settings) {
362  settings.enable_surface_control = true;
363  })
364  .Build();
365 
366  EXPECT_FALSE(context->GetShouldEnableSurfaceControlSwapchain());
367  }
368 
369  ContextVK::EmbedderData data;
370  auto other_context = MockVulkanContextBuilder().Build();
371 
372  data.instance = other_context->GetInstance();
373  data.device = other_context->GetDevice();
374  data.physical_device = other_context->GetPhysicalDevice();
375  data.queue = VkQueue{};
376  data.queue_family_index = 0;
377  data.instance_extensions = {"VK_KHR_surface", "VK_KHR_android_surface"};
378  data.device_extensions = {"VK_KHR_swapchain",
379  VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME,
380  VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME,
381  VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
382  VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME};
383 
384  auto context = MockVulkanContextBuilder()
385  .SetSettingsCallback([](ContextVK::Settings& settings) {
386  settings.enable_surface_control = true;
387  })
388  .SetEmbedderData(data)
389  .Build();
390 
391  EXPECT_TRUE(context->GetShouldEnableSurfaceControlSwapchain());
392 
393 } // namespace impeller

References data, and impeller::ContextVK::Settings::enable_surface_control.

◆ TEST() [58/525]

impeller::testing::TEST ( ContextVKTest  ,
BatchSubmitCommandBuffersOnArm   
)

Definition at line 306 of file context_vk_unittests.cc.

306  {
307  std::shared_ptr<ContextVK> context =
308  MockVulkanContextBuilder()
309  .SetPhysicalPropertiesCallback(
310  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
311  prop->vendorID = 0x13B5; // ARM
312  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
313  })
314  .Build();
315 
316  EXPECT_TRUE(context->EnqueueCommandBuffer(context->CreateCommandBuffer()));
317  EXPECT_TRUE(context->EnqueueCommandBuffer(context->CreateCommandBuffer()));
318 
319  // If command buffers are batch submitted, we should have created them but not
320  // created the fence to track them after enqueing.
321  auto functions = GetMockVulkanFunctions(context->GetDevice());
322  EXPECT_TRUE(std::find(functions->begin(), functions->end(),
323  "vkAllocateCommandBuffers") != functions->end());
324  EXPECT_TRUE(std::find(functions->begin(), functions->end(),
325  "vkCreateFence") == functions->end());
326 
327  context->FlushCommandBuffers();
328 
329  // After flushing, the fence should be created.
330  functions = GetMockVulkanFunctions(context->GetDevice());
331  EXPECT_TRUE(std::find(functions->begin(), functions->end(),
332  "vkCreateFence") != functions->end());
333 }

◆ TEST() [59/525]

impeller::testing::TEST ( ContextVKTest  ,
BatchSubmitCommandBuffersOnNonArm   
)

Definition at line 335 of file context_vk_unittests.cc.

335  {
336  std::shared_ptr<ContextVK> context =
337  MockVulkanContextBuilder()
338  .SetPhysicalPropertiesCallback(
339  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
340  prop->vendorID = 0x8686; // Made up ID
341  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
342  })
343  .Build();
344 
345  EXPECT_TRUE(context->EnqueueCommandBuffer(context->CreateCommandBuffer()));
346  EXPECT_TRUE(context->EnqueueCommandBuffer(context->CreateCommandBuffer()));
347 
348  // If command buffers are batched and not submitted, we should have created
349  // them and a corresponding fence immediately.
350  auto functions = GetMockVulkanFunctions(context->GetDevice());
351  EXPECT_TRUE(std::find(functions->begin(), functions->end(),
352  "vkAllocateCommandBuffers") != functions->end());
353  EXPECT_FALSE(std::find(functions->begin(), functions->end(),
354  "vkCreateFence") != functions->end());
355 }

◆ TEST() [60/525]

impeller::testing::TEST ( ContextVKTest  ,
CanCreateContextInAbsenceOfValidationLayers   
)

Definition at line 152 of file context_vk_unittests.cc.

152  {
153  // The mocked methods don't report the presence of a validation layer but we
154  // explicitly ask for validation. Context creation should continue anyway.
155  auto context = MockVulkanContextBuilder()
156  .SetSettingsCallback([](auto& settings) {
157  settings.enable_validation = true;
158  })
159  .Build();
160  ASSERT_NE(context, nullptr);
161  const CapabilitiesVK* capabilites_vk =
162  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
163  ASSERT_FALSE(capabilites_vk->AreValidationsEnabled());
164 }

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [61/525]

impeller::testing::TEST ( ContextVKTest  ,
CanCreateContextWithValidationLayers   
)

Definition at line 166 of file context_vk_unittests.cc.

166  {
167  auto context =
168  MockVulkanContextBuilder()
169  .SetSettingsCallback(
170  [](auto& settings) { settings.enable_validation = true; })
171  .SetInstanceExtensions(
172  {"VK_KHR_surface", "VK_MVK_macos_surface", "VK_EXT_debug_utils"})
173  .SetInstanceLayers({"VK_LAYER_KHRONOS_validation"})
174  .Build();
175  ASSERT_NE(context, nullptr);
176  const CapabilitiesVK* capabilites_vk =
177  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
178  ASSERT_TRUE(capabilites_vk->AreValidationsEnabled());
179 }

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [62/525]

impeller::testing::TEST ( ContextVKTest  ,
CommonHardwareConcurrencyConfigurations   
)

Definition at line 17 of file context_vk_unittests.cc.

17  {
18  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(100u), 4u);
19  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(9u), 4u);
20  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(8u), 4u);
21  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(7u), 3u);
22  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(6u), 3u);
23  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(5u), 2u);
24  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(4u), 2u);
25  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(3u), 1u);
26  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(2u), 1u);
27  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(1u), 1u);
28 }

References impeller::ContextVK::ChooseThreadCountForWorkers().

◆ TEST() [63/525]

impeller::testing::TEST ( ContextVKTest  ,
DeletePipelineAfterContext   
)

Definition at line 95 of file context_vk_unittests.cc.

95  {
96  std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
97  std::shared_ptr<std::vector<std::string>> functions;
98  {
99  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
100  PipelineDescriptor pipeline_desc;
101  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
102  PipelineFuture<PipelineDescriptor> pipeline_future =
103  context->GetPipelineLibrary()->GetPipeline(pipeline_desc);
104  pipeline = pipeline_future.Get();
105  ASSERT_TRUE(pipeline);
106  functions = GetMockVulkanFunctions(context->GetDevice());
107  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
108  "vkCreateGraphicsPipelines") != functions->end());
109  }
110  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
111  "vkDestroyDevice") != functions->end());
112 }

References impeller::PipelineFuture< T >::Get(), and impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [64/525]

impeller::testing::TEST ( ContextVKTest  ,
DeletePipelineLibraryAfterContext   
)

Definition at line 136 of file context_vk_unittests.cc.

136  {
137  std::shared_ptr<PipelineLibrary> pipeline_library;
138  std::shared_ptr<std::vector<std::string>> functions;
139  {
140  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
141  PipelineDescriptor pipeline_desc;
142  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
143  pipeline_library = context->GetPipelineLibrary();
144  functions = GetMockVulkanFunctions(context->GetDevice());
145  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
146  "vkCreatePipelineCache") != functions->end());
147  }
148  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
149  "vkDestroyDevice") != functions->end());
150 }

References impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [65/525]

impeller::testing::TEST ( ContextVKTest  ,
DeletesCommandPools   
)

Definition at line 30 of file context_vk_unittests.cc.

30  {
31  std::weak_ptr<ContextVK> weak_context;
32  std::weak_ptr<CommandPoolVK> weak_pool;
33  {
34  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
35  auto const pool = context->GetCommandPoolRecycler()->Get();
36  weak_pool = pool;
37  weak_context = context;
38  ASSERT_TRUE(weak_pool.lock());
39  ASSERT_TRUE(weak_context.lock());
40  }
41  ASSERT_FALSE(weak_pool.lock());
42  ASSERT_FALSE(weak_context.lock());
43 }

◆ TEST() [66/525]

impeller::testing::TEST ( ContextVKTest  ,
DeletesCommandPoolsOnAllThreads   
)

Definition at line 45 of file context_vk_unittests.cc.

45  {
46  std::weak_ptr<ContextVK> weak_context;
47  std::weak_ptr<CommandPoolVK> weak_pool_main;
48 
49  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
50  weak_pool_main = context->GetCommandPoolRecycler()->Get();
51  weak_context = context;
52  ASSERT_TRUE(weak_pool_main.lock());
53  ASSERT_TRUE(weak_context.lock());
54 
55  // Start a second thread that obtains a command pool.
56  fml::AutoResetWaitableEvent latch1, latch2;
57  std::weak_ptr<CommandPoolVK> weak_pool_thread;
58  std::thread thread([&]() {
59  weak_pool_thread = context->GetCommandPoolRecycler()->Get();
60  latch1.Signal();
61  latch2.Wait();
62  });
63 
64  // Delete the ContextVK on the main thread.
65  latch1.Wait();
66  context.reset();
67  ASSERT_FALSE(weak_pool_main.lock());
68  ASSERT_FALSE(weak_context.lock());
69 
70  // Stop the second thread and check that its command pool has been deleted.
71  latch2.Signal();
72  thread.join();
73  ASSERT_FALSE(weak_pool_thread.lock());
74 }

◆ TEST() [67/525]

impeller::testing::TEST ( ContextVKTest  ,
DeleteShaderFunctionAfterContext   
)

Definition at line 114 of file context_vk_unittests.cc.

114  {
115  std::shared_ptr<const ShaderFunction> shader_function;
116  std::shared_ptr<std::vector<std::string>> functions;
117  {
118  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
119  PipelineDescriptor pipeline_desc;
120  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
121  std::vector<uint8_t> data = {0x03, 0x02, 0x23, 0x07};
122  context->GetShaderLibrary()->RegisterFunction(
123  "foobar_fragment_main", ShaderStage::kFragment,
124  std::make_shared<fml::DataMapping>(data), [](bool) {});
125  shader_function = context->GetShaderLibrary()->GetFunction(
126  "foobar_fragment_main", ShaderStage::kFragment);
127  ASSERT_TRUE(shader_function);
128  functions = GetMockVulkanFunctions(context->GetDevice());
129  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
130  "vkCreateShaderModule") != functions->end());
131  }
132  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
133  "vkDestroyDevice") != functions->end());
134 }

References data, impeller::kFragment, and impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [68/525]

impeller::testing::TEST ( ContextVKTest  ,
EmbedderOverrides   
)

Definition at line 283 of file context_vk_unittests.cc.

283  {
284  ContextVK::EmbedderData data;
285  auto other_context = MockVulkanContextBuilder().Build();
286 
287  data.instance = other_context->GetInstance();
288  data.device = other_context->GetDevice();
289  data.physical_device = other_context->GetPhysicalDevice();
290  data.queue = VkQueue{};
291  data.queue_family_index = 0;
292  data.instance_extensions = {"VK_KHR_surface",
293  "VK_KHR_portability_enumeration"};
294  data.device_extensions = {"VK_KHR_swapchain"};
295 
296  auto context = MockVulkanContextBuilder().SetEmbedderData(data).Build();
297 
298  EXPECT_TRUE(context->IsValid());
299  EXPECT_EQ(context->GetInstance(), other_context->GetInstance());
300  EXPECT_EQ(context->GetDevice(), other_context->GetDevice());
301  EXPECT_EQ(context->GetPhysicalDevice(), other_context->GetPhysicalDevice());
302  EXPECT_EQ(context->GetGraphicsQueue()->GetIndex().index, 0u);
303  EXPECT_EQ(context->GetGraphicsQueue()->GetIndex().family, 0u);
304 }

References data.

◆ TEST() [69/525]

impeller::testing::TEST ( ContextVKTest  ,
EmbedderOverridesUsesInstanceExtensions   
)

Definition at line 264 of file context_vk_unittests.cc.

264  {
265  ContextVK::EmbedderData data;
266  auto other_context = MockVulkanContextBuilder().Build();
267 
268  data.instance = other_context->GetInstance();
269  data.device = other_context->GetDevice();
270  data.physical_device = other_context->GetPhysicalDevice();
271  data.queue = VkQueue{};
272  data.queue_family_index = 0;
273  // Missing surface extension.
274  data.instance_extensions = {};
275  data.device_extensions = {"VK_KHR_swapchain"};
276 
277  ScopedValidationDisable scoped;
278  auto context = MockVulkanContextBuilder().SetEmbedderData(data).Build();
279 
280  EXPECT_EQ(context, nullptr);
281 }

References data.

◆ TEST() [70/525]

impeller::testing::TEST ( ContextVKTest  ,
FatalMissingValidations   
)

Definition at line 245 of file context_vk_unittests.cc.

245  {
246  EXPECT_DEATH(const std::shared_ptr<ContextVK> context =
247  MockVulkanContextBuilder()
248  .SetSettingsCallback([](ContextVK::Settings& settings) {
249  settings.enable_validation = true;
250  settings.fatal_missing_validations = true;
251  })
252  .Build(),
253  "");
254 }

References impeller::ContextVK::Settings::enable_validation, and impeller::ContextVK::Settings::fatal_missing_validations.

◆ TEST() [71/525]

impeller::testing::TEST ( ContextVKTest  ,
HasDefaultColorFormat   
)

Definition at line 256 of file context_vk_unittests.cc.

256  {
257  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
258 
259  const CapabilitiesVK* capabilites_vk =
260  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
261  ASSERT_NE(capabilites_vk->GetDefaultColorFormat(), PixelFormat::kUnknown);
262 }

References impeller::CapabilitiesVK::GetDefaultColorFormat(), and impeller::kUnknown.

◆ TEST() [72/525]

impeller::testing::TEST ( ContextVKTest  ,
HashIsUniqueAcrossThreads   
)

Definition at line 395 of file context_vk_unittests.cc.

395  {
396  uint64_t hash1, hash2;
397  std::thread thread1([&]() {
398  auto context = MockVulkanContextBuilder().Build();
399  hash1 = context->GetHash();
400  });
401  std::thread thread2([&]() {
402  auto context = MockVulkanContextBuilder().Build();
403  hash2 = context->GetHash();
404  });
405  thread1.join();
406  thread2.join();
407 
408  EXPECT_NE(hash1, hash2);
409 }

◆ TEST() [73/525]

impeller::testing::TEST ( ContextVKTest  ,
ThreadLocalCleanupDeletesCommandPool   
)

Definition at line 76 of file context_vk_unittests.cc.

76  {
77  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
78 
79  fml::AutoResetWaitableEvent latch1, latch2;
80  std::weak_ptr<CommandPoolVK> weak_pool;
81  std::thread thread([&]() {
82  weak_pool = context->GetCommandPoolRecycler()->Get();
83  context->DisposeThreadLocalCachedResources();
84  latch1.Signal();
85  latch2.Wait();
86  });
87 
88  latch1.Wait();
89  ASSERT_FALSE(weak_pool.lock());
90 
91  latch2.Signal();
92  thread.join();
93 }

◆ TEST() [74/525]

impeller::testing::TEST ( ContextVKTest  ,
WarmUpFunctionCreatesRenderPass   
)

Definition at line 234 of file context_vk_unittests.cc.

234  {
235  const std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
236 
237  context->SetOffscreenFormat(PixelFormat::kR8G8B8A8UNormInt);
238  context->InitializeCommonlyUsedShadersIfNeeded();
239 
240  auto functions = GetMockVulkanFunctions(context->GetDevice());
241  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
242  "vkCreateRenderPass") != functions->end());
243 }

References impeller::kR8G8B8A8UNormInt.

◆ TEST() [75/525]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
DescriptorsAreRecycled   
)

Definition at line 110 of file descriptor_pool_vk_unittests.cc.

110  {
111  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
112 
113  {
114  DescriptorPoolVK pool = DescriptorPoolVK(context);
115  pool.AllocateDescriptorSets({}, /*pipeline_key=*/0, *context);
116  }
117 
118  // Should reuse the same descriptor set allocated above.
119  std::shared_ptr<DescriptorPoolVK> pool =
120  context->GetDescriptorPoolRecycler()->GetDescriptorPool();
121  pool->AllocateDescriptorSets({}, /*pipeline_key=*/0, *context);
122 
123  std::shared_ptr<std::vector<std::string>> called =
124  GetMockVulkanFunctions(context->GetDevice());
125  EXPECT_EQ(
126  std::count(called->begin(), called->end(), "vkAllocateDescriptorSets"),
127  1);
128 
129  // Should allocate a new descriptor set.
130  pool->AllocateDescriptorSets({}, /*pipeline_key=*/0, *context);
131  EXPECT_EQ(
132  std::count(called->begin(), called->end(), "vkAllocateDescriptorSets"),
133  2);
134 }

References impeller::DescriptorPoolVK::AllocateDescriptorSets().

◆ TEST() [76/525]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
GetDescriptorPoolRecyclerCreatesNewPools   
)

Definition at line 13 of file descriptor_pool_vk_unittests.cc.

13  {
14  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
15 
16  vk::UniqueDescriptorPool pool1 = context->GetDescriptorPoolRecycler()->Get();
17  vk::UniqueDescriptorPool pool2 = context->GetDescriptorPoolRecycler()->Get();
18 
19  // The two descriptor pools should be different.
20  EXPECT_NE(pool1.get(), pool2.get());
21 
22  context->Shutdown();
23 }

◆ TEST() [77/525]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
MultipleCommandBuffersShareDescriptorPool   
)

Definition at line 88 of file descriptor_pool_vk_unittests.cc.

88  {
89  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
90 
91  std::shared_ptr<CommandBuffer> cmd_buffer_1 = context->CreateCommandBuffer();
92  std::shared_ptr<CommandBuffer> cmd_buffer_2 = context->CreateCommandBuffer();
93 
94  CommandBufferVK& vk_1 = CommandBufferVK::Cast(*cmd_buffer_1);
95  CommandBufferVK& vk_2 = CommandBufferVK::Cast(*cmd_buffer_2);
96 
97  EXPECT_EQ(&vk_1.GetDescriptorPool(), &vk_2.GetDescriptorPool());
98 
99  // Resetting resources creates a new pool.
100  context->DisposeThreadLocalCachedResources();
101 
102  std::shared_ptr<CommandBuffer> cmd_buffer_3 = context->CreateCommandBuffer();
103  CommandBufferVK& vk_3 = CommandBufferVK::Cast(*cmd_buffer_3);
104 
105  EXPECT_NE(&vk_1.GetDescriptorPool(), &vk_3.GetDescriptorPool());
106 
107  context->Shutdown();
108 }

References impeller::BackendCast< CommandBufferVK, CommandBuffer >::Cast(), and impeller::CommandBufferVK::GetDescriptorPool().

◆ TEST() [78/525]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
ReclaimDropsDescriptorPoolIfSizeIsExceeded   
)

Definition at line 46 of file descriptor_pool_vk_unittests.cc.

46  {
47  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
48 
49  // Create 33 pools
50  {
51  std::vector<std::unique_ptr<DescriptorPoolVK>> pools;
52  for (size_t i = 0u; i < 33; i++) {
53  std::unique_ptr<DescriptorPoolVK> pool =
54  std::make_unique<DescriptorPoolVK>(context);
55  pool->AllocateDescriptorSets({}, /*pipeline_key=*/0, *context);
56  pools.push_back(std::move(pool));
57  }
58  }
59 
60  std::shared_ptr<std::vector<std::string>> called =
61  GetMockVulkanFunctions(context->GetDevice());
62  EXPECT_EQ(
63  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"),
64  33u);
65 
66  // Now create 33 more descriptor pools and observe that only one more is
67  // allocated.
68  {
69  std::vector<std::shared_ptr<DescriptorPoolVK>> pools;
70  for (size_t i = 0u; i < 33; i++) {
71  std::shared_ptr<DescriptorPoolVK> pool =
72  context->GetDescriptorPoolRecycler()->GetDescriptorPool();
73  pool->AllocateDescriptorSets({}, /*pipeline_key=*/0, *context);
74  pools.push_back(std::move(pool));
75  }
76  }
77 
78  std::shared_ptr<std::vector<std::string>> called_twice =
79  GetMockVulkanFunctions(context->GetDevice());
80  // 32 of the descriptor pools were recycled, so only one more is created.
81  EXPECT_EQ(
82  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"),
83  34u);
84 
85  context->Shutdown();
86 }

◆ TEST() [79/525]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
ReclaimMakesDescriptorPoolAvailable   
)

Definition at line 25 of file descriptor_pool_vk_unittests.cc.

25  {
26  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
27 
28  {
29  // Fetch a pool (which will be created).
30  DescriptorPoolVK pool = DescriptorPoolVK(context);
31  pool.AllocateDescriptorSets({}, /*pipeline_key=*/0, *context);
32  }
33 
34  std::shared_ptr<DescriptorPoolVK> pool =
35  context->GetDescriptorPoolRecycler()->GetDescriptorPool();
36 
37  // Now check that we only ever created one pool.
38  std::shared_ptr<std::vector<std::string>> called =
39  GetMockVulkanFunctions(context->GetDevice());
40  EXPECT_EQ(
41  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"), 1u);
42 
43  context->Shutdown();
44 }

References impeller::DescriptorPoolVK::AllocateDescriptorSets().

◆ TEST() [80/525]

impeller::testing::TEST ( DeviceBufferGLESTest  ,
BindUniformData   
)

Definition at line 25 of file device_buffer_gles_unittests.cc.

25  {
26  auto mock_gles_impl = std::make_unique<MockGLESImpl>();
27 
28  EXPECT_CALL(*mock_gles_impl, GenBuffers(1, _)).Times(1);
29 
30  std::shared_ptr<MockGLES> mock_gled =
31  MockGLES::Init(std::move(mock_gles_impl));
32  ProcTableGLES::Resolver resolver = kMockResolverGLES;
33  auto proc_table = std::make_unique<ProcTableGLES>(resolver);
34  auto worker = std::make_shared<TestWorker>();
35  auto reactor = std::make_shared<ReactorGLES>(std::move(proc_table));
36  reactor->AddWorker(worker);
37 
38  std::shared_ptr<Allocation> backing_store = std::make_shared<Allocation>();
39  ASSERT_TRUE(backing_store->Truncate(Bytes{sizeof(float)}));
40  DeviceBufferGLES device_buffer(DeviceBufferDescriptor{.size = sizeof(float)},
41  reactor, backing_store);
42  EXPECT_FALSE(device_buffer.GetHandle().has_value());
43  EXPECT_TRUE(device_buffer.BindAndUploadDataIfNecessary(
44  DeviceBufferGLES::BindingType::kUniformBuffer));
45  EXPECT_TRUE(device_buffer.GetHandle().has_value());
46 }

References impeller::DeviceBufferGLES::kUniformBuffer, and impeller::DeviceBufferDescriptor::size.

◆ TEST() [81/525]

impeller::testing::TEST ( DrawOrderResolverTest  ,
GetSortedDrawsRespectsSkipCounts   
)

Definition at line 89 of file draw_order_resolver_unittests.cc.

89  {
90  DrawOrderResolver resolver;
91 
92  // These items will be skipped.
93  resolver.AddElement(0, false);
94  resolver.AddElement(1, true);
95  resolver.AddElement(2, false);
96  // These ones will be included in the final draw list.
97  resolver.AddElement(3, false);
98  resolver.AddElement(4, true);
99  resolver.AddElement(5, true);
100 
101  // Form the draw list, skipping elements 0, 1, and 2.
102  // This emulates what happens when entitypass applies the clear color
103  // optimization.
104  auto sorted_elements = resolver.GetSortedDraws(1, 2);
105 
106  EXPECT_EQ(sorted_elements.size(), 3u);
107  // First, opaque items are drawn in reverse order.
108  EXPECT_EQ(sorted_elements[0], 5u);
109  EXPECT_EQ(sorted_elements[1], 4u);
110  // Then, translucent items are drawn.
111  EXPECT_EQ(sorted_elements[2], 3u);
112 }

References impeller::DrawOrderResolver::AddElement(), and impeller::DrawOrderResolver::GetSortedDraws().

◆ TEST() [82/525]

impeller::testing::TEST ( DrawOrderResolverTest  ,
GetSortedDrawsReturnsCorrectOrderWithClips   
)

Definition at line 33 of file draw_order_resolver_unittests.cc.

33  {
34  DrawOrderResolver resolver;
35 
36  // Items before clip.
37  resolver.AddElement(0, false);
38  resolver.AddElement(1, true);
39  resolver.AddElement(2, false);
40  resolver.AddElement(3, true);
41 
42  // Clip.
43  resolver.PushClip(4);
44  {
45  // Clipped items.
46  resolver.AddElement(5, false);
47  resolver.AddElement(6, false);
48  // Clipped translucent items.
49  resolver.AddElement(7, true);
50  resolver.AddElement(8, true);
51  }
52  resolver.PopClip();
53 
54  // Items after clip.
55  resolver.AddElement(9, true);
56  resolver.AddElement(10, false);
57  resolver.AddElement(11, true);
58  resolver.AddElement(12, false);
59 
60  auto sorted_elements = resolver.GetSortedDraws(0, 0);
61 
62  EXPECT_EQ(sorted_elements.size(), 13u);
63  // First, all the non-clipped opaque items are drawn in reverse order.
64  EXPECT_EQ(sorted_elements[0], 11u);
65  EXPECT_EQ(sorted_elements[1], 9u);
66  EXPECT_EQ(sorted_elements[2], 3u);
67  EXPECT_EQ(sorted_elements[3], 1u);
68  // Then, non-clipped translucent items that came before the clip are drawn in
69  // their original order.
70  EXPECT_EQ(sorted_elements[4], 0u);
71  EXPECT_EQ(sorted_elements[5], 2u);
72 
73  // Then, the clip and its sorted child items are drawn.
74  EXPECT_EQ(sorted_elements[6], 4u);
75  {
76  // Opaque clipped items are drawn in reverse order.
77  EXPECT_EQ(sorted_elements[7], 8u);
78  EXPECT_EQ(sorted_elements[8], 7u);
79  // Translucent clipped items are drawn.
80  EXPECT_EQ(sorted_elements[9], 5u);
81  EXPECT_EQ(sorted_elements[10], 6u);
82  }
83  // Finally, the non-clipped translucent items which came after the clip are
84  // drawn in their original order.
85  EXPECT_EQ(sorted_elements[11], 10u);
86  EXPECT_EQ(sorted_elements[12], 12u);
87 }

References impeller::DrawOrderResolver::AddElement(), impeller::DrawOrderResolver::GetSortedDraws(), impeller::DrawOrderResolver::PopClip(), and impeller::DrawOrderResolver::PushClip().

◆ TEST() [83/525]

impeller::testing::TEST ( DrawOrderResolverTest  ,
GetSortedDrawsReturnsCorrectOrderWithFlush   
)

Definition at line 114 of file draw_order_resolver_unittests.cc.

114  {
115  DrawOrderResolver resolver;
116 
117  resolver.AddElement(0, false);
118  resolver.AddElement(1, true);
119  resolver.AddElement(2, false);
120  resolver.AddElement(3, true);
121 
122  resolver.Flush();
123 
124  resolver.AddElement(4, false);
125  resolver.AddElement(5, true);
126  resolver.AddElement(6, false);
127  resolver.AddElement(7, true);
128 
129  resolver.Flush();
130 
131  resolver.AddElement(8, false);
132  resolver.AddElement(9, true);
133  resolver.AddElement(10, false);
134  resolver.AddElement(11, true);
135 
136  auto sorted_elements = resolver.GetSortedDraws(1, 1);
137 
138  EXPECT_EQ(sorted_elements.size(), 10u);
139 
140  // Skipped draws apply to the first flush.
141  EXPECT_EQ(sorted_elements[0], 3u);
142  EXPECT_EQ(sorted_elements[1], 2u);
143 
144  EXPECT_EQ(sorted_elements[2], 7u);
145  EXPECT_EQ(sorted_elements[3], 5u);
146  EXPECT_EQ(sorted_elements[4], 4u);
147  EXPECT_EQ(sorted_elements[5], 6u);
148 
149  EXPECT_EQ(sorted_elements[6], 11u);
150  EXPECT_EQ(sorted_elements[7], 9u);
151  EXPECT_EQ(sorted_elements[8], 8u);
152  EXPECT_EQ(sorted_elements[9], 10u);
153 }

References impeller::DrawOrderResolver::AddElement(), impeller::DrawOrderResolver::Flush(), and impeller::DrawOrderResolver::GetSortedDraws().

◆ TEST() [84/525]

impeller::testing::TEST ( DrawOrderResolverTest  ,
GetSortedDrawsReturnsCorrectOrderWithNoClips   
)

Definition at line 12 of file draw_order_resolver_unittests.cc.

12  {
13  DrawOrderResolver resolver;
14 
15  // Opaque items.
16  resolver.AddElement(0, true);
17  resolver.AddElement(1, true);
18  // Translucent items.
19  resolver.AddElement(2, false);
20  resolver.AddElement(3, false);
21 
22  auto sorted_elements = resolver.GetSortedDraws(0, 0);
23 
24  EXPECT_EQ(sorted_elements.size(), 4u);
25  // First, the opaque items are drawn in reverse order.
26  EXPECT_EQ(sorted_elements[0], 1u);
27  EXPECT_EQ(sorted_elements[1], 0u);
28  // Then the translucent items are drawn.
29  EXPECT_EQ(sorted_elements[2], 2u);
30  EXPECT_EQ(sorted_elements[3], 3u);
31 }

References impeller::DrawOrderResolver::AddElement(), and impeller::DrawOrderResolver::GetSortedDraws().

◆ TEST() [85/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
CanBatchSubmitCommandBuffers   
)

Definition at line 90 of file driver_info_vk_unittests.cc.

90  {
91  // Old Adreno no batch submit!
92  EXPECT_FALSE(CanBatchSubmitTest("Adreno (TM) 540", true));
93 
94  EXPECT_TRUE(CanBatchSubmitTest("Mali-G51", false));
95  EXPECT_TRUE(CanBatchSubmitTest("Adreno (TM) 750", true));
96 }
bool CanBatchSubmitTest(std::string_view driver_name, bool qc=true)

References CanBatchSubmitTest().

◆ TEST() [86/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
CanGenerateMipMaps   
)

Definition at line 146 of file driver_info_vk_unittests.cc.

146  {
147  // Adreno no mips
148  EXPECT_FALSE(CanUseMipgeneration("Adreno (TM) 540", true));
149  EXPECT_FALSE(CanUseMipgeneration("Adreno (TM) 750", true));
150 
151  // Mali A-OK
152  EXPECT_TRUE(CanUseMipgeneration("Mali-G51", false));
153 }
bool CanUseMipgeneration(std::string_view driver_name, bool qc=true)

References CanUseMipgeneration().

◆ TEST() [87/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
CanIdentifyBadMaleoonDriver   
)

Definition at line 40 of file driver_info_vk_unittests.cc.

40  {
41  auto const context =
42  MockVulkanContextBuilder()
43  .SetPhysicalPropertiesCallback(
44  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
45  prop->vendorID = 0x19E5; // Huawei
46  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
47  })
48  .Build();
49 
50  EXPECT_TRUE(context->GetDriverInfo()->IsKnownBadDriver());
51 }

◆ TEST() [88/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
CanUseFramebufferFetch   
)

Definition at line 216 of file driver_info_vk_unittests.cc.

216  {
217  // Adreno no primitive restart on models as or older than 630.
218  EXPECT_FALSE(CanUseFramebufferFetch("Adreno (TM) 540", true));
219  EXPECT_FALSE(CanUseFramebufferFetch("Adreno (TM) 630", true));
220 
221  EXPECT_TRUE(CanUseFramebufferFetch("Adreno (TM) 640", true));
222  EXPECT_TRUE(CanUseFramebufferFetch("Adreno (TM) 750", true));
223  EXPECT_TRUE(CanUseFramebufferFetch("Mali-G51", false));
224 }
bool CanUseFramebufferFetch(std::string_view driver_name, bool qc=true)

References CanUseFramebufferFetch().

◆ TEST() [89/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
CanUsePrimitiveRestart   
)

Definition at line 118 of file driver_info_vk_unittests.cc.

118  {
119  // Adreno no primitive restart
120  EXPECT_FALSE(CanUsePrimitiveRestartSubmitTest("Adreno (TM) 540", true));
121  EXPECT_FALSE(CanUsePrimitiveRestartSubmitTest("Adreno (TM) 750", true));
122 
123  // Mali A-OK
124  EXPECT_TRUE(CanUsePrimitiveRestartSubmitTest("Mali-G51", false));
125 }
bool CanUsePrimitiveRestartSubmitTest(std::string_view driver_name, bool qc=true)

References CanUsePrimitiveRestartSubmitTest().

◆ TEST() [90/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
DisabledDevices   
)

Definition at line 166 of file driver_info_vk_unittests.cc.

166  {
167  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 620"));
168  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 610"));
169  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 530"));
170  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 512"));
171  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 509"));
172  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 508"));
173  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 506"));
174  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 505"));
175  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 504"));
176  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 630"));
177  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 640"));
178  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 650"));
179 }
bool IsBadVersionTest(std::string_view driver_name, bool qc=true)

References IsBadVersionTest().

◆ TEST() [91/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
DisableOldXclipseDriver   
)

Definition at line 226 of file driver_info_vk_unittests.cc.

226  {
227  auto context =
228  MockVulkanContextBuilder()
229  .SetPhysicalPropertiesCallback(
230  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
231  prop->vendorID = 0x144D; // Samsung
232  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
233  // Version 1.1.0
234  prop->apiVersion = (1 << 22) | (1 << 12);
235  })
236  .Build();
237 
238  EXPECT_TRUE(context->GetDriverInfo()->IsKnownBadDriver());
239 
240  context =
241  MockVulkanContextBuilder()
242  .SetPhysicalPropertiesCallback(
243  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
244  prop->vendorID = 0x144D; // Samsung
245  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
246  // Version 1.3.0
247  prop->apiVersion = (1 << 22) | (3 << 12);
248  })
249  .Build();
250 
251  EXPECT_FALSE(context->GetDriverInfo()->IsKnownBadDriver());
252 }

◆ TEST() [92/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
DriverParsingAdreno   
)

Definition at line 161 of file driver_info_vk_unittests.cc.

161  {
162  EXPECT_EQ(GetAdrenoVersion("Adreno (TM) 540"), AdrenoGPU::kAdreno540);
163  EXPECT_EQ(GetAdrenoVersion("Foo Bar"), AdrenoGPU::kUnknown);
164 }
AdrenoGPU GetAdrenoVersion(std::string_view version)

References impeller::GetAdrenoVersion(), impeller::kAdreno540, and impeller::kUnknown.

◆ TEST() [93/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
DriverParsingMali   
)

Definition at line 155 of file driver_info_vk_unittests.cc.

155  {
156  EXPECT_EQ(GetMaliVersion("Mali-G51-MORE STUFF"), MaliGPU::kG51);
157  EXPECT_EQ(GetMaliVersion("Mali-G51"), MaliGPU::kG51);
158  EXPECT_EQ(GetMaliVersion("Mali-111111"), MaliGPU::kUnknown);
159 }
MaliGPU GetMaliVersion(std::string_view version)

References impeller::GetMaliVersion(), impeller::kG51, and impeller::kUnknown.

◆ TEST() [94/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
EnabledDevicesAdreno   
)

Definition at line 186 of file driver_info_vk_unittests.cc.

186  {
187  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 750"));
188  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 740"));
189  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 732"));
190  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 730"));
191  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 725"));
192  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 720"));
193  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 710"));
194  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 702"));
195 }

References IsBadVersionTest().

◆ TEST() [95/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
EnabledDevicesMali   
)

Definition at line 181 of file driver_info_vk_unittests.cc.

181  {
182  EXPECT_FALSE(IsBadVersionTest("Mali-G52", /*qc=*/false));
183  EXPECT_FALSE(IsBadVersionTest("Mali-G54-MORE STUFF", /*qc=*/false));
184 }

References IsBadVersionTest().

◆ TEST() [96/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
NewPowerVREnabled   
)

Definition at line 271 of file driver_info_vk_unittests.cc.

271  {
272  std::shared_ptr<ContextVK> context =
273  MockVulkanContextBuilder()
274  .SetPhysicalPropertiesCallback(
275  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
276  prop->vendorID = 0x1010;
277  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
278  std::string name = "PowerVR DXT 123";
279  name.copy(prop->deviceName, name.size());
280  })
281  .Build();
282 
283  EXPECT_FALSE(context->GetDriverInfo()->IsKnownBadDriver());
284  EXPECT_EQ(context->GetDriverInfo()->GetPowerVRGPUInfo(),
285  std::optional<PowerVRGPU>(PowerVRGPU::kDXT));
286  EXPECT_TRUE(GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
288 }

References impeller::GetWorkaroundsFromDriverInfo(), impeller::WorkaroundsVK::input_attachment_self_dependency_broken, and impeller::kDXT.

◆ TEST() [97/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
OldPowerVRDisabled   
)

Definition at line 254 of file driver_info_vk_unittests.cc.

254  {
255  std::shared_ptr<ContextVK> context =
256  MockVulkanContextBuilder()
257  .SetPhysicalPropertiesCallback(
258  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
259  prop->vendorID = 0x1010;
260  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
261  std::string name = "PowerVR Rogue GE8320";
262  name.copy(prop->deviceName, name.size());
263  })
264  .Build();
265 
266  EXPECT_TRUE(context->GetDriverInfo()->IsKnownBadDriver());
267  EXPECT_EQ(context->GetDriverInfo()->GetPowerVRGPUInfo(),
268  std::optional<PowerVRGPU>(PowerVRGPU::kUnknown));
269 }

References impeller::kUnknown.

◆ TEST() [98/525]

impeller::testing::TEST ( DriverInfoVKTest  ,
PowerVRBSeries   
)

Definition at line 290 of file driver_info_vk_unittests.cc.

290  {
291  std::shared_ptr<ContextVK> context =
292  MockVulkanContextBuilder()
293  .SetPhysicalPropertiesCallback(
294  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
295  prop->vendorID = 0x1010;
296  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
297  std::string name = "PowerVR BXM-8-256";
298  name.copy(prop->deviceName, name.size());
299  })
300  .Build();
301 
302  EXPECT_FALSE(context->GetDriverInfo()->IsKnownBadDriver());
303  EXPECT_EQ(context->GetDriverInfo()->GetPowerVRGPUInfo(),
304  std::optional<PowerVRGPU>(PowerVRGPU::kBXM));
305 }

References impeller::kBXM.

◆ TEST() [99/525]

impeller::testing::TEST ( EntityGeometryTest  ,
AlphaCoverageStrokePaths   
)

Definition at line 543 of file geometry_unittests.cc.

543  {
544  auto matrix = Matrix::MakeScale(Vector2{3.0, 3.0});
545  EXPECT_EQ(Geometry::MakeStrokePath({}, {.width = 0.5f})
546  ->ComputeAlphaCoverage(matrix),
547  1.0f);
548  EXPECT_NEAR(Geometry::MakeStrokePath({}, {.width = 0.1f})
549  ->ComputeAlphaCoverage(matrix),
550  0.6, 0.05);
551  EXPECT_NEAR(Geometry::MakeStrokePath({}, {.width = 0.05})
552  ->ComputeAlphaCoverage(matrix),
553  0.3, 0.05);
554  EXPECT_NEAR(Geometry::MakeStrokePath({}, {.width = 0.01})
555  ->ComputeAlphaCoverage(matrix),
556  0.1, 0.1);
557  EXPECT_NEAR(Geometry::MakeStrokePath({}, {.width = 0.0000005f})
558  ->ComputeAlphaCoverage(matrix),
559  1e-05, 0.001);
560  EXPECT_EQ(Geometry::MakeStrokePath({}, {.width = 0.0f})
561  ->ComputeAlphaCoverage(matrix),
562  1.0f);
563  EXPECT_EQ(Geometry::MakeStrokePath({}, {.width = 40.0f})
564  ->ComputeAlphaCoverage(matrix),
565  1.0f);
566 }
Point Vector2
Definition: point.h:331

References impeller::Matrix::MakeScale(), and impeller::Geometry::MakeStrokePath().

◆ TEST() [100/525]

impeller::testing::TEST ( EntityGeometryTest  ,
FillArcGeometryCoverage   
)

Definition at line 104 of file geometry_unittests.cc.

104  {
105  Rect oval_bounds = Rect::MakeLTRB(100, 100, 200, 200);
106  Matrix transform45 = Matrix::MakeTranslation(oval_bounds.GetCenter()) *
107  Matrix::MakeRotationZ(Degrees(45)) *
108  Matrix::MakeTranslation(-oval_bounds.GetCenter());
109 
110  { // Sweeps <=-360 or >=360
111  for (int start = -720; start <= 720; start += 10) {
112  for (int sweep = 360; sweep <= 720; sweep += 30) {
113  std::string label =
114  "start: " + std::to_string(start) + " + " + std::to_string(sweep);
115  auto geometry = Geometry::MakeFilledArc(oval_bounds, Degrees(start),
116  Degrees(sweep), false);
117  EXPECT_EQ(geometry->GetCoverage({}), oval_bounds)
118  << "start: " << start << ", sweep: " << sweep;
119  geometry = Geometry::MakeFilledArc(oval_bounds, Degrees(start),
120  Degrees(-sweep), false);
121  EXPECT_EQ(geometry->GetCoverage({}), oval_bounds)
122  << "start: " << start << ", sweep: " << -sweep;
123  geometry = Geometry::MakeFilledArc(oval_bounds, Degrees(start),
124  Degrees(-sweep), true);
125  EXPECT_EQ(geometry->GetCoverage({}), oval_bounds)
126  << "start: " << start << ", sweep: " << -sweep << ", with center";
127  }
128  }
129  }
130  { // Sweep from late in one quadrant to earlier in same quadrant
131  for (int start = 60; start < 360; start += 90) {
132  auto geometry = Geometry::MakeFilledArc(oval_bounds, Degrees(start),
133  Degrees(330), false);
134  EXPECT_EQ(geometry->GetCoverage({}), oval_bounds)
135  << "start: " << start << " without center";
136  geometry = Geometry::MakeFilledArc(oval_bounds, Degrees(start),
137  Degrees(330), true);
138  EXPECT_EQ(geometry->GetCoverage({}), oval_bounds)
139  << "start: " << start << " with center";
140  }
141  }
142  { // Sweep from early in one quadrant backwards to later in same quadrant
143  for (int start = 30; start < 360; start += 90) {
144  auto geometry = Geometry::MakeFilledArc(oval_bounds, Degrees(start),
145  Degrees(-330), false);
146  EXPECT_EQ(geometry->GetCoverage({}), oval_bounds)
147  << "start: " << start << " without center";
148  geometry = Geometry::MakeFilledArc(oval_bounds, Degrees(start),
149  Degrees(-330), true);
150  EXPECT_EQ(geometry->GetCoverage({}), oval_bounds)
151  << "start: " << start << " with center";
152  }
153  }
154  { // Sweep past each quadrant axis individually, no center
155  for (int start = -360; start <= 720; start += 360) {
156  { // Quadrant 0
157  auto geometry = Geometry::MakeFilledArc(
158  oval_bounds, Degrees(start - 45), Degrees(90), false);
159  Rect expected_bounds = Rect::MakeLTRB(150 + 50 * kSqrt2Over2, //
160  150 - 50 * kSqrt2Over2, //
161  200, //
162  150 + 50 * kSqrt2Over2);
163  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
164  expected_bounds)
165  << "start: " << start - 45;
166  }
167  { // Quadrant 1
168  auto geometry = Geometry::MakeFilledArc(
169  oval_bounds, Degrees(start + 45), Degrees(90), false);
170  Rect expected_bounds = Rect::MakeLTRB(150 - 50 * kSqrt2Over2, //
171  150 + 50 * kSqrt2Over2, //
172  150 + 50 * kSqrt2Over2, //
173  200);
174  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
175  expected_bounds)
176  << "start: " << start + 45;
177  }
178  { // Quadrant 2
179  auto geometry = Geometry::MakeFilledArc(
180  oval_bounds, Degrees(start + 135), Degrees(90), false);
181  Rect expected_bounds = Rect::MakeLTRB(100, //
182  150 - 50 * kSqrt2Over2, //
183  150 - 50 * kSqrt2Over2, //
184  150 + 50 * kSqrt2Over2);
185  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
186  expected_bounds)
187  << "start: " << start + 135;
188  }
189  { // Quadrant 3
190  auto geometry = Geometry::MakeFilledArc(
191  oval_bounds, Degrees(start + 225), Degrees(90), false);
192  Rect expected_bounds = Rect::MakeLTRB(150 - 50 * kSqrt2Over2, //
193  100, //
194  150 + 50 * kSqrt2Over2, //
195  150 - 50 * kSqrt2Over2);
196  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
197  expected_bounds)
198  << "start: " << start + 225;
199  }
200  }
201  }
202  { // Sweep past each quadrant axis individually, including the center
203  for (int start = -360; start <= 720; start += 360) {
204  { // Quadrant 0
205  auto geometry = Geometry::MakeFilledArc(
206  oval_bounds, Degrees(start - 45), Degrees(90), true);
207  Rect expected_bounds = Rect::MakeLTRB(150, //
208  150 - 50 * kSqrt2Over2, //
209  200, //
210  150 + 50 * kSqrt2Over2);
211  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
212  expected_bounds)
213  << "start: " << start - 45;
214  }
215  { // Quadrant 1
216  auto geometry = Geometry::MakeFilledArc(
217  oval_bounds, Degrees(start + 45), Degrees(90), true);
218  Rect expected_bounds = Rect::MakeLTRB(150 - 50 * kSqrt2Over2, //
219  150, //
220  150 + 50 * kSqrt2Over2, //
221  200);
222  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
223  expected_bounds)
224  << "start: " << start + 45;
225  }
226  { // Quadrant 2
227  auto geometry = Geometry::MakeFilledArc(
228  oval_bounds, Degrees(start + 135), Degrees(90), true);
229  Rect expected_bounds = Rect::MakeLTRB(100, //
230  150 - 50 * kSqrt2Over2, //
231  150, //
232  150 + 50 * kSqrt2Over2);
233  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
234  expected_bounds)
235  << "start: " << start + 135;
236  }
237  { // Quadrant 3
238  auto geometry = Geometry::MakeFilledArc(
239  oval_bounds, Degrees(start + 225), Degrees(90), true);
240  Rect expected_bounds = Rect::MakeLTRB(150 - 50 * kSqrt2Over2, //
241  100, //
242  150 + 50 * kSqrt2Over2, //
243  150);
244  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
245  expected_bounds)
246  << "start: " << start + 225;
247  }
248  }
249  }
250  { // 45 degree tilted full circle
251  auto geometry =
252  Geometry::MakeFilledArc(oval_bounds, Degrees(0), Degrees(360), false);
253  ASSERT_TRUE(oval_bounds.TransformBounds(transform45).Contains(oval_bounds));
254 
255  EXPECT_TRUE(geometry->GetCoverage(transform45)
256  .value_or(Rect())
257  .Contains(oval_bounds));
258  }
259  { // 45 degree tilted mostly full circle
260  auto geometry =
261  Geometry::MakeFilledArc(oval_bounds, Degrees(3), Degrees(359), false);
262  ASSERT_TRUE(oval_bounds.TransformBounds(transform45).Contains(oval_bounds));
263 
264  EXPECT_TRUE(geometry->GetCoverage(transform45)
265  .value_or(Rect())
266  .Contains(oval_bounds));
267  }
268 }
#define EXPECT_RECT_NEAR(a, b)
constexpr float kSqrt2Over2
Definition: constants.h:51
TRect< Scalar > Rect
Definition: rect.h:788

References impeller::TRect< T >::Contains(), EXPECT_RECT_NEAR, impeller::TRect< T >::GetCenter(), impeller::kSqrt2Over2, impeller::Geometry::MakeFilledArc(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), start, and impeller::TRect< T >::TransformBounds().

◆ TEST() [101/525]

impeller::testing::TEST ( EntityGeometryTest  ,
FillPathGeometryCoversArea   
)

Definition at line 81 of file geometry_unittests.cc.

81  {
82  auto path = flutter::DlPathBuilder{}
83  .AddRect(Rect::MakeLTRB(0, 0, 100, 100))
84  .TakePath();
85  auto geometry = Geometry::MakeFillPath(
86  path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
87  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
88  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
89  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
90  ASSERT_TRUE(geometry->CoversArea({}, Rect()));
91 }

References impeller::Geometry::MakeFillPath(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [102/525]

impeller::testing::TEST ( EntityGeometryTest  ,
FillPathGeometryCoversAreaNoInnerRect   
)

Definition at line 93 of file geometry_unittests.cc.

93  {
94  auto path = flutter::DlPathBuilder{}
95  .AddRect(Rect::MakeLTRB(0, 0, 100, 100))
96  .TakePath();
97  auto geometry = Geometry::MakeFillPath(path);
98  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
99  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
100  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
101  ASSERT_FALSE(geometry->CoversArea({}, Rect()));
102 }

References impeller::Geometry::MakeFillPath(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [103/525]

impeller::testing::TEST ( EntityGeometryTest  ,
FillRoundRectGeometryCoversArea   
)

Definition at line 471 of file geometry_unittests.cc.

471  {
472  Rect bounds = Rect::MakeLTRB(100, 100, 200, 200);
473  RoundRect round_rect =
474  RoundRect::MakeRectRadii(bounds, RoundingRadii{
475  .top_left = Size(1, 11),
476  .top_right = Size(2, 12),
477  .bottom_left = Size(3, 13),
478  .bottom_right = Size(4, 14),
479  });
480  FillRoundRectGeometry geom(round_rect);
481 
482  // Tall middle rect should barely be covered.
483  EXPECT_TRUE(geom.CoversArea({}, Rect::MakeLTRB(103, 100, 196, 200)));
484  EXPECT_FALSE(geom.CoversArea({}, Rect::MakeLTRB(102, 100, 196, 200)));
485  EXPECT_FALSE(geom.CoversArea({}, Rect::MakeLTRB(103, 99, 196, 200)));
486  EXPECT_FALSE(geom.CoversArea({}, Rect::MakeLTRB(103, 100, 197, 200)));
487  EXPECT_FALSE(geom.CoversArea({}, Rect::MakeLTRB(103, 100, 196, 201)));
488 
489  // Wide middle rect should barely be covered.
490  EXPECT_TRUE(geom.CoversArea({}, Rect::MakeLTRB(100, 112, 200, 186)));
491  EXPECT_FALSE(geom.CoversArea({}, Rect::MakeLTRB(99, 112, 200, 186)));
492  EXPECT_FALSE(geom.CoversArea({}, Rect::MakeLTRB(100, 111, 200, 186)));
493  EXPECT_FALSE(geom.CoversArea({}, Rect::MakeLTRB(100, 112, 201, 186)));
494  EXPECT_FALSE(geom.CoversArea({}, Rect::MakeLTRB(100, 112, 200, 187)));
495 }
TSize< Scalar > Size
Definition: size.h:159

References impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), and impeller::RoundingRadii::top_left.

◆ TEST() [104/525]

impeller::testing::TEST ( EntityGeometryTest  ,
GeometryResultHasReasonableDefaults   
)

Definition at line 536 of file geometry_unittests.cc.

536  {
537  GeometryResult result;
538  EXPECT_EQ(result.type, PrimitiveType::kTriangleStrip);
539  EXPECT_EQ(result.transform, Matrix());
540  EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
541 }

References impeller::GeometryResult::kNormal, impeller::kTriangleStrip, impeller::GeometryResult::mode, impeller::GeometryResult::transform, and impeller::GeometryResult::type.

◆ TEST() [105/525]

impeller::testing::TEST ( EntityGeometryTest  ,
LineGeometryCoverage   
)

Definition at line 497 of file geometry_unittests.cc.

497  {
498  {
499  auto geometry = Geometry::MakeLine( //
500  {10, 10}, {20, 10}, {.width = 2, .cap = Cap::kButt});
501  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(10, 9, 20, 11));
502  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(10, 9, 20, 11)));
503  }
504 
505  {
506  auto geometry = Geometry::MakeLine( //
507  {10, 10}, {20, 10}, {.width = 2, .cap = Cap::kSquare});
508  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 9, 21, 11));
509  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 9, 21, 11)));
510  }
511 
512  {
513  auto geometry = Geometry::MakeLine( //
514  {10, 10}, {10, 20}, {.width = 2, .cap = Cap::kButt});
515  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 10, 11, 20));
516  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 10, 11, 20)));
517  }
518 
519  {
520  auto geometry = Geometry::MakeLine( //
521  {10, 10}, {10, 20}, {.width = 2, .cap = Cap::kSquare});
522  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 9, 11, 21));
523  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 9, 11, 21)));
524  }
525 }

References impeller::kButt, impeller::kSquare, impeller::Geometry::MakeLine(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [106/525]

impeller::testing::TEST ( EntityGeometryTest  ,
RectGeometryCoversArea   
)

Definition at line 73 of file geometry_unittests.cc.

73  {
74  auto geometry = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 100, 100));
75  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
76  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
77  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
78  ASSERT_TRUE(geometry->CoversArea({}, Rect()));
79 }

References impeller::TRect< Scalar >::MakeLTRB(), and impeller::Geometry::MakeRect().

◆ TEST() [107/525]

impeller::testing::TEST ( EntityGeometryTest  ,
RotatedFilledCircleGeometryCoverage   
)

Definition at line 1315 of file geometry_unittests.cc.

1315  {
1316  Point center = Point(50, 50);
1317  auto geometry = Geometry::MakeCircle(center, 50);
1318  Rect circle_bounds = Rect::MakeLTRB(0, 0, 100, 100);
1319  ASSERT_EQ(geometry->GetCoverage({}).value_or(Rect()), circle_bounds);
1320 
1321  Matrix transform45 = Matrix::MakeTranslation(center) *
1322  Matrix::MakeRotationZ(Degrees(45)) *
1323  Matrix::MakeTranslation(-center);
1324 
1325  EXPECT_TRUE(geometry->GetCoverage(transform45).has_value());
1326  Rect bounds = geometry->GetCoverage(transform45).value_or(Rect());
1327  EXPECT_TRUE(bounds.Contains(circle_bounds))
1328  << "geometry bounds: " << bounds << std::endl
1329  << " circle bounds: " << circle_bounds;
1330 }

References impeller::TRect< T >::Contains(), impeller::Geometry::MakeCircle(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationZ(), and impeller::Matrix::MakeTranslation().

◆ TEST() [108/525]

impeller::testing::TEST ( EntityGeometryTest  ,
RotatedStrokedCircleGeometryCoverage   
)

Definition at line 1332 of file geometry_unittests.cc.

1332  {
1333  Point center = Point(50, 50);
1334  auto geometry = Geometry::MakeStrokedCircle(center, 50, 10);
1335  Rect circle_bounds = Rect::MakeLTRB(0, 0, 100, 100).Expand(5);
1336  ASSERT_EQ(geometry->GetCoverage({}).value_or(Rect()), circle_bounds);
1337 
1338  Matrix transform45 = Matrix::MakeTranslation(center) *
1339  Matrix::MakeRotationZ(Degrees(45)) *
1340  Matrix::MakeTranslation(-center);
1341 
1342  EXPECT_TRUE(geometry->GetCoverage(transform45).has_value());
1343  Rect bounds = geometry->GetCoverage(transform45).value_or(Rect());
1344  EXPECT_TRUE(bounds.Contains(circle_bounds))
1345  << "geometry bounds: " << bounds << std::endl
1346  << " circle bounds: " << circle_bounds;
1347 }
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
Definition: rect.h:618

References impeller::TRect< T >::Contains(), impeller::TRect< T >::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationZ(), impeller::Geometry::MakeStrokedCircle(), and impeller::Matrix::MakeTranslation().

◆ TEST() [109/525]

impeller::testing::TEST ( EntityGeometryTest  ,
RoundRectGeometryCoversArea   
)

Definition at line 527 of file geometry_unittests.cc.

527  {
528  auto geometry =
529  Geometry::MakeRoundRect(Rect::MakeLTRB(0, 0, 100, 100), Size(20, 20));
530  EXPECT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(15, 15, 85, 85)));
531  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(20, 20, 80, 80)));
532  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(30, 1, 70, 99)));
533  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 30, 99, 70)));
534 }

References impeller::TRect< Scalar >::MakeLTRB(), and impeller::Geometry::MakeRoundRect().

◆ TEST() [110/525]

impeller::testing::TEST ( EntityGeometryTest  ,
SimpleTwoLineStrokeVerticesButtCap   
)

Definition at line 568 of file geometry_unittests.cc.

568  {
569  flutter::DlPathBuilder path_builder;
570  path_builder.MoveTo({20, 20});
571  path_builder.LineTo({30, 20});
572  path_builder.MoveTo({120, 20});
573  path_builder.LineTo({130, 20});
574  flutter::DlPath path = path_builder.TakePath();
575 
576  auto points = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
577  path,
578  {
579  .width = 10.0f,
580  .cap = Cap::kButt,
581  .join = Join::kBevel,
582  .miter_limit = 4.0f,
583  },
584  1.0f);
585 
586  std::vector<Point> expected = {
587  // The points for the first segment (20, 20) -> (30, 20)
588  Point(20, 25),
589  Point(20, 15),
590  Point(30, 25),
591  Point(30, 15),
592 
593  // The glue points that allow us to "pick up the pen" between segments
594  Point(30, 20),
595  Point(30, 20),
596  Point(120, 20),
597  Point(120, 20),
598 
599  // The points for the second segment (120, 20) -> (130, 20)
600  Point(120, 25),
601  Point(120, 15),
602  Point(130, 25),
603  Point(130, 15),
604  };
605 
606  EXPECT_EQ(points, expected);
607 }
std::vector< Point > points

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kButt, and points.

◆ TEST() [111/525]

impeller::testing::TEST ( EntityGeometryTest  ,
SimpleTwoLineStrokeVerticesRoundCap   
)

Definition at line 609 of file geometry_unittests.cc.

609  {
610  flutter::DlPathBuilder path_builder;
611  path_builder.MoveTo({20, 20});
612  path_builder.LineTo({30, 20});
613  path_builder.MoveTo({120, 20});
614  path_builder.LineTo({130, 20});
615  flutter::DlPath path = path_builder.TakePath();
616 
617  auto points = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
618  path,
619  {
620  .width = 10.0f,
621  .cap = Cap::kRound,
622  .join = Join::kBevel,
623  .miter_limit = 4.0f,
624  },
625  1.0f);
626 
627  size_t count = points.size();
628  ASSERT_TRUE((count & 0x1) == 0x0); // Should always be even
629 
630  // For a scale factor of 1.0 and a stroke width of 10.0 we currently
631  // generate 40 total points for the 2 line segments based on the number
632  // of quadrant circle divisions for a radius of 5.0
633  //
634  // If the number of points changes because of a change in the way we
635  // compute circle divisions, we need to recompute the circular offsets
636  ASSERT_EQ(points.size(), 40u);
637 
638  // Compute the indicated circular end cap offset based on the current
639  // step out of 4 divisions [1, 2, 3] (not 0 or 4) based on whether this
640  // is the left or right side of the path and whether this is a backwards
641  // (starting) cap or a forwards (ending) cap.
642  auto offset = [](int step, bool left, bool backwards) -> Point {
643  Radians angle(kPiOver2 * (step / 4.0f));
644  Point along = Point(5.0f, 0.0f) * std::cos(angle.radians);
645  Point across = Point(0.0f, 5.0f) * std::sin(angle.radians);
646  Point center = backwards ? -along : along;
647  return left ? center + across : center - across;
648  };
649 
650  // The points for the first segment (20, 20) -> (30, 20)
651  EXPECT_EQ(points[0], Point(15, 20));
652  EXPECT_EQ(points[1], Point(20, 20) + offset(1, true, true));
653  EXPECT_EQ(points[2], Point(20, 20) + offset(1, false, true));
654  EXPECT_EQ(points[3], Point(20, 20) + offset(2, true, true));
655  EXPECT_EQ(points[4], Point(20, 20) + offset(2, false, true));
656  EXPECT_EQ(points[5], Point(20, 20) + offset(3, true, true));
657  EXPECT_EQ(points[6], Point(20, 20) + offset(3, false, true));
658  EXPECT_EQ(points[7], Point(20, 25));
659  EXPECT_EQ(points[8], Point(20, 15));
660  EXPECT_EQ(points[9], Point(30, 25));
661  EXPECT_EQ(points[10], Point(30, 15));
662  EXPECT_EQ(points[11], Point(30, 20) + offset(3, true, false));
663  EXPECT_EQ(points[12], Point(30, 20) + offset(3, false, false));
664  EXPECT_EQ(points[13], Point(30, 20) + offset(2, true, false));
665  EXPECT_EQ(points[14], Point(30, 20) + offset(2, false, false));
666  EXPECT_EQ(points[15], Point(30, 20) + offset(1, true, false));
667  EXPECT_EQ(points[16], Point(30, 20) + offset(1, false, false));
668  EXPECT_EQ(points[17], Point(35, 20));
669 
670  // The glue points that allow us to "pick up the pen" between segments
671  EXPECT_EQ(points[18], Point(30, 20));
672  EXPECT_EQ(points[19], Point(30, 20));
673  EXPECT_EQ(points[20], Point(120, 20));
674  EXPECT_EQ(points[21], Point(120, 20));
675 
676  // The points for the second segment (120, 20) -> (130, 20)
677  EXPECT_EQ(points[22], Point(115, 20));
678  EXPECT_EQ(points[23], Point(120, 20) + offset(1, true, true));
679  EXPECT_EQ(points[24], Point(120, 20) + offset(1, false, true));
680  EXPECT_EQ(points[25], Point(120, 20) + offset(2, true, true));
681  EXPECT_EQ(points[26], Point(120, 20) + offset(2, false, true));
682  EXPECT_EQ(points[27], Point(120, 20) + offset(3, true, true));
683  EXPECT_EQ(points[28], Point(120, 20) + offset(3, false, true));
684  EXPECT_EQ(points[29], Point(120, 25));
685  EXPECT_EQ(points[30], Point(120, 15));
686  EXPECT_EQ(points[31], Point(130, 25));
687  EXPECT_EQ(points[32], Point(130, 15));
688  EXPECT_EQ(points[33], Point(130, 20) + offset(3, true, false));
689  EXPECT_EQ(points[34], Point(130, 20) + offset(3, false, false));
690  EXPECT_EQ(points[35], Point(130, 20) + offset(2, true, false));
691  EXPECT_EQ(points[36], Point(130, 20) + offset(2, false, false));
692  EXPECT_EQ(points[37], Point(130, 20) + offset(1, true, false));
693  EXPECT_EQ(points[38], Point(130, 20) + offset(1, false, false));
694  EXPECT_EQ(points[39], Point(135, 20));
695 }
constexpr float kPiOver2
Definition: constants.h:32

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kPiOver2, impeller::kRound, points, and impeller::Radians::radians.

◆ TEST() [112/525]

impeller::testing::TEST ( EntityGeometryTest  ,
SimpleTwoLineStrokeVerticesSquareCap   
)

Definition at line 697 of file geometry_unittests.cc.

697  {
698  flutter::DlPathBuilder path_builder;
699  path_builder.MoveTo({20, 20});
700  path_builder.LineTo({30, 20});
701  path_builder.MoveTo({120, 20});
702  path_builder.LineTo({130, 20});
703  flutter::DlPath path = path_builder.TakePath();
704 
705  auto points = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
706  path,
707  {
708  .width = 10.0f,
709  .cap = Cap::kSquare,
710  .join = Join::kBevel,
711  .miter_limit = 4.0f,
712  },
713  1.0f);
714 
715  // clang-format off
716  std::vector<Point> expected = {
717  // The points for the first segment (20, 20) -> (30, 20)
718  Point(15, 25),
719  Point(15, 15),
720  Point(20, 25),
721  Point(20, 15),
722  Point(30, 25),
723  Point(30, 15),
724  Point(35, 25),
725  Point(35, 15),
726 
727  // The glue points that allow us to "pick up the pen" between segments
728  Point(30, 20),
729  Point(30, 20),
730  Point(120, 20),
731  Point(120, 20),
732 
733  // The points for the second segment (120, 20) -> (130, 20)
734  Point(115, 25),
735  Point(115, 15),
736  Point(120, 25),
737  Point(120, 15),
738  Point(130, 25),
739  Point(130, 15),
740  Point(135, 25),
741  Point(135, 15),
742  };
743  // clang-format on
744 
745  EXPECT_EQ(points, expected);
746 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kSquare, and points.

◆ TEST() [113/525]

impeller::testing::TEST ( EntityGeometryTest  ,
StrokeArcGeometryCoverage   
)

Definition at line 270 of file geometry_unittests.cc.

270  {
271  Rect oval_bounds = Rect::MakeLTRB(100, 100, 200, 200);
272  Rect expanded_bounds = Rect::MakeLTRB(95, 95, 205, 205);
273  Rect squared_bounds = Rect::MakeLTRB(100 - 5 * kSqrt2, 100 - 5 * kSqrt2,
274  200 + 5 * kSqrt2, 200 + 5 * kSqrt2);
275  Matrix transform45 = Matrix::MakeTranslation(oval_bounds.GetCenter()) *
276  Matrix::MakeRotationZ(Degrees(45)) *
277  Matrix::MakeTranslation(-oval_bounds.GetCenter());
278 
279  StrokeParameters butt_params = {
280  .width = 10.0f,
281  .cap = Cap::kButt,
282  };
283  StrokeParameters square_params = {
284  .width = 10.0f,
285  .cap = Cap::kSquare,
286  };
287 
288  { // Sweeps <=-360 or >=360
289  for (int start = -720; start <= 720; start += 10) {
290  for (int sweep = 360; sweep <= 720; sweep += 30) {
291  std::string label =
292  "start: " + std::to_string(start) + " + " + std::to_string(sweep);
293  auto geometry = Geometry::MakeStrokedArc(oval_bounds, Degrees(start),
294  Degrees(sweep), butt_params);
295  EXPECT_EQ(geometry->GetCoverage({}), expanded_bounds)
296  << "start: " << start << ", sweep: " << sweep;
297  geometry = Geometry::MakeStrokedArc(oval_bounds, Degrees(start),
298  Degrees(-sweep), butt_params);
299  EXPECT_EQ(geometry->GetCoverage({}), expanded_bounds)
300  << "start: " << start << ", sweep: " << -sweep;
301  geometry = Geometry::MakeStrokedArc(oval_bounds, Degrees(start),
302  Degrees(-sweep), square_params);
303  EXPECT_EQ(geometry->GetCoverage({}), expanded_bounds)
304  << "start: " << start << ", sweep: " << -sweep << ", square caps";
305  }
306  }
307  }
308  { // Sweep from late in one quadrant to earlier in same quadrant
309  for (int start = 60; start < 360; start += 90) {
310  auto geometry = Geometry::MakeStrokedArc(oval_bounds, Degrees(start),
311  Degrees(330), butt_params);
312  EXPECT_EQ(geometry->GetCoverage({}), expanded_bounds)
313  << "start: " << start << ", butt caps";
314  geometry = Geometry::MakeStrokedArc(oval_bounds, Degrees(start),
315  Degrees(330), square_params);
316  EXPECT_EQ(geometry->GetCoverage({}), squared_bounds)
317  << "start: " << start << ", square caps";
318  }
319  }
320  { // Sweep from early in one quadrant backwards to later in same quadrant
321  for (int start = 30; start < 360; start += 90) {
322  auto geometry = Geometry::MakeStrokedArc(oval_bounds, Degrees(start),
323  Degrees(-330), butt_params);
324  EXPECT_EQ(geometry->GetCoverage({}), expanded_bounds)
325  << "start: " << start << " without center";
326  geometry = Geometry::MakeStrokedArc(oval_bounds, Degrees(start),
327  Degrees(-330), square_params);
328  EXPECT_EQ(geometry->GetCoverage({}), squared_bounds)
329  << "start: " << start << " with center";
330  }
331  }
332  { // Sweep past each quadrant axis individually with butt caps
333  for (int start = -360; start <= 720; start += 360) {
334  { // Quadrant 0
335  auto geometry = Geometry::MakeStrokedArc(
336  oval_bounds, Degrees(start - 45), Degrees(90), butt_params);
337  Rect expected_bounds = Rect::MakeLTRB(150 + 50 * kSqrt2Over2 - 5, //
338  150 - 50 * kSqrt2Over2 - 5, //
339  205, //
340  150 + 50 * kSqrt2Over2 + 5);
341  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
342  expected_bounds)
343  << "start: " << start - 45;
344  }
345  { // Quadrant 1
346  auto geometry = Geometry::MakeStrokedArc(
347  oval_bounds, Degrees(start + 45), Degrees(90), butt_params);
348  Rect expected_bounds = Rect::MakeLTRB(150 - 50 * kSqrt2Over2 - 5, //
349  150 + 50 * kSqrt2Over2 - 5, //
350  150 + 50 * kSqrt2Over2 + 5, //
351  205);
352  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
353  expected_bounds)
354  << "start: " << start + 45;
355  }
356  { // Quadrant 2
357  auto geometry = Geometry::MakeStrokedArc(
358  oval_bounds, Degrees(start + 135), Degrees(90), butt_params);
359  Rect expected_bounds = Rect::MakeLTRB(95, //
360  150 - 50 * kSqrt2Over2 - 5, //
361  150 - 50 * kSqrt2Over2 + 5, //
362  150 + 50 * kSqrt2Over2 + 5);
363  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
364  expected_bounds)
365  << "start: " << start + 135;
366  }
367  { // Quadrant 3
368  auto geometry = Geometry::MakeStrokedArc(
369  oval_bounds, Degrees(start + 225), Degrees(90), butt_params);
370  Rect expected_bounds = Rect::MakeLTRB(150 - 50 * kSqrt2Over2 - 5, //
371  95, //
372  150 + 50 * kSqrt2Over2 + 5, //
373  150 - 50 * kSqrt2Over2 + 5);
374  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
375  expected_bounds)
376  << "start: " << start + 225;
377  }
378  }
379  }
380  { // Sweep past each quadrant axis individually with square caps
381  Scalar pad = 5 * kSqrt2;
382  for (int start = -360; start <= 720; start += 360) {
383  { // Quadrant 0
384  auto geometry = Geometry::MakeStrokedArc(
385  oval_bounds, Degrees(start - 45), Degrees(90), square_params);
386  Rect expected_bounds = Rect::MakeLTRB(150 + 50 * kSqrt2Over2 - pad, //
387  150 - 50 * kSqrt2Over2 - pad, //
388  200 + pad, //
389  150 + 50 * kSqrt2Over2 + pad);
390  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
391  expected_bounds)
392  << "start: " << start - 45;
393  }
394  { // Quadrant 1
395  auto geometry = Geometry::MakeStrokedArc(
396  oval_bounds, Degrees(start + 45), Degrees(90), square_params);
397  Rect expected_bounds = Rect::MakeLTRB(150 - 50 * kSqrt2Over2 - pad, //
398  150 + 50 * kSqrt2Over2 - pad, //
399  150 + 50 * kSqrt2Over2 + pad, //
400  200 + pad);
401  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
402  expected_bounds)
403  << "start: " << start + 45;
404  }
405  { // Quadrant 2
406  auto geometry = Geometry::MakeStrokedArc(
407  oval_bounds, Degrees(start + 135), Degrees(90), square_params);
408  Rect expected_bounds = Rect::MakeLTRB(100 - pad, //
409  150 - 50 * kSqrt2Over2 - pad, //
410  150 - 50 * kSqrt2Over2 + pad, //
411  150 + 50 * kSqrt2Over2 + pad);
412  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
413  expected_bounds)
414  << "start: " << start + 135;
415  }
416  { // Quadrant 3
417  auto geometry = Geometry::MakeStrokedArc(
418  oval_bounds, Degrees(start + 225), Degrees(90), square_params);
419  Rect expected_bounds = Rect::MakeLTRB(150 - 50 * kSqrt2Over2 - pad, //
420  100 - pad, //
421  150 + 50 * kSqrt2Over2 + pad, //
422  150 - 50 * kSqrt2Over2 + pad);
423  EXPECT_RECT_NEAR(geometry->GetCoverage({}).value_or(Rect()),
424  expected_bounds)
425  << "start: " << start + 225;
426  }
427  }
428  }
429  { // 45 degree tilted full circle, butt caps
430  auto geometry = Geometry::MakeStrokedArc( //
431  oval_bounds, Degrees(0), Degrees(360), butt_params);
432  ASSERT_TRUE(
433  oval_bounds.TransformBounds(transform45).Contains(expanded_bounds));
434 
435  EXPECT_TRUE(geometry->GetCoverage(transform45)
436  .value_or(Rect())
437  .Contains(expanded_bounds));
438  }
439  { // 45 degree tilted full circle, square caps
440  auto geometry = Geometry::MakeStrokedArc( //
441  oval_bounds, Degrees(0), Degrees(360), square_params);
442  ASSERT_TRUE(
443  oval_bounds.TransformBounds(transform45).Contains(expanded_bounds));
444 
445  EXPECT_TRUE(geometry->GetCoverage(transform45)
446  .value_or(Rect())
447  .Contains(squared_bounds));
448  }
449  { // 45 degree tilted mostly full circle, butt caps
450  auto geometry = Geometry::MakeStrokedArc( //
451  oval_bounds, Degrees(3), Degrees(359), butt_params);
452  ASSERT_TRUE(
453  oval_bounds.TransformBounds(transform45).Contains(expanded_bounds));
454 
455  EXPECT_TRUE(geometry->GetCoverage(transform45)
456  .value_or(Rect())
457  .Contains(expanded_bounds));
458  }
459  { // 45 degree tilted mostly full circle, square caps
460  auto geometry = Geometry::MakeStrokedArc( //
461  oval_bounds, Degrees(3), Degrees(359), square_params);
462  ASSERT_TRUE(
463  oval_bounds.TransformBounds(transform45).Contains(expanded_bounds));
464 
465  EXPECT_TRUE(geometry->GetCoverage(transform45)
466  .value_or(Rect())
467  .Contains(squared_bounds));
468  }
469 }
constexpr float kSqrt2
Definition: constants.h:47

References impeller::TRect< T >::Contains(), EXPECT_RECT_NEAR, impeller::TRect< T >::GetCenter(), impeller::kButt, impeller::kSqrt2, impeller::kSqrt2Over2, impeller::kSquare, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationZ(), impeller::Geometry::MakeStrokedArc(), impeller::Matrix::MakeTranslation(), start, impeller::TRect< T >::TransformBounds(), and impeller::StrokeParameters::width.

◆ TEST() [114/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TightConic180DegreeJoins   
)

Definition at line 1180 of file geometry_unittests.cc.

1180  {
1181  // First, create a mild conic that helps us verify how many points
1182  // should normally be on a quad with 2 legs of length 90.
1183  flutter::DlPathBuilder path_builder_refrence;
1184  path_builder_refrence.MoveTo(Point(10, 10));
1185  path_builder_refrence.ConicCurveTo(Point(100, 10), Point(100, 100), 0.9f);
1186  flutter::DlPath path_reference = path_builder_refrence.TakePath();
1187 
1188  auto points_bevel_reference =
1189  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1190  path_reference,
1191  {
1192  .width = 20.0f,
1193  .cap = Cap::kButt,
1194  .join = Join::kBevel,
1195  .miter_limit = 4.0f,
1196  },
1197  1.0f);
1198  // Generates no joins because the curve is smooth
1199  EXPECT_EQ(points_bevel_reference.size(), 78u);
1200 
1201  // Now create a path that doubles back on itself with a conic.
1202  flutter::DlPathBuilder path_builder;
1203  path_builder.MoveTo(Point(10, 10));
1204  path_builder.QuadraticCurveTo(Point(100, 10), Point(10, 10));
1205  flutter::DlPath path = path_builder.TakePath();
1206 
1207  auto points_bevel =
1208  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1209  path,
1210  {
1211  .width = 20.0f,
1212  .cap = Cap::kButt,
1213  .join = Join::kBevel,
1214  .miter_limit = 4.0f,
1215  },
1216  1.0f);
1217  // Generates round join because it is in the middle of a curved segment
1218  EXPECT_GT(points_bevel.size(), points_bevel_reference.size());
1219 
1220  auto points_miter =
1221  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1222  path,
1223  {
1224  .width = 20.0f,
1225  .cap = Cap::kButt,
1226  .join = Join::kMiter,
1227  .miter_limit = 400.0f,
1228  },
1229  1.0f);
1230  // Generates round join because it is in the middle of a curved segment
1231  EXPECT_GT(points_miter.size(), points_bevel_reference.size());
1232 
1233  auto points_round =
1234  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1235  path,
1236  {
1237  .width = 20.0f,
1238  .cap = Cap::kButt,
1239  .join = Join::kRound,
1240  .miter_limit = 4.0f,
1241  },
1242  1.0f);
1243  // Generates round join because it is in the middle of a curved segment
1244  EXPECT_GT(points_round.size(), points_bevel_reference.size());
1245 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kButt, impeller::kMiter, and impeller::kRound.

◆ TEST() [115/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TightCubic180DegreeJoins   
)

Definition at line 1247 of file geometry_unittests.cc.

1247  {
1248  // First, create a mild cubic that helps us verify how many points
1249  // should normally be on a quad with 3 legs of length ~50.
1250  flutter::DlPathBuilder path_builder_reference;
1251  path_builder_reference.MoveTo(Point(10, 10));
1252  path_builder_reference.CubicCurveTo(Point(60, 10), Point(100, 40),
1253  Point(100, 90));
1254  flutter::DlPath path_reference = path_builder_reference.TakePath();
1255 
1256  auto points_reference =
1257  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1258  path_reference,
1259  {
1260  .width = 20.0f,
1261  .cap = Cap::kButt,
1262  .join = Join::kBevel,
1263  .miter_limit = 4.0f,
1264  },
1265  1.0f);
1266  // Generates no joins because the curve is smooth
1267  EXPECT_EQ(points_reference.size(), 80u);
1268 
1269  // Now create a path that doubles back on itself with a cubic.
1270  flutter::DlPathBuilder path_builder;
1271  path_builder.MoveTo(Point(10, 10));
1272  path_builder.CubicCurveTo(Point(60, 10), Point(100, 40), Point(60, 10));
1273  flutter::DlPath path = path_builder.TakePath();
1274 
1275  auto points_bevel =
1276  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1277  path,
1278  {
1279  .width = 20.0f,
1280  .cap = Cap::kButt,
1281  .join = Join::kBevel,
1282  .miter_limit = 4.0f,
1283  },
1284  1.0f);
1285  // Generates round join because it is in the middle of a curved segment
1286  EXPECT_GT(points_bevel.size(), points_reference.size());
1287 
1288  auto points_miter =
1289  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1290  path,
1291  {
1292  .width = 20.0f,
1293  .cap = Cap::kButt,
1294  .join = Join::kMiter,
1295  .miter_limit = 400.0f,
1296  },
1297  1.0f);
1298  // Generates round join because it is in the middle of a curved segment
1299  EXPECT_GT(points_miter.size(), points_reference.size());
1300 
1301  auto points_round =
1302  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1303  path,
1304  {
1305  .width = 20.0f,
1306  .cap = Cap::kButt,
1307  .join = Join::kRound,
1308  .miter_limit = 4.0f,
1309  },
1310  1.0f);
1311  // Generates round join because it is in the middle of a curved segment
1312  EXPECT_GT(points_round.size(), points_reference.size());
1313 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kButt, impeller::kMiter, and impeller::kRound.

◆ TEST() [116/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TightQuadratic180DegreeJoins   
)

Definition at line 1113 of file geometry_unittests.cc.

1113  {
1114  // First, create a mild quadratic that helps us verify how many points
1115  // should normally be on a quad with 2 legs of length 90.
1116  flutter::DlPathBuilder path_builder_refrence;
1117  path_builder_refrence.MoveTo(Point(10, 10));
1118  path_builder_refrence.QuadraticCurveTo(Point(100, 10), Point(100, 100));
1119  flutter::DlPath path_reference = path_builder_refrence.TakePath();
1120 
1121  auto points_bevel_reference =
1122  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1123  path_reference,
1124  {
1125  .width = 20.0f,
1126  .cap = Cap::kButt,
1127  .join = Join::kBevel,
1128  .miter_limit = 4.0f,
1129  },
1130  1.0f);
1131  // Generates no joins because the curve is smooth
1132  EXPECT_EQ(points_bevel_reference.size(), 74u);
1133 
1134  // Now create a path that doubles back on itself with a quadratic.
1135  flutter::DlPathBuilder path_builder;
1136  path_builder.MoveTo(Point(10, 10));
1137  path_builder.QuadraticCurveTo(Point(100, 10), Point(10, 10));
1138  flutter::DlPath path = path_builder.TakePath();
1139 
1140  auto points_bevel =
1141  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1142  path,
1143  {
1144  .width = 20.0f,
1145  .cap = Cap::kButt,
1146  .join = Join::kBevel,
1147  .miter_limit = 4.0f,
1148  },
1149  1.0f);
1150  // Generates round join because it is in the middle of a curved segment
1151  EXPECT_GT(points_bevel.size(), points_bevel_reference.size());
1152 
1153  auto points_miter =
1154  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1155  path,
1156  {
1157  .width = 20.0f,
1158  .cap = Cap::kButt,
1159  .join = Join::kMiter,
1160  .miter_limit = 400.0f,
1161  },
1162  1.0f);
1163  // Generates round join because it is in the middle of a curved segment
1164  EXPECT_GT(points_miter.size(), points_bevel_reference.size());
1165 
1166  auto points_round =
1167  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1168  path,
1169  {
1170  .width = 20.0f,
1171  .cap = Cap::kButt,
1172  .join = Join::kRound,
1173  .miter_limit = 4.0f,
1174  },
1175  1.0f);
1176  // Generates round join because it is in the middle of a curved segment
1177  EXPECT_GT(points_round.size(), points_bevel_reference.size());
1178 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kButt, impeller::kMiter, and impeller::kRound.

◆ TEST() [117/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TinyConicGeneratesCaps   
)

Definition at line 927 of file geometry_unittests.cc.

927  {
928  flutter::DlPathBuilder path_builder;
929  path_builder.MoveTo({20, 20});
930  path_builder.ConicCurveTo({20.125, 20}, {20.250, 20}, 0.6);
931  flutter::DlPath path = path_builder.TakePath();
932 
933  auto points = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
934  path,
935  {
936  .width = 4.0f,
937  .cap = Cap::kSquare,
938  .join = Join::kBevel,
939  .miter_limit = 4.0f,
940  },
941  1.0f);
942 
943  std::vector<Point> expected = {
944  // The points for the opening square cap
945  Point(18, 22),
946  Point(18, 18),
947 
948  // The points for the start of the curve
949  Point(20, 22),
950  Point(20, 18),
951 
952  // The points for the end of the curve
953  Point(20.25, 22),
954  Point(20.25, 18),
955 
956  // The points for the closing square cap
957  Point(22.25, 22),
958  Point(22.25, 18),
959  };
960 
961  EXPECT_EQ(points, expected);
962 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kSquare, and points.

◆ TEST() [118/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TinyCubicGeneratesCaps   
)

Definition at line 964 of file geometry_unittests.cc.

964  {
965  flutter::DlPathBuilder path_builder;
966  path_builder.MoveTo({20, 20});
967  path_builder.CubicCurveTo({20.0625, 20}, {20.125, 20}, {20.250, 20});
968  flutter::DlPath path = path_builder.TakePath();
969 
970  auto points = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
971  path,
972  {
973  .width = 4.0f,
974  .cap = Cap::kSquare,
975  .join = Join::kBevel,
976  .miter_limit = 4.0f,
977  },
978  1.0f);
979 
980  std::vector<Point> expected = {
981  // The points for the opening square cap
982  Point(18, 22),
983  Point(18, 18),
984 
985  // The points for the start of the curve
986  Point(20, 22),
987  Point(20, 18),
988 
989  // The points for the end of the curve
990  Point(20.25, 22),
991  Point(20.25, 18),
992 
993  // The points for the closing square cap
994  Point(22.25, 22),
995  Point(22.25, 18),
996  };
997 
998  EXPECT_EQ(points, expected);
999 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kSquare, and points.

◆ TEST() [119/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TinyQuadGeneratesCaps   
)

Definition at line 890 of file geometry_unittests.cc.

890  {
891  flutter::DlPathBuilder path_builder;
892  path_builder.MoveTo({20, 20});
893  path_builder.QuadraticCurveTo({20.125, 20}, {20.250, 20});
894  flutter::DlPath path = path_builder.TakePath();
895 
896  auto points = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
897  path,
898  {
899  .width = 4.0f,
900  .cap = Cap::kSquare,
901  .join = Join::kBevel,
902  .miter_limit = 4.0f,
903  },
904  1.0f);
905 
906  std::vector<Point> expected = {
907  // The points for the opening square cap
908  Point(18, 22),
909  Point(18, 18),
910 
911  // The points for the start of the curve
912  Point(20, 22),
913  Point(20, 18),
914 
915  // The points for the end of the curve
916  Point(20.25, 22),
917  Point(20.25, 18),
918 
919  // The points for the closing square cap
920  Point(22.25, 22),
921  Point(22.25, 18),
922  };
923 
924  EXPECT_EQ(points, expected);
925 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kSquare, and points.

◆ TEST() [120/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TwoLineSegments180DegreeJoins   
)

Definition at line 1065 of file geometry_unittests.cc.

1065  {
1066  // First, create a path that doubles back on itself.
1067  flutter::DlPathBuilder path_builder;
1068  path_builder.MoveTo(Point(10, 10));
1069  path_builder.LineTo(Point(100, 10));
1070  path_builder.LineTo(Point(10, 10));
1071  flutter::DlPath path = path_builder.TakePath();
1072 
1073  auto points_bevel =
1074  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1075  path,
1076  {
1077  .width = 20.0f,
1078  .cap = Cap::kButt,
1079  .join = Join::kBevel,
1080  .miter_limit = 4.0f,
1081  },
1082  1.0f);
1083  // Generates no join - because it is a bevel join
1084  EXPECT_EQ(points_bevel.size(), 8u);
1085 
1086  auto points_miter =
1087  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1088  path,
1089  {
1090  .width = 20.0f,
1091  .cap = Cap::kButt,
1092  .join = Join::kMiter,
1093  .miter_limit = 400.0f,
1094  },
1095  1.0f);
1096  // Generates no join - even with a very large miter limit
1097  EXPECT_EQ(points_miter.size(), 8u);
1098 
1099  auto points_round =
1100  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1101  path,
1102  {
1103  .width = 20.0f,
1104  .cap = Cap::kButt,
1105  .join = Join::kRound,
1106  .miter_limit = 4.0f,
1107  },
1108  1.0f);
1109  // Generates lots of join points - to round off the 180 degree bend
1110  EXPECT_EQ(points_round.size(), 19u);
1111 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kButt, impeller::kMiter, and impeller::kRound.

◆ TEST() [121/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TwoLineSegmentsLeftTurnStrokeVerticesBevelJoin   
)

Definition at line 782 of file geometry_unittests.cc.

782  {
783  flutter::DlPathBuilder path_builder;
784  path_builder.MoveTo({20, 20});
785  path_builder.LineTo({30, 20});
786  path_builder.LineTo({30, 10});
787  flutter::DlPath path = path_builder.TakePath();
788 
789  auto points = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
790  path,
791  {
792  .width = 10.0f,
793  .cap = Cap::kButt,
794  .join = Join::kBevel,
795  .miter_limit = 4.0f,
796  },
797  1.0f);
798 
799  std::vector<Point> expected = {
800  // The points for the first segment (20, 20) -> (30, 20)
801  Point(20, 25),
802  Point(20, 15),
803  Point(30, 25),
804  Point(30, 15),
805 
806  // The points for the second segment (120, 20) -> (130, 20)
807  Point(35, 20),
808  Point(25, 20),
809  Point(35, 10),
810  Point(25, 10),
811  };
812 
813  EXPECT_EQ(points, expected);
814 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kButt, and points.

◆ TEST() [122/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TwoLineSegmentsLeftTurnStrokeVerticesMiterJoin   
)

Definition at line 853 of file geometry_unittests.cc.

853  {
854  flutter::DlPathBuilder path_builder;
855  path_builder.MoveTo({20, 20});
856  path_builder.LineTo({30, 20});
857  path_builder.LineTo({30, 10});
858  flutter::DlPath path = path_builder.TakePath();
859 
860  auto points = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
861  path,
862  {
863  .width = 10.0f,
864  .cap = Cap::kButt,
865  .join = Join::kMiter,
866  .miter_limit = 4.0f,
867  },
868  1.0f);
869 
870  std::vector<Point> expected = {
871  // The points for the first segment (20, 20) -> (30, 20)
872  Point(20, 25),
873  Point(20, 15),
874  Point(30, 25),
875  Point(30, 15),
876 
877  // And one point makes a Miter
878  Point(35, 25),
879 
880  // The points for the second segment (120, 20) -> (130, 20)
881  Point(35, 20),
882  Point(25, 20),
883  Point(35, 10),
884  Point(25, 10),
885  };
886 
887  EXPECT_EQ(points, expected);
888 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kButt, impeller::kMiter, and points.

◆ TEST() [123/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TwoLineSegmentsMiterLimit   
)

Definition at line 1001 of file geometry_unittests.cc.

1001  {
1002  // degrees is the angle that the line deviates from "straight ahead"
1003  for (int degrees = 10; degrees < 180; degrees += 10) {
1004  // Start with a width of 2 since line widths of 1 usually decide
1005  // that they don't need join geometry at a scale of 1.0
1006  for (int width = 2; width <= 10; width++) {
1007  Degrees d(degrees);
1008  Radians r(d);
1009  Point pixel_delta = Point(std::cos(r.radians), std::sin(r.radians));
1010 
1011  if (pixel_delta.GetDistance(Point(1, 0)) * width < 1.0f) {
1012  // Some combinations of angle and width result in a join that is
1013  // less than a pixel in size. We don't care about compliance on
1014  // such a small join delta (and, in fact, the implementation may
1015  // decide to elide those small joins).
1016  continue;
1017  }
1018 
1019  // Miter limits are based on angle between the vectors/segments
1020  Degrees between(180 - degrees);
1021  Radians r_between(between);
1022  Scalar limit = 1.0f / std::sin(r_between.radians / 2.0f);
1023 
1024  flutter::DlPathBuilder path_builder;
1025  path_builder.MoveTo(Point(20, 20));
1026  path_builder.LineTo(Point(30, 20));
1027  path_builder.LineTo(Point(30, 20) + pixel_delta * 10.0f);
1028  flutter::DlPath path = path_builder.TakePath();
1029 
1030  // Miter limit too small (99% of required) to allow a miter
1031  auto points1 =
1032  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1033  path,
1034  {
1035  .width = static_cast<Scalar>(width),
1036  .cap = Cap::kButt,
1037  .join = Join::kMiter,
1038  .miter_limit = limit * 0.99f,
1039  },
1040  1.0f);
1041  EXPECT_EQ(points1.size(), 8u)
1042  << "degrees: " << degrees << ", width: " << width << ", "
1043  << points1[4];
1044 
1045  // Miter limit large enough (101% of required) to allow a miter
1046  auto points2 =
1047  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
1048  path,
1049  {
1050  .width = static_cast<Scalar>(width),
1051  .cap = Cap::kButt,
1052  .join = Join::kMiter,
1053  .miter_limit = limit * 1.01f,
1054  },
1055  1.0f);
1056  EXPECT_EQ(points2.size(), 9u)
1057  << "degrees: " << degrees << ", width: " << width;
1058  EXPECT_LE(points2[4].GetDistance({30, 20}), width * limit * 1.05f)
1059  << "degrees: " << degrees << ", width: " << width << ", "
1060  << points2[4];
1061  }
1062  }
1063 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::TPoint< T >::GetDistance(), impeller::kButt, impeller::kMiter, and impeller::Radians::radians.

◆ TEST() [124/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TwoLineSegmentsRightTurnStrokeVerticesBevelJoin   
)

Definition at line 748 of file geometry_unittests.cc.

748  {
749  flutter::DlPathBuilder path_builder;
750  path_builder.MoveTo({20, 20});
751  path_builder.LineTo({30, 20});
752  path_builder.LineTo({30, 30});
753  flutter::DlPath path = path_builder.TakePath();
754 
755  auto points = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
756  path,
757  {
758  .width = 10.0f,
759  .cap = Cap::kButt,
760  .join = Join::kBevel,
761  .miter_limit = 4.0f,
762  },
763  1.0f);
764 
765  std::vector<Point> expected = {
766  // The points for the first segment (20, 20) -> (30, 20)
767  Point(20, 25),
768  Point(20, 15),
769  Point(30, 25),
770  Point(30, 15),
771 
772  // The points for the second segment (120, 20) -> (130, 20)
773  Point(25, 20),
774  Point(35, 20),
775  Point(25, 30),
776  Point(35, 30),
777  };
778 
779  EXPECT_EQ(points, expected);
780 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kBevel, impeller::kButt, and points.

◆ TEST() [125/525]

impeller::testing::TEST ( EntityGeometryTest  ,
TwoLineSegmentsRightTurnStrokeVerticesMiterJoin   
)

Definition at line 816 of file geometry_unittests.cc.

816  {
817  flutter::DlPathBuilder path_builder;
818  path_builder.MoveTo({20, 20});
819  path_builder.LineTo({30, 20});
820  path_builder.LineTo({30, 30});
821  flutter::DlPath path = path_builder.TakePath();
822 
823  auto points = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
824  path,
825  {
826  .width = 10.0f,
827  .cap = Cap::kButt,
828  .join = Join::kMiter,
829  .miter_limit = 4.0f,
830  },
831  1.0f);
832 
833  std::vector<Point> expected = {
834  // The points for the first segment (20, 20) -> (30, 20)
835  Point(20, 25),
836  Point(20, 15),
837  Point(30, 25),
838  Point(30, 15),
839 
840  // And one point makes a Miter
841  Point(35, 15),
842 
843  // The points for the second segment (120, 20) -> (130, 20)
844  Point(25, 20),
845  Point(35, 20),
846  Point(25, 30),
847  Point(35, 30),
848  };
849 
850  EXPECT_EQ(points, expected);
851 }

References impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::kButt, impeller::kMiter, and points.

◆ TEST() [126/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
AppendAndRestoreClipCoverage   
)

Definition at line 58 of file clip_stack_unittests.cc.

58  {
59  EntityPassClipStack recorder =
60  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
61 
62  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
63 
64  // Push a clip.
65  EntityPassClipStack::ClipStateResult result =
66  recorder.RecordClip(ClipContents(Rect::MakeLTRB(50, 50, 55.5, 55.5),
67  /*is_axis_aligned_rect=*/true),
68  Matrix(), {0, 0}, 0, 100, /*is_aa=*/true);
69  EXPECT_TRUE(result.should_render);
70  EXPECT_TRUE(result.clip_did_change);
71 
72  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
73  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
74  Rect::MakeLTRB(50, 50, 55.5, 55.5));
75  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
76  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
77 
78  // Restore the clip.
79  recorder.RecordRestore({0, 0}, 0);
80 
81  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
82  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
83  Rect::MakeSize(Size::MakeWH(100, 100)));
84  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
85  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
86 }

References impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TSize< Scalar >::MakeWH(), impeller::EntityPassClipStack::RecordClip(), impeller::EntityPassClipStack::RecordRestore(), and impeller::EntityPassClipStack::ClipStateResult::should_render.

◆ TEST() [127/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
AppendAndRestoreClipCoverageNonAA   
)

Definition at line 88 of file clip_stack_unittests.cc.

88  {
89  EntityPassClipStack recorder =
90  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
91 
92  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
93 
94  // Push a clip.
95  EntityPassClipStack::ClipStateResult result =
96  recorder.RecordClip(ClipContents(Rect::MakeLTRB(50, 50, 55.4, 55.4),
97  /*is_axis_aligned_rect=*/true),
98  Matrix(), {0, 0}, 0, 100, /*is_aa=*/false);
99  EXPECT_FALSE(result.should_render);
100  EXPECT_TRUE(result.clip_did_change);
101 
102  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
103  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
104  Rect::MakeLTRB(50, 50, 55, 55));
105  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
106  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
107 
108  // Restore the clip.
109  recorder.RecordRestore({0, 0}, 0);
110 
111  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
112  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
113  Rect::MakeSize(Size::MakeWH(100, 100)));
114  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
115  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
116 }

References impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TSize< Scalar >::MakeWH(), impeller::EntityPassClipStack::RecordClip(), impeller::EntityPassClipStack::RecordRestore(), and impeller::EntityPassClipStack::ClipStateResult::should_render.

◆ TEST() [128/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
AppendDecreasingSizeClipCoverage   
)

Definition at line 171 of file clip_stack_unittests.cc.

171  {
172  EntityPassClipStack recorder =
173  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
174 
175  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
176 
177  // Push Clips that shrink in size. All should be applied.
178  Entity entity;
179 
180  for (auto i = 1; i < 20; i++) {
181  EntityPassClipStack::ClipStateResult result = recorder.RecordClip(
182  ClipContents(Rect::MakeLTRB(i, i, 99.6 - i, 99.6 - i),
183  /*is_axis_aligned_rect=*/true),
184  Matrix(), {0, 0}, 0, 100, /*is_aa=*/true);
185 
186  EXPECT_TRUE(result.should_render);
187  EXPECT_TRUE(result.clip_did_change);
188  EXPECT_EQ(recorder.CurrentClipCoverage(),
189  Rect::MakeLTRB(i, i, 99.6 - i, 99.6 - i));
190  }
191 }

References impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::CurrentClipCoverage(), impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::TRect< Scalar >::MakeLTRB(), impeller::EntityPassClipStack::RecordClip(), and impeller::EntityPassClipStack::ClipStateResult::should_render.

◆ TEST() [129/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
AppendIncreasingSizeClipCoverage   
)

Definition at line 193 of file clip_stack_unittests.cc.

193  {
194  EntityPassClipStack recorder =
195  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
196 
197  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
198 
199  // Push Clips that grow in size. All should be skipped.
200 
201  for (auto i = 1; i < 20; i++) {
202  EntityPassClipStack::ClipStateResult result = recorder.RecordClip(
203  ClipContents(Rect::MakeLTRB(0 - i, 0 - i, 100 + i, 100 + i),
204  /*is_axis_aligned_rect=*/true),
205  Matrix(), {0, 0}, 0, 100, /*is_aa=*/true);
206 
207  EXPECT_FALSE(result.should_render);
208  EXPECT_FALSE(result.clip_did_change);
209  EXPECT_EQ(recorder.CurrentClipCoverage(), Rect::MakeLTRB(0, 0, 100, 100));
210  }
211 }

References impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::CurrentClipCoverage(), impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::TRect< Scalar >::MakeLTRB(), impeller::EntityPassClipStack::RecordClip(), and impeller::EntityPassClipStack::ClipStateResult::should_render.

◆ TEST() [130/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
AppendLargerClipCoverage   
)

Definition at line 120 of file clip_stack_unittests.cc.

120  {
121  EntityPassClipStack recorder =
122  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
123 
124  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
125 
126  // Push a clip.
127  EntityPassClipStack::ClipStateResult result =
128  recorder.RecordClip(ClipContents(Rect::MakeLTRB(50, 50, 55.5, 55.5),
129  /*is_axis_aligned_rect=*/true),
130  Matrix(), {0, 0}, 0, 100, /*is_aa=*/true);
131 
132  EXPECT_TRUE(result.should_render);
133  EXPECT_TRUE(result.clip_did_change);
134 
135  // Push a clip with larger coverage than the previous state.
136  result = recorder.RecordClip(ClipContents(Rect::MakeLTRB(0, 0, 100.5, 100.5),
137  /*is_axis_aligned_rect=*/true),
138  Matrix(), {0, 0}, 1, 100, /*is_aa=*/true);
139 
140  EXPECT_FALSE(result.should_render);
141  EXPECT_FALSE(result.clip_did_change);
142 }

References impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::TRect< Scalar >::MakeLTRB(), impeller::EntityPassClipStack::RecordClip(), and impeller::EntityPassClipStack::ClipStateResult::should_render.

◆ TEST() [131/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
AppendLargerClipCoverageWithDifferenceOrNonSquare   
)

Definition at line 146 of file clip_stack_unittests.cc.

147  {
148  EntityPassClipStack recorder =
149  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
150 
151  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
152 
153  // Push a clip.
154  EntityPassClipStack::ClipStateResult result =
155  recorder.RecordClip(ClipContents(Rect::MakeLTRB(50, 50, 55, 55),
156  /*is_axis_aligned_rect=*/true),
157  Matrix(), {0, 0}, 0, 100, /*is_aa=*/true);
158 
159  EXPECT_FALSE(result.should_render);
160  EXPECT_TRUE(result.clip_did_change);
161 
162  // Push a clip with larger coverage than the previous state.
163  result = recorder.RecordClip(ClipContents(Rect::MakeLTRB(0, 0, 100, 100),
164  /*is_axis_aligned_rect=*/false),
165  Matrix(), {0, 0}, 0, 100, /*is_aa=*/true);
166 
167  EXPECT_TRUE(result.should_render);
168  EXPECT_TRUE(result.clip_did_change);
169 }

References impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::TRect< Scalar >::MakeLTRB(), impeller::EntityPassClipStack::RecordClip(), and impeller::EntityPassClipStack::ClipStateResult::should_render.

◆ TEST() [132/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
CanPopEntitiesSafely   
)

Definition at line 48 of file clip_stack_unittests.cc.

48  {
49  EntityPassClipStack recorder =
50  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
51 
52  EXPECT_TRUE(recorder.GetReplayEntities().empty());
53 
54  recorder.RecordRestore({0, 0}, 0);
55  EXPECT_TRUE(recorder.GetReplayEntities().empty());
56 }

References impeller::EntityPassClipStack::GetReplayEntities(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::EntityPassClipStack::RecordRestore().

◆ TEST() [133/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
CanPushAndPopEntities   
)

Definition at line 14 of file clip_stack_unittests.cc.

14  {
15  EntityPassClipStack recorder =
16  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
17 
18  EXPECT_TRUE(recorder.GetReplayEntities().empty());
19 
20  recorder.RecordClip(ClipContents(Rect::MakeLTRB(0, 0, 100, 100),
21  /*is_axis_aligned_rect=*/false),
22  Matrix(), {0, 0}, 0, 100, /*is_aa=*/true);
23 
24  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
25 
26  recorder.RecordClip(ClipContents(Rect::MakeLTRB(0, 0, 50.5, 50.5),
27  /*is_axis_aligned_rect=*/true),
28  Matrix(), {0, 0}, 2, 100, /*is_aa=*/true);
29 
30  EXPECT_EQ(recorder.GetReplayEntities().size(), 2u);
31  ASSERT_TRUE(recorder.GetReplayEntities()[0].clip_coverage.has_value());
32  ASSERT_TRUE(recorder.GetReplayEntities()[1].clip_coverage.has_value());
33 
34  // NOLINTBEGIN(bugprone-unchecked-optional-access)
35  EXPECT_EQ(recorder.GetReplayEntities()[0].clip_coverage.value(),
36  Rect::MakeLTRB(0, 0, 100, 100));
37  EXPECT_EQ(recorder.GetReplayEntities()[1].clip_coverage.value(),
38  Rect::MakeLTRB(0, 0, 50.5, 50.5));
39  // NOLINTEND(bugprone-unchecked-optional-access)
40 
41  recorder.RecordRestore({0, 0}, 1);
42  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
43 
44  recorder.RecordRestore({0, 0}, 0);
45  EXPECT_TRUE(recorder.GetReplayEntities().empty());
46 }

References impeller::EntityPassClipStack::GetReplayEntities(), impeller::TRect< Scalar >::MakeLTRB(), impeller::EntityPassClipStack::RecordClip(), and impeller::EntityPassClipStack::RecordRestore().

◆ TEST() [134/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
ClipAndRestoreWithSubpasses   
)

Definition at line 232 of file clip_stack_unittests.cc.

232  {
233  EntityPassClipStack recorder =
234  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
235 
236  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
237 
238  // Push a clip.
239  {
240  EntityPassClipStack::ClipStateResult result =
241  recorder.RecordClip(ClipContents(Rect::MakeLTRB(50, 50, 55.5, 55.5),
242  /*is_axis_aligned_rect=*/true),
243  Matrix(), {0, 0}, 0, 100, /*is_aa=*/true);
244 
245  EXPECT_TRUE(result.should_render);
246  EXPECT_TRUE(result.clip_did_change);
247  }
248 
249  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
250  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
251  Rect::MakeLTRB(50, 50, 55.5, 55.5));
252  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
253  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
254 
255  // Begin a subpass.
256  recorder.PushSubpass(Rect::MakeLTRB(50, 50, 55, 55), 1);
257  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
258  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
259  Rect::MakeLTRB(50, 50, 55, 55));
260 
261  {
262  EntityPassClipStack::ClipStateResult result =
263  recorder.RecordClip(ClipContents(Rect::MakeLTRB(54, 54, 54.5, 54.5),
264  /*is_axis_aligned_rect=*/true),
265  Matrix(), {0, 0}, 0, 100, /*is_aa=*/true);
266 
267  EXPECT_TRUE(result.should_render);
268  EXPECT_TRUE(result.clip_did_change);
269  }
270 
271  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
272  Rect::MakeLTRB(54, 54, 54.5, 54.5));
273 
274  // End subpass.
275  recorder.PopSubpass();
276 
277  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
278  Rect::MakeLTRB(50, 50, 55.5, 55.5));
279 }

References impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::TRect< Scalar >::MakeLTRB(), impeller::EntityPassClipStack::PopSubpass(), impeller::EntityPassClipStack::PushSubpass(), impeller::EntityPassClipStack::RecordClip(), and impeller::EntityPassClipStack::ClipStateResult::should_render.

◆ TEST() [135/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
ClipAndRestoreWithSubpassesNonAA   
)

Definition at line 281 of file clip_stack_unittests.cc.

281  {
282  EntityPassClipStack recorder =
283  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
284 
285  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
286 
287  // Push a clip.
288  {
289  EntityPassClipStack::ClipStateResult result =
290  recorder.RecordClip(ClipContents(Rect::MakeLTRB(50, 50, 55.4, 55.4),
291  /*is_axis_aligned_rect=*/true),
292  Matrix(), {0, 0}, 0, 100, /*is_aa=*/false);
293 
294  EXPECT_FALSE(result.should_render);
295  EXPECT_TRUE(result.clip_did_change);
296  }
297 
298  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
299  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
300  Rect::MakeLTRB(50, 50, 55.0, 55.0));
301  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
302  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
303 
304  // Begin a subpass.
305  recorder.PushSubpass(Rect::MakeLTRB(50, 50, 55, 55), 1);
306  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
307  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
308  Rect::MakeLTRB(50, 50, 55, 55));
309 
310  {
311  EntityPassClipStack::ClipStateResult result =
312  recorder.RecordClip(ClipContents(Rect::MakeLTRB(54, 54, 55.4, 55.4),
313  /*is_axis_aligned_rect=*/true),
314  Matrix(), {0, 0}, 0, 100, /*is_aa=*/false);
315 
316  EXPECT_FALSE(result.should_render);
317  EXPECT_TRUE(result.clip_did_change);
318  }
319 
320  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
321  Rect::MakeLTRB(54, 54, 55.0, 55.0));
322 
323  // End subpass.
324  recorder.PopSubpass();
325 
326  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
327  Rect::MakeLTRB(50, 50, 55, 55));
328 }

References impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::TRect< Scalar >::MakeLTRB(), impeller::EntityPassClipStack::PopSubpass(), impeller::EntityPassClipStack::PushSubpass(), impeller::EntityPassClipStack::RecordClip(), and impeller::EntityPassClipStack::ClipStateResult::should_render.

◆ TEST() [136/525]

impeller::testing::TEST ( EntityPassClipStackTest  ,
UnbalancedRestore   
)

Definition at line 213 of file clip_stack_unittests.cc.

213  {
214  EntityPassClipStack recorder =
215  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
216 
217  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
218 
219  // Restore the clip.
220  EntityPassClipStack::ClipStateResult result =
221  recorder.RecordRestore(Point(0, 0), 0);
222  EXPECT_FALSE(result.should_render);
223  EXPECT_FALSE(result.clip_did_change);
224 
225  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
226  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
227  Rect::MakeSize(Size::MakeWH(100, 100)));
228  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
229  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
230 }

References impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TSize< Scalar >::MakeWH(), impeller::EntityPassClipStack::RecordRestore(), and impeller::EntityPassClipStack::ClipStateResult::should_render.

◆ TEST() [137/525]

impeller::testing::TEST ( FenceWaiterVKTest  ,
AddFenceDoesNothingIfTerminating   
)

Definition at line 86 of file fence_waiter_vk_unittests.cc.

86  {
87  auto signal = fml::ManualResetWaitableEvent();
88 
89  {
90  auto const context = MockVulkanContextBuilder().Build();
91  auto const device = context->GetDevice();
92  auto const waiter = context->GetFenceWaiter();
93  waiter->Terminate();
94 
95  auto fence = device.createFenceUnique({}).value;
96  waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
97  }
98 
99  // Ensure the fence did _not_ signal.
100  EXPECT_TRUE(signal.WaitWithTimeout(fml::TimeDelta::FromMilliseconds(100)));
101 }
int32_t value

References value.

◆ TEST() [138/525]

impeller::testing::TEST ( FenceWaiterVKTest  ,
ExecutesFenceCallback   
)

Definition at line 28 of file fence_waiter_vk_unittests.cc.

28  {
29  auto const context = MockVulkanContextBuilder().Build();
30  auto const device = context->GetDevice();
31  auto const waiter = context->GetFenceWaiter();
32 
33  auto signal = fml::ManualResetWaitableEvent();
34  auto fence = device.createFenceUnique({}).value;
35  waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
36 
37  signal.Wait();
38 }

References value.

◆ TEST() [139/525]

impeller::testing::TEST ( FenceWaiterVKTest  ,
ExecutesFenceCallbackX2   
)

Definition at line 40 of file fence_waiter_vk_unittests.cc.

40  {
41  auto const context = MockVulkanContextBuilder().Build();
42  auto const device = context->GetDevice();
43  auto const waiter = context->GetFenceWaiter();
44 
45  auto signal = fml::ManualResetWaitableEvent();
46  auto fence = device.createFenceUnique({}).value;
47  waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
48 
49  auto signal2 = fml::ManualResetWaitableEvent();
50  auto fence2 = device.createFenceUnique({}).value;
51  waiter->AddFence(std::move(fence2), [&signal2]() { signal2.Signal(); });
52 
53  signal.Wait();
54  signal2.Wait();
55 }

References value.

◆ TEST() [140/525]

impeller::testing::TEST ( FenceWaiterVKTest  ,
ExecutesNewFenceThenOldFence   
)

Definition at line 57 of file fence_waiter_vk_unittests.cc.

57  {
58  auto const context = MockVulkanContextBuilder().Build();
59  auto const device = context->GetDevice();
60  auto const waiter = context->GetFenceWaiter();
61 
62  auto signal = fml::ManualResetWaitableEvent();
63  auto fence = device.createFenceUnique({}).value;
64  MockFence::SetStatus(fence, vk::Result::eNotReady);
65  auto raw_fence = MockFence::GetRawPointer(fence);
66  waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
67 
68  // The easiest way to verify that the callback was _not_ called is to wait
69  // for a timeout, but that could introduce flakiness. Instead, we'll add a
70  // second fence that will signal immediately, and wait for that one instead.
71  {
72  auto signal2 = fml::ManualResetWaitableEvent();
73  auto fence2 = device.createFenceUnique({}).value;
74  MockFence::SetStatus(fence2, vk::Result::eSuccess);
75  waiter->AddFence(std::move(fence2), [&signal2]() { signal2.Signal(); });
76  signal2.Wait();
77  }
78 
79  // Now, we'll signal the first fence, and wait for the callback to be called.
80  raw_fence->SetStatus(vk::Result::eSuccess);
81 
82  // Now, we'll signal the first fence, and wait for the callback to be called.
83  signal.Wait();
84 }

References value.

◆ TEST() [141/525]

impeller::testing::TEST ( FenceWaiterVKTest  ,
IgnoresNullCallback   
)

Definition at line 19 of file fence_waiter_vk_unittests.cc.

19  {
20  auto const context = MockVulkanContextBuilder().Build();
21  auto const device = context->GetDevice();
22  auto const waiter = context->GetFenceWaiter();
23 
24  auto fence = device.createFenceUnique({}).value;
25  EXPECT_FALSE(waiter->AddFence(std::move(fence), nullptr));
26 }

References value.

◆ TEST() [142/525]

impeller::testing::TEST ( FenceWaiterVKTest  ,
IgnoresNullFence   
)

Definition at line 13 of file fence_waiter_vk_unittests.cc.

13  {
14  auto const context = MockVulkanContextBuilder().Build();
15  auto const waiter = context->GetFenceWaiter();
16  EXPECT_FALSE(waiter->AddFence(vk::UniqueFence(), []() {}));
17 }

◆ TEST() [143/525]

impeller::testing::TEST ( FenceWaiterVKTest  ,
InProgressFencesStillWaitIfTerminated   
)

Definition at line 103 of file fence_waiter_vk_unittests.cc.

103  {
104  MockFence* raw_fence = nullptr;
105  auto signal = fml::ManualResetWaitableEvent();
106 
107  auto const context = MockVulkanContextBuilder().Build();
108  auto const device = context->GetDevice();
109  auto const waiter = context->GetFenceWaiter();
110 
111  // Add a fence that isn't signalled yet.
112  auto fence = device.createFenceUnique({}).value;
113 
114  // Even if the fence is eSuccess, it's not guaranteed to be called in time.
115  MockFence::SetStatus(fence, vk::Result::eNotReady);
116  raw_fence = MockFence::GetRawPointer(fence);
117  waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
118 
119  // Signal the fence after a delay.
120  std::thread thread([&]() {
121  std::this_thread::sleep_for(std::chrono::milliseconds{100u});
122  raw_fence->SetStatus(vk::Result::eSuccess);
123  });
124 
125  // Terminate the waiter. This will block until all pending fences are
126  // signalled.
127  waiter->Terminate();
128 
129  // This will hang if the fence was not signalled.
130  signal.Wait();
131 
132  thread.join();
133 }

References value.

◆ TEST() [144/525]

impeller::testing::TEST ( FilterInputTest  ,
CanSetLocalTransformForTexture   
)

Definition at line 15 of file filter_input_unittests.cc.

15  {
16  std::shared_ptr<Texture> texture = nullptr;
17  auto input =
18  FilterInput::Make(texture, Matrix::MakeTranslation({1.0, 0.0, 0.0}));
19  Entity e;
20  e.SetTransform(Matrix::MakeTranslation({0.0, 2.0, 0.0}));
21 
22  ASSERT_MATRIX_NEAR(input->GetLocalTransform(e),
23  Matrix::MakeTranslation({1.0, 0.0, 0.0}));
24  ASSERT_MATRIX_NEAR(input->GetTransform(e),
25  Matrix::MakeTranslation({1.0, 2.0, 0.0}));
26 }
#define ASSERT_MATRIX_NEAR(a, b)

References ASSERT_MATRIX_NEAR, impeller::FilterInput::Make(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST() [145/525]

impeller::testing::TEST ( FormatsVKTest  ,
DescriptorMapping   
)

Definition at line 11 of file formats_vk_unittests.cc.

11  {
13  vk::DescriptorType::eCombinedImageSampler);
14  EXPECT_EQ(ToVKDescriptorType(DescriptorType::kUniformBuffer),
15  vk::DescriptorType::eUniformBuffer);
16  EXPECT_EQ(ToVKDescriptorType(DescriptorType::kStorageBuffer),
17  vk::DescriptorType::eStorageBuffer);
18  EXPECT_EQ(ToVKDescriptorType(DescriptorType::kImage),
19  vk::DescriptorType::eSampledImage);
20  EXPECT_EQ(ToVKDescriptorType(DescriptorType::kSampler),
21  vk::DescriptorType::eSampler);
22  EXPECT_EQ(ToVKDescriptorType(DescriptorType::kInputAttachment),
23  vk::DescriptorType::eInputAttachment);
24 }
constexpr vk::DescriptorType ToVKDescriptorType(DescriptorType type)
Definition: formats_vk.h:292

References impeller::kImage, impeller::kInputAttachment, impeller::kSampledImage, impeller::kSampler, impeller::kStorageBuffer, impeller::kUniformBuffer, and impeller::ToVKDescriptorType().

◆ TEST() [146/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CalculateSigmaForBlurRadius   
)

Definition at line 458 of file gaussian_blur_filter_contents_unittests.cc.

458  {
459  Scalar sigma = 1.0;
460  Scalar radius = GaussianBlurFilterContents::CalculateBlurRadius(
461  GaussianBlurFilterContents::ScaleSigma(sigma));
462  fml::StatusOr<Scalar> derived_sigma =
463  CalculateSigmaForBlurRadius(radius, Matrix());
464  ASSERT_TRUE(derived_sigma.ok());
465  EXPECT_NEAR(sigma, derived_sigma.value(), 0.01f);
466 }

References impeller::GaussianBlurFilterContents::CalculateBlurRadius(), and impeller::GaussianBlurFilterContents::ScaleSigma().

◆ TEST() [147/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CalculateSigmaValues   
)

Definition at line 225 of file gaussian_blur_filter_contents_unittests.cc.

225  {
226  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1.0f), 1);
227  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(2.0f), 1);
228  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(3.0f), 1);
229  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(4.0f), 1);
230  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(16.0f), 0.25);
231  // Hang on to 1/8 as long as possible.
232  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(95.0f), 0.125);
233  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(96.0f), 0.0625);
234  // Downsample clamped to 1/16th.
235  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1024.0f), 0.0625);
236 }

References impeller::GaussianBlurFilterContents::CalculateScale().

◆ TEST() [148/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
ChopHugeBlurs   
)

Definition at line 621 of file gaussian_blur_filter_contents_unittests.cc.

621  {
622  Scalar sigma = 30.5f;
623  int32_t blur_radius = static_cast<int32_t>(
624  std::ceil(GaussianBlurFilterContents::CalculateBlurRadius(sigma)));
625  BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
626  .blur_sigma = sigma,
627  .blur_radius = blur_radius,
628  .step_size = 1};
629  KernelSamples kernel_samples = GenerateBlurInfo(parameters);
630  GaussianBlurPipeline::FragmentShader::KernelSamples frag_kernel_samples =
631  LerpHackKernelSamples(kernel_samples);
632  EXPECT_TRUE(frag_kernel_samples.sample_count <= kGaussianBlurMaxKernelSize);
633 }
Vector2 blur_radius
Blur radius in source pixels based on scaled_sigma.
static constexpr int32_t kGaussianBlurMaxKernelSize
KernelSamples GenerateBlurInfo(BlurParameters parameters)
GaussianBlurPipeline::FragmentShader::KernelSamples LerpHackKernelSamples(KernelSamples parameters)

References blur_radius, impeller::BlurParameters::blur_uv_offset, impeller::GaussianBlurFilterContents::CalculateBlurRadius(), impeller::GenerateBlurInfo(), impeller::kGaussianBlurMaxKernelSize, and impeller::LerpHackKernelSamples().

◆ TEST() [149/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
Coefficients   
)

Definition at line 468 of file gaussian_blur_filter_contents_unittests.cc.

468  {
469  BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
470  .blur_sigma = 1,
471  .blur_radius = 5,
472  .step_size = 1};
473  KernelSamples samples = GenerateBlurInfo(parameters);
474  EXPECT_EQ(samples.sample_count, 11);
475 
476  // Coefficients should add up to 1.
477  Scalar tally = 0;
478  for (int i = 0; i < samples.sample_count; ++i) {
479  tally += samples.samples[i].coefficient;
480  }
481  EXPECT_FLOAT_EQ(tally, 1.0f);
482 
483  // Verify the shape of the curve.
484  for (int i = 0; i < 4; ++i) {
485  EXPECT_FLOAT_EQ(samples.samples[i].coefficient,
486  samples.samples[10 - i].coefficient);
487  EXPECT_TRUE(samples.samples[i + 1].coefficient >
488  samples.samples[i].coefficient);
489  }
490 }

References impeller::BlurParameters::blur_uv_offset, impeller::KernelSample::coefficient, impeller::GenerateBlurInfo(), impeller::KernelSamples::sample_count, and impeller::KernelSamples::samples.

◆ TEST() [150/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CoverageEmpty   
)

Definition at line 121 of file gaussian_blur_filter_contents_unittests.cc.

121  {
122  GaussianBlurFilterContents contents(
123  /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
124  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
125  FilterInput::Vector inputs = {};
126  Entity entity;
127  std::optional<Rect> coverage =
128  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
129  ASSERT_FALSE(coverage.has_value());
130 }

References impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, and impeller::FilterContents::kNormal.

◆ TEST() [151/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CoverageSimple   
)

Definition at line 132 of file gaussian_blur_filter_contents_unittests.cc.

132  {
133  GaussianBlurFilterContents contents(
134  /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
135  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
136  FilterInput::Vector inputs = {
137  FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))};
138  Entity entity;
139  std::optional<Rect> coverage =
140  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
141 
142  ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110));
143 }

References impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::FilterInput::Make(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [152/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CoverageWithSigma   
)

Definition at line 145 of file gaussian_blur_filter_contents_unittests.cc.

145  {
146  fml::StatusOr<Scalar> sigma_radius_1 =
147  CalculateSigmaForBlurRadius(1.0, Matrix());
148  ASSERT_TRUE(sigma_radius_1.ok());
149  GaussianBlurFilterContents contents(
150  /*sigma_x=*/sigma_radius_1.value(),
151  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
152  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
153  FilterInput::Vector inputs = {
154  FilterInput::Make(Rect::MakeLTRB(100, 100, 200, 200))};
155  Entity entity;
156  std::optional<Rect> coverage =
157  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
158 
159  EXPECT_TRUE(coverage.has_value());
160  if (coverage.has_value()) {
161  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
162  }
163 }

References EXPECT_RECT_NEAR, impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::FilterInput::Make(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [153/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
Create   
)

Definition at line 113 of file gaussian_blur_filter_contents_unittests.cc.

113  {
114  GaussianBlurFilterContents contents(
115  /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
116  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
117  EXPECT_EQ(contents.GetSigmaX(), 0.0);
118  EXPECT_EQ(contents.GetSigmaY(), 0.0);
119 }

References impeller::GaussianBlurFilterContents::GetSigmaX(), impeller::GaussianBlurFilterContents::GetSigmaY(), impeller::Entity::kDecal, and impeller::FilterContents::kNormal.

◆ TEST() [154/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
FilterSourceCoverage   
)

Definition at line 208 of file gaussian_blur_filter_contents_unittests.cc.

208  {
209  fml::StatusOr<Scalar> sigma_radius_1 =
210  CalculateSigmaForBlurRadius(1.0, Matrix());
211  ASSERT_TRUE(sigma_radius_1.ok());
212  auto contents = std::make_unique<GaussianBlurFilterContents>(
213  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
214  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
215  std::optional<Rect> coverage = contents->GetFilterSourceCoverage(
216  /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}),
217  /*output_limit=*/Rect::MakeLTRB(100, 100, 200, 200));
218  EXPECT_TRUE(coverage.has_value());
219  if (coverage.has_value()) {
220  EXPECT_RECT_NEAR(coverage.value(),
221  Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2));
222  }
223 }

References EXPECT_RECT_NEAR, impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Matrix::MakeScale().

◆ TEST() [155/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
LerpHackKernelSamplesComplex   
)

Definition at line 567 of file gaussian_blur_filter_contents_unittests.cc.

567  {
568  Scalar sigma = 10.0f;
569  int32_t blur_radius = static_cast<int32_t>(
570  std::ceil(GaussianBlurFilterContents::CalculateBlurRadius(sigma)));
571  BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
572  .blur_sigma = sigma,
573  .blur_radius = blur_radius,
574  .step_size = 1};
575  KernelSamples kernel_samples = GenerateBlurInfo(parameters);
576  EXPECT_EQ(kernel_samples.sample_count, 33);
577  GaussianBlurPipeline::FragmentShader::KernelSamples fast_kernel_samples =
578  LerpHackKernelSamples(kernel_samples);
579  EXPECT_EQ(fast_kernel_samples.sample_count, 17);
580  float data[33];
581  srand(0);
582  for (int i = 0; i < 33; i++) {
583  data[i] = 255.0 * static_cast<double>(IMPELLER_RAND()) / RAND_MAX;
584  }
585 
586  auto sampler = [data](Point point) -> Scalar {
587  FML_CHECK(point.y == 0.0f);
588  FML_CHECK(point.x >= -16);
589  FML_CHECK(point.x <= 16);
590  Scalar fint_part;
591  Scalar fract = fabsf(modf(point.x, &fint_part));
592  if (fract == 0) {
593  int32_t int_part = static_cast<int32_t>(fint_part) + 16;
594  return data[int_part];
595  } else {
596  int32_t left = static_cast<int32_t>(floor(point.x)) + 16;
597  int32_t right = static_cast<int32_t>(ceil(point.x)) + 16;
598  if (point.x < 0) {
599  return fract * data[left] + (1.0 - fract) * data[right];
600  } else {
601  return (1.0 - fract) * data[left] + fract * data[right];
602  }
603  }
604  };
605 
606  Scalar output = 0.0;
607  for (int i = 0; i < kernel_samples.sample_count; ++i) {
608  auto sample = kernel_samples.samples[i];
609  output += sample.coefficient * sampler(sample.uv_offset);
610  }
611 
612  Scalar fast_output = 0.0;
613  for (int i = 0; i < fast_kernel_samples.sample_count; i++) {
614  fast_output += GetCoefficient(fast_kernel_samples.sample_data[i]) *
615  sampler(GetUVOffset(fast_kernel_samples.sample_data[i]));
616  }
617 
618  EXPECT_NEAR(output, fast_output, 0.1);
619 }

References blur_radius, impeller::BlurParameters::blur_uv_offset, impeller::GaussianBlurFilterContents::CalculateBlurRadius(), impeller::KernelSample::coefficient, data, impeller::GenerateBlurInfo(), IMPELLER_RAND, impeller::LerpHackKernelSamples(), impeller::KernelSamples::sample_count, and impeller::KernelSamples::samples.

◆ TEST() [156/525]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
LerpHackKernelSamplesSimple   
)

Definition at line 492 of file gaussian_blur_filter_contents_unittests.cc.

492  {
493  KernelSamples kernel_samples = {
494  .sample_count = 5,
495  .samples =
496  {
497  {
498  .uv_offset = Vector2(-2, 0),
499  .coefficient = 0.1f,
500  },
501  {
502  .uv_offset = Vector2(-1, 0),
503  .coefficient = 0.2f,
504  },
505  {
506  .uv_offset = Vector2(0, 0),
507  .coefficient = 0.4f,
508  },
509  {
510  .uv_offset = Vector2(1, 0),
511  .coefficient = 0.2f,
512  },
513  {
514  .uv_offset = Vector2(2, 0),
515  .coefficient = 0.1f,
516  },
517  },
518  };
519 
520  GaussianBlurPipeline::FragmentShader::KernelSamples blur_info =
521  LerpHackKernelSamples(kernel_samples);
522  EXPECT_EQ(blur_info.sample_count, 3);
523 
524  KernelSample* samples = kernel_samples.samples;
525 
526  //////////////////////////////////////////////////////////////////////////////
527  // Check output kernel.
528 
529  EXPECT_POINT_NEAR(GetUVOffset(blur_info.sample_data[0]),
530  Point(-1.3333333, 0));
531  EXPECT_FLOAT_EQ(GetCoefficient(blur_info.sample_data[0]), 0.3);
532 
533  EXPECT_POINT_NEAR(GetUVOffset(blur_info.sample_data[1]), Point(0, 0));
534  EXPECT_FLOAT_EQ(GetCoefficient(blur_info.sample_data[1]), 0.4);
535 
536  EXPECT_POINT_NEAR(GetUVOffset(blur_info.sample_data[2]), Point(1.333333, 0));
537  EXPECT_FLOAT_EQ(GetCoefficient(blur_info.sample_data[2]), 0.3);
538 
539  //////////////////////////////////////////////////////////////////////////////
540  // Check output of fast kernel versus original kernel.
541 
542  Scalar data[5] = {0.25, 0.5, 0.5, 1.0, 0.2};
543  Scalar original_output =
544  samples[0].coefficient * data[0] + samples[1].coefficient * data[1] +
545  samples[2].coefficient * data[2] + samples[3].coefficient * data[3] +
546  samples[4].coefficient * data[4];
547 
548  auto lerp = [](const Point& point, Scalar left, Scalar right) {
549  Scalar int_part;
550  Scalar fract = fabsf(modf(point.x, &int_part));
551  if (point.x < 0) {
552  return left * fract + right * (1.0 - fract);
553  } else {
554  return left * (1.0 - fract) + right * fract;
555  }
556  };
557  Scalar fast_output =
558  /*1st*/ lerp(GetUVOffset(blur_info.sample_data[0]), data[0], data[1]) *
559  GetCoefficient(blur_info.sample_data[0]) +
560  /*2nd*/ data[2] * GetCoefficient(blur_info.sample_data[1]) +
561  /*3rd*/ lerp(GetUVOffset(blur_info.sample_data[2]), data[3], data[4]) *
562  GetCoefficient(blur_info.sample_data[2]);
563 
564  EXPECT_NEAR(original_output, fast_output, 0.01);
565 }
#define EXPECT_POINT_NEAR(a, b)

References impeller::KernelSample::coefficient, data, EXPECT_POINT_NEAR, impeller::LerpHackKernelSamples(), impeller::KernelSamples::sample_count, impeller::KernelSamples::samples, and impeller::TPoint< T >::x.

◆ TEST() [157/525]

impeller::testing::TEST ( GeometryTest  ,
BlendModeToString   
)

Definition at line 1709 of file geometry_unittests.cc.

1709  {
1710  using BlendT = std::underlying_type_t<BlendMode>;
1711  for (BlendT i = 0; i <= static_cast<BlendT>(BlendMode::kLastMode); i++) {
1712  auto mode = static_cast<BlendMode>(i);
1713  auto result = BlendModeToString(mode);
1715  }
1716 }
#define _BLEND_MODE_NAME_CHECK(blend_mode)
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
BlendMode
Definition: color.h:58

References _BLEND_MODE_NAME_CHECK, impeller::BlendModeToString(), IMPELLER_FOR_EACH_BLEND_MODE, and impeller::kLastMode.

◆ TEST() [158/525]

impeller::testing::TEST ( GeometryTest  ,
CanConvertBetweenDegressAndRadians   
)

Definition at line 1718 of file geometry_unittests.cc.

1718  {
1719  {
1720  auto deg = Degrees{90.0};
1721  Radians rad = deg;
1722  ASSERT_FLOAT_EQ(rad.radians, kPiOver2);
1723  }
1724 }

References impeller::kPiOver2, and impeller::Radians::radians.

◆ TEST() [159/525]

impeller::testing::TEST ( GeometryTest  ,
CanConvertTTypesExplicitly   
)

Definition at line 593 of file geometry_unittests.cc.

593  {
594  {
595  Point p1(1.0, 2.0);
596  IPoint p2 = static_cast<IPoint>(p1);
597  ASSERT_EQ(p2.x, 1u);
598  ASSERT_EQ(p2.y, 2u);
599  }
600 
601  {
602  Size s1(1.0, 2.0);
603  ISize s2 = static_cast<ISize>(s1);
604  ASSERT_EQ(s2.width, 1u);
605  ASSERT_EQ(s2.height, 2u);
606  }
607 
608  {
609  Size s1(1.0, 2.0);
610  Point p1 = static_cast<Point>(s1);
611  ASSERT_EQ(p1.x, 1u);
612  ASSERT_EQ(p1.y, 2u);
613  }
614 }
TPoint< int64_t > IPoint
Definition: point.h:328

References impeller::TSize< T >::height, impeller::TSize< T >::width, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [160/525]

impeller::testing::TEST ( GeometryTest  ,
CanGenerateMipCounts   
)

Definition at line 580 of file geometry_unittests.cc.

580  {
581  EXPECT_EQ((Size{128, 128}.MipCount()), 7u);
582  EXPECT_EQ((Size{128, 256}.MipCount()), 7u);
583  EXPECT_EQ((Size{128, 130}.MipCount()), 7u);
584  EXPECT_EQ((Size{128, 257}.MipCount()), 7u);
585  EXPECT_EQ((Size{257, 128}.MipCount()), 7u);
586  EXPECT_EQ((Size{128, 0}.MipCount()), 1u);
587  EXPECT_EQ((Size{128, -25}.MipCount()), 1u);
588  EXPECT_EQ((Size{-128, 25}.MipCount()), 1u);
589  EXPECT_EQ((Size{1, 1}.MipCount()), 1u);
590  EXPECT_EQ((Size{0, 0}.MipCount()), 1u);
591 }
constexpr size_t MipCount() const
Return the mip count of the texture.
Definition: size.h:137

References impeller::TSize< T >::MipCount().

◆ TEST() [161/525]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicPointOps   
)

Definition at line 616 of file geometry_unittests.cc.

616  {
617  {
618  IPoint p1(1, 2);
619  IPoint p2 = p1 + IPoint(1, 2);
620  ASSERT_EQ(p2.x, 2u);
621  ASSERT_EQ(p2.y, 4u);
622  }
623 
624  {
625  IPoint p1(3, 6);
626  IPoint p2 = p1 - IPoint(1, 2);
627  ASSERT_EQ(p2.x, 2u);
628  ASSERT_EQ(p2.y, 4u);
629  }
630 
631  {
632  IPoint p1(1, 2);
633  IPoint p2 = p1 * IPoint(2, 3);
634  ASSERT_EQ(p2.x, 2u);
635  ASSERT_EQ(p2.y, 6u);
636  }
637 
638  {
639  IPoint p1(2, 6);
640  IPoint p2 = p1 / IPoint(2, 3);
641  ASSERT_EQ(p2.x, 1u);
642  ASSERT_EQ(p2.y, 2u);
643  }
644 }

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [162/525]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicPointOpsWithArithmeticTypes   
)

Definition at line 646 of file geometry_unittests.cc.

646  {
647  // LHS
648  {
649  IPoint p1(1, 2);
650  IPoint p2 = p1 * 2.0f;
651  ASSERT_EQ(p2.x, 2u);
652  ASSERT_EQ(p2.y, 4u);
653  }
654 
655  {
656  IPoint p1(2, 6);
657  IPoint p2 = p1 / 2.0f;
658  ASSERT_EQ(p2.x, 1u);
659  ASSERT_EQ(p2.y, 3u);
660  }
661 
662  // RHS
663  {
664  IPoint p1(1, 2);
665  IPoint p2 = 2.0f * p1;
666  ASSERT_EQ(p2.x, 2u);
667  ASSERT_EQ(p2.y, 4u);
668  }
669 
670  {
671  IPoint p1(2, 6);
672  IPoint p2 = 12.0f / p1;
673  ASSERT_EQ(p2.x, 6u);
674  ASSERT_EQ(p2.y, 2u);
675  }
676 }

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [163/525]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicVector3Ops   
)

Definition at line 1276 of file geometry_unittests.cc.

1276  {
1277  {
1278  Vector3 p1(1, 2, 3);
1279  Vector3 p2 = p1 + Vector3(1, 2, 3);
1280  ASSERT_EQ(p2.x, 2u);
1281  ASSERT_EQ(p2.y, 4u);
1282  ASSERT_EQ(p2.z, 6u);
1283  }
1284 
1285  {
1286  Vector3 p1(3, 6, 9);
1287  Vector3 p2 = p1 - Vector3(1, 2, 3);
1288  ASSERT_EQ(p2.x, 2u);
1289  ASSERT_EQ(p2.y, 4u);
1290  ASSERT_EQ(p2.z, 6u);
1291  }
1292 
1293  {
1294  Vector3 p1(1, 2, 3);
1295  Vector3 p2 = p1 * Vector3(2, 3, 4);
1296  ASSERT_EQ(p2.x, 2u);
1297  ASSERT_EQ(p2.y, 6u);
1298  ASSERT_EQ(p2.z, 12u);
1299  }
1300 
1301  {
1302  Vector3 p1(2, 6, 12);
1303  Vector3 p2 = p1 / Vector3(2, 3, 4);
1304  ASSERT_EQ(p2.x, 1u);
1305  ASSERT_EQ(p2.y, 2u);
1306  ASSERT_EQ(p2.z, 3u);
1307  }
1308 }

References impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

◆ TEST() [164/525]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicVector3OpsWithArithmeticTypes   
)

Definition at line 1310 of file geometry_unittests.cc.

1310  {
1311  // LHS
1312  {
1313  Vector3 p1(1, 2, 3);
1314  Vector3 p2 = p1 + 2.0f;
1315  ASSERT_EQ(p2.x, 3);
1316  ASSERT_EQ(p2.y, 4);
1317  ASSERT_EQ(p2.z, 5);
1318  }
1319 
1320  {
1321  Vector3 p1(1, 2, 3);
1322  Vector3 p2 = p1 - 2.0f;
1323  ASSERT_EQ(p2.x, -1);
1324  ASSERT_EQ(p2.y, 0);
1325  ASSERT_EQ(p2.z, 1);
1326  }
1327 
1328  {
1329  Vector3 p1(1, 2, 3);
1330  Vector3 p2 = p1 * 2.0f;
1331  ASSERT_EQ(p2.x, 2);
1332  ASSERT_EQ(p2.y, 4);
1333  ASSERT_EQ(p2.z, 6);
1334  }
1335 
1336  {
1337  Vector3 p1(2, 6, 12);
1338  Vector3 p2 = p1 / 2.0f;
1339  ASSERT_EQ(p2.x, 1);
1340  ASSERT_EQ(p2.y, 3);
1341  ASSERT_EQ(p2.z, 6);
1342  }
1343 
1344  // RHS
1345  {
1346  Vector3 p1(1, 2, 3);
1347  Vector3 p2 = 2.0f + p1;
1348  ASSERT_EQ(p2.x, 3);
1349  ASSERT_EQ(p2.y, 4);
1350  ASSERT_EQ(p2.z, 5);
1351  }
1352 
1353  {
1354  Vector3 p1(1, 2, 3);
1355  Vector3 p2 = 2.0f - p1;
1356  ASSERT_EQ(p2.x, 1);
1357  ASSERT_EQ(p2.y, 0);
1358  ASSERT_EQ(p2.z, -1);
1359  }
1360 
1361  {
1362  Vector3 p1(1, 2, 3);
1363  Vector3 p2 = 2.0f * p1;
1364  ASSERT_EQ(p2.x, 2);
1365  ASSERT_EQ(p2.y, 4);
1366  ASSERT_EQ(p2.z, 6);
1367  }
1368 
1369  {
1370  Vector3 p1(2, 6, 12);
1371  Vector3 p2 = 12.0f / p1;
1372  ASSERT_EQ(p2.x, 6);
1373  ASSERT_EQ(p2.y, 2);
1374  ASSERT_EQ(p2.z, 1);
1375  }
1376 }

References impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

◆ TEST() [165/525]

impeller::testing::TEST ( GeometryTest  ,
CanUsePointAssignmentOperators   
)

Definition at line 798 of file geometry_unittests.cc.

798  {
799  // Point on RHS
800  {
801  IPoint p(1, 2);
802  p += IPoint(1, 2);
803  ASSERT_EQ(p.x, 2u);
804  ASSERT_EQ(p.y, 4u);
805  }
806 
807  {
808  IPoint p(3, 6);
809  p -= IPoint(1, 2);
810  ASSERT_EQ(p.x, 2u);
811  ASSERT_EQ(p.y, 4u);
812  }
813 
814  {
815  IPoint p(1, 2);
816  p *= IPoint(2, 3);
817  ASSERT_EQ(p.x, 2u);
818  ASSERT_EQ(p.y, 6u);
819  }
820 
821  {
822  IPoint p(2, 6);
823  p /= IPoint(2, 3);
824  ASSERT_EQ(p.x, 1u);
825  ASSERT_EQ(p.y, 2u);
826  }
827 
828  // Size on RHS
829  {
830  IPoint p(1, 2);
831  p += ISize(1, 2);
832  ASSERT_EQ(p.x, 2u);
833  ASSERT_EQ(p.y, 4u);
834  }
835 
836  {
837  IPoint p(3, 6);
838  p -= ISize(1, 2);
839  ASSERT_EQ(p.x, 2u);
840  ASSERT_EQ(p.y, 4u);
841  }
842 
843  {
844  IPoint p(1, 2);
845  p *= ISize(2, 3);
846  ASSERT_EQ(p.x, 2u);
847  ASSERT_EQ(p.y, 6u);
848  }
849 
850  {
851  IPoint p(2, 6);
852  p /= ISize(2, 3);
853  ASSERT_EQ(p.x, 1u);
854  ASSERT_EQ(p.y, 2u);
855  }
856 
857  // Arithmetic type on RHS
858  {
859  IPoint p(1, 2);
860  p *= 3;
861  ASSERT_EQ(p.x, 3u);
862  ASSERT_EQ(p.y, 6u);
863  }
864 
865  {
866  IPoint p(3, 6);
867  p /= 3;
868  ASSERT_EQ(p.x, 1u);
869  ASSERT_EQ(p.y, 2u);
870  }
871 }

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [166/525]

impeller::testing::TEST ( GeometryTest  ,
CanUseVector3AssignmentOperators   
)

Definition at line 1226 of file geometry_unittests.cc.

1226  {
1227  {
1228  Vector3 p(1, 2, 4);
1229  p += Vector3(1, 2, 4);
1230  ASSERT_EQ(p.x, 2u);
1231  ASSERT_EQ(p.y, 4u);
1232  ASSERT_EQ(p.z, 8u);
1233  }
1234 
1235  {
1236  Vector3 p(3, 6, 8);
1237  p -= Vector3(1, 2, 3);
1238  ASSERT_EQ(p.x, 2u);
1239  ASSERT_EQ(p.y, 4u);
1240  ASSERT_EQ(p.z, 5u);
1241  }
1242 
1243  {
1244  Vector3 p(1, 2, 3);
1245  p *= Vector3(2, 3, 4);
1246  ASSERT_EQ(p.x, 2u);
1247  ASSERT_EQ(p.y, 6u);
1248  ASSERT_EQ(p.z, 12u);
1249  }
1250 
1251  {
1252  Vector3 p(1, 2, 3);
1253  p *= 2;
1254  ASSERT_EQ(p.x, 2u);
1255  ASSERT_EQ(p.y, 4u);
1256  ASSERT_EQ(p.z, 6u);
1257  }
1258 
1259  {
1260  Vector3 p(2, 6, 12);
1261  p /= Vector3(2, 3, 4);
1262  ASSERT_EQ(p.x, 1u);
1263  ASSERT_EQ(p.y, 2u);
1264  ASSERT_EQ(p.z, 3u);
1265  }
1266 
1267  {
1268  Vector3 p(2, 6, 12);
1269  p /= 2;
1270  ASSERT_EQ(p.x, 1u);
1271  ASSERT_EQ(p.y, 3u);
1272  ASSERT_EQ(p.z, 6u);
1273  }
1274 }

References impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

◆ TEST() [167/525]

impeller::testing::TEST ( GeometryTest  ,
ColorApplyColorMatrix   
)

Definition at line 1483 of file geometry_unittests.cc.

1483  {
1484  {
1485  ColorMatrix color_matrix = {
1486  1, 1, 1, 1, 1, //
1487  1, 1, 1, 1, 1, //
1488  1, 1, 1, 1, 1, //
1489  1, 1, 1, 1, 1, //
1490  };
1491  auto result = Color::White().ApplyColorMatrix(color_matrix);
1492  auto expected = Color(1, 1, 1, 1);
1493  ASSERT_COLOR_NEAR(result, expected);
1494  }
1495 
1496  {
1497  ColorMatrix color_matrix = {
1498  0.1, 0, 0, 0, 0.01, //
1499  0, 0.2, 0, 0, 0.02, //
1500  0, 0, 0.3, 0, 0.03, //
1501  0, 0, 0, 0.4, 0.04, //
1502  };
1503  auto result = Color::White().ApplyColorMatrix(color_matrix);
1504  auto expected = Color(0.11, 0.22, 0.33, 0.44);
1505  ASSERT_COLOR_NEAR(result, expected);
1506  }
1507 }
#define ASSERT_COLOR_NEAR(a, b)

References impeller::Color::ApplyColorMatrix(), ASSERT_COLOR_NEAR, and impeller::Color::White().

◆ TEST() [168/525]

impeller::testing::TEST ( GeometryTest  ,
ColorBlendReturnsExpectedResults   
)

Definition at line 1692 of file geometry_unittests.cc.

1692  {
1693  Color dst = ColorBlendTestData::kDestinationColor;
1694  for (size_t source_i = 0;
1695  source_i < sizeof(ColorBlendTestData::kSourceColors) / sizeof(Color);
1696  source_i++) {
1697  Color src = ColorBlendTestData::kSourceColors[source_i];
1698 
1699  Color expected;
1701  }
1702 }
#define _BLEND_MODE_RESULT_CHECK(blend_mode)

References _BLEND_MODE_RESULT_CHECK, IMPELLER_FOR_EACH_BLEND_MODE, impeller::testing::ColorBlendTestData::kDestinationColor, and impeller::testing::ColorBlendTestData::kSourceColors.

◆ TEST() [169/525]

impeller::testing::TEST ( GeometryTest  ,
ColorClamp01   
)

Definition at line 1443 of file geometry_unittests.cc.

1443  {
1444  {
1445  Color result = Color(0.5, 0.5, 0.5, 0.5).Clamp01();
1446  Color expected = Color(0.5, 0.5, 0.5, 0.5);
1447  ASSERT_COLOR_NEAR(result, expected);
1448  }
1449 
1450  {
1451  Color result = Color(-1, -1, -1, -1).Clamp01();
1452  Color expected = Color(0, 0, 0, 0);
1453  ASSERT_COLOR_NEAR(result, expected);
1454  }
1455 
1456  {
1457  Color result = Color(2, 2, 2, 2).Clamp01();
1458  Color expected = Color(1, 1, 1, 1);
1459  ASSERT_COLOR_NEAR(result, expected);
1460  }
1461 }

References ASSERT_COLOR_NEAR, and impeller::Color::Clamp01().

◆ TEST() [170/525]

impeller::testing::TEST ( GeometryTest  ,
ColorLerp   
)

Definition at line 1421 of file geometry_unittests.cc.

1421  {
1422  {
1423  Color a(0.0, 0.0, 0.0, 0.0);
1424  Color b(1.0, 1.0, 1.0, 1.0);
1425 
1426  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.5, 0.5, 0.5, 0.5));
1427  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.0), a);
1428  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 1.0), b);
1429  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.2, 0.2, 0.2, 0.2));
1430  }
1431 
1432  {
1433  Color a(0.2, 0.4, 1.0, 0.5);
1434  Color b(0.4, 1.0, 0.2, 0.3);
1435 
1436  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.3, 0.7, 0.6, 0.4));
1437  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.0), a);
1438  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 1.0), b);
1439  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.24, 0.52, 0.84, 0.46));
1440  }
1441 }

References ASSERT_COLOR_NEAR, impeller::saturated::b, and impeller::Color::Lerp().

◆ TEST() [171/525]

impeller::testing::TEST ( GeometryTest  ,
ColorLinearToSRGB   
)

Definition at line 1509 of file geometry_unittests.cc.

1509  {
1510  {
1511  auto result = Color::White().LinearToSRGB();
1512  auto expected = Color(1, 1, 1, 1);
1513  ASSERT_COLOR_NEAR(result, expected);
1514  }
1515 
1516  {
1517  auto result = Color::BlackTransparent().LinearToSRGB();
1518  auto expected = Color(0, 0, 0, 0);
1519  ASSERT_COLOR_NEAR(result, expected);
1520  }
1521 
1522  {
1523  auto result = Color(0.2, 0.4, 0.6, 0.8).LinearToSRGB();
1524  auto expected = Color(0.484529, 0.665185, 0.797738, 0.8);
1525  ASSERT_COLOR_NEAR(result, expected);
1526  }
1527 }

References ASSERT_COLOR_NEAR, impeller::Color::BlackTransparent(), impeller::Color::LinearToSRGB(), and impeller::Color::White().

◆ TEST() [172/525]

impeller::testing::TEST ( GeometryTest  ,
ColorMakeRGBA8   
)

Definition at line 1463 of file geometry_unittests.cc.

1463  {
1464  {
1465  Color a = Color::MakeRGBA8(0, 0, 0, 0);
1466  Color b = Color::BlackTransparent();
1467  ASSERT_COLOR_NEAR(a, b);
1468  }
1469 
1470  {
1471  Color a = Color::MakeRGBA8(255, 255, 255, 255);
1472  Color b = Color::White();
1473  ASSERT_COLOR_NEAR(a, b);
1474  }
1475 
1476  {
1477  Color a = Color::MakeRGBA8(63, 127, 191, 127);
1478  Color b(0.247059, 0.498039, 0.74902, 0.498039);
1479  ASSERT_COLOR_NEAR(a, b);
1480  }
1481 }

References ASSERT_COLOR_NEAR, impeller::saturated::b, impeller::Color::BlackTransparent(), impeller::Color::MakeRGBA8(), and impeller::Color::White().

◆ TEST() [173/525]

impeller::testing::TEST ( GeometryTest  ,
ColorPremultiply   
)

Definition at line 1378 of file geometry_unittests.cc.

1378  {
1379  {
1380  Color a(1.0, 0.5, 0.2, 0.5);
1381  Color premultiplied = a.Premultiply();
1382  Color expected = Color(0.5, 0.25, 0.1, 0.5);
1383  ASSERT_COLOR_NEAR(premultiplied, expected);
1384  }
1385 
1386  {
1387  Color a(0.5, 0.25, 0.1, 0.5);
1388  Color unpremultiplied = a.Unpremultiply();
1389  Color expected = Color(1.0, 0.5, 0.2, 0.5);
1390  ASSERT_COLOR_NEAR(unpremultiplied, expected);
1391  }
1392 
1393  {
1394  Color a(0.5, 0.25, 0.1, 0.0);
1395  Color unpremultiplied = a.Unpremultiply();
1396  Color expected = Color(0.0, 0.0, 0.0, 0.0);
1397  ASSERT_COLOR_NEAR(unpremultiplied, expected);
1398  }
1399 }

References ASSERT_COLOR_NEAR, impeller::Color::Premultiply(), and impeller::Color::Unpremultiply().

◆ TEST() [174/525]

impeller::testing::TEST ( GeometryTest  ,
ColorPrinting   
)

Definition at line 1801 of file geometry_unittests.cc.

1801  {
1802  {
1803  std::stringstream stream;
1804  Color m;
1805  stream << m;
1806  ASSERT_EQ(stream.str(), "(0, 0, 0, 0)");
1807  }
1808 
1809  {
1810  std::stringstream stream;
1811  Color m(1, 2, 3, 4);
1812  stream << m;
1813  ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
1814  }
1815 }

◆ TEST() [175/525]

impeller::testing::TEST ( GeometryTest  ,
ColorR8G8B8A8   
)

Definition at line 1401 of file geometry_unittests.cc.

1401  {
1402  {
1403  Color a(1.0, 0.5, 0.2, 0.5);
1404  std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1405  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1406  }
1407 
1408  {
1409  Color a(0.0, 0.0, 0.0, 0.0);
1410  std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1411  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1412  }
1413 
1414  {
1415  Color a(1.0, 1.0, 1.0, 1.0);
1416  std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1417  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1418  }
1419 }
#define ASSERT_ARRAY_4_NEAR(a, b)

References ASSERT_ARRAY_4_NEAR, and impeller::Color::ToR8G8B8A8().

◆ TEST() [176/525]

impeller::testing::TEST ( GeometryTest  ,
ColorSRGBToLinear   
)

Definition at line 1529 of file geometry_unittests.cc.

1529  {
1530  {
1531  auto result = Color::White().SRGBToLinear();
1532  auto expected = Color(1, 1, 1, 1);
1533  ASSERT_COLOR_NEAR(result, expected);
1534  }
1535 
1536  {
1537  auto result = Color::BlackTransparent().SRGBToLinear();
1538  auto expected = Color(0, 0, 0, 0);
1539  ASSERT_COLOR_NEAR(result, expected);
1540  }
1541 
1542  {
1543  auto result = Color(0.2, 0.4, 0.6, 0.8).SRGBToLinear();
1544  auto expected = Color(0.0331048, 0.132868, 0.318547, 0.8);
1545  ASSERT_COLOR_NEAR(result, expected);
1546  }
1547 }

References ASSERT_COLOR_NEAR, impeller::Color::BlackTransparent(), impeller::Color::SRGBToLinear(), and impeller::Color::White().

◆ TEST() [177/525]

impeller::testing::TEST ( GeometryTest  ,
DeterminantTest   
)

Definition at line 121 of file geometry_unittests.cc.

121  {
122  auto matrix = Matrix{3, 4, 14, 155, 2, 1, 3, 4, 2, 3, 2, 1, 1, 2, 4, 2};
123  ASSERT_EQ(matrix.GetDeterminant(), -1889);
124 }

◆ TEST() [178/525]

impeller::testing::TEST ( GeometryTest  ,
Gradient   
)

Definition at line 1823 of file geometry_unittests.cc.

1823  {
1824  {
1825  // Simple 2 color gradient produces color buffer containing exactly those
1826  // values.
1827  std::vector<Color> colors = {Color::Red(), Color::Blue()};
1828  std::vector<Scalar> stops = {0.0, 1.0};
1829 
1830  auto gradient = CreateGradientBuffer(colors, stops);
1831 
1832  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
1833  ASSERT_EQ(gradient.texture_size, 2u);
1834  }
1835 
1836  {
1837  // Gradient with duplicate stops does not create an empty texture.
1838  std::vector<Color> colors = {Color::Red(), Color::Yellow(), Color::Black(),
1839  Color::Blue()};
1840  std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
1841 
1842  auto gradient = CreateGradientBuffer(colors, stops);
1843  ASSERT_EQ(gradient.texture_size, 5u);
1844  }
1845 
1846  {
1847  // Simple N color gradient produces color buffer containing exactly those
1848  // values.
1849  std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green(),
1850  Color::White()};
1851  std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
1852 
1853  auto gradient = CreateGradientBuffer(colors, stops);
1854 
1855  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
1856  ASSERT_EQ(gradient.texture_size, 4u);
1857  }
1858 
1859  {
1860  // Gradient with color stops will lerp and scale buffer.
1861  std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green()};
1862  std::vector<Scalar> stops = {0.0, 0.25, 1.0};
1863 
1864  auto gradient = CreateGradientBuffer(colors, stops);
1865 
1866  std::vector<Color> lerped_colors = {
1867  Color::Red(),
1868  Color::Blue(),
1869  Color::Lerp(Color::Blue(), Color::Green(), 0.3333),
1870  Color::Lerp(Color::Blue(), Color::Green(), 0.6666),
1871  Color::Green(),
1872  };
1873  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, lerped_colors);
1874  ASSERT_EQ(gradient.texture_size, 5u);
1875  }
1876 
1877  {
1878  // Gradient size is capped at 1024.
1879  std::vector<Color> colors = {};
1880  std::vector<Scalar> stops = {};
1881  for (auto i = 0u; i < 1025; i++) {
1882  colors.push_back(Color::Blue());
1883  stops.push_back(i / 1025.0);
1884  }
1885 
1886  auto gradient = CreateGradientBuffer(colors, stops);
1887 
1888  ASSERT_EQ(gradient.texture_size, 1024u);
1889  ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
1890  }
1891 }
#define ASSERT_COLOR_BUFFER_NEAR(a, b)
GradientData CreateGradientBuffer(const std::vector< Color > &colors, const std::vector< Scalar > &stops)
Populate a vector with the interpolated color bytes for the linear gradient described by colors and s...
Definition: gradient.cc:20

References ASSERT_COLOR_BUFFER_NEAR, impeller::Color::Black(), impeller::Color::Blue(), impeller::CreateGradientBuffer(), impeller::Color::Green(), impeller::Color::Lerp(), impeller::Color::Red(), impeller::Color::White(), and impeller::Color::Yellow().

◆ TEST() [179/525]

impeller::testing::TEST ( GeometryTest  ,
HalfConversions   
)

Definition at line 1893 of file geometry_unittests.cc.

1893  {
1894 #if defined(FML_OS_MACOSX) || defined(FML_OS_IOS) || \
1895  defined(FML_OS_IOS_SIMULATOR)
1896  ASSERT_EQ(ScalarToHalf(0.0), 0.0f16);
1897  ASSERT_EQ(ScalarToHalf(0.05), 0.05f16);
1898  ASSERT_EQ(ScalarToHalf(2.43), 2.43f16);
1899  ASSERT_EQ(ScalarToHalf(-1.45), -1.45f16);
1900 
1901  // 65504 is the largest possible half.
1902  ASSERT_EQ(ScalarToHalf(65504.0f), 65504.0f16);
1903  ASSERT_EQ(ScalarToHalf(65504.0f + 1), 65504.0f16);
1904 
1905  // Colors
1906  ASSERT_EQ(HalfVector4(Color::Red()),
1907  HalfVector4(1.0f16, 0.0f16, 0.0f16, 1.0f16));
1908  ASSERT_EQ(HalfVector4(Color::Green()),
1909  HalfVector4(0.0f16, 1.0f16, 0.0f16, 1.0f16));
1910  ASSERT_EQ(HalfVector4(Color::Blue()),
1911  HalfVector4(0.0f16, 0.0f16, 1.0f16, 1.0f16));
1912  ASSERT_EQ(HalfVector4(Color::Black().WithAlpha(0)),
1913  HalfVector4(0.0f16, 0.0f16, 0.0f16, 0.0f16));
1914 
1915  ASSERT_EQ(HalfVector3(Vector3(4.0, 6.0, -1.0)),
1916  HalfVector3(4.0f16, 6.0f16, -1.0f16));
1917  ASSERT_EQ(HalfVector2(Vector2(4.0, 6.0)), HalfVector2(4.0f16, 6.0f16));
1918 
1919  ASSERT_EQ(Half(0.5f), Half(0.5f16));
1920  ASSERT_EQ(Half(0.5), Half(0.5f16));
1921  ASSERT_EQ(Half(5), Half(5.0f16));
1922 #else
1923  GTEST_SKIP() << "Half-precision floats (IEEE 754) are not portable and "
1924  "only used on Apple platforms.";
1925 #endif // FML_OS_MACOSX || FML_OS_IOS || FML_OS_IOS_SIMULATOR
1926 }
constexpr InternalHalf ScalarToHalf(Scalar f)
Convert a scalar to a half precision float.
Definition: half.h:32

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Color::Green(), impeller::Color::Red(), and impeller::ScalarToHalf().

◆ TEST() [180/525]

impeller::testing::TEST ( GeometryTest  ,
InvertMatrix   
)

Definition at line 126 of file geometry_unittests.cc.

126  {
127  auto inverted = Matrix{10, -9, -12, 8, //
128  7, -12, 11, 22, //
129  -10, 10, 3, 6, //
130  -2, 22, 2, 1}
131  .Invert();
132 
133  auto result = Matrix{
134  438.0 / 85123.0, 1751.0 / 85123.0, -7783.0 / 85123.0, 4672.0 / 85123.0,
135  393.0 / 85123.0, -178.0 / 85123.0, -570.0 / 85123.0, 4192 / 85123.0,
136  -5230.0 / 85123.0, 2802.0 / 85123.0, -3461.0 / 85123.0, 962.0 / 85123.0,
137  2690.0 / 85123.0, 1814.0 / 85123.0, 3896.0 / 85123.0, 319.0 / 85123.0};
138 
139  ASSERT_MATRIX_NEAR(inverted, result);
140 }

References ASSERT_MATRIX_NEAR, and impeller::Matrix::Invert().

◆ TEST() [181/525]

impeller::testing::TEST ( GeometryTest  ,
InvertMultMatrix   
)

Definition at line 79 of file geometry_unittests.cc.

79  {
80  {
81  auto rotation = Matrix::MakeRotationZ(Radians{kPiOver4});
82  auto invert = rotation.Invert();
83  // clang-format off
84  auto expect = Matrix{k1OverSqrt2, -k1OverSqrt2, 0, 0,
85  k1OverSqrt2, k1OverSqrt2, 0, 0,
86  0, 0, 1, 0,
87  0, 0, 0, 1};
88  // clang-format on
89  ASSERT_MATRIX_NEAR(invert, expect);
90  }
91  {
92  auto scale = Matrix::MakeScale(Vector2{2, 4});
93  auto invert = scale.Invert();
94  auto expect = Matrix{0.5, 0, 0, 0, //
95  0, 0.25, 0, 0, //
96  0, 0, 1, 0, //
97  0, 0, 0, 1};
98  ASSERT_MATRIX_NEAR(invert, expect);
99  }
100 }
constexpr float kPiOver4
Definition: constants.h:35
constexpr float k1OverSqrt2
Definition: constants.h:50

References ASSERT_MATRIX_NEAR, impeller::Matrix::Invert(), impeller::k1OverSqrt2, impeller::kPiOver4, impeller::Matrix::MakeRotationZ(), and impeller::Matrix::MakeScale().

◆ TEST() [182/525]

impeller::testing::TEST ( GeometryTest  ,
MakeColumn   
)

Definition at line 40 of file geometry_unittests.cc.

40  {
41  auto matrix = Matrix::MakeColumn(1, 2, 3, 4, //
42  5, 6, 7, 8, //
43  9, 10, 11, 12, //
44  13, 14, 15, 16);
45 
46  auto expect = Matrix{1, 2, 3, 4, //
47  5, 6, 7, 8, //
48  9, 10, 11, 12, //
49  13, 14, 15, 16};
50 
51  ASSERT_TRUE(matrix == expect);
52 }

References impeller::Matrix::MakeColumn().

◆ TEST() [183/525]

impeller::testing::TEST ( GeometryTest  ,
MakeRow   
)

Definition at line 54 of file geometry_unittests.cc.

54  {
55  auto matrix = Matrix::MakeRow(1, 2, 3, 4, //
56  5, 6, 7, 8, //
57  9, 10, 11, 12, //
58  13, 14, 15, 16);
59 
60  auto expect = Matrix{1, 5, 9, 13, //
61  2, 6, 10, 14, //
62  3, 7, 11, 15, //
63  4, 8, 12, 16};
64 
65  ASSERT_TRUE(matrix == expect);
66 }

References impeller::Matrix::MakeRow().

◆ TEST() [184/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixBasis   
)

Definition at line 102 of file geometry_unittests.cc.

102  {
103  auto matrix = Matrix{1, 2, 3, 4, //
104  5, 6, 7, 8, //
105  9, 10, 11, 12, //
106  13, 14, 15, 16};
107  auto basis = matrix.Basis();
108  auto expect = Matrix{1, 2, 3, 0, //
109  5, 6, 7, 0, //
110  9, 10, 11, 0, //
111  0, 0, 0, 1};
112  ASSERT_MATRIX_NEAR(basis, expect);
113 }

References ASSERT_MATRIX_NEAR, and impeller::Matrix::Basis().

◆ TEST() [185/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetBasisVectors   
)

Definition at line 408 of file geometry_unittests.cc.

408  {
409  {
410  auto m = Matrix();
411  Vector3 x = m.GetBasisX();
412  Vector3 y = m.GetBasisY();
413  Vector3 z = m.GetBasisZ();
414  ASSERT_VECTOR3_NEAR(x, Vector3(1, 0, 0));
415  ASSERT_VECTOR3_NEAR(y, Vector3(0, 1, 0));
416  ASSERT_VECTOR3_NEAR(z, Vector3(0, 0, 1));
417  }
418 
419  {
420  auto m = Matrix::MakeRotationZ(Radians{kPiOver2}) *
421  Matrix::MakeRotationX(Radians{kPiOver2}) *
422  Matrix::MakeScale(Vector3(2, 3, 4));
423  Vector3 x = m.GetBasisX();
424  Vector3 y = m.GetBasisY();
425  Vector3 z = m.GetBasisZ();
426  ASSERT_VECTOR3_NEAR(x, Vector3(0, 2, 0));
427  ASSERT_VECTOR3_NEAR(y, Vector3(0, 0, 3));
428  ASSERT_VECTOR3_NEAR(z, Vector3(4, 0, 0));
429  }
430 }
#define ASSERT_VECTOR3_NEAR(a, b)

References ASSERT_VECTOR3_NEAR, impeller::kPiOver2, impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and x.

◆ TEST() [186/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetDirectionScale   
)

Definition at line 432 of file geometry_unittests.cc.

432  {
433  {
434  auto m = Matrix();
435  Scalar result = m.GetDirectionScale(Vector3{1, 0, 0});
436  ASSERT_FLOAT_EQ(result, 1);
437  }
438 
439  {
440  auto m = Matrix::MakeRotationX(Degrees{10}) *
441  Matrix::MakeRotationY(Degrees{83}) *
442  Matrix::MakeRotationZ(Degrees{172});
443  Scalar result = m.GetDirectionScale(Vector3{0, 1, 0});
444  ASSERT_FLOAT_EQ(result, 1);
445  }
446 
447  {
448  auto m = Matrix::MakeRotationZ(Radians{kPiOver2}) *
449  Matrix::MakeScale(Vector3(3, 4, 5));
450  Scalar result = m.GetDirectionScale(Vector3{2, 0, 0});
451  ASSERT_FLOAT_EQ(result, 8);
452  }
453 }

References impeller::Matrix::GetDirectionScale(), impeller::kPiOver2, impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), and impeller::Matrix::MakeScale().

◆ TEST() [187/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetMaxBasisLengthXY   
)

Definition at line 333 of file geometry_unittests.cc.

333  {
334  {
335  auto m = Matrix::MakeScale({3, 1, 1});
336  ASSERT_EQ(m.GetMaxBasisLengthXY(), 3);
337 
338  m = m * Matrix::MakeSkew(0, 4);
339  ASSERT_EQ(m.GetMaxBasisLengthXY(), 5);
340  }
341 
342  {
343  auto m = Matrix::MakeScale({-3, 4, 7});
344  ASSERT_EQ(m.GetMaxBasisLengthXY(), 4);
345  }
346 
347  {
348  // clang-format off
349  auto m = Matrix::MakeColumn(
350  1.0f, 0.0f, 0.0f, 0.0f,
351  0.0f, 1.0f, 0.0f, 0.0f,
352  4.0f, 0.0f, 1.0f, 0.0f,
353  0.0f, 0.0f, 0.0f, 1.0f
354  );
355  // clang-format on
356  ASSERT_EQ(m.GetMaxBasisLengthXY(), 1.0f);
357  }
358 }

References impeller::Matrix::MakeColumn(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeSkew().

◆ TEST() [188/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixLookAt   
)

Definition at line 481 of file geometry_unittests.cc.

481  {
482  {
483  auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),
484  Vector3(0, 1, 0));
485  auto expected = Matrix{
486  1, 0, 0, 0, //
487  0, 1, 0, 0, //
488  0, 0, 1, 0, //
489  0, 0, 1, 1, //
490  };
491  ASSERT_MATRIX_NEAR(m, expected);
492  }
493 
494  // Sideways tilt.
495  {
496  auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),
497  Vector3(1, 1, 0).Normalize());
498 
499  // clang-format off
500  auto expected = Matrix{
501  k1OverSqrt2, k1OverSqrt2, 0, 0,
502  -k1OverSqrt2, k1OverSqrt2, 0, 0,
503  0, 0, 1, 0,
504  0, 0, 1, 1,
505  };
506  // clang-format on
507  ASSERT_MATRIX_NEAR(m, expected);
508  }
509 
510  // Half way between +x and -y, yaw 90
511  {
512  auto m =
513  Matrix::MakeLookAt(Vector3(), Vector3(10, -10, 0), Vector3(0, 0, -1));
514 
515  // clang-format off
516  auto expected = Matrix{
517  -k1OverSqrt2, 0, k1OverSqrt2, 0,
518  -k1OverSqrt2, 0, -k1OverSqrt2, 0,
519  0, -1, 0, 0,
520  0, 0, 0, 1,
521  };
522  // clang-format on
523  ASSERT_MATRIX_NEAR(m, expected);
524  }
525 }

References ASSERT_MATRIX_NEAR, impeller::k1OverSqrt2, and impeller::Matrix::MakeLookAt().

◆ TEST() [189/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixMakeOrthographic   
)

Definition at line 360 of file geometry_unittests.cc.

360  {
361  {
362  auto m = Matrix::MakeOrthographic(Size(100, 200));
363  auto expect = Matrix{
364  0.02, 0, 0, 0, //
365  0, -0.01, 0, 0, //
366  0, 0, 0, 0, //
367  -1, 1, 0.5, 1, //
368  };
369  ASSERT_MATRIX_NEAR(m, expect);
370  }
371 
372  {
373  auto m = Matrix::MakeOrthographic(Size(400, 100));
374  auto expect = Matrix{
375  0.005, 0, 0, 0, //
376  0, -0.02, 0, 0, //
377  0, 0, 0, 0, //
378  -1, 1, 0.5, 1, //
379  };
380  ASSERT_MATRIX_NEAR(m, expect);
381  }
382 }

References ASSERT_MATRIX_NEAR, and impeller::Matrix::MakeOrthographic().

◆ TEST() [190/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixMakePerspective   
)

Definition at line 384 of file geometry_unittests.cc.

384  {
385  {
386  auto m = Matrix::MakePerspective(Degrees(60), Size(100, 200), 1, 10);
387  auto expect = Matrix{
388  3.4641, 0, 0, 0, //
389  0, 1.73205, 0, 0, //
390  0, 0, 1.11111, 1, //
391  0, 0, -1.11111, 0, //
392  };
393  ASSERT_MATRIX_NEAR(m, expect);
394  }
395 
396  {
397  auto m = Matrix::MakePerspective(Radians(1), 2, 10, 20);
398  auto expect = Matrix{
399  0.915244, 0, 0, 0, //
400  0, 1.83049, 0, 0, //
401  0, 0, 2, 1, //
402  0, 0, -20, 0, //
403  };
404  ASSERT_MATRIX_NEAR(m, expect);
405  }
406 }

References ASSERT_MATRIX_NEAR, and impeller::Matrix::MakePerspective().

◆ TEST() [191/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixMakeRotationFromQuaternion   
)

Definition at line 278 of file geometry_unittests.cc.

278  {
279  {
280  auto matrix = Matrix::MakeRotation(Quaternion({1, 0, 0}, kPiOver2));
281  auto expected = Matrix::MakeRotationX(Radians(kPiOver2));
282  ASSERT_MATRIX_NEAR(matrix, expected);
283  }
284 
285  {
286  auto matrix = Matrix::MakeRotation(Quaternion({0, 1, 0}, kPiOver2));
287  auto expected = Matrix::MakeRotationY(Radians(kPiOver2));
288  ASSERT_MATRIX_NEAR(matrix, expected);
289  }
290 
291  {
292  auto matrix = Matrix::MakeRotation(Quaternion({0, 0, 1}, kPiOver2));
293  auto expected = Matrix::MakeRotationZ(Radians(kPiOver2));
294  ASSERT_MATRIX_NEAR(matrix, expected);
295  }
296 }

References ASSERT_MATRIX_NEAR, impeller::kPiOver2, impeller::Matrix::MakeRotation(), impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), and impeller::Matrix::MakeRotationZ().

◆ TEST() [192/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixPrinting   
)

Definition at line 1726 of file geometry_unittests.cc.

1726  {
1727  {
1728  std::stringstream stream;
1729  Matrix m;
1730  stream << m;
1731  ASSERT_EQ(stream.str(), R"((
1732  1.000000, 0.000000, 0.000000, 0.000000,
1733  0.000000, 1.000000, 0.000000, 0.000000,
1734  0.000000, 0.000000, 1.000000, 0.000000,
1735  0.000000, 0.000000, 0.000000, 1.000000,
1736 ))");
1737  }
1738 
1739  {
1740  std::stringstream stream;
1741  Matrix m = Matrix::MakeTranslation(Vector3(10, 20, 30));
1742  stream << m;
1743 
1744  ASSERT_EQ(stream.str(), R"((
1745  1.000000, 0.000000, 0.000000, 10.000000,
1746  0.000000, 1.000000, 0.000000, 20.000000,
1747  0.000000, 0.000000, 1.000000, 30.000000,
1748  0.000000, 0.000000, 0.000000, 1.000000,
1749 ))");
1750  }
1751 }

References impeller::Matrix::MakeTranslation().

◆ TEST() [193/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixTransformDirection   
)

Definition at line 298 of file geometry_unittests.cc.

298  {
299  {
300  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
301  Matrix::MakeRotationZ(Radians{kPiOver2}) *
302  Matrix::MakeScale({2.0, 2.0, 2.0});
303  auto vector = Vector4(10, 20, 30, 2);
304 
305  Vector4 result = matrix.TransformDirection(vector);
306  auto expected = Vector4(-40, 20, 60, 2);
307  ASSERT_VECTOR4_NEAR(result, expected);
308  }
309 
310  {
311  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
312  Matrix::MakeRotationZ(Radians{kPiOver2}) *
313  Matrix::MakeScale({2.0, 2.0, 2.0});
314  auto vector = Vector3(10, 20, 30);
315 
316  Vector3 result = matrix.TransformDirection(vector);
317  auto expected = Vector3(-40, 20, 60);
318  ASSERT_VECTOR3_NEAR(result, expected);
319  }
320 
321  {
322  auto matrix = Matrix::MakeTranslation({0, -0.4, 100}) *
323  Matrix::MakeRotationZ(Radians{kPiOver2}) *
324  Matrix::MakeScale({2.0, 2.0, 2.0});
325  auto vector = Point(10, 20);
326 
327  Point result = matrix.TransformDirection(vector);
328  auto expected = Point(-40, 20);
329  ASSERT_POINT_NEAR(result, expected);
330  }
331 }
#define ASSERT_VECTOR4_NEAR(a, b)
#define ASSERT_POINT_NEAR(a, b)

References ASSERT_POINT_NEAR, ASSERT_VECTOR3_NEAR, ASSERT_VECTOR4_NEAR, impeller::kPiOver2, impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [194/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixTranslationScaleOnly   
)

Definition at line 455 of file geometry_unittests.cc.

455  {
456  {
457  auto m = Matrix();
458  bool result = m.IsTranslationScaleOnly();
459  ASSERT_TRUE(result);
460  }
461 
462  {
463  auto m = Matrix::MakeScale(Vector3(2, 3, 4));
464  bool result = m.IsTranslationScaleOnly();
465  ASSERT_TRUE(result);
466  }
467 
468  {
469  auto m = Matrix::MakeTranslation(Vector3(2, 3, 4));
470  bool result = m.IsTranslationScaleOnly();
471  ASSERT_TRUE(result);
472  }
473 
474  {
475  auto m = Matrix::MakeRotationZ(Degrees(10));
476  bool result = m.IsTranslationScaleOnly();
477  ASSERT_FALSE(result);
478  }
479 }

References impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [195/525]

impeller::testing::TEST ( GeometryTest  ,
MatrixVectorMultiplication   
)

Definition at line 213 of file geometry_unittests.cc.

213  {
214  {
215  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
216  Matrix::MakeRotationZ(Radians{kPiOver2}) *
217  Matrix::MakeScale({2.0, 2.0, 2.0});
218  auto vector = Vector4(10, 20, 30, 2);
219 
220  Vector4 result = matrix * vector;
221  auto expected = Vector4(160, 220, 260, 2);
222  ASSERT_VECTOR4_NEAR(result, expected);
223  }
224 
225  {
226  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
227  Matrix::MakeRotationZ(Radians{kPiOver2}) *
228  Matrix::MakeScale({2.0, 2.0, 2.0});
229  auto vector = Vector3(10, 20, 30);
230 
231  Vector3 result = matrix * vector;
232  auto expected = Vector3(60, 120, 160);
233  ASSERT_VECTOR3_NEAR(result, expected);
234  }
235 
236  {
237  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
238  Matrix::MakeRotationZ(Radians{kPiOver2}) *
239  Matrix::MakeScale({2.0, 2.0, 2.0});
240  auto vector = Point(10, 20);
241 
242  Point result = matrix * vector;
243  auto expected = Point(60, 120);
244  ASSERT_POINT_NEAR(result, expected);
245  }
246 
247  // Matrix Vector ops should respect perspective transforms.
248  {
249  auto matrix = Matrix::MakePerspective(Radians(kPiOver2), 1, 1, 100);
250  auto vector = Vector3(3, 3, -3);
251 
252  Vector3 result = matrix * vector;
253  auto expected = Vector3(-1, -1, 1.3468);
254  ASSERT_VECTOR3_NEAR(result, expected);
255  }
256 
257  {
258  auto matrix = Matrix::MakePerspective(Radians(kPiOver2), 1, 1, 100) *
259  Matrix::MakeTranslation(Vector3(0, 0, -3));
260  auto point = Point(3, 3);
261 
262  Point result = matrix * point;
263  auto expected = Point(-1, -1);
264  ASSERT_POINT_NEAR(result, expected);
265  }
266 
267  // Resolves to 0 on perspective singularity.
268  {
269  auto matrix = Matrix::MakePerspective(Radians(kPiOver2), 1, 1, 100);
270  auto point = Point(3, 3);
271 
272  Point result = matrix * point;
273  auto expected = Point(0, 0);
274  ASSERT_POINT_NEAR(result, expected);
275  }
276 }

References ASSERT_POINT_NEAR, ASSERT_VECTOR3_NEAR, ASSERT_VECTOR4_NEAR, impeller::kPiOver2, impeller::Matrix::MakePerspective(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [196/525]

impeller::testing::TEST ( GeometryTest  ,
MutliplicationMatrix   
)

Definition at line 115 of file geometry_unittests.cc.

115  {
116  auto rotation = Matrix::MakeRotationZ(Radians{kPiOver4});
117  auto invert = rotation.Invert();
118  ASSERT_MATRIX_NEAR(rotation * invert, Matrix{});
119 }

References ASSERT_MATRIX_NEAR, impeller::Matrix::Invert(), impeller::kPiOver4, and impeller::Matrix::MakeRotationZ().

◆ TEST() [197/525]

impeller::testing::TEST ( GeometryTest  ,
PointAbs   
)

Definition at line 938 of file geometry_unittests.cc.

938  {
939  Point a(-1, -2);
940  auto a_abs = a.Abs();
941  auto expected = Point(1, 2);
942  ASSERT_POINT_NEAR(a_abs, expected);
943 }

References impeller::TPoint< T >::Abs(), and ASSERT_POINT_NEAR.

◆ TEST() [198/525]

impeller::testing::TEST ( GeometryTest  ,
PointAngleTo   
)

Definition at line 975 of file geometry_unittests.cc.

975  {
976  // Negative result in the CCW (with up = -Y) direction.
977  {
978  Point a(1, 1);
979  Point b(1, -1);
980  Radians actual = a.AngleTo(b);
981  Radians expected = Radians{-kPi / 2};
982  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
983  }
984 
985  // Check the other direction to ensure the result is signed correctly.
986  {
987  Point a(1, -1);
988  Point b(1, 1);
989  Radians actual = a.AngleTo(b);
990  Radians expected = Radians{kPi / 2};
991  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
992  }
993 
994  // Differences in magnitude should have no impact on the result.
995  {
996  Point a(100, -100);
997  Point b(0.01, 0.01);
998  Radians actual = a.AngleTo(b);
999  Radians expected = Radians{kPi / 2};
1000  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
1001  }
1002 }
constexpr float kPi
Definition: constants.h:26

References impeller::TPoint< T >::AngleTo(), impeller::saturated::b, impeller::kPi, and impeller::Radians::radians.

◆ TEST() [199/525]

impeller::testing::TEST ( GeometryTest  ,
PointCeil   
)

Definition at line 1113 of file geometry_unittests.cc.

1113  {
1114  Point p(1.5, 2.3);
1115  Point result = p.Ceil();
1116  Point expected(2, 3);
1117  ASSERT_POINT_NEAR(result, expected);
1118 }
constexpr TPoint Ceil() const
Definition: point.h:196

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Ceil().

◆ TEST() [200/525]

impeller::testing::TEST ( GeometryTest  ,
PointCrossProduct   
)

Definition at line 893 of file geometry_unittests.cc.

893  {
894  {
895  Point p(1, 0);
896  Scalar s = p.Cross(Point(-1, 0));
897  ASSERT_FLOAT_EQ(s, 0);
898  }
899 
900  {
901  Point p(0, -1);
902  Scalar s = p.Cross(Point(-1, 0));
903  ASSERT_FLOAT_EQ(s, -1);
904  }
905 
906  {
907  Point p(1, 2);
908  Scalar s = p.Cross(Point(3, -4));
909  ASSERT_FLOAT_EQ(s, -10);
910  }
911 }

References impeller::TPoint< T >::Cross().

◆ TEST() [201/525]

impeller::testing::TEST ( GeometryTest  ,
PointDotProduct   
)

Definition at line 873 of file geometry_unittests.cc.

873  {
874  {
875  Point p(1, 0);
876  Scalar s = p.Dot(Point(-1, 0));
877  ASSERT_FLOAT_EQ(s, -1);
878  }
879 
880  {
881  Point p(0, -1);
882  Scalar s = p.Dot(Point(-1, 0));
883  ASSERT_FLOAT_EQ(s, 0);
884  }
885 
886  {
887  Point p(1, 2);
888  Scalar s = p.Dot(Point(3, -4));
889  ASSERT_FLOAT_EQ(s, -5);
890  }
891 }

References impeller::TPoint< T >::Dot().

◆ TEST() [202/525]

impeller::testing::TEST ( GeometryTest  ,
PointFloor   
)

Definition at line 1092 of file geometry_unittests.cc.

1092  {
1093  Point p(1.5, 2.3);
1094  Point result = p.Floor();
1095  Point expected(1, 2);
1096  ASSERT_POINT_NEAR(result, expected);
1097 }
constexpr TPoint Floor() const
Definition: point.h:194

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Floor().

◆ TEST() [203/525]

impeller::testing::TEST ( GeometryTest  ,
PointIntegerCoercesToFloat   
)

Definition at line 678 of file geometry_unittests.cc.

678  {
679  // Integer on LHS, float on RHS
680  {
681  IPoint p1(1, 2);
682  Point p2 = p1 + Point(1, 2);
683  ASSERT_FLOAT_EQ(p2.x, 2u);
684  ASSERT_FLOAT_EQ(p2.y, 4u);
685  }
686 
687  {
688  IPoint p1(3, 6);
689  Point p2 = p1 - Point(1, 2);
690  ASSERT_FLOAT_EQ(p2.x, 2u);
691  ASSERT_FLOAT_EQ(p2.y, 4u);
692  }
693 
694  {
695  IPoint p1(1, 2);
696  Point p2 = p1 * Point(2, 3);
697  ASSERT_FLOAT_EQ(p2.x, 2u);
698  ASSERT_FLOAT_EQ(p2.y, 6u);
699  }
700 
701  {
702  IPoint p1(2, 6);
703  Point p2 = p1 / Point(2, 3);
704  ASSERT_FLOAT_EQ(p2.x, 1u);
705  ASSERT_FLOAT_EQ(p2.y, 2u);
706  }
707 
708  // Float on LHS, integer on RHS
709  {
710  Point p1(1, 2);
711  Point p2 = p1 + IPoint(1, 2);
712  ASSERT_FLOAT_EQ(p2.x, 2u);
713  ASSERT_FLOAT_EQ(p2.y, 4u);
714  }
715 
716  {
717  Point p1(3, 6);
718  Point p2 = p1 - IPoint(1, 2);
719  ASSERT_FLOAT_EQ(p2.x, 2u);
720  ASSERT_FLOAT_EQ(p2.y, 4u);
721  }
722 
723  {
724  Point p1(1, 2);
725  Point p2 = p1 * IPoint(2, 3);
726  ASSERT_FLOAT_EQ(p2.x, 2u);
727  ASSERT_FLOAT_EQ(p2.y, 6u);
728  }
729 
730  {
731  Point p1(2, 6);
732  Point p2 = p1 / IPoint(2, 3);
733  ASSERT_FLOAT_EQ(p2.x, 1u);
734  ASSERT_FLOAT_EQ(p2.y, 2u);
735  }
736 }

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [204/525]

impeller::testing::TEST ( GeometryTest  ,
PointLerp   
)

Definition at line 1155 of file geometry_unittests.cc.

1155  {
1156  Point p(1, 2);
1157  Point result = p.Lerp({5, 10}, 0.75);
1158  Point expected(4, 8);
1159  ASSERT_POINT_NEAR(result, expected);
1160 }
constexpr TPoint Lerp(const TPoint &p, Scalar t) const
Definition: point.h:236

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Lerp().

◆ TEST() [205/525]

impeller::testing::TEST ( GeometryTest  ,
PointMax   
)

Definition at line 1071 of file geometry_unittests.cc.

1071  {
1072  Point p(1, 2);
1073  Point result = p.Max({0, 10});
1074  Point expected(1, 10);
1075  ASSERT_POINT_NEAR(result, expected);
1076 }
constexpr TPoint Max(const TPoint &p) const
Definition: point.h:190

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Max().

◆ TEST() [206/525]

impeller::testing::TEST ( GeometryTest  ,
PointMin   
)

Definition at line 1004 of file geometry_unittests.cc.

1004  {
1005  Point p(1, 2);
1006  Point result = p.Min({0, 10});
1007  Point expected(0, 2);
1008  ASSERT_POINT_NEAR(result, expected);
1009 }
constexpr TPoint Min(const TPoint &p) const
Definition: point.h:186

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Min().

◆ TEST() [207/525]

impeller::testing::TEST ( GeometryTest  ,
PointPrinting   
)

Definition at line 1753 of file geometry_unittests.cc.

1753  {
1754  {
1755  std::stringstream stream;
1756  Point m;
1757  stream << m;
1758  ASSERT_EQ(stream.str(), "(0, 0)");
1759  }
1760 
1761  {
1762  std::stringstream stream;
1763  Point m(13, 37);
1764  stream << m;
1765  ASSERT_EQ(stream.str(), "(13, 37)");
1766  }
1767 }

◆ TEST() [208/525]

impeller::testing::TEST ( GeometryTest  ,
PointReflect   
)

Definition at line 913 of file geometry_unittests.cc.

913  {
914  {
915  Point axis = Point(0, 1);
916  Point a(2, 3);
917  auto reflected = a.Reflect(axis);
918  auto expected = Point(2, -3);
919  ASSERT_POINT_NEAR(reflected, expected);
920  }
921 
922  {
923  Point axis = Point(1, 1).Normalize();
924  Point a(1, 0);
925  auto reflected = a.Reflect(axis);
926  auto expected = Point(0, -1);
927  ASSERT_POINT_NEAR(reflected, expected);
928  }
929 
930  {
931  Point axis = Point(1, 1).Normalize();
932  Point a(-1, -1);
933  auto reflected = a.Reflect(axis);
934  ASSERT_POINT_NEAR(reflected, -a);
935  }
936 }
constexpr TPoint Normalize() const
Definition: point.h:208

References ASSERT_POINT_NEAR, impeller::TPoint< T >::Normalize(), and impeller::TPoint< T >::Reflect().

◆ TEST() [209/525]

impeller::testing::TEST ( GeometryTest  ,
PointRotate   
)

Definition at line 945 of file geometry_unittests.cc.

945  {
946  {
947  Point a(1, 0);
948  auto rotated = a.Rotate(Radians{kPiOver2});
949  auto expected = Point(0, 1);
950  ASSERT_POINT_NEAR(rotated, expected);
951  }
952 
953  {
954  Point a(1, 0);
955  auto rotated = a.Rotate(Radians{-kPiOver2});
956  auto expected = Point(0, -1);
957  ASSERT_POINT_NEAR(rotated, expected);
958  }
959 
960  {
961  Point a(1, 0);
962  auto rotated = a.Rotate(Radians{kPi});
963  auto expected = Point(-1, 0);
964  ASSERT_POINT_NEAR(rotated, expected);
965  }
966 
967  {
968  Point a(1, 0);
969  auto rotated = a.Rotate(Radians{kPi * 1.5});
970  auto expected = Point(0, -1);
971  ASSERT_POINT_NEAR(rotated, expected);
972  }
973 }

References ASSERT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, and impeller::TPoint< T >::Rotate().

◆ TEST() [210/525]

impeller::testing::TEST ( GeometryTest  ,
PointRound   
)

Definition at line 1134 of file geometry_unittests.cc.

1134  {
1135  Point p(1.5, 2.3);
1136  Point result = p.Round();
1137  Point expected(2, 2);
1138  ASSERT_POINT_NEAR(result, expected);
1139 }
static constexpr TPoint Round(const TPoint< U > &other)
Definition: point.h:49

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Round().

◆ TEST() [211/525]

impeller::testing::TEST ( GeometryTest  ,
QuaternionLerp   
)

Definition at line 527 of file geometry_unittests.cc.

527  {
528  auto q1 = Quaternion{{0.0, 0.0, 1.0}, 0.0};
529  auto q2 = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
530 
531  auto q3 = q1.Slerp(q2, 0.5);
532 
533  auto expected = Quaternion{{0.0, 0.0, 1.0}, kPiOver4 / 2.0};
534 
535  ASSERT_QUATERNION_NEAR(q3, expected);
536 }
#define ASSERT_QUATERNION_NEAR(a, b)

References ASSERT_QUATERNION_NEAR, and impeller::kPiOver4.

◆ TEST() [212/525]

impeller::testing::TEST ( GeometryTest  ,
QuaternionVectorMultiply   
)

Definition at line 538 of file geometry_unittests.cc.

538  {
539  {
540  Quaternion q({0, 0, 1}, 0);
541  Vector3 v(0, 1, 0);
542 
543  Vector3 result = q * v;
544  Vector3 expected(0, 1, 0);
545 
546  ASSERT_VECTOR3_NEAR(result, expected);
547  }
548 
549  {
550  Quaternion q({0, 0, 1}, k2Pi);
551  Vector3 v(1, 0, 0);
552 
553  Vector3 result = q * v;
554  Vector3 expected(1, 0, 0);
555 
556  ASSERT_VECTOR3_NEAR(result, expected);
557  }
558 
559  {
560  Quaternion q({0, 0, 1}, kPiOver4);
561  Vector3 v(0, 1, 0);
562 
563  Vector3 result = q * v;
564  Vector3 expected(-k1OverSqrt2, k1OverSqrt2, 0);
565 
566  ASSERT_VECTOR3_NEAR(result, expected);
567  }
568 
569  {
570  Quaternion q(Vector3(1, 0, 1).Normalize(), kPi);
571  Vector3 v(0, 0, -1);
572 
573  Vector3 result = q * v;
574  Vector3 expected(-1, 0, 0);
575 
576  ASSERT_VECTOR3_NEAR(result, expected);
577  }
578 }
constexpr float k2Pi
Definition: constants.h:29

References ASSERT_VECTOR3_NEAR, impeller::k1OverSqrt2, impeller::k2Pi, impeller::kPi, and impeller::kPiOver4.

◆ TEST() [213/525]

impeller::testing::TEST ( GeometryTest  ,
RotationMatrix   
)

Definition at line 68 of file geometry_unittests.cc.

68  {
69  auto rotation = Matrix::MakeRotationZ(Radians{kPiOver4});
70  // clang-format off
71  auto expect = Matrix{k1OverSqrt2, k1OverSqrt2, 0, 0,
72  -k1OverSqrt2, k1OverSqrt2, 0, 0,
73  0, 0, 1, 0,
74  0, 0, 0, 1};
75  // clang-format on
76  ASSERT_MATRIX_NEAR(rotation, expect);
77 }

References ASSERT_MATRIX_NEAR, impeller::k1OverSqrt2, impeller::kPiOver4, and impeller::Matrix::MakeRotationZ().

◆ TEST() [214/525]

impeller::testing::TEST ( GeometryTest  ,
ScalarNearlyEqual   
)

Definition at line 31 of file geometry_unittests.cc.

31  {
32  ASSERT_FALSE(ScalarNearlyEqual(0.0021f, 0.001f));
33  ASSERT_TRUE(ScalarNearlyEqual(0.0019f, 0.001f));
34  ASSERT_TRUE(ScalarNearlyEqual(0.002f, 0.001f, 0.0011f));
35  ASSERT_FALSE(ScalarNearlyEqual(0.002f, 0.001f, 0.0009f));
36  ASSERT_TRUE(ScalarNearlyEqual(
37  1.0f, 1.0f + std::numeric_limits<float>::epsilon() * 4));
38 }
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:36

References impeller::ScalarNearlyEqual().

◆ TEST() [215/525]

impeller::testing::TEST ( GeometryTest  ,
SeparatedVector2AngleTo   
)

Definition at line 1210 of file geometry_unittests.cc.

1210  {
1211  {
1212  SeparatedVector2 v(Vector2(10, 0));
1213  Radians actual = v.AngleTo(SeparatedVector2(Vector2(5, 0)));
1214  Radians expected = Radians{0};
1215  ASSERT_NEAR(actual.radians, expected.radians, kEhCloseEnough);
1216  }
1217 
1218  {
1219  SeparatedVector2 v(Vector2(10, 0));
1220  Radians actual = v.AngleTo(SeparatedVector2(Vector2(0, -5)));
1221  Radians expected = Radians{-kPi / 2};
1222  ASSERT_NEAR(actual.radians, expected.radians, kEhCloseEnough);
1223  }
1224 }
constexpr float kEhCloseEnough
Definition: constants.h:57

References impeller::SeparatedVector2::AngleTo(), impeller::kEhCloseEnough, impeller::kPi, and impeller::Radians::radians.

◆ TEST() [216/525]

impeller::testing::TEST ( GeometryTest  ,
SeparatedVector2GetAlignment   
)

Definition at line 1187 of file geometry_unittests.cc.

1187  {
1188  // Parallel
1189  {
1190  SeparatedVector2 v(Vector2(10, 0));
1191  Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(5, 0)));
1192  ASSERT_NEAR(actual, 1, kEhCloseEnough);
1193  }
1194 
1195  // Perpendicular
1196  {
1197  SeparatedVector2 v(Vector2(10, 0));
1198  Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(0, 5)));
1199  ASSERT_NEAR(actual, 0, kEhCloseEnough);
1200  }
1201 
1202  // Opposite parallel
1203  {
1204  SeparatedVector2 v(Vector2(0, 10));
1205  Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(0, -5)));
1206  ASSERT_NEAR(actual, -1, kEhCloseEnough);
1207  }
1208 }

References impeller::SeparatedVector2::GetAlignment(), and impeller::kEhCloseEnough.

◆ TEST() [217/525]

impeller::testing::TEST ( GeometryTest  ,
SeparatedVector2GetVector   
)

Definition at line 1182 of file geometry_unittests.cc.

1182  {
1183  SeparatedVector2 v(Vector2(10, 0));
1184  ASSERT_POINT_NEAR(v.GetVector(), Vector2(10, 0));
1185 }

References ASSERT_POINT_NEAR, and impeller::SeparatedVector2::GetVector().

◆ TEST() [218/525]

impeller::testing::TEST ( GeometryTest  ,
SeparatedVector2NormalizesWithConstructor   
)

Definition at line 1176 of file geometry_unittests.cc.

1176  {
1177  SeparatedVector2 v(Vector2(10, 0));
1178  ASSERT_POINT_NEAR(v.direction, Vector2(1, 0));
1179  ASSERT_NEAR(v.magnitude, 10, kEhCloseEnough);
1180 }

References ASSERT_POINT_NEAR, impeller::SeparatedVector2::direction, impeller::kEhCloseEnough, and impeller::SeparatedVector2::magnitude.

◆ TEST() [219/525]

impeller::testing::TEST ( GeometryTest  ,
SizeCoercesToPoint   
)

Definition at line 738 of file geometry_unittests.cc.

738  {
739  // Point on LHS, Size on RHS
740  {
741  IPoint p1(1, 2);
742  IPoint p2 = p1 + ISize(1, 2);
743  ASSERT_EQ(p2.x, 2u);
744  ASSERT_EQ(p2.y, 4u);
745  }
746 
747  {
748  IPoint p1(3, 6);
749  IPoint p2 = p1 - ISize(1, 2);
750  ASSERT_EQ(p2.x, 2u);
751  ASSERT_EQ(p2.y, 4u);
752  }
753 
754  {
755  IPoint p1(1, 2);
756  IPoint p2 = p1 * ISize(2, 3);
757  ASSERT_EQ(p2.x, 2u);
758  ASSERT_EQ(p2.y, 6u);
759  }
760 
761  {
762  IPoint p1(2, 6);
763  IPoint p2 = p1 / ISize(2, 3);
764  ASSERT_EQ(p2.x, 1u);
765  ASSERT_EQ(p2.y, 2u);
766  }
767 
768  // Size on LHS, Point on RHS
769  {
770  ISize p1(1, 2);
771  IPoint p2 = p1 + IPoint(1, 2);
772  ASSERT_EQ(p2.x, 2u);
773  ASSERT_EQ(p2.y, 4u);
774  }
775 
776  {
777  ISize p1(3, 6);
778  IPoint p2 = p1 - IPoint(1, 2);
779  ASSERT_EQ(p2.x, 2u);
780  ASSERT_EQ(p2.y, 4u);
781  }
782 
783  {
784  ISize p1(1, 2);
785  IPoint p2 = p1 * IPoint(2, 3);
786  ASSERT_EQ(p2.x, 2u);
787  ASSERT_EQ(p2.y, 6u);
788  }
789 
790  {
791  ISize p1(2, 6);
792  IPoint p2 = p1 / IPoint(2, 3);
793  ASSERT_EQ(p2.x, 1u);
794  ASSERT_EQ(p2.y, 2u);
795  }
796 }

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [220/525]

impeller::testing::TEST ( GeometryTest  ,
TestDecomposition   
)

Definition at line 142 of file geometry_unittests.cc.

142  {
143  auto rotated = Matrix::MakeRotationZ(Radians{kPiOver4});
144 
145  auto result = rotated.Decompose();
146 
147  ASSERT_TRUE(result.has_value());
148 
149  MatrixDecomposition res = result.value();
150 
151  auto quaternion = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
152  ASSERT_QUATERNION_NEAR(res.rotation, quaternion);
153 }

References ASSERT_QUATERNION_NEAR, impeller::Matrix::Decompose(), impeller::kPiOver4, impeller::Matrix::MakeRotationZ(), and impeller::MatrixDecomposition::rotation.

◆ TEST() [221/525]

impeller::testing::TEST ( GeometryTest  ,
TestDecomposition2   
)

Definition at line 155 of file geometry_unittests.cc.

155  {
156  auto rotated = Matrix::MakeRotationZ(Radians{kPiOver4});
157  auto scaled = Matrix::MakeScale({2.0, 3.0, 1.0});
158  auto translated = Matrix::MakeTranslation({-200, 750, 20});
159 
160  auto result = (translated * rotated * scaled).Decompose();
161 
162  ASSERT_TRUE(result.has_value());
163 
164  MatrixDecomposition res = result.value();
165 
166  auto quaternion = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
167 
168  ASSERT_QUATERNION_NEAR(res.rotation, quaternion);
169 
170  ASSERT_FLOAT_EQ(res.translation.x, -200);
171  ASSERT_FLOAT_EQ(res.translation.y, 750);
172  ASSERT_FLOAT_EQ(res.translation.z, 20);
173 
174  ASSERT_FLOAT_EQ(res.scale.x, 2);
175  ASSERT_FLOAT_EQ(res.scale.y, 3);
176  ASSERT_FLOAT_EQ(res.scale.z, 1);
177 }

References ASSERT_QUATERNION_NEAR, impeller::kPiOver4, impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::MatrixDecomposition::rotation, impeller::MatrixDecomposition::scale, impeller::MatrixDecomposition::translation, impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

◆ TEST() [222/525]

impeller::testing::TEST ( GeometryTest  ,
TestRecomposition   
)

Definition at line 179 of file geometry_unittests.cc.

179  {
180  /*
181  * Decomposition.
182  */
183  auto rotated = Matrix::MakeRotationZ(Radians{kPiOver4});
184 
185  auto result = rotated.Decompose();
186 
187  ASSERT_TRUE(result.has_value());
188 
189  MatrixDecomposition res = result.value();
190 
191  auto quaternion = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
192 
193  ASSERT_QUATERNION_NEAR(res.rotation, quaternion);
194 
195  /*
196  * Recomposition.
197  */
198  ASSERT_MATRIX_NEAR(rotated, Matrix{res});
199 }

References ASSERT_MATRIX_NEAR, ASSERT_QUATERNION_NEAR, impeller::Matrix::Decompose(), impeller::kPiOver4, impeller::Matrix::MakeRotationZ(), and impeller::MatrixDecomposition::rotation.

◆ TEST() [223/525]

impeller::testing::TEST ( GeometryTest  ,
TestRecomposition2   
)

Definition at line 201 of file geometry_unittests.cc.

201  {
202  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
203  Matrix::MakeRotationZ(Radians{kPiOver4}) *
204  Matrix::MakeScale({2.0, 2.0, 2.0});
205 
206  auto result = matrix.Decompose();
207 
208  ASSERT_TRUE(result.has_value());
209 
210  ASSERT_MATRIX_NEAR(matrix, Matrix{result.value()});
211 }

References ASSERT_MATRIX_NEAR, impeller::Matrix::Decompose(), impeller::kPiOver4, impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [224/525]

impeller::testing::TEST ( GeometryTest  ,
ToIColor   
)

Definition at line 1817 of file geometry_unittests.cc.

1817  {
1818  ASSERT_EQ(Color::ToIColor(Color(0, 0, 0, 0)), 0u);
1819  ASSERT_EQ(Color::ToIColor(Color(1.0, 1.0, 1.0, 1.0)), 0xFFFFFFFF);
1820  ASSERT_EQ(Color::ToIColor(Color(0.5, 0.5, 1.0, 1.0)), 0xFF8080FF);
1821 }

References impeller::Color::ToIColor().

◆ TEST() [225/525]

impeller::testing::TEST ( GeometryTest  ,
Vector3Ceil   
)

Definition at line 1120 of file geometry_unittests.cc.

1120  {
1121  Vector3 p(1.5, 2.3, 3.9);
1122  Vector3 result = p.Ceil();
1123  Vector3 expected(2, 3, 4);
1124  ASSERT_VECTOR3_NEAR(result, expected);
1125 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Ceil().

◆ TEST() [226/525]

impeller::testing::TEST ( GeometryTest  ,
Vector3Floor   
)

Definition at line 1099 of file geometry_unittests.cc.

1099  {
1100  Vector3 p(1.5, 2.3, 3.9);
1101  Vector3 result = p.Floor();
1102  Vector3 expected(1, 2, 3);
1103  ASSERT_VECTOR3_NEAR(result, expected);
1104 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Floor().

◆ TEST() [227/525]

impeller::testing::TEST ( GeometryTest  ,
Vector3Lerp   
)

Definition at line 1162 of file geometry_unittests.cc.

1162  {
1163  Vector3 p(1, 2, 3);
1164  Vector3 result = p.Lerp({5, 10, 15}, 0.75);
1165  Vector3 expected(4, 8, 12);
1166  ASSERT_VECTOR3_NEAR(result, expected);
1167 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Lerp().

◆ TEST() [228/525]

impeller::testing::TEST ( GeometryTest  ,
Vector3Max   
)

Definition at line 1078 of file geometry_unittests.cc.

1078  {
1079  Vector3 p(1, 2, 3);
1080  Vector3 result = p.Max({0, 10, 2});
1081  Vector3 expected(1, 10, 3);
1082  ASSERT_VECTOR3_NEAR(result, expected);
1083 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Max().

◆ TEST() [229/525]

impeller::testing::TEST ( GeometryTest  ,
Vector3Min   
)

Definition at line 1057 of file geometry_unittests.cc.

1057  {
1058  Vector3 p(1, 2, 3);
1059  Vector3 result = p.Min({0, 10, 2});
1060  Vector3 expected(0, 2, 2);
1061  ASSERT_VECTOR3_NEAR(result, expected);
1062 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Min().

◆ TEST() [230/525]

impeller::testing::TEST ( GeometryTest  ,
Vector3Printing   
)

Definition at line 1769 of file geometry_unittests.cc.

1769  {
1770  {
1771  std::stringstream stream;
1772  Vector3 m;
1773  stream << m;
1774  ASSERT_EQ(stream.str(), "(0, 0, 0)");
1775  }
1776 
1777  {
1778  std::stringstream stream;
1779  Vector3 m(1, 2, 3);
1780  stream << m;
1781  ASSERT_EQ(stream.str(), "(1, 2, 3)");
1782  }
1783 }

◆ TEST() [231/525]

impeller::testing::TEST ( GeometryTest  ,
Vector3Round   
)

Definition at line 1141 of file geometry_unittests.cc.

1141  {
1142  Vector3 p(1.5, 2.3, 3.9);
1143  Vector3 result = p.Round();
1144  Vector3 expected(2, 2, 4);
1145  ASSERT_VECTOR3_NEAR(result, expected);
1146 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Round().

◆ TEST() [232/525]

impeller::testing::TEST ( GeometryTest  ,
Vector4Ceil   
)

Definition at line 1127 of file geometry_unittests.cc.

1127  {
1128  Vector4 p(1.5, 2.3, 3.9, 4.0);
1129  Vector4 result = p.Ceil();
1130  Vector4 expected(2, 3, 4, 4);
1131  ASSERT_VECTOR4_NEAR(result, expected);
1132 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Ceil().

◆ TEST() [233/525]

impeller::testing::TEST ( GeometryTest  ,
Vector4Floor   
)

Definition at line 1106 of file geometry_unittests.cc.

1106  {
1107  Vector4 p(1.5, 2.3, 3.9, 4.0);
1108  Vector4 result = p.Floor();
1109  Vector4 expected(1, 2, 3, 4);
1110  ASSERT_VECTOR4_NEAR(result, expected);
1111 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Floor().

◆ TEST() [234/525]

impeller::testing::TEST ( GeometryTest  ,
Vector4IsFinite   
)

Definition at line 1011 of file geometry_unittests.cc.

1011  {
1012  {
1013  Vector4 v;
1014  ASSERT_TRUE(v.IsFinite());
1015  v.x = std::numeric_limits<Scalar>::infinity();
1016  ASSERT_FALSE(v.IsFinite());
1017  v.x = -std::numeric_limits<Scalar>::infinity();
1018  ASSERT_FALSE(v.IsFinite());
1019  v.x = -std::numeric_limits<Scalar>::quiet_NaN();
1020  ASSERT_FALSE(v.IsFinite());
1021  }
1022 
1023  {
1024  Vector4 v;
1025  ASSERT_TRUE(v.IsFinite());
1026  v.y = std::numeric_limits<Scalar>::infinity();
1027  ASSERT_FALSE(v.IsFinite());
1028  v.y = -std::numeric_limits<Scalar>::infinity();
1029  ASSERT_FALSE(v.IsFinite());
1030  v.y = -std::numeric_limits<Scalar>::quiet_NaN();
1031  ASSERT_FALSE(v.IsFinite());
1032  }
1033 
1034  {
1035  Vector4 v;
1036  ASSERT_TRUE(v.IsFinite());
1037  v.z = std::numeric_limits<Scalar>::infinity();
1038  ASSERT_FALSE(v.IsFinite());
1039  v.z = -std::numeric_limits<Scalar>::infinity();
1040  ASSERT_FALSE(v.IsFinite());
1041  v.z = -std::numeric_limits<Scalar>::quiet_NaN();
1042  ASSERT_FALSE(v.IsFinite());
1043  }
1044 
1045  {
1046  Vector4 v;
1047  ASSERT_TRUE(v.IsFinite());
1048  v.w = std::numeric_limits<Scalar>::infinity();
1049  ASSERT_FALSE(v.IsFinite());
1050  v.w = -std::numeric_limits<Scalar>::infinity();
1051  ASSERT_FALSE(v.IsFinite());
1052  v.w = -std::numeric_limits<Scalar>::quiet_NaN();
1053  ASSERT_FALSE(v.IsFinite());
1054  }
1055 }

References impeller::Vector4::IsFinite(), impeller::Vector4::w, impeller::Vector4::x, impeller::Vector4::y, and impeller::Vector4::z.

◆ TEST() [235/525]

impeller::testing::TEST ( GeometryTest  ,
Vector4Lerp   
)

Definition at line 1169 of file geometry_unittests.cc.

1169  {
1170  Vector4 p(1, 2, 3, 4);
1171  Vector4 result = p.Lerp({5, 10, 15, 20}, 0.75);
1172  Vector4 expected(4, 8, 12, 16);
1173  ASSERT_VECTOR4_NEAR(result, expected);
1174 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Lerp().

◆ TEST() [236/525]

impeller::testing::TEST ( GeometryTest  ,
Vector4Max   
)

Definition at line 1085 of file geometry_unittests.cc.

1085  {
1086  Vector4 p(1, 2, 3, 4);
1087  Vector4 result = p.Max({0, 10, 2, 1});
1088  Vector4 expected(1, 10, 3, 4);
1089  ASSERT_VECTOR4_NEAR(result, expected);
1090 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Max().

◆ TEST() [237/525]

impeller::testing::TEST ( GeometryTest  ,
Vector4Min   
)

Definition at line 1064 of file geometry_unittests.cc.

1064  {
1065  Vector4 p(1, 2, 3, 4);
1066  Vector4 result = p.Min({0, 10, 2, 1});
1067  Vector4 expected(0, 2, 2, 1);
1068  ASSERT_VECTOR4_NEAR(result, expected);
1069 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Min().

◆ TEST() [238/525]

impeller::testing::TEST ( GeometryTest  ,
Vector4Printing   
)

Definition at line 1785 of file geometry_unittests.cc.

1785  {
1786  {
1787  std::stringstream stream;
1788  Vector4 m;
1789  stream << m;
1790  ASSERT_EQ(stream.str(), "(0, 0, 0, 1)");
1791  }
1792 
1793  {
1794  std::stringstream stream;
1795  Vector4 m(1, 2, 3, 4);
1796  stream << m;
1797  ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
1798  }
1799 }

◆ TEST() [239/525]

impeller::testing::TEST ( GeometryTest  ,
Vector4Round   
)

Definition at line 1148 of file geometry_unittests.cc.

1148  {
1149  Vector4 p(1.5, 2.3, 3.9, 4.0);
1150  Vector4 result = p.Round();
1151  Vector4 expected(2, 2, 4, 4);
1152  ASSERT_VECTOR4_NEAR(result, expected);
1153 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Round().

◆ TEST() [240/525]

impeller::testing::TEST ( LineContents  ,
CalculatePerVertex   
)

Definition at line 59 of file line_contents_unittests.cc.

59  {
60  LineVertexShader::PerVertexData per_vertex[4];
61  auto geometry = std::make_unique<LineGeometry>(
62  /*p0=*/Point{100, 100}, //
63  /*p1=*/Point{200, 100}, //
64  StrokeParameters{
65  .width = 5.f,
66  .cap = Cap::kButt,
67  });
68  Matrix transform;
69 
70  fml::StatusOr<LineContents::EffectiveLineParameters> status =
71  LineContents::CalculatePerVertex(per_vertex, geometry.get(), transform);
72  Scalar offset =
73  (LineContents::kSampleRadius * 2.0 + geometry->GetWidth()) / 2.f;
74  ASSERT_TRUE(status.ok());
75  EXPECT_EQ(status.value().width, 5.f);
76  EXPECT_EQ(status.value().radius, LineContents::kSampleRadius);
77  EXPECT_POINT_NEAR(per_vertex[0].position,
78  Point(100 - LineContents::kSampleRadius, 100 + offset));
79  EXPECT_POINT_NEAR(per_vertex[1].position,
80  Point(200 + LineContents::kSampleRadius, 100 + offset));
81  EXPECT_POINT_NEAR(per_vertex[2].position,
82  Point(100 - LineContents::kSampleRadius, 100 - offset));
83  EXPECT_POINT_NEAR(per_vertex[3].position,
84  Point(200 + LineContents::kSampleRadius, 100 - offset));
85 
86  for (int i = 1; i < 4; ++i) {
87  EXPECT_VECTOR3_NEAR(per_vertex[0].e0, per_vertex[i].e0) << i;
88  EXPECT_VECTOR3_NEAR(per_vertex[0].e1, per_vertex[i].e1) << i;
89  EXPECT_VECTOR3_NEAR(per_vertex[0].e2, per_vertex[i].e2) << i;
90  EXPECT_VECTOR3_NEAR(per_vertex[0].e3, per_vertex[i].e3) << i;
91  }
92 
93  EXPECT_EQ(CalculateLine(per_vertex[0], Point(0, 0)), 0.f);
94  EXPECT_NEAR(CalculateLine(per_vertex[0], Point(150, 100 + offset)), 0.f,
96  EXPECT_NEAR(CalculateLine(per_vertex[0], Point(150, 100 + offset * 0.5)),
97  0.5f, kEhCloseEnough);
98  EXPECT_NEAR(CalculateLine(per_vertex[0], Point(150, 100)), 1.f,
100 }
#define EXPECT_VECTOR3_NEAR(a, b)
Vector3 e0
Vector3 e2
Vector3 e1

References impeller::LineContents::CalculatePerVertex(), e0, e1, e2, e3, EXPECT_POINT_NEAR, EXPECT_VECTOR3_NEAR, impeller::kButt, impeller::kEhCloseEnough, impeller::LineContents::kSampleRadius, transform, and impeller::StrokeParameters::width.

◆ TEST() [241/525]

impeller::testing::TEST ( LineContents  ,
CalculatePerVertexLimit   
)

Definition at line 125 of file line_contents_unittests.cc.

125  {
126  LineVertexShader::PerVertexData per_vertex[4];
127  Scalar scale = 0.05;
128  auto geometry = std::make_unique<LineGeometry>(
129  /*p0=*/Point{100, 100}, //
130  /*p1=*/Point{200, 100}, //
131  StrokeParameters{
132  .width = 10.f,
133  .cap = Cap::kButt,
134  });
135  Matrix transform = Matrix::MakeTranslation({100, 100, 1.0}) *
136  Matrix::MakeScale({scale, scale, 1.0}) *
137  Matrix::MakeTranslation({-100, -100, 1.0});
138 
139  fml::StatusOr<LineContents::EffectiveLineParameters> status =
140  LineContents::CalculatePerVertex(per_vertex, geometry.get(), transform);
141 
142  Scalar one_radius_size = std::max(LineContents::kSampleRadius / scale,
143  LineContents::kSampleRadius);
144  Scalar one_px_size = 1.f / scale;
145  Scalar offset = one_px_size / 2.f + one_radius_size;
146  ASSERT_TRUE(status.ok());
147  EXPECT_NEAR(status.value().width, 20.f, kEhCloseEnough);
148  EXPECT_NEAR(status.value().radius, one_px_size * LineContents::kSampleRadius,
150  EXPECT_POINT_NEAR(per_vertex[0].position,
151  Point(100 - one_radius_size, 100 + offset));
152  EXPECT_POINT_NEAR(per_vertex[1].position,
153  Point(200 + one_radius_size, 100 + offset));
154  EXPECT_POINT_NEAR(per_vertex[2].position,
155  Point(100 - one_radius_size, 100 - offset));
156  EXPECT_POINT_NEAR(per_vertex[3].position,
157  Point(200 + one_radius_size, 100 - offset));
158 
159  EXPECT_NEAR(CalculateLine(per_vertex[0], Point(150, 100)), 1.f,
161  // EXPECT_NEAR(CalculateLine(per_vertex[0], Point(150, 100 +
162  // one_px_size)), 1.f,
163  // kEhCloseEnough);
164 }

References impeller::LineContents::CalculatePerVertex(), EXPECT_POINT_NEAR, impeller::kButt, impeller::kEhCloseEnough, impeller::LineContents::kSampleRadius, impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), transform, and impeller::StrokeParameters::width.

◆ TEST() [242/525]

impeller::testing::TEST ( LineContents  ,
Create   
)

Definition at line 37 of file line_contents_unittests.cc.

37  {
38  Scalar width = 5.0f;
39  auto geometry = std::make_unique<LineGeometry>(
40  /*p0=*/Point{0, 0}, //
41  /*p1=*/Point{100, 100}, //
42  StrokeParameters{
43  .width = width,
44  .cap = Cap::kSquare,
45  });
46  std::unique_ptr<LineContents> contents =
47  LineContents::Make(std::move(geometry), Color(1.f, 0.f, 0.f, 1.f));
48  EXPECT_TRUE(contents);
49  Entity entity;
50  std::optional<Rect> coverage = contents->GetCoverage(entity);
51  EXPECT_TRUE(coverage.has_value());
52  if (coverage.has_value()) {
53  Scalar lip = sqrt((width * width) / 2.f);
54  EXPECT_EQ(*coverage,
55  Rect::MakeXYWH(-lip, -lip, 100 + 2 * lip, 100 + 2 * lip));
56  }
57 }

References impeller::Entity::GetCoverage(), impeller::kSquare, impeller::LineContents::Make(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::StrokeParameters::width.

◆ TEST() [243/525]

impeller::testing::TEST ( LineContents  ,
CreateCurveData   
)

Definition at line 102 of file line_contents_unittests.cc.

102  {
103  std::vector<uint8_t> data = LineContents::CreateCurveData(/*width=*/31,
104  /*radius=*/1,
105  /*scale=*/1);
106  EXPECT_EQ(data.size(), 32u);
107  EXPECT_NEAR(data[0] / 255.f, 0.f, kEhCloseEnough);
108  EXPECT_NEAR(data[1] / 255.f, 0.5f, 0.02);
109  EXPECT_NEAR(data[2] / 255.f, 1.f, kEhCloseEnough);
110  EXPECT_NEAR(data[3] / 255.f, 1.f, kEhCloseEnough);
111 }

References impeller::LineContents::CreateCurveData(), data, and impeller::kEhCloseEnough.

◆ TEST() [244/525]

impeller::testing::TEST ( LineContents  ,
CreateCurveDataScaled   
)

Definition at line 113 of file line_contents_unittests.cc.

113  {
114  std::vector<uint8_t> data = LineContents::CreateCurveData(/*width=*/15.5,
115  /*radius=*/1,
116  /*scale=*/2);
117  EXPECT_EQ(data.size(), 32u);
118  EXPECT_NEAR(data[0] / 255.f, 0.f, kEhCloseEnough);
119  EXPECT_NEAR(data[1] / 255.f, 0.5f, 0.02);
120  EXPECT_NEAR(data[2] / 255.f, 1.f, kEhCloseEnough);
121  EXPECT_NEAR(data[3] / 255.f, 1.f, kEhCloseEnough);
122 }

References impeller::LineContents::CreateCurveData(), data, and impeller::kEhCloseEnough.

◆ TEST() [245/525]

impeller::testing::TEST ( MatrixFilterContentsTest  ,
Coverage2x   
)

Definition at line 65 of file matrix_filter_contents_unittests.cc.

65  {
66  MatrixFilterContents contents;
67  contents.SetMatrix(Matrix::MakeScale({2.0, 2.0, 1.0}));
68  FilterInput::Vector inputs = {
69  FilterInput::Make(Rect::MakeXYWH(10, 10, 100, 100))};
70  Entity entity;
71  std::optional<Rect> coverage =
72  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
73 
74  ASSERT_EQ(coverage, Rect::MakeXYWH(20, 20, 200, 200));
75 }

References impeller::MatrixFilterContents::GetFilterCoverage(), impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::MatrixFilterContents::SetMatrix().

◆ TEST() [246/525]

impeller::testing::TEST ( MatrixFilterContentsTest  ,
Coverage2xEffect   
)

Definition at line 77 of file matrix_filter_contents_unittests.cc.

77  {
78  MatrixFilterContents contents;
79  FilterInput::Vector inputs = {
80  FilterInput::Make(Rect::MakeXYWH(10, 10, 100, 100))};
81  Entity entity;
82  std::optional<Rect> coverage = contents.GetFilterCoverage(
83  inputs, entity, /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}));
84 
85  ASSERT_EQ(coverage, Rect::MakeXYWH(10, 10, 100, 100));
86 }

References impeller::MatrixFilterContents::GetFilterCoverage(), impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [247/525]

impeller::testing::TEST ( MatrixFilterContentsTest  ,
CoverageEmpty   
)

Definition at line 45 of file matrix_filter_contents_unittests.cc.

45  {
46  MatrixFilterContents contents;
47  FilterInput::Vector inputs = {};
48  Entity entity;
49  std::optional<Rect> coverage =
50  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
51  ASSERT_FALSE(coverage.has_value());
52 }

References impeller::MatrixFilterContents::GetFilterCoverage().

◆ TEST() [248/525]

impeller::testing::TEST ( MatrixFilterContentsTest  ,
CoverageSimple   
)

Definition at line 54 of file matrix_filter_contents_unittests.cc.

54  {
55  MatrixFilterContents contents;
56  FilterInput::Vector inputs = {
57  FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))};
58  Entity entity;
59  std::optional<Rect> coverage =
60  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
61 
62  ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110));
63 }

References impeller::MatrixFilterContents::GetFilterCoverage(), impeller::FilterInput::Make(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [249/525]

impeller::testing::TEST ( MatrixTest  ,
Equals   
)

Definition at line 28 of file matrix_unittests.cc.

28  {
29  Matrix x;
30  Matrix y = x;
31  EXPECT_TRUE(x.Equals(y));
32 }

References x.

◆ TEST() [250/525]

impeller::testing::TEST ( MatrixTest  ,
GetMaxBasisXYNegativeScale   
)

Definition at line 263 of file matrix_unittests.cc.

263  {
264  Matrix m = Matrix::MakeScale({-2, 1, 1});
265 
266  EXPECT_EQ(m.GetMaxBasisLengthXY(), 2);
267 
268  m = Matrix::MakeScale({1, -3, 1});
269 
270  EXPECT_EQ(m.GetMaxBasisLengthXY(), 3);
271 }

References impeller::Matrix::GetMaxBasisLengthXY(), and impeller::Matrix::MakeScale().

◆ TEST() [251/525]

impeller::testing::TEST ( MatrixTest  ,
GetMaxBasisXYWithLargeAndSmallScalingFactor   
)

Definition at line 274 of file matrix_unittests.cc.

274  {
275  Matrix m = Matrix::MakeScale({2.625e+20, 2.625e+20, 1});
276  EXPECT_NEAR(m.GetMaxBasisLengthXY(), 2.625e+20, 1e+20);
277 
278  m = Matrix::MakeScale({2.625e-20, 2.625e-20, 1});
279  EXPECT_NEAR(m.GetMaxBasisLengthXY(), 2.625e-20, 1e-20);
280 }

References impeller::Matrix::GetMaxBasisLengthXY(), and impeller::Matrix::MakeScale().

◆ TEST() [252/525]

impeller::testing::TEST ( MatrixTest  ,
GetMaxBasisXYWithLargeAndSmallScalingFactorNonScaleTranslate   
)

Definition at line 282 of file matrix_unittests.cc.

282  {
283  Matrix m = Matrix::MakeScale({2.625e+20, 2.625e+20, 1});
284  m.e[0][1] = 2;
285 
286  EXPECT_TRUE(std::isinf(m.GetMaxBasisLengthXY()));
287 }

References impeller::Matrix::e, impeller::Matrix::GetMaxBasisLengthXY(), and impeller::Matrix::MakeScale().

◆ TEST() [253/525]

impeller::testing::TEST ( MatrixTest  ,
HasPerspective   
)

Definition at line 58 of file matrix_unittests.cc.

58  {
59  EXPECT_FALSE(Matrix().HasPerspective());
60 
61  auto test = [](int index, bool expect) {
62  Matrix matrix;
63  EXPECT_FALSE(matrix.HasPerspective());
64  matrix.m[index] = 0.5f;
65  EXPECT_EQ(matrix.HasPerspective(), expect) << "index: " << index;
66  };
67 
68  // clang-format off
69  test( 0, false); test( 1, false); test( 2, false); test( 3, true);
70  test( 4, false); test( 5, false); test( 6, false); test( 7, true);
71  test( 8, false); test( 9, false); test(10, false); test(11, true);
72  test(12, false); test(13, false); test(14, false); test(15, true);
73  // clang-format on
74 }

References impeller::Matrix::HasPerspective(), and impeller::Matrix::m.

◆ TEST() [254/525]

impeller::testing::TEST ( MatrixTest  ,
HasPerspective2D   
)

Definition at line 40 of file matrix_unittests.cc.

40  {
41  EXPECT_FALSE(Matrix().HasPerspective2D());
42 
43  auto test = [](int index, bool expect) {
44  Matrix matrix;
45  EXPECT_FALSE(matrix.HasPerspective2D());
46  matrix.m[index] = 0.5f;
47  EXPECT_EQ(matrix.HasPerspective2D(), expect) << "index: " << index;
48  };
49 
50  // clang-format off
51  test( 0, false); test( 1, false); test( 2, false); test( 3, true);
52  test( 4, false); test( 5, false); test( 6, false); test( 7, true);
53  test( 8, false); test( 9, false); test(10, false); test(11, false);
54  test(12, false); test(13, false); test(14, false); test(15, true);
55  // clang-format on
56 }

References impeller::Matrix::HasPerspective2D(), and impeller::Matrix::m.

◆ TEST() [255/525]

impeller::testing::TEST ( MatrixTest  ,
HasTranslation   
)

Definition at line 76 of file matrix_unittests.cc.

76  {
77  EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).HasTranslation());
78  EXPECT_TRUE(Matrix::MakeTranslation({0, 100, 0}).HasTranslation());
79  EXPECT_TRUE(Matrix::MakeTranslation({100, 0, 0}).HasTranslation());
80  EXPECT_FALSE(Matrix().HasTranslation());
81 }

References impeller::Matrix::MakeTranslation().

◆ TEST() [256/525]

impeller::testing::TEST ( MatrixTest  ,
IsAligned   
)

Definition at line 203 of file matrix_unittests.cc.

203  {
204  EXPECT_TRUE(Matrix().IsAligned());
205  EXPECT_TRUE(Matrix::MakeScale({1.0f, 1.0f, 2.0f}).IsAligned());
206 
207  // Begin Legacy tests transferred over from geometry_unittests.cc
208  {
209  auto m = Matrix::MakeTranslation({1, 2, 3});
210  bool result = m.IsAligned();
211  ASSERT_TRUE(result);
212  }
213 
214  {
215  auto m = Matrix::MakeRotationZ(Degrees{123});
216  bool result = m.IsAligned();
217  ASSERT_FALSE(result);
218  }
219  // End Legacy tests transferred over from geometry_unittests.cc
220 
221  auto test = [](int index, bool expect) {
222  Matrix matrix;
223  EXPECT_TRUE(matrix.IsAligned());
224  matrix.m[index] = 0.5f;
225  EXPECT_EQ(matrix.IsAligned(), expect) << "index: " << index;
226  };
227 
228  // clang-format off
229  test( 0, true); test( 1, false); test( 2, false); test( 3, false);
230  test( 4, false); test( 5, true); test( 6, false); test( 7, false);
231  test( 8, false); test( 9, false); test(10, true); test(11, false);
232  test(12, true); test(13, true); test(14, true); test(15, false);
233  // clang-format on
234 
235  // True for quadrant rotations from -250 to +250 full circles
236  for (int i = -1000; i < 1000; i++) {
237  Degrees d = Degrees(i * 90);
238  Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
239  EXPECT_TRUE(matrix.IsAligned()) << "degrees: " << d.degrees;
240  }
241 
242  // False for half degree rotations from -999.5 to +1000.5 degrees
243  for (int i = -1000; i < 1000; i++) {
244  Degrees d = Degrees(i + 0.5f);
245  Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
246  EXPECT_FALSE(matrix.IsAligned()) << "degrees: " << d.degrees;
247  }
248 }

References impeller::Degrees::degrees, impeller::Matrix::IsAligned(), impeller::Matrix::m, impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [257/525]

impeller::testing::TEST ( MatrixTest  ,
IsAligned2D   
)

Definition at line 170 of file matrix_unittests.cc.

170  {
171  EXPECT_TRUE(Matrix().IsAligned2D());
172  EXPECT_TRUE(Matrix::MakeScale({1.0f, 1.0f, 2.0f}).IsAligned2D());
173 
174  auto test = [](int index, bool expect) {
175  Matrix matrix;
176  EXPECT_TRUE(matrix.IsAligned2D());
177  matrix.m[index] = 0.5f;
178  EXPECT_EQ(matrix.IsAligned2D(), expect) << "index: " << index;
179  };
180 
181  // clang-format off
182  test( 0, true); test( 1, false); test( 2, true); test( 3, false);
183  test( 4, false); test( 5, true); test( 6, true); test( 7, false);
184  test( 8, true); test( 9, true); test(10, true); test(11, true);
185  test(12, true); test(13, true); test(14, true); test(15, false);
186  // clang-format on
187 
188  // True for quadrant rotations from -250 to +250 full circles
189  for (int i = -1000; i < 1000; i++) {
190  Degrees d = Degrees(i * 90);
191  Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
192  EXPECT_TRUE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
193  }
194 
195  // False for half degree rotations from -999.5 to +1000.5 degrees
196  for (int i = -1000; i < 1000; i++) {
197  Degrees d = Degrees(i + 0.5f);
198  Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
199  EXPECT_FALSE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
200  }
201 }

References impeller::Degrees::degrees, impeller::Matrix::IsAligned2D(), impeller::Matrix::m, impeller::Matrix::MakeRotationZ(), and impeller::Matrix::MakeScale().

◆ TEST() [258/525]

impeller::testing::TEST ( MatrixTest  ,
IsFinite   
)

Definition at line 132 of file matrix_unittests.cc.

132  {
133  EXPECT_TRUE(Matrix().IsFinite());
134 
135  EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).IsFinite());
136  EXPECT_TRUE(Matrix::MakeScale({100, 100, 1}).IsFinite());
137 
138  EXPECT_TRUE(Matrix::MakeRotationX(Degrees(30)).IsFinite());
139  EXPECT_TRUE(Matrix::MakeRotationY(Degrees(30)).IsFinite());
140  EXPECT_TRUE(Matrix::MakeRotationZ(Degrees(30)).IsFinite());
141 
142  EXPECT_TRUE(Matrix::MakeScale({0, 1, 1}).IsFinite());
143  EXPECT_TRUE(Matrix::MakeScale({1, 0, 1}).IsFinite());
144  EXPECT_TRUE(Matrix::MakeScale({1, 1, 0}).IsFinite());
145 
146  for (int i = 0; i < 16; i++) {
147  {
148  Matrix matrix;
149  ASSERT_TRUE(matrix.IsFinite());
150  matrix.m[i] = std::numeric_limits<Scalar>::infinity();
151  ASSERT_FALSE(matrix.IsFinite());
152  }
153 
154  {
155  Matrix matrix;
156  ASSERT_TRUE(matrix.IsFinite());
157  matrix.m[i] = -std::numeric_limits<Scalar>::infinity();
158  ASSERT_FALSE(matrix.IsFinite());
159  }
160 
161  {
162  Matrix matrix;
163  ASSERT_TRUE(matrix.IsFinite());
164  matrix.m[i] = -std::numeric_limits<Scalar>::quiet_NaN();
165  ASSERT_FALSE(matrix.IsFinite());
166  }
167  }
168 }

References impeller::Matrix::IsFinite(), impeller::Matrix::m, impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [259/525]

impeller::testing::TEST ( MatrixTest  ,
IsInvertibleGetDeterminant   
)

Definition at line 105 of file matrix_unittests.cc.

105  {
106  EXPECT_TRUE(Matrix().IsInvertible());
107  EXPECT_NE(Matrix().GetDeterminant(), 0.0f);
108 
109  EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).IsInvertible());
110  EXPECT_NE(Matrix::MakeTranslation({100, 100, 0}).GetDeterminant(), 0.0f);
111 
112  EXPECT_TRUE(Matrix::MakeScale({100, 100, 1}).IsInvertible());
113  EXPECT_NE(Matrix::MakeScale({100, 100, 1}).GetDeterminant(), 0.0f);
114 
115  EXPECT_TRUE(Matrix::MakeRotationX(Degrees(30)).IsInvertible());
116  EXPECT_NE(Matrix::MakeRotationX(Degrees(30)).GetDeterminant(), 0.0f);
117 
118  EXPECT_TRUE(Matrix::MakeRotationY(Degrees(30)).IsInvertible());
119  EXPECT_NE(Matrix::MakeRotationY(Degrees(30)).GetDeterminant(), 0.0f);
120 
121  EXPECT_TRUE(Matrix::MakeRotationZ(Degrees(30)).IsInvertible());
122  EXPECT_NE(Matrix::MakeRotationZ(Degrees(30)).GetDeterminant(), 0.0f);
123 
124  EXPECT_FALSE(Matrix::MakeScale({0, 1, 1}).IsInvertible());
125  EXPECT_EQ(Matrix::MakeScale({0, 1, 1}).GetDeterminant(), 0.0f);
126  EXPECT_FALSE(Matrix::MakeScale({1, 0, 1}).IsInvertible());
127  EXPECT_EQ(Matrix::MakeScale({1, 0, 1}).GetDeterminant(), 0.0f);
128  EXPECT_FALSE(Matrix::MakeScale({1, 1, 0}).IsInvertible());
129  EXPECT_EQ(Matrix::MakeScale({1, 1, 0}).GetDeterminant(), 0.0f);
130 }

References impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [260/525]

impeller::testing::TEST ( MatrixTest  ,
IsTranslationOnly   
)

Definition at line 83 of file matrix_unittests.cc.

83  {
84  EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).IsTranslationOnly());
85  EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).IsTranslationScaleOnly());
86  EXPECT_TRUE(Matrix::MakeTranslation({0, 100, 0}).IsTranslationOnly());
87  EXPECT_TRUE(Matrix::MakeTranslation({0, 100, 0}).IsTranslationScaleOnly());
88  EXPECT_TRUE(Matrix::MakeTranslation({100, 0, 0}).IsTranslationOnly());
89  EXPECT_TRUE(Matrix::MakeTranslation({100, 0, 0}).IsTranslationScaleOnly());
90  EXPECT_TRUE(Matrix().IsTranslationOnly());
91  EXPECT_TRUE(Matrix().IsTranslationScaleOnly());
92 }

References impeller::Matrix::MakeTranslation().

◆ TEST() [261/525]

impeller::testing::TEST ( MatrixTest  ,
IsTranslationScaleOnly   
)

Definition at line 94 of file matrix_unittests.cc.

94  {
95  EXPECT_FALSE(Matrix::MakeScale({100, 100, 1}).IsTranslationOnly());
96  EXPECT_TRUE(Matrix::MakeScale({100, 100, 1}).IsTranslationScaleOnly());
97  EXPECT_FALSE(Matrix::MakeScale({1, 100, 1}).IsTranslationOnly());
98  EXPECT_TRUE(Matrix::MakeScale({1, 100, 1}).IsTranslationScaleOnly());
99  EXPECT_FALSE(Matrix::MakeScale({100, 1, 1}).IsTranslationOnly());
100  EXPECT_TRUE(Matrix::MakeScale({100, 1, 1}).IsTranslationScaleOnly());
101  EXPECT_TRUE(Matrix().IsTranslationOnly());
102  EXPECT_TRUE(Matrix().IsTranslationScaleOnly());
103 }

References impeller::Matrix::MakeScale().

◆ TEST() [262/525]

impeller::testing::TEST ( MatrixTest  ,
MakeScaleTranslate   
)

Definition at line 301 of file matrix_unittests.cc.

301  {
302  EXPECT_TRUE(MatrixNear(
303  Matrix::MakeTranslateScale({1, 1, 1.0 / 1024}, {10, 10, 1.0 / 1024}),
304  Matrix::MakeTranslation({10, 10, 1.0 / 1024}) *
305  Matrix::MakeScale({1, 1, 1.0 / 1024})));
306 
307  EXPECT_TRUE(MatrixNear(
308  Matrix::MakeTranslateScale({2, 2, 2}, {10, 10, 0}),
309  Matrix::MakeTranslation({10, 10, 0}) * Matrix::MakeScale({2, 2, 2})));
310 
311  EXPECT_TRUE(MatrixNear(
312  Matrix::MakeTranslateScale({0, 0, 0}, {0, 0, 0}),
313  Matrix::MakeTranslation({0, 0, 0}) * Matrix::MakeScale({0, 0, 0})));
314 }
inline ::testing::AssertionResult MatrixNear(impeller::Matrix a, impeller::Matrix b)

References impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslateScale(), impeller::Matrix::MakeTranslation(), and MatrixNear().

◆ TEST() [263/525]

impeller::testing::TEST ( MatrixTest  ,
MinMaxScales2D   
)

Definition at line 325 of file matrix_unittests.cc.

325  {
326  // The GetScales2D() method is allowed to return the scales in any
327  // order so we need to take special care in verifying the return
328  // value to test them in either order.
329  auto check_pair = [](const Matrix& matrix, Scalar scale1, Scalar scale2) {
330  auto pair = matrix.GetScales2D();
331  EXPECT_TRUE(pair.has_value())
332  << "Scales: " << scale1 << ", " << scale2 << ", " << matrix;
333  if (ScalarNearlyEqual(pair->first, scale1)) {
334  EXPECT_FLOAT_EQ(pair->first, scale1) << matrix;
335  EXPECT_FLOAT_EQ(pair->second, scale2) << matrix;
336  } else {
337  EXPECT_FLOAT_EQ(pair->first, scale2) << matrix;
338  EXPECT_FLOAT_EQ(pair->second, scale1) << matrix;
339  }
340  };
341 
342  for (int i = 1; i < 10; i++) {
343  Scalar xScale = static_cast<Scalar>(i);
344  for (int j = 1; j < 10; j++) {
345  Scalar yScale = static_cast<Scalar>(j);
346  Scalar minScale = std::min(xScale, yScale);
347  Scalar maxScale = std::max(xScale, yScale);
348 
349  {
350  // Simple scale
351  Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
352  EXPECT_TRUE(matrix.GetMinScale2D().has_value());
353  EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
354  EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
355  EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
356  check_pair(matrix, xScale, yScale);
357  }
358 
359  {
360  // Simple scale with Z scale
361  Matrix matrix = Matrix::MakeScale({xScale, yScale, 5.0f});
362  EXPECT_TRUE(matrix.GetMinScale2D().has_value());
363  EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
364  EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
365  EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
366  check_pair(matrix, xScale, yScale);
367  }
368 
369  {
370  // Simple scale + translate
371  Matrix matrix = Matrix::MakeTranslateScale({xScale, yScale, 1.0f},
372  {10.0f, 15.0f, 2.0f});
373  EXPECT_TRUE(matrix.GetMinScale2D().has_value());
374  EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
375  EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
376  EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
377  check_pair(matrix, xScale, yScale);
378  }
379 
380  for (int d = 45; d < 360; d += 45) {
381  {
382  // Rotation * Scale
383  Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f}) *
384  Matrix::MakeRotationZ(Degrees(d));
385  EXPECT_TRUE(matrix.GetMinScale2D().has_value());
386  EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
387  EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
388  EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
389  check_pair(matrix, xScale, yScale);
390  }
391 
392  {
393  // Scale * Rotation
394  Matrix matrix = Matrix::MakeRotationZ(Degrees(d)) *
395  Matrix::MakeScale({xScale, yScale, 1.0f});
396  EXPECT_TRUE(matrix.GetMinScale2D().has_value());
397  EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
398  EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
399  EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
400  check_pair(matrix, xScale, yScale);
401  }
402  }
403 
404  {
405  // Scale + PerspectiveX (returns invalid values)
406  Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
407  matrix.m[3] = 0.1;
408  EXPECT_FALSE(matrix.GetMinScale2D().has_value());
409  EXPECT_FALSE(matrix.GetMaxScale2D().has_value());
410  EXPECT_FALSE(matrix.GetScales2D().has_value());
411  }
412 
413  {
414  // Scale + PerspectiveY (returns invalid values)
415  Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
416  matrix.m[7] = 0.1;
417  EXPECT_FALSE(matrix.GetMinScale2D().has_value());
418  EXPECT_FALSE(matrix.GetMaxScale2D().has_value());
419  EXPECT_FALSE(matrix.GetScales2D().has_value());
420  }
421 
422  {
423  // Scale + PerspectiveZ (Z ignored; returns actual scales)
424  Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
425  matrix.m[11] = 0.1;
426  EXPECT_TRUE(matrix.GetMinScale2D().has_value());
427  EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
428  EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
429  EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
430  check_pair(matrix, xScale, yScale);
431  }
432 
433  {
434  // Scale + PerspectiveW (returns invalid values)
435  Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
436  matrix.m[15] = 0.1;
437  EXPECT_FALSE(matrix.GetMinScale2D().has_value());
438  EXPECT_FALSE(matrix.GetMaxScale2D().has_value());
439  EXPECT_FALSE(matrix.GetScales2D().has_value());
440  }
441  }
442  }
443 }

References impeller::Matrix::GetMaxScale2D(), impeller::Matrix::GetMinScale2D(), impeller::Matrix::GetScales2D(), impeller::Matrix::m, impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslateScale(), and impeller::ScalarNearlyEqual().

◆ TEST() [264/525]

impeller::testing::TEST ( MatrixTest  ,
Multiply   
)

Definition at line 15 of file matrix_unittests.cc.

15  {
16  Matrix x(0.0, 0.0, 0.0, 1.0, //
17  1.0, 0.0, 0.0, 1.0, //
18  0.0, 1.0, 0.0, 1.0, //
19  1.0, 1.0, 0.0, 1.0);
20  Matrix translate = Matrix::MakeTranslation({10, 20, 0});
21  Matrix result = translate * x;
22  EXPECT_TRUE(MatrixNear(result, Matrix(10.0, 20.0, 0.0, 1.0, //
23  11.0, 20.0, 0.0, 1.0, //
24  10.0, 21.0, 0.0, 1.0, //
25  11.0, 21.0, 0.0, 1.0)));
26 }

References impeller::Matrix::MakeTranslation(), MatrixNear(), and x.

◆ TEST() [265/525]

impeller::testing::TEST ( MatrixTest  ,
NotEquals   
)

Definition at line 34 of file matrix_unittests.cc.

34  {
35  Matrix x;
36  Matrix y = x.Translate({1, 0, 0});
37  EXPECT_FALSE(x.Equals(y));
38 }

References x.

◆ TEST() [266/525]

impeller::testing::TEST ( MatrixTest  ,
To3x3   
)

Definition at line 316 of file matrix_unittests.cc.

316  {
317  Matrix x(1.0, 0.0, 4.0, 0.0, //
318  0.0, 1.0, 4.0, 0.0, //
319  6.0, 5.0, 111.0, 7.0, //
320  0.0, 0.0, 9.0, 1.0);
321 
322  EXPECT_TRUE(MatrixNear(x.To3x3(), Matrix()));
323 }

References MatrixNear(), and x.

◆ TEST() [267/525]

impeller::testing::TEST ( MatrixTest  ,
TransformHomogenous   
)

Definition at line 250 of file matrix_unittests.cc.

250  {
251  Matrix matrix = Matrix::MakeColumn(
252  // clang-format off
253  2.0f, 3.0f, 5.0f, 7.0f,
254  11.0f, 13.0f, 17.0f, 19.0f,
255  23.0f, 29.0f, 31.0f, 37.0f,
256  41.0f, 43.0f, 47.0f, 53.0f
257  // clang-format on
258  );
259  EXPECT_EQ(matrix.TransformHomogenous({1.0f, -1.0f}),
260  Vector3(32.0f, 33.0f, 41.0f));
261 }

References impeller::Matrix::MakeColumn(), and impeller::Matrix::TransformHomogenous().

◆ TEST() [268/525]

impeller::testing::TEST ( MatrixTest  ,
TranslateWithPerspective   
)

Definition at line 289 of file matrix_unittests.cc.

289  {
290  Matrix m = Matrix::MakeRow(1.0, 0.0, 0.0, 10.0, //
291  0.0, 1.0, 0.0, 20.0, //
292  0.0, 0.0, 1.0, 0.0, //
293  0.0, 2.0, 0.0, 30.0);
294  Matrix result = m.Translate({100, 200});
295  EXPECT_TRUE(MatrixNear(result, Matrix::MakeRow(1.0, 0.0, 0.0, 110.0, //
296  0.0, 1.0, 0.0, 220.0, //
297  0.0, 0.0, 1.0, 0.0, //
298  0.0, 2.0, 0.0, 430.0)));
299 }

References impeller::Matrix::MakeRow(), MatrixNear(), and impeller::Matrix::Translate().

◆ TEST() [269/525]

impeller::testing::TEST ( PaintTest  ,
GradientConversionNonMonotonic   
)

Definition at line 121 of file paint_unittests.cc.

121  {
122  std::vector<flutter::DlColor> colors = {
123  flutter::DlColor::kBlue(), flutter::DlColor::kGreen(),
124  flutter::DlColor::kGreen(), flutter::DlColor::kRed()};
125  std::vector<float> stops = {0.0, 0.5, 0.4, 1.0};
126  const auto gradient =
127  flutter::DlColorSource::MakeLinear(flutter::DlPoint(0, 0), //
128  flutter::DlPoint(1.0, 1.0), //
129  4, //
130  colors.data(), //
131  stops.data(), //
132  flutter::DlTileMode::kClamp, //
133  nullptr //
134  );
135 
136  std::vector<Color> converted_colors;
137  std::vector<Scalar> converted_stops;
138  Paint::ConvertStops(gradient->asLinearGradient(), converted_colors,
139  converted_stops);
140 
141  // Value is clamped to 0.5
142  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
143  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
144  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 0.5f));
145  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[3], 1.0f));
146 }

References impeller::Paint::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [270/525]

impeller::testing::TEST ( PaintTest  ,
GradientMissing0   
)

Definition at line 43 of file paint_unittests.cc.

43  {
44  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
45  flutter::DlColor::kRed()};
46  std::vector<float> stops = {0.5, 1.0};
47  const auto gradient =
48  flutter::DlColorSource::MakeLinear(flutter::DlPoint(0, 0), //
49  flutter::DlPoint(1.0, 1.0), //
50  2, //
51  colors.data(), //
52  stops.data(), //
53  flutter::DlTileMode::kClamp, //
54  nullptr //
55  );
56 
57  std::vector<Color> converted_colors;
58  std::vector<Scalar> converted_stops;
59  Paint::ConvertStops(gradient->asLinearGradient(), converted_colors,
60  converted_stops);
61 
62  // First color is inserted as blue.
63  ASSERT_TRUE(ScalarNearlyEqual(converted_colors[0].blue, 1.0f));
64  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
65  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
66  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
67 }

References impeller::Paint::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [271/525]

impeller::testing::TEST ( PaintTest  ,
GradientMissingLastValue   
)

Definition at line 69 of file paint_unittests.cc.

69  {
70  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
71  flutter::DlColor::kRed()};
72  std::vector<float> stops = {0.0, .5};
73  const auto gradient =
74  flutter::DlColorSource::MakeLinear(flutter::DlPoint(0, 0), //
75  flutter::DlPoint(1.0, 1.0), //
76  2, //
77  colors.data(), //
78  stops.data(), //
79  flutter::DlTileMode::kClamp, //
80  nullptr //
81  );
82 
83  std::vector<Color> converted_colors;
84  std::vector<Scalar> converted_stops;
85  Paint::ConvertStops(gradient->asLinearGradient(), converted_colors,
86  converted_stops);
87 
88  // Last color is inserted as red.
89  ASSERT_TRUE(ScalarNearlyEqual(converted_colors[2].red, 1.0f));
90  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
91  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
92  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
93 }

References impeller::Paint::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [272/525]

impeller::testing::TEST ( PaintTest  ,
GradientStopConversion   
)

Definition at line 17 of file paint_unittests.cc.

17  {
18  // Typical gradient.
19  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
20  flutter::DlColor::kRed(),
21  flutter::DlColor::kGreen()};
22  std::vector<float> stops = {0.0, 0.5, 1.0};
23  const auto gradient =
24  flutter::DlColorSource::MakeLinear(flutter::DlPoint(0, 0), //
25  flutter::DlPoint(1.0, 1.0), //
26  3, //
27  colors.data(), //
28  stops.data(), //
29  flutter::DlTileMode::kClamp, //
30  nullptr //
31  );
32 
33  std::vector<Color> converted_colors;
34  std::vector<Scalar> converted_stops;
35  Paint::ConvertStops(gradient->asLinearGradient(), converted_colors,
36  converted_stops);
37 
38  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
39  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
40  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
41 }

References impeller::Paint::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [273/525]

impeller::testing::TEST ( PaintTest  ,
GradientStopGreaterThan1   
)

Definition at line 95 of file paint_unittests.cc.

95  {
96  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
97  flutter::DlColor::kGreen(),
98  flutter::DlColor::kRed()};
99  std::vector<float> stops = {0.0, 100, 1.0};
100  const auto gradient =
101  flutter::DlColorSource::MakeLinear(flutter::DlPoint(0, 0), //
102  flutter::DlPoint(1.0, 1.0), //
103  3, //
104  colors.data(), //
105  stops.data(), //
106  flutter::DlTileMode::kClamp, //
107  nullptr //
108  );
109 
110  std::vector<Color> converted_colors;
111  std::vector<Scalar> converted_stops;
112  Paint::ConvertStops(gradient->asLinearGradient(), converted_colors,
113  converted_stops);
114 
115  // Value is clamped to 1.0
116  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
117  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 1.0f));
118  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
119 }

References impeller::Paint::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [274/525]

impeller::testing::TEST ( PathSourceTest  ,
DashedLinePathSource   
)

Definition at line 157 of file path_source_unittests.cc.

157  {
158  DashedLinePathSource source(Point(10, 10), Point(30, 10), 5, 5);
159 
160  EXPECT_FALSE(source.IsConvex());
161  EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
162  EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
163 
164  ::testing::StrictMock<DlPathReceiverMock> receiver;
165 
166  {
167  ::testing::Sequence sequence;
168 
169  EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
170  EXPECT_CALL(receiver, LineTo(Point(15, 10)));
171  EXPECT_CALL(receiver, MoveTo(Point(20, 10), false));
172  EXPECT_CALL(receiver, LineTo(Point(25, 10)));
173  }
174 
175  source.Dispatch(receiver);
176 }
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:20
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:24

References impeller::DashedLinePathSource::Dispatch(), impeller::DashedLinePathSource::GetBounds(), impeller::DashedLinePathSource::GetFillType(), impeller::DashedLinePathSource::IsConvex(), impeller::kNonZero, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::MoveTo().

◆ TEST() [275/525]

impeller::testing::TEST ( PathSourceTest  ,
DashedLinePathSourceInvalidOffGaps   
)

Definition at line 216 of file path_source_unittests.cc.

216  {
217  DashedLinePathSource source(Point(10, 10), Point(30, 10), 5, -1);
218 
219  EXPECT_FALSE(source.IsConvex());
220  EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
221  EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
222 
223  ::testing::StrictMock<DlPathReceiverMock> receiver;
224 
225  {
226  ::testing::Sequence sequence;
227 
228  EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
229  EXPECT_CALL(receiver, LineTo(Point(30, 10)));
230  }
231 
232  source.Dispatch(receiver);
233 }

References impeller::DashedLinePathSource::Dispatch(), impeller::DashedLinePathSource::GetBounds(), impeller::DashedLinePathSource::GetFillType(), impeller::DashedLinePathSource::IsConvex(), impeller::kNonZero, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::MoveTo().

◆ TEST() [276/525]

impeller::testing::TEST ( PathSourceTest  ,
DashedLinePathSourceInvalidOnRegion   
)

Definition at line 235 of file path_source_unittests.cc.

235  {
236  DashedLinePathSource source(Point(10, 10), Point(30, 10), -1, 5);
237 
238  EXPECT_FALSE(source.IsConvex());
239  EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
240  EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
241 
242  ::testing::StrictMock<DlPathReceiverMock> receiver;
243 
244  {
245  ::testing::Sequence sequence;
246 
247  EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
248  EXPECT_CALL(receiver, LineTo(Point(30, 10)));
249  }
250 
251  source.Dispatch(receiver);
252 }

References impeller::DashedLinePathSource::Dispatch(), impeller::DashedLinePathSource::GetBounds(), impeller::DashedLinePathSource::GetFillType(), impeller::DashedLinePathSource::IsConvex(), impeller::kNonZero, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::MoveTo().

◆ TEST() [277/525]

impeller::testing::TEST ( PathSourceTest  ,
DashedLinePathSourceZeroOffGaps   
)

Definition at line 197 of file path_source_unittests.cc.

197  {
198  DashedLinePathSource source(Point(10, 10), Point(30, 10), 5, 0);
199 
200  EXPECT_FALSE(source.IsConvex());
201  EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
202  EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
203 
204  ::testing::StrictMock<DlPathReceiverMock> receiver;
205 
206  {
207  ::testing::Sequence sequence;
208 
209  EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
210  EXPECT_CALL(receiver, LineTo(Point(30, 10)));
211  }
212 
213  source.Dispatch(receiver);
214 }

References impeller::DashedLinePathSource::Dispatch(), impeller::DashedLinePathSource::GetBounds(), impeller::DashedLinePathSource::GetFillType(), impeller::DashedLinePathSource::IsConvex(), impeller::kNonZero, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::MoveTo().

◆ TEST() [278/525]

impeller::testing::TEST ( PathSourceTest  ,
DiffRoundRectSourceTest   
)

Definition at line 104 of file path_source_unittests.cc.

104  {
105  Rect outer_rect = Rect::MakeLTRB(10, 15, 200, 300);
106  Rect inner_rect = Rect::MakeLTRB(50, 60, 100, 200);
107  ASSERT_TRUE(outer_rect.Contains(inner_rect));
108  RoundingRadii radii = {
109  .top_left = Size(1, 11),
110  .top_right = Size(2, 12),
111  .bottom_left = Size(4, 14),
112  .bottom_right = Size(3, 13),
113  };
114  RoundRect outer_rrect = RoundRect::MakeRectRadii(outer_rect, radii);
115  RoundRect inner_rrect = RoundRect::MakeRectRadii(inner_rect, radii);
116  DiffRoundRectPathSource source(outer_rrect, inner_rrect);
117 
118  EXPECT_FALSE(source.IsConvex());
119  EXPECT_EQ(source.GetFillType(), FillType::kOdd);
120  EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 200, 300));
121 
122  ::testing::StrictMock<DlPathReceiverMock> receiver;
123 
124  {
125  ::testing::Sequence sequence;
126 
127  EXPECT_CALL(receiver, MoveTo(Point(11, 15), true));
128  EXPECT_CALL(receiver, LineTo(Point(198, 15)));
129  EXPECT_CALL(receiver, ConicTo(Point(200, 15), Point(200, 27), kSqrt2Over2));
130  EXPECT_CALL(receiver, LineTo(Point(200, 287)));
131  EXPECT_CALL(receiver,
132  ConicTo(Point(200, 300), Point(197, 300), kSqrt2Over2));
133  EXPECT_CALL(receiver, LineTo(Point(14, 300)));
134  EXPECT_CALL(receiver, ConicTo(Point(10, 300), Point(10, 286), kSqrt2Over2));
135  EXPECT_CALL(receiver, LineTo(Point(10, 26)));
136  EXPECT_CALL(receiver, ConicTo(Point(10, 15), Point(11, 15), kSqrt2Over2));
137  // RetiresOnSaturation keeps identical calls from matching each other
138  EXPECT_CALL(receiver, Close()).RetiresOnSaturation();
139 
140  EXPECT_CALL(receiver, MoveTo(Point(51, 60), true));
141  EXPECT_CALL(receiver, LineTo(Point(98, 60)));
142  EXPECT_CALL(receiver, ConicTo(Point(100, 60), Point(100, 72), kSqrt2Over2));
143  EXPECT_CALL(receiver, LineTo(Point(100, 187)));
144  EXPECT_CALL(receiver,
145  ConicTo(Point(100, 200), Point(97, 200), kSqrt2Over2));
146  EXPECT_CALL(receiver, LineTo(Point(54, 200)));
147  EXPECT_CALL(receiver, ConicTo(Point(50, 200), Point(50, 186), kSqrt2Over2));
148  EXPECT_CALL(receiver, LineTo(Point(50, 71)));
149  EXPECT_CALL(receiver, ConicTo(Point(50, 60), Point(51, 60), kSqrt2Over2));
150  // RetiresOnSaturation keeps identical calls from matching each other
151  EXPECT_CALL(receiver, Close()).RetiresOnSaturation();
152  }
153 
154  source.Dispatch(receiver);
155 }
void Close(PathBuilder *builder)
Definition: tessellator.cc:38

References impeller::Close(), impeller::TRect< T >::Contains(), impeller::DiffRoundRectPathSource::Dispatch(), impeller::DiffRoundRectPathSource::GetBounds(), impeller::DiffRoundRectPathSource::GetFillType(), impeller::DiffRoundRectPathSource::IsConvex(), impeller::kOdd, impeller::kSqrt2Over2, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), impeller::MoveTo(), and impeller::RoundingRadii::top_left.

◆ TEST() [279/525]

impeller::testing::TEST ( PathSourceTest  ,
EllipseSourceTest   
)

Definition at line 45 of file path_source_unittests.cc.

45  {
46  Rect rect = Rect::MakeLTRB(10, 15, 20, 30);
47  EllipsePathSource source(rect);
48 
49  EXPECT_TRUE(source.IsConvex());
50  EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
51  EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 20, 30));
52 
53  ::testing::StrictMock<DlPathReceiverMock> receiver;
54 
55  {
56  ::testing::Sequence sequence;
57 
58  EXPECT_CALL(receiver, MoveTo(Point(10, 22.5), true));
59  EXPECT_CALL(receiver, ConicTo(Point(10, 15), Point(15, 15), kSqrt2Over2));
60  EXPECT_CALL(receiver, ConicTo(Point(20, 15), Point(20, 22.5), kSqrt2Over2));
61  EXPECT_CALL(receiver, ConicTo(Point(20, 30), Point(15, 30), kSqrt2Over2));
62  EXPECT_CALL(receiver, ConicTo(Point(10, 30), Point(10, 22.5), kSqrt2Over2));
63  EXPECT_CALL(receiver, Close());
64  }
65 
66  source.Dispatch(receiver);
67 }

References impeller::Close(), impeller::EllipsePathSource::Dispatch(), impeller::EllipsePathSource::GetBounds(), impeller::EllipsePathSource::GetFillType(), impeller::EllipsePathSource::IsConvex(), impeller::kNonZero, impeller::kSqrt2Over2, impeller::TRect< Scalar >::MakeLTRB(), and impeller::MoveTo().

◆ TEST() [280/525]

impeller::testing::TEST ( PathSourceTest  ,
EmptyDashedLinePathSource   
)

Definition at line 178 of file path_source_unittests.cc.

178  {
179  DashedLinePathSource source(Point(10, 10), Point(10, 10), 5, 5);
180 
181  EXPECT_FALSE(source.IsConvex());
182  EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
183  EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 10, 10));
184 
185  ::testing::StrictMock<DlPathReceiverMock> receiver;
186 
187  {
188  ::testing::Sequence sequence;
189 
190  EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
191  EXPECT_CALL(receiver, LineTo(Point(10, 10)));
192  }
193 
194  source.Dispatch(receiver);
195 }

References impeller::DashedLinePathSource::Dispatch(), impeller::DashedLinePathSource::GetBounds(), impeller::DashedLinePathSource::GetFillType(), impeller::DashedLinePathSource::IsConvex(), impeller::kNonZero, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::MoveTo().

◆ TEST() [281/525]

impeller::testing::TEST ( PathSourceTest  ,
RectSourceTest   
)

Definition at line 21 of file path_source_unittests.cc.

21  {
22  Rect rect = Rect::MakeLTRB(10, 15, 20, 30);
23  RectPathSource source(rect);
24 
25  EXPECT_TRUE(source.IsConvex());
26  EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
27  EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 20, 30));
28 
29  ::testing::StrictMock<DlPathReceiverMock> receiver;
30 
31  {
32  ::testing::Sequence sequence;
33 
34  EXPECT_CALL(receiver, MoveTo(Point(10, 15), true));
35  EXPECT_CALL(receiver, LineTo(Point(20, 15)));
36  EXPECT_CALL(receiver, LineTo(Point(20, 30)));
37  EXPECT_CALL(receiver, LineTo(Point(10, 30)));
38  EXPECT_CALL(receiver, LineTo(Point(10, 15)));
39  EXPECT_CALL(receiver, Close());
40  }
41 
42  source.Dispatch(receiver);
43 }

References impeller::Close(), impeller::RectPathSource::Dispatch(), impeller::RectPathSource::GetBounds(), impeller::RectPathSource::GetFillType(), impeller::RectPathSource::IsConvex(), impeller::kNonZero, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::MoveTo().

◆ TEST() [282/525]

impeller::testing::TEST ( PathSourceTest  ,
RoundRectSourceTest   
)

Definition at line 69 of file path_source_unittests.cc.

69  {
70  Rect rect = Rect::MakeLTRB(10, 15, 40, 60);
71  RoundingRadii radii = {
72  .top_left = Size(1, 11),
73  .top_right = Size(2, 12),
74  .bottom_left = Size(4, 14),
75  .bottom_right = Size(3, 13),
76  };
77  RoundRect round_rect = RoundRect::MakeRectRadii(rect, radii);
78  RoundRectPathSource source(round_rect);
79 
80  EXPECT_TRUE(source.IsConvex());
81  EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
82  EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 40, 60));
83 
84  ::testing::StrictMock<DlPathReceiverMock> receiver;
85 
86  {
87  ::testing::Sequence sequence;
88 
89  EXPECT_CALL(receiver, MoveTo(Point(11, 15), true));
90  EXPECT_CALL(receiver, LineTo(Point(38, 15)));
91  EXPECT_CALL(receiver, ConicTo(Point(40, 15), Point(40, 27), kSqrt2Over2));
92  EXPECT_CALL(receiver, LineTo(Point(40, 47)));
93  EXPECT_CALL(receiver, ConicTo(Point(40, 60), Point(37, 60), kSqrt2Over2));
94  EXPECT_CALL(receiver, LineTo(Point(14, 60)));
95  EXPECT_CALL(receiver, ConicTo(Point(10, 60), Point(10, 46), kSqrt2Over2));
96  EXPECT_CALL(receiver, LineTo(Point(10, 26)));
97  EXPECT_CALL(receiver, ConicTo(Point(10, 15), Point(11, 15), kSqrt2Over2));
98  EXPECT_CALL(receiver, Close());
99  }
100 
101  source.Dispatch(receiver);
102 }

References impeller::Close(), impeller::RoundRectPathSource::Dispatch(), impeller::RoundRectPathSource::GetBounds(), impeller::RoundRectPathSource::GetFillType(), impeller::RoundRectPathSource::IsConvex(), impeller::kNonZero, impeller::kSqrt2Over2, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), impeller::MoveTo(), and impeller::RoundingRadii::top_left.

◆ TEST() [283/525]

impeller::testing::TEST ( PathTessellatorTest  ,
ComplexPath   
)

Definition at line 396 of file path_tessellator_unittests.cc.

396  {
397  PathTessellator::Quad quad{{10, 10}, {20, 20}, {20, 10}};
398  PathTessellator::Conic conic{{20, 10}, {30, 20}, {30, 10}, 2.0f};
399  PathTessellator::Cubic cubic{{30, 10}, {40, 20}, {40, 10}, {42, 15}};
400 
401  flutter::DlPathBuilder builder;
402  builder.MoveTo({0, 0});
403  builder.LineTo({10, 10});
404  builder.QuadraticCurveTo(quad.cp, quad.p2);
405  builder.ConicCurveTo(conic.cp, conic.p2, conic.weight);
406  builder.CubicCurveTo(cubic.cp1, cubic.cp2, cubic.p2);
407  builder.Close();
408  flutter::DlPath path = builder.TakePath();
409 
410  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
411  {
412  ::testing::InSequence sequence;
413 
414  EXPECT_CALL(mock_receiver,
415  BeginContour(Point(0, 0), /*will_be_closed=*/true));
416  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 0), Point(10, 10)));
417  EXPECT_CALL(mock_receiver, RecordQuad(quad.p1, quad.cp, quad.p2));
418  EXPECT_CALL(mock_receiver,
419  RecordConic(conic.p1, conic.cp, conic.p2, conic.weight));
420  EXPECT_CALL(mock_receiver,
421  RecordCubic(cubic.p1, cubic.cp1, cubic.cp2, cubic.p2));
422  EXPECT_CALL(mock_receiver, RecordLine(cubic.p2, Point(0, 0)));
423  EXPECT_CALL(mock_receiver, EndContour(Point(0, 0), /*with_close=*/true));
424  }
425  PathTessellator::PathToFilledSegments(path, mock_receiver);
426 
427  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
428  EXPECT_EQ(points, 25u);
429  EXPECT_EQ(contours, 1u);
430 
431  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
432  {
433  ::testing::InSequence sequence;
434 
435  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
436  EXPECT_CALL(mock_writer, Write(Point(10, 10)));
437  {
438  EXPECT_CALL(mock_writer, Write(quad.Solve(1 / 5.0f)));
439  EXPECT_CALL(mock_writer, Write(quad.Solve(2 / 5.0f)));
440  EXPECT_CALL(mock_writer, Write(quad.Solve(3 / 5.0f)));
441  EXPECT_CALL(mock_writer, Write(quad.Solve(4 / 5.0f)));
442  EXPECT_CALL(mock_writer, Write(quad.p2));
443  }
444  {
445  EXPECT_CALL(mock_writer, Write(conic.Solve(1 / 8.0f)));
446  EXPECT_CALL(mock_writer, Write(conic.Solve(2 / 8.0f)));
447  EXPECT_CALL(mock_writer, Write(conic.Solve(3 / 8.0f)));
448  EXPECT_CALL(mock_writer, Write(conic.Solve(4 / 8.0f)));
449  EXPECT_CALL(mock_writer, Write(conic.Solve(5 / 8.0f)));
450  EXPECT_CALL(mock_writer, Write(conic.Solve(6 / 8.0f)));
451  EXPECT_CALL(mock_writer, Write(conic.Solve(7 / 8.0f)));
452  EXPECT_CALL(mock_writer, Write(conic.p2));
453  }
454  {
455  EXPECT_CALL(mock_writer, Write(cubic.Solve(1 / 9.0f)));
456  EXPECT_CALL(mock_writer, Write(cubic.Solve(2 / 9.0f)));
457  EXPECT_CALL(mock_writer, Write(cubic.Solve(3 / 9.0f)));
458  EXPECT_CALL(mock_writer, Write(cubic.Solve(4 / 9.0f)));
459  EXPECT_CALL(mock_writer, Write(cubic.Solve(5 / 9.0f)));
460  EXPECT_CALL(mock_writer, Write(cubic.Solve(6 / 9.0f)));
461  EXPECT_CALL(mock_writer, Write(cubic.Solve(7 / 9.0f)));
462  EXPECT_CALL(mock_writer, Write(cubic.Solve(8 / 9.0f)));
463  EXPECT_CALL(mock_writer, Write(cubic.p2));
464  }
465  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
466  EXPECT_CALL(mock_writer, EndContour());
467  }
468  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
469 }
std::array< Point, 4 > Quad
Definition: point.h:332
std::vector< Contour > contours

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [284/525]

impeller::testing::TEST ( PathTessellatorTest  ,
ComplexPathTrailingMoveTo   
)

Definition at line 471 of file path_tessellator_unittests.cc.

471  {
472  PathTessellator::Quad quad{{10, 10}, {20, 20}, {20, 10}};
473  PathTessellator::Conic conic{{20, 10}, {30, 20}, {30, 10}, 2.0f};
474  PathTessellator::Cubic cubic{{30, 10}, {40, 20}, {40, 10}, {42, 15}};
475 
476  flutter::DlPathBuilder builder;
477  builder.MoveTo({0, 0});
478  builder.LineTo({10, 10});
479  builder.QuadraticCurveTo(quad.cp, quad.p2);
480  builder.ConicCurveTo(conic.cp, conic.p2, conic.weight);
481  builder.CubicCurveTo(cubic.cp1, cubic.cp2, cubic.p2);
482  builder.Close();
483  builder.MoveTo({500, 100});
484  flutter::DlPath path = builder.TakePath();
485 
486  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
487  {
488  ::testing::InSequence sequence;
489 
490  EXPECT_CALL(mock_receiver,
491  BeginContour(Point(0, 0), /*will_be_closed=*/true));
492  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 0), Point(10, 10)));
493  EXPECT_CALL(mock_receiver, RecordQuad(quad.p1, quad.cp, quad.p2));
494  EXPECT_CALL(mock_receiver,
495  RecordConic(conic.p1, conic.cp, conic.p2, conic.weight));
496  EXPECT_CALL(mock_receiver,
497  RecordCubic(cubic.p1, cubic.cp1, cubic.cp2, cubic.p2));
498  EXPECT_CALL(mock_receiver, RecordLine(cubic.p2, Point(0, 0)));
499  EXPECT_CALL(mock_receiver, EndContour(Point(0, 0), /*with_close=*/true));
500  }
501  PathTessellator::PathToFilledSegments(path, mock_receiver);
502 
503  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
504  EXPECT_EQ(points, 25u);
505  EXPECT_EQ(contours, 1u);
506 
507  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
508  {
509  ::testing::InSequence sequence;
510 
511  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
512  EXPECT_CALL(mock_writer, Write(Point(10, 10)));
513  {
514  EXPECT_CALL(mock_writer, Write(quad.Solve(1 / 5.0f)));
515  EXPECT_CALL(mock_writer, Write(quad.Solve(2 / 5.0f)));
516  EXPECT_CALL(mock_writer, Write(quad.Solve(3 / 5.0f)));
517  EXPECT_CALL(mock_writer, Write(quad.Solve(4 / 5.0f)));
518  EXPECT_CALL(mock_writer, Write(quad.p2));
519  }
520  {
521  EXPECT_CALL(mock_writer, Write(conic.Solve(1 / 8.0f)));
522  EXPECT_CALL(mock_writer, Write(conic.Solve(2 / 8.0f)));
523  EXPECT_CALL(mock_writer, Write(conic.Solve(3 / 8.0f)));
524  EXPECT_CALL(mock_writer, Write(conic.Solve(4 / 8.0f)));
525  EXPECT_CALL(mock_writer, Write(conic.Solve(5 / 8.0f)));
526  EXPECT_CALL(mock_writer, Write(conic.Solve(6 / 8.0f)));
527  EXPECT_CALL(mock_writer, Write(conic.Solve(7 / 8.0f)));
528  EXPECT_CALL(mock_writer, Write(conic.p2));
529  }
530  {
531  EXPECT_CALL(mock_writer, Write(cubic.Solve(1 / 9.0f)));
532  EXPECT_CALL(mock_writer, Write(cubic.Solve(2 / 9.0f)));
533  EXPECT_CALL(mock_writer, Write(cubic.Solve(3 / 9.0f)));
534  EXPECT_CALL(mock_writer, Write(cubic.Solve(4 / 9.0f)));
535  EXPECT_CALL(mock_writer, Write(cubic.Solve(5 / 9.0f)));
536  EXPECT_CALL(mock_writer, Write(cubic.Solve(6 / 9.0f)));
537  EXPECT_CALL(mock_writer, Write(cubic.Solve(7 / 9.0f)));
538  EXPECT_CALL(mock_writer, Write(cubic.Solve(8 / 9.0f)));
539  EXPECT_CALL(mock_writer, Write(cubic.p2));
540  }
541  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
542  EXPECT_CALL(mock_writer, EndContour());
543  }
544  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
545 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [285/525]

impeller::testing::TEST ( PathTessellatorTest  ,
ConicToLineToOptimization   
)

Definition at line 269 of file path_tessellator_unittests.cc.

269  {
270  flutter::DlPathBuilder builder;
271  builder.MoveTo({0, 0});
272  // CP == P1
273  builder.ConicCurveTo({0, 0}, {10, 10}, 2.0f);
274  // CP == P2
275  builder.ConicCurveTo({20, 10}, {20, 10}, 2.0f);
276  // weight == 0
277  builder.ConicCurveTo({20, 0}, {10, 0}, 0.0f);
278  builder.Close();
279  flutter::DlPath path = builder.TakePath();
280 
281  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
282  {
283  ::testing::InSequence sequence;
284 
285  EXPECT_CALL(mock_receiver,
286  BeginContour(Point(0, 0), /*will_be_closed=*/true));
287  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 0), Point(10, 10)));
288  EXPECT_CALL(mock_receiver, RecordLine(Point(10, 10), Point(20, 10)));
289  EXPECT_CALL(mock_receiver, RecordLine(Point(20, 10), Point(10, 0)));
290  EXPECT_CALL(mock_receiver, RecordLine(Point(10, 0), Point(0, 0)));
291  EXPECT_CALL(mock_receiver, EndContour(Point(0, 0), /*with_close=*/true));
292  }
293  PathTessellator::PathToFilledSegments(path, mock_receiver);
294 
295  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
296  EXPECT_EQ(points, 5u);
297  EXPECT_EQ(contours, 1u);
298 
299  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
300  {
301  ::testing::InSequence sequence;
302 
303  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
304  EXPECT_CALL(mock_writer, Write(Point(10, 10)));
305  EXPECT_CALL(mock_writer, Write(Point(20, 10)));
306  EXPECT_CALL(mock_writer, Write(Point(10, 0)));
307  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
308  EXPECT_CALL(mock_writer, EndContour());
309  }
310  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
311 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [286/525]

impeller::testing::TEST ( PathTessellatorTest  ,
ConicToQuadToOptimization   
)

Definition at line 313 of file path_tessellator_unittests.cc.

313  {
314  // The conic below will simplify to this quad
315  PathTessellator::Quad quad{{0, 0}, {10, 0}, {0, 10}};
316 
317  flutter::DlPathBuilder builder;
318  builder.MoveTo(quad.p1);
319  // weight == 1
320  builder.ConicCurveTo(quad.cp, quad.p2, 1.0f);
321  builder.Close();
322  flutter::DlPath path = builder.TakePath();
323 
324  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
325  {
326  ::testing::InSequence sequence;
327 
328  EXPECT_CALL(mock_receiver, BeginContour(quad.p1, /*will_be_closed=*/true));
329  EXPECT_CALL(mock_receiver, RecordQuad(quad.p1, quad.cp, quad.p2));
330  EXPECT_CALL(mock_receiver, RecordLine(quad.p2, quad.p1));
331  EXPECT_CALL(mock_receiver, EndContour(quad.p1, /*with_close=*/true));
332  }
333  PathTessellator::PathToFilledSegments(path, mock_receiver);
334 
335  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
336  EXPECT_EQ(points, 7u);
337  EXPECT_EQ(contours, 1u);
338 
339  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
340  {
341  ::testing::InSequence sequence;
342 
343  EXPECT_CALL(mock_writer, Write(quad.p1));
344  {
345  EXPECT_CALL(mock_writer, Write(quad.Solve(1 / 5.0f)));
346  EXPECT_CALL(mock_writer, Write(quad.Solve(2 / 5.0f)));
347  EXPECT_CALL(mock_writer, Write(quad.Solve(3 / 5.0f)));
348  EXPECT_CALL(mock_writer, Write(quad.Solve(4 / 5.0f)));
349  EXPECT_CALL(mock_writer, Write(quad.p2));
350  }
351  EXPECT_CALL(mock_writer, Write(quad.p1));
352  EXPECT_CALL(mock_writer, EndContour());
353  }
354  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
355 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [287/525]

impeller::testing::TEST ( PathTessellatorTest  ,
DegenerateSegmentsPath   
)

Definition at line 191 of file path_tessellator_unittests.cc.

191  {
192  flutter::DlPathBuilder builder;
193  builder.MoveTo({0, 0});
194  builder.LineTo({0, 0});
195  builder.LineTo({0, 0});
196  builder.QuadraticCurveTo({0, 0}, {0, 0});
197  builder.QuadraticCurveTo({0, 0}, {0, 0});
198  builder.ConicCurveTo({0, 0}, {0, 0}, 12.0f);
199  builder.ConicCurveTo({0, 0}, {0, 0}, 12.0f);
200  builder.CubicCurveTo({0, 0}, {0, 0}, {0, 0});
201  builder.CubicCurveTo({0, 0}, {0, 0}, {0, 0});
202  builder.Close();
203  flutter::DlPath path = builder.TakePath();
204 
205  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
206  {
207  ::testing::InSequence sequence;
208 
209  EXPECT_CALL(mock_receiver,
210  BeginContour(Point(0, 0), /*will_be_closed=*/true));
211  EXPECT_CALL(mock_receiver, EndContour(Point(0, 0), /*with_close=*/true));
212  }
213  PathTessellator::PathToFilledSegments(path, mock_receiver);
214 
215  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
216  EXPECT_EQ(points, 1u);
217  EXPECT_EQ(contours, 1u);
218 
219  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
220  {
221  ::testing::InSequence sequence;
222 
223  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
224  EXPECT_CALL(mock_writer, EndContour());
225  }
226  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
227 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [288/525]

impeller::testing::TEST ( PathTessellatorTest  ,
EmptyPath   
)

Definition at line 42 of file path_tessellator_unittests.cc.

42  {
43  flutter::DlPathBuilder builder;
44  builder.MoveTo({0, 0});
45  flutter::DlPath path = builder.TakePath();
46 
47  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
48  PathTessellator::PathToFilledSegments(path, mock_receiver);
49 
50  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
51  EXPECT_EQ(points, 0u);
52  EXPECT_EQ(contours, 0u);
53 
54  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
55  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
56 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [289/525]

impeller::testing::TEST ( PathTessellatorTest  ,
EmptyPathMultipleMoveTo   
)

Definition at line 58 of file path_tessellator_unittests.cc.

58  {
59  flutter::DlPathBuilder builder;
60  builder.MoveTo({0, 0});
61  builder.MoveTo({10, 10});
62  builder.MoveTo({20, 20});
63  flutter::DlPath path = builder.TakePath();
64 
65  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
66  PathTessellator::PathToFilledSegments(path, mock_receiver);
67 
68  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
69  EXPECT_EQ(points, 0u);
70  EXPECT_EQ(contours, 0u);
71 
72  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
73  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
74 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [290/525]

impeller::testing::TEST ( PathTessellatorTest  ,
LinearConicToPointCount   
)

Definition at line 559 of file path_tessellator_unittests.cc.

559  {
560  flutter::DlPathBuilder builder;
561  builder.MoveTo({316.3, 121.5});
562  builder.ConicCurveTo({316.4, 121.5}, {316.5, 121.5}, 2.0f);
563  builder.Close();
564  auto path = builder.TakePath();
565 
566  auto [points, contours] = PathTessellator::CountFillStorage(path, 2.0f);
567  EXPECT_EQ(points, 3u);
568  EXPECT_EQ(contours, 1u);
569 }

References contours, impeller::PathTessellator::CountFillStorage(), and points.

◆ TEST() [291/525]

impeller::testing::TEST ( PathTessellatorTest  ,
LinearCubicToPointCount   
)

Definition at line 571 of file path_tessellator_unittests.cc.

571  {
572  flutter::DlPathBuilder builder;
573  builder.MoveTo({316.3, 121.5});
574  builder.CubicCurveTo({316.4, 121.5}, {316.5, 121.5}, {316.6, 121.5});
575  builder.Close();
576  auto path = builder.TakePath();
577 
578  auto [points, contours] = PathTessellator::CountFillStorage(path, 2.0f);
579  EXPECT_EQ(points, 3u);
580  EXPECT_EQ(contours, 1u);
581 }

References contours, impeller::PathTessellator::CountFillStorage(), and points.

◆ TEST() [292/525]

impeller::testing::TEST ( PathTessellatorTest  ,
LinearQuadToPointCount   
)

Definition at line 547 of file path_tessellator_unittests.cc.

547  {
548  flutter::DlPathBuilder builder;
549  builder.MoveTo({316.3, 121.5});
550  builder.QuadraticCurveTo({316.4, 121.5}, {316.5, 121.5});
551  builder.Close();
552  auto path = builder.TakePath();
553 
554  auto [points, contours] = PathTessellator::CountFillStorage(path, 2.0f);
555  EXPECT_EQ(points, 3u);
556  EXPECT_EQ(contours, 1u);
557 }

References contours, impeller::PathTessellator::CountFillStorage(), and points.

◆ TEST() [293/525]

impeller::testing::TEST ( PathTessellatorTest  ,
QuadToLineToOptimization   
)

Definition at line 229 of file path_tessellator_unittests.cc.

229  {
230  flutter::DlPathBuilder builder;
231  builder.MoveTo({0, 0});
232  // CP == P1
233  builder.QuadraticCurveTo({0, 0}, {10, 10});
234  // CP == P2
235  builder.QuadraticCurveTo({20, 10}, {20, 10});
236  builder.Close();
237  flutter::DlPath path = builder.TakePath();
238 
239  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
240  {
241  ::testing::InSequence sequence;
242 
243  EXPECT_CALL(mock_receiver,
244  BeginContour(Point(0, 0), /*will_be_closed=*/true));
245  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 0), Point(10, 10)));
246  EXPECT_CALL(mock_receiver, RecordLine(Point(10, 10), Point(20, 10)));
247  EXPECT_CALL(mock_receiver, RecordLine(Point(20, 10), Point(0, 0)));
248  EXPECT_CALL(mock_receiver, EndContour(Point(0, 0), /*with_close=*/true));
249  }
250  PathTessellator::PathToFilledSegments(path, mock_receiver);
251 
252  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
253  EXPECT_EQ(points, 4u);
254  EXPECT_EQ(contours, 1u);
255 
256  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
257  {
258  ::testing::InSequence sequence;
259 
260  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
261  EXPECT_CALL(mock_writer, Write(Point(10, 10)));
262  EXPECT_CALL(mock_writer, Write(Point(20, 10)));
263  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
264  EXPECT_CALL(mock_writer, EndContour());
265  }
266  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
267 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [294/525]

impeller::testing::TEST ( PathTessellatorTest  ,
SimpleClosedPath   
)

Definition at line 76 of file path_tessellator_unittests.cc.

76  {
77  flutter::DlPathBuilder builder;
78  builder.MoveTo({0, 0});
79  builder.LineTo({10, 10});
80  builder.LineTo({0, 20});
81  builder.Close();
82  flutter::DlPath path = builder.TakePath();
83 
84  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
85  {
86  ::testing::InSequence sequence;
87 
88  EXPECT_CALL(mock_receiver,
89  BeginContour(Point(0, 0), /*will_be_closed=*/true));
90  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 0), Point(10, 10)));
91  EXPECT_CALL(mock_receiver, RecordLine(Point(10, 10), Point(0, 20)));
92  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 20), Point(0, 0)));
93  EXPECT_CALL(mock_receiver, EndContour(Point(0, 0), /*with_close=*/true));
94  }
95  PathTessellator::PathToFilledSegments(path, mock_receiver);
96 
97  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
98  EXPECT_EQ(points, 4u);
99  EXPECT_EQ(contours, 1u);
100 
101  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
102  {
103  ::testing::InSequence sequence;
104 
105  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
106  EXPECT_CALL(mock_writer, Write(Point(10, 10)));
107  EXPECT_CALL(mock_writer, Write(Point(0, 20)));
108  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
109  EXPECT_CALL(mock_writer, EndContour());
110  }
111  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
112 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [295/525]

impeller::testing::TEST ( PathTessellatorTest  ,
SimplePathMultipleMoveTo   
)

Definition at line 357 of file path_tessellator_unittests.cc.

357  {
358  flutter::DlPathBuilder builder;
359  builder.MoveTo({500, 100});
360  builder.MoveTo({0, 0});
361  builder.LineTo({10, 10});
362  builder.LineTo({0, 20});
363  builder.Close();
364  flutter::DlPath path = builder.TakePath();
365 
366  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
367  {
368  ::testing::InSequence sequence;
369 
370  EXPECT_CALL(mock_receiver,
371  BeginContour(Point(0, 0), /*will_be_closed=*/true));
372  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 0), Point(10, 10)));
373  EXPECT_CALL(mock_receiver, RecordLine(Point(10, 10), Point(0, 20)));
374  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 20), Point(0, 0)));
375  EXPECT_CALL(mock_receiver, EndContour(Point(0, 0), /*with_close=*/true));
376  }
377  PathTessellator::PathToFilledSegments(path, mock_receiver);
378 
379  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
380  EXPECT_EQ(points, 4u);
381  EXPECT_EQ(contours, 1u);
382 
383  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
384  {
385  ::testing::InSequence sequence;
386 
387  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
388  EXPECT_CALL(mock_writer, Write(Point(10, 10)));
389  EXPECT_CALL(mock_writer, Write(Point(0, 20)));
390  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
391  EXPECT_CALL(mock_writer, EndContour());
392  }
393  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
394 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [296/525]

impeller::testing::TEST ( PathTessellatorTest  ,
SimplePathTrailingMoveTo   
)

Definition at line 152 of file path_tessellator_unittests.cc.

152  {
153  flutter::DlPathBuilder builder;
154  builder.MoveTo({0, 0});
155  builder.LineTo({10, 10});
156  builder.LineTo({0, 20});
157  builder.Close();
158  builder.MoveTo({500, 100});
159  flutter::DlPath path = builder.TakePath();
160 
161  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
162  {
163  ::testing::InSequence sequence;
164 
165  EXPECT_CALL(mock_receiver,
166  BeginContour(Point(0, 0), /*will_be_closed=*/true));
167  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 0), Point(10, 10)));
168  EXPECT_CALL(mock_receiver, RecordLine(Point(10, 10), Point(0, 20)));
169  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 20), Point(0, 0)));
170  EXPECT_CALL(mock_receiver, EndContour(Point(0, 0), /*with_close=*/true));
171  }
172  PathTessellator::PathToFilledSegments(path, mock_receiver);
173 
174  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
175  EXPECT_EQ(points, 4u);
176  EXPECT_EQ(contours, 1u);
177 
178  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
179  {
180  ::testing::InSequence sequence;
181 
182  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
183  EXPECT_CALL(mock_writer, Write(Point(10, 10)));
184  EXPECT_CALL(mock_writer, Write(Point(0, 20)));
185  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
186  EXPECT_CALL(mock_writer, EndContour());
187  }
188  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
189 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [297/525]

impeller::testing::TEST ( PathTessellatorTest  ,
SimpleUnclosedPath   
)

Definition at line 114 of file path_tessellator_unittests.cc.

114  {
115  flutter::DlPathBuilder builder;
116  builder.MoveTo({0, 0});
117  builder.LineTo({10, 10});
118  builder.LineTo({0, 20});
119  // Close not really needed for filled paths
120  flutter::DlPath path = builder.TakePath();
121 
122  ::testing::StrictMock<MockSegmentReceiver> mock_receiver;
123  {
124  ::testing::InSequence sequence;
125 
126  EXPECT_CALL(mock_receiver,
127  BeginContour(Point(0, 0), /*will_be_closed=*/false));
128  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 0), Point(10, 10)));
129  EXPECT_CALL(mock_receiver, RecordLine(Point(10, 10), Point(0, 20)));
130  EXPECT_CALL(mock_receiver, RecordLine(Point(0, 20), Point(0, 0)));
131  EXPECT_CALL(mock_receiver, EndContour(Point(0, 0), /*with_close=*/false));
132  }
133  PathTessellator::PathToFilledSegments(path, mock_receiver);
134 
135  auto [points, contours] = PathTessellator::CountFillStorage(path, 1.0f);
136  EXPECT_EQ(points, 4u);
137  EXPECT_EQ(contours, 1u);
138 
139  ::testing::StrictMock<MockPathVertexWriter> mock_writer;
140  {
141  ::testing::InSequence sequence;
142 
143  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
144  EXPECT_CALL(mock_writer, Write(Point(10, 10)));
145  EXPECT_CALL(mock_writer, Write(Point(0, 20)));
146  EXPECT_CALL(mock_writer, Write(Point(0, 0)));
147  EXPECT_CALL(mock_writer, EndContour());
148  }
149  PathTessellator::PathToFilledVertices(path, mock_writer, 1.0f);
150 }

References contours, impeller::PathTessellator::CountFillStorage(), impeller::PathTessellator::PathToFilledSegments(), impeller::PathTessellator::PathToFilledVertices(), and points.

◆ TEST() [298/525]

impeller::testing::TEST ( PipelineCacheDataVKTest  ,
CanCreateFromDeviceProperties   
)

Definition at line 77 of file pipeline_cache_data_vk_unittests.cc.

77  {
78  vk::PhysicalDeviceProperties props;
79  std::array<uint8_t, 16> uuid{
80  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
81  };
82  props.pipelineCacheUUID = uuid;
83  props.deviceID = 10;
84  props.vendorID = 11;
85  props.driverVersion = 12;
86  PipelineCacheHeaderVK header(props, 99);
87  EXPECT_EQ(uuid.size(), std::size(header.uuid));
88  EXPECT_EQ(props.deviceID, header.device_id);
89  EXPECT_EQ(props.vendorID, header.vendor_id);
90  EXPECT_EQ(props.driverVersion, header.driver_version);
91  for (size_t i = 0; i < uuid.size(); i++) {
92  EXPECT_EQ(header.uuid[i], uuid.at(i));
93  }
94 }

References impeller::PipelineCacheHeaderVK::device_id, impeller::PipelineCacheHeaderVK::driver_version, impeller::PipelineCacheHeaderVK::uuid, and impeller::PipelineCacheHeaderVK::vendor_id.

◆ TEST() [299/525]

impeller::testing::TEST ( PipelineCacheDataVKTest  ,
CanTestHeaderCompatibility   
)

Definition at line 17 of file pipeline_cache_data_vk_unittests.cc.

17  {
18  {
19  PipelineCacheHeaderVK a;
20  PipelineCacheHeaderVK b;
21  EXPECT_EQ(a.abi, sizeof(void*));
22 #ifdef FML_ARCH_CPU_64_BITS
23  EXPECT_EQ(a.abi, 8u);
24 #elif FML_ARCH_CPU_32_BITS
25  EXPECT_EQ(a.abi, 4u);
26 #endif
27  EXPECT_TRUE(a.IsCompatibleWith(b));
28  }
29  // Different data sizes don't matter.
30  {
31  PipelineCacheHeaderVK a;
32  PipelineCacheHeaderVK b;
33  a.data_size = b.data_size + 100u;
34  EXPECT_TRUE(a.IsCompatibleWith(b));
35  }
36  // Magic, Driver, vendor, ABI, and UUID matter.
37  {
38  PipelineCacheHeaderVK a;
39  PipelineCacheHeaderVK b;
40  b.magic = 100;
41  EXPECT_FALSE(a.IsCompatibleWith(b));
42  }
43  {
44  PipelineCacheHeaderVK a;
45  PipelineCacheHeaderVK b;
46  b.driver_version = 100;
47  EXPECT_FALSE(a.IsCompatibleWith(b));
48  }
49  {
50  PipelineCacheHeaderVK a;
51  PipelineCacheHeaderVK b;
52  b.vendor_id = 100;
53  EXPECT_FALSE(a.IsCompatibleWith(b));
54  }
55  {
56  PipelineCacheHeaderVK a;
57  PipelineCacheHeaderVK b;
58  b.device_id = 100;
59  EXPECT_FALSE(a.IsCompatibleWith(b));
60  }
61  {
62  PipelineCacheHeaderVK a;
63  PipelineCacheHeaderVK b;
64  b.abi = a.abi / 2u;
65  EXPECT_FALSE(a.IsCompatibleWith(b));
66  }
67  {
68  PipelineCacheHeaderVK a;
69  PipelineCacheHeaderVK b;
70  for (size_t i = 0; i < VK_UUID_SIZE; i++) {
71  b.uuid[i] = a.uuid[i] + 1;
72  }
73  EXPECT_FALSE(a.IsCompatibleWith(b));
74  }
75 }

References impeller::PipelineCacheHeaderVK::abi, impeller::saturated::b, impeller::PipelineCacheHeaderVK::data_size, impeller::PipelineCacheHeaderVK::IsCompatibleWith(), and impeller::PipelineCacheHeaderVK::uuid.

◆ TEST() [300/525]

impeller::testing::TEST ( PipelineCacheDataVKTest  ,
WritesIncompleteCacheData   
)

Definition at line 96 of file pipeline_cache_data_vk_unittests.cc.

96  {
97  fml::ScopedTemporaryDirectory temp_dir;
98  auto context = MockVulkanContextBuilder().Build();
99  auto cache = context->GetDevice().createPipelineCacheUnique({});
100  const auto& caps = CapabilitiesVK::Cast(*context->GetCapabilities());
101 
102  ASSERT_TRUE(PipelineCacheDataPersist(
103  temp_dir.fd(), caps.GetPhysicalDeviceProperties(), cache.value));
104 
105  std::unique_ptr<fml::FileMapping> mapping = fml::FileMapping::CreateReadOnly(
106  temp_dir.fd(), "flutter.impeller.vkcache");
107  ASSERT_TRUE(mapping);
108  PipelineCacheHeaderVK header;
109  ASSERT_GE(mapping->GetSize(), sizeof(header));
110  std::memcpy(&header, mapping->GetMapping(), sizeof(header));
111  ASSERT_EQ(mapping->GetSize(), sizeof(header) + header.data_size);
112 }
bool PipelineCacheDataPersist(const fml::UniqueFD &cache_directory, const VkPhysicalDeviceProperties &props, const vk::UniquePipelineCache &cache)
Persist the pipeline cache to a file in the given cache directory. This function performs integrity c...

References impeller::BackendCast< CapabilitiesVK, Capabilities >::Cast(), impeller::PipelineCacheHeaderVK::data_size, and impeller::PipelineCacheDataPersist().

◆ TEST() [301/525]

impeller::testing::TEST ( PipelineDescriptorTest  ,
PrimitiveTypeHashEquality   
)

Definition at line 13 of file pipeline_descriptor_unittests.cc.

13  {
14  PipelineDescriptor descA;
15  PipelineDescriptor descB;
16 
17  ASSERT_TRUE(descA.IsEqual(descB));
18  ASSERT_EQ(descA.GetHash(), descB.GetHash());
19 
20  descA.SetPrimitiveType(PrimitiveType::kTriangleStrip);
21 
22  ASSERT_FALSE(descA.IsEqual(descB));
23  ASSERT_NE(descA.GetHash(), descB.GetHash());
24 }

References impeller::PipelineDescriptor::GetHash(), impeller::PipelineDescriptor::IsEqual(), impeller::kTriangleStrip, and impeller::PipelineDescriptor::SetPrimitiveType().

◆ TEST() [302/525]

impeller::testing::TEST ( PoolTest  ,
Overload   
)

Definition at line 47 of file pool_unittests.cc.

47  {
48  Pool<Foobar> pool(1'000);
49  {
50  std::vector<std::shared_ptr<Foobar>> values;
51  values.reserve(20);
52  for (int i = 0; i < 20; i++) {
53  values.push_back(pool.Grab());
54  }
55  for (const auto& value : values) {
56  value->SetSize(100);
57  pool.Recycle(value);
58  }
59  }
60  EXPECT_EQ(pool.GetSize(), 1'000u);
61 }

References impeller::Pool< T >::GetSize(), impeller::Pool< T >::Grab(), impeller::Pool< T >::Recycle(), and value.

◆ TEST() [303/525]

impeller::testing::TEST ( PoolTest  ,
Simple   
)

Definition at line 33 of file pool_unittests.cc.

33  {
34  Pool<Foobar> pool(1'000);
35  {
36  auto grabbed = pool.Grab();
37  grabbed->SetSize(123);
38  pool.Recycle(grabbed);
39  EXPECT_EQ(pool.GetSize(), 123u);
40  }
41  auto grabbed = pool.Grab();
42  EXPECT_EQ(grabbed->GetSize(), 123u);
43  EXPECT_TRUE(grabbed->GetIsReset());
44  EXPECT_EQ(pool.GetSize(), 0u);
45 }

References impeller::Pool< T >::GetSize(), impeller::Pool< T >::Grab(), and impeller::Pool< T >::Recycle().

◆ TEST() [304/525]

impeller::testing::TEST ( RectTest  ,
ContainsFloatingPoint   
)

Definition at line 1316 of file rect_unittests.cc.

1316  {
1317  auto rect1 =
1318  Rect::MakeXYWH(472.599945f, 440.999969f, 1102.80005f, 654.000061f);
1319  auto rect2 = Rect::MakeXYWH(724.f, 618.f, 600.f, 300.f);
1320  EXPECT_TRUE(rect1.Contains(rect2));
1321 }

References impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [305/525]

impeller::testing::TEST ( RectTest  ,
EmptyIRectDoesNotIntersect   
)

Definition at line 899 of file rect_unittests.cc.

899  {
900  IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
901 
902  auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
903  const std::string& label) {
904  EXPECT_FALSE(IRect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
905  << label << " with Top/Bottom swapped";
906  EXPECT_FALSE(IRect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
907  << label << " with Left/Right swapped";
908  EXPECT_FALSE(IRect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
909  << label << " with all sides swapped";
910  };
911 
912  test(20, 20, 30, 30, "Above and Left");
913  test(70, 20, 80, 30, "Above");
914  test(120, 20, 130, 30, "Above and Right");
915  test(120, 70, 130, 80, "Right");
916  test(120, 120, 130, 130, "Below and Right");
917  test(70, 120, 80, 130, "Below");
918  test(20, 120, 30, 130, "Below and Left");
919  test(20, 70, 30, 80, "Left");
920 
921  test(70, 70, 80, 80, "Inside");
922 
923  test(40, 70, 60, 80, "Straddling Left");
924  test(70, 40, 80, 60, "Straddling Top");
925  test(90, 70, 110, 80, "Straddling Right");
926  test(70, 90, 80, 110, "Straddling Bottom");
927 }
IRect64 IRect
Definition: rect.h:791

References impeller::saturated::b, and impeller::TRect< T >::MakeLTRB().

◆ TEST() [306/525]

impeller::testing::TEST ( RectTest  ,
EmptyRectDoesNotIntersect   
)

Definition at line 869 of file rect_unittests.cc.

869  {
870  Rect rect = Rect::MakeLTRB(50, 50, 100, 100);
871 
872  auto test = [&rect](Scalar l, Scalar t, Scalar r, Scalar b,
873  const std::string& label) {
874  EXPECT_FALSE(Rect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
875  << label << " with Top/Bottom swapped";
876  EXPECT_FALSE(Rect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
877  << label << " with Left/Right swapped";
878  EXPECT_FALSE(Rect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
879  << label << " with all sides swapped";
880  };
881 
882  test(20, 20, 30, 30, "Above and Left");
883  test(70, 20, 80, 30, "Above");
884  test(120, 20, 130, 30, "Above and Right");
885  test(120, 70, 130, 80, "Right");
886  test(120, 120, 130, 130, "Below and Right");
887  test(70, 120, 80, 130, "Below");
888  test(20, 120, 30, 130, "Below and Left");
889  test(20, 70, 30, 80, "Left");
890 
891  test(70, 70, 80, 80, "Inside");
892 
893  test(40, 70, 60, 80, "Straddling Left");
894  test(70, 40, 80, 60, "Straddling Top");
895  test(90, 70, 110, 80, "Straddling Right");
896  test(70, 90, 80, 110, "Straddling Bottom");
897 }

References impeller::saturated::b, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [307/525]

impeller::testing::TEST ( RectTest  ,
GetCenter   
)

Definition at line 1239 of file rect_unittests.cc.

1239  {
1240  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1241  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1242  EXPECT_EQ(Rect::MakeMaximum().GetCenter(), Point(0, 0));
1243 
1244  // Note that we expect a Point as the answer from an IRect
1245  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1246  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1247  EXPECT_EQ(IRect::MakeMaximum().GetCenter(), Point(0, 0));
1248 }

References impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< T >::MakeMaximum(), impeller::TRect< T >::MakeXYWH(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [308/525]

impeller::testing::TEST ( RectTest  ,
IRectArea   
)

Definition at line 1025 of file rect_unittests.cc.

1025  {
1026  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
1027  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
1028  EXPECT_EQ(IRect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
1029  EXPECT_EQ(IRect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
1030  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
1031  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
1032 }

References impeller::TRect< T >::MakeXYWH().

◆ TEST() [309/525]

impeller::testing::TEST ( RectTest  ,
IRectContainsInclusiveIPoint   
)

Definition at line 2404 of file rect_unittests.cc.

2404  {
2405  auto check_empty_flips = [](const IRect& rect, const IPoint& point,
2406  const std::string& label) {
2407  ASSERT_FALSE(rect.IsEmpty());
2408 
2409  EXPECT_FALSE(flip_lr(rect).ContainsInclusive(point)) << label;
2410  EXPECT_FALSE(flip_tb(rect).ContainsInclusive(point)) << label;
2411  EXPECT_FALSE(flip_lrtb(rect).ContainsInclusive(point)) << label;
2412  };
2413 
2414  auto test_inside = [&check_empty_flips](const IRect& rect,
2415  const IPoint& point) {
2416  ASSERT_FALSE(rect.IsEmpty()) << rect;
2417 
2418  std::stringstream stream;
2419  stream << rect << " contains " << point;
2420  auto label = stream.str();
2421 
2422  EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2423  check_empty_flips(rect, point, label);
2424  };
2425 
2426  auto test_outside = [&check_empty_flips](const IRect& rect,
2427  const IPoint& point) {
2428  ASSERT_FALSE(rect.IsEmpty()) << rect;
2429 
2430  std::stringstream stream;
2431  stream << rect << " contains " << point;
2432  auto label = stream.str();
2433 
2434  EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2435  check_empty_flips(rect, point, label);
2436  };
2437 
2438  {
2439  // Origin is inclusive
2440  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2441  auto p = IPoint(100, 100);
2442 
2443  test_inside(r, p);
2444  }
2445  {
2446  // Size is inclusive
2447  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2448  auto p = IPoint(200, 200);
2449 
2450  test_inside(r, p);
2451  }
2452  {
2453  // Size + "epsilon" is exclusive
2454  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2455  auto p = IPoint(201, 201);
2456 
2457  test_outside(r, p);
2458  }
2459  {
2460  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2461  auto p = IPoint(99, 99);
2462 
2463  test_outside(r, p);
2464  }
2465  {
2466  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2467  auto p = IPoint(199, 199);
2468 
2469  test_inside(r, p);
2470  }
2471 
2472  {
2473  auto r = IRect::MakeMaximum();
2474  auto p = IPoint(199, 199);
2475 
2476  test_inside(r, p);
2477  }
2478 }
static constexpr R flip_lrtb(R rect)

References impeller::TRect< T >::ContainsInclusive(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::MakeMaximum(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [310/525]

impeller::testing::TEST ( RectTest  ,
IRectContainsIPoint   
)

Definition at line 2242 of file rect_unittests.cc.

2242  {
2243  auto check_empty_flips = [](const IRect& rect, const IPoint& point,
2244  const std::string& label) {
2245  ASSERT_FALSE(rect.IsEmpty());
2246 
2247  EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2248  EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2249  EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2250  };
2251 
2252  auto test_inside = [&check_empty_flips](const IRect& rect,
2253  const IPoint& point) {
2254  ASSERT_FALSE(rect.IsEmpty()) << rect;
2255 
2256  std::stringstream stream;
2257  stream << rect << " contains " << point;
2258  auto label = stream.str();
2259 
2260  EXPECT_TRUE(rect.Contains(point)) << label;
2261  check_empty_flips(rect, point, label);
2262  };
2263 
2264  auto test_outside = [&check_empty_flips](const IRect& rect,
2265  const IPoint& point) {
2266  ASSERT_FALSE(rect.IsEmpty()) << rect;
2267 
2268  std::stringstream stream;
2269  stream << rect << " contains " << point;
2270  auto label = stream.str();
2271 
2272  EXPECT_FALSE(rect.Contains(point)) << label;
2273  check_empty_flips(rect, point, label);
2274  };
2275 
2276  {
2277  // Origin is inclusive
2278  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2279  auto p = IPoint(100, 100);
2280 
2281  test_inside(r, p);
2282  }
2283  {
2284  // Size is exclusive
2285  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2286  auto p = IPoint(200, 200);
2287 
2288  test_outside(r, p);
2289  }
2290  {
2291  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2292  auto p = IPoint(99, 99);
2293 
2294  test_outside(r, p);
2295  }
2296  {
2297  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2298  auto p = IPoint(199, 199);
2299 
2300  test_inside(r, p);
2301  }
2302 
2303  {
2304  auto r = IRect::MakeMaximum();
2305  auto p = IPoint(199, 199);
2306 
2307  test_inside(r, p);
2308  }
2309 }

References impeller::TRect< T >::Contains(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::MakeMaximum(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [311/525]

impeller::testing::TEST ( RectTest  ,
IRectContainsIRect   
)

Definition at line 2595 of file rect_unittests.cc.

2595  {
2596  auto check_empty_flips = [](const IRect& a, const IRect& b,
2597  const std::string& label) {
2598  ASSERT_FALSE(a.IsEmpty());
2599  // test b rects are allowed to have 0 w/h, but not be backwards
2600  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2601 
2602  // unflipped a vs flipped (empty) b yields true
2603  EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2604  EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2605  EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2606 
2607  // flipped (empty) a vs unflipped b yields false
2608  EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2609  EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2610  EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2611 
2612  // flipped (empty) a vs flipped (empty) b yields empty
2613  EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2614  EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2615  EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2616  };
2617 
2618  auto test_inside = [&check_empty_flips](const IRect& a, const IRect& b) {
2619  ASSERT_FALSE(a.IsEmpty()) << a;
2620  // test b rects are allowed to have 0 w/h, but not be backwards
2621  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2622 
2623  std::stringstream stream;
2624  stream << a << " contains " << b;
2625  auto label = stream.str();
2626 
2627  EXPECT_TRUE(a.Contains(b)) << label;
2628  check_empty_flips(a, b, label);
2629  };
2630 
2631  auto test_not_inside = [&check_empty_flips](const IRect& a, const IRect& b) {
2632  ASSERT_FALSE(a.IsEmpty()) << a;
2633  // If b was empty, it would be contained and should not be tested with
2634  // this function - use |test_inside| instead.
2635  ASSERT_FALSE(b.IsEmpty()) << b;
2636 
2637  std::stringstream stream;
2638  stream << a << " contains " << b;
2639  auto label = stream.str();
2640 
2641  EXPECT_FALSE(a.Contains(b)) << label;
2642  check_empty_flips(a, b, label);
2643  };
2644 
2645  {
2646  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2647 
2648  test_inside(a, a);
2649  }
2650  {
2651  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2652  auto b = IRect::MakeXYWH(0, 0, 0, 0);
2653 
2654  test_inside(a, b);
2655  }
2656  {
2657  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2658  auto b = IRect::MakeXYWH(150, 150, 20, 20);
2659 
2660  test_inside(a, b);
2661  }
2662  {
2663  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2664  auto b = IRect::MakeXYWH(150, 150, 100, 100);
2665 
2666  test_not_inside(a, b);
2667  }
2668  {
2669  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2670  auto b = IRect::MakeXYWH(50, 50, 100, 100);
2671 
2672  test_not_inside(a, b);
2673  }
2674  {
2675  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2676  auto b = IRect::MakeXYWH(0, 0, 300, 300);
2677 
2678  test_not_inside(a, b);
2679  }
2680  {
2681  auto a = IRect::MakeMaximum();
2682  auto b = IRect::MakeXYWH(0, 0, 300, 300);
2683 
2684  test_inside(a, b);
2685  }
2686 }

References impeller::saturated::b, impeller::TRect< T >::Contains(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::MakeMaximum(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [312/525]

impeller::testing::TEST ( RectTest  ,
IRectCopy   
)

Definition at line 686 of file rect_unittests.cc.

686  {
687  IRect rect = IRect::MakeLTRB(5, 10, 20, 25);
688  IRect copy = rect;
689 
690  EXPECT_EQ(rect, copy);
691  EXPECT_EQ(copy.GetLeft(), 5);
692  EXPECT_EQ(copy.GetTop(), 10);
693  EXPECT_EQ(copy.GetRight(), 20);
694  EXPECT_EQ(copy.GetBottom(), 25);
695  EXPECT_EQ(copy.GetX(), 5);
696  EXPECT_EQ(copy.GetY(), 10);
697  EXPECT_EQ(copy.GetWidth(), 15);
698  EXPECT_EQ(copy.GetHeight(), 15);
699  EXPECT_FALSE(copy.IsEmpty());
700 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeLTRB().

◆ TEST() [313/525]

impeller::testing::TEST ( RectTest  ,
IRectCutOut   
)

Definition at line 2840 of file rect_unittests.cc.

2840  {
2841  IRect cull_rect = IRect::MakeLTRB(20, 20, 40, 40);
2842 
2843  auto check_empty_flips = [&cull_rect](const IRect& diff_rect,
2844  const std::string& label) {
2845  EXPECT_FALSE(diff_rect.IsEmpty());
2846  EXPECT_FALSE(cull_rect.IsEmpty());
2847 
2848  // unflipped cull_rect vs flipped(empty) diff_rect
2849  // == cull_rect
2850  EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2851  EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2852  EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2853  EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2854  EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2855  EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2856 
2857  // flipped(empty) cull_rect vs flipped(empty) diff_rect
2858  // == empty
2859  EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2860  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2861  EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2862  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2863  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2864  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2865 
2866  // flipped(empty) cull_rect vs unflipped diff_rect
2867  // == empty
2868  EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2869  << label;
2870  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), IRect())
2871  << label;
2872  EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2873  << label;
2874  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), IRect())
2875  << label;
2876  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2877  << label;
2878  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), IRect())
2879  << label;
2880  };
2881 
2882  auto non_reducing = [&cull_rect, &check_empty_flips](
2883  const IRect& diff_rect, const std::string& label) {
2884  EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2885  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2886  check_empty_flips(diff_rect, label);
2887  };
2888 
2889  auto reducing = [&cull_rect, &check_empty_flips](const IRect& diff_rect,
2890  const IRect& result_rect,
2891  const std::string& label) {
2892  EXPECT_TRUE(!result_rect.IsEmpty());
2893  EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2894  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2895  check_empty_flips(diff_rect, label);
2896  };
2897 
2898  auto emptying = [&cull_rect, &check_empty_flips](const IRect& diff_rect,
2899  const std::string& label) {
2900  EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2901  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), IRect()) << label;
2902  check_empty_flips(diff_rect, label);
2903  };
2904 
2905  // Skim the corners and edge
2906  non_reducing(IRect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2907  non_reducing(IRect::MakeLTRB(20, 10, 40, 20), "Above");
2908  non_reducing(IRect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2909  non_reducing(IRect::MakeLTRB(40, 20, 50, 40), "Right");
2910  non_reducing(IRect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2911  non_reducing(IRect::MakeLTRB(20, 40, 40, 50), "Below");
2912  non_reducing(IRect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2913  non_reducing(IRect::MakeLTRB(10, 20, 20, 40), "Left");
2914 
2915  // Overlap corners
2916  non_reducing(IRect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2917  non_reducing(IRect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2918  non_reducing(IRect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2919  non_reducing(IRect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2920 
2921  // Overlap edges, but not across an entire side
2922  non_reducing(IRect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2923  non_reducing(IRect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2924  non_reducing(IRect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2925  non_reducing(IRect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2926  non_reducing(IRect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2927  non_reducing(IRect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2928  non_reducing(IRect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2929  non_reducing(IRect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2930 
2931  // Slice all the way through the middle
2932  non_reducing(IRect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2933  non_reducing(IRect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2934 
2935  // Slice off each edge
2936  reducing(IRect::MakeLTRB(20, 15, 40, 25), //
2937  IRect::MakeLTRB(20, 25, 40, 40), //
2938  "Slice off top");
2939  reducing(IRect::MakeLTRB(35, 20, 45, 40), //
2940  IRect::MakeLTRB(20, 20, 35, 40), //
2941  "Slice off right");
2942  reducing(IRect::MakeLTRB(20, 35, 40, 45), //
2943  IRect::MakeLTRB(20, 20, 40, 35), //
2944  "Slice off bottom");
2945  reducing(IRect::MakeLTRB(15, 20, 25, 40), //
2946  IRect::MakeLTRB(25, 20, 40, 40), //
2947  "Slice off left");
2948 
2949  // cull rect contains diff rect
2950  non_reducing(IRect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2951 
2952  // cull rect equals diff rect
2953  emptying(cull_rect, "Perfectly covering");
2954 
2955  // diff rect contains cull rect
2956  emptying(IRect::MakeLTRB(15, 15, 45, 45), "Smothering");
2957 }

References impeller::TRect< T >::Cutout(), impeller::TRect< T >::CutoutOrEmpty(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeLTRB().

◆ TEST() [314/525]

impeller::testing::TEST ( RectTest  ,
IRectDefaultConstructor   
)

Definition at line 59 of file rect_unittests.cc.

59  {
60  IRect rect = IRect();
61 
62  EXPECT_EQ(rect.GetLeft(), 0);
63  EXPECT_EQ(rect.GetTop(), 0);
64  EXPECT_EQ(rect.GetRight(), 0);
65  EXPECT_EQ(rect.GetBottom(), 0);
66  EXPECT_EQ(rect.GetX(), 0);
67  EXPECT_EQ(rect.GetY(), 0);
68  EXPECT_EQ(rect.GetWidth(), 0);
69  EXPECT_EQ(rect.GetHeight(), 0);
70  EXPECT_TRUE(rect.IsEmpty());
71 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), and impeller::TRect< T >::IsEmpty().

◆ TEST() [315/525]

impeller::testing::TEST ( RectTest  ,
IRectDoesNotIntersectEmpty   
)

Definition at line 839 of file rect_unittests.cc.

839  {
840  IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
841 
842  auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
843  const std::string& label) {
844  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(l, b, r, t)))
845  << label << " with Top/Bottom swapped";
846  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(r, b, l, t)))
847  << label << " with Left/Right swapped";
848  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(r, t, l, b)))
849  << label << " with all sides swapped";
850  };
851 
852  test(20, 20, 30, 30, "Above and Left");
853  test(70, 20, 80, 30, "Above");
854  test(120, 20, 130, 30, "Above and Right");
855  test(120, 70, 130, 80, "Right");
856  test(120, 120, 130, 130, "Below and Right");
857  test(70, 120, 80, 130, "Below");
858  test(20, 120, 30, 130, "Below and Left");
859  test(20, 70, 30, 80, "Left");
860 
861  test(70, 70, 80, 80, "Inside");
862 
863  test(40, 70, 60, 80, "Straddling Left");
864  test(70, 40, 80, 60, "Straddling Top");
865  test(90, 70, 110, 80, "Straddling Right");
866  test(70, 90, 80, 110, "Straddling Bottom");
867 }

References impeller::saturated::b, impeller::TRect< T >::IntersectsWithRect(), and impeller::TRect< T >::MakeLTRB().

◆ TEST() [316/525]

impeller::testing::TEST ( RectTest  ,
IRectEmptyDeclaration   
)

Definition at line 29 of file rect_unittests.cc.

29  {
30  IRect rect;
31 
32  EXPECT_EQ(rect.GetLeft(), 0);
33  EXPECT_EQ(rect.GetTop(), 0);
34  EXPECT_EQ(rect.GetRight(), 0);
35  EXPECT_EQ(rect.GetBottom(), 0);
36  EXPECT_EQ(rect.GetX(), 0);
37  EXPECT_EQ(rect.GetY(), 0);
38  EXPECT_EQ(rect.GetWidth(), 0);
39  EXPECT_EQ(rect.GetHeight(), 0);
40  EXPECT_TRUE(rect.IsEmpty());
41  // EXPECT_TRUE(rect.IsFinite()); // should fail to compile
42 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), and impeller::TRect< T >::IsEmpty().

◆ TEST() [317/525]

impeller::testing::TEST ( RectTest  ,
IRectExpand   
)

Definition at line 1283 of file rect_unittests.cc.

1283  {
1284  auto rect = IRect::MakeLTRB(100, 100, 200, 200);
1285 
1286  // Expand(T amount)
1287  EXPECT_EQ(rect.Expand(10), IRect::MakeLTRB(90, 90, 210, 210));
1288  EXPECT_EQ(rect.Expand(-10), IRect::MakeLTRB(110, 110, 190, 190));
1289 
1290  // Expand(amount, amount)
1291  EXPECT_EQ(rect.Expand(10, 10), IRect::MakeLTRB(90, 90, 210, 210));
1292  EXPECT_EQ(rect.Expand(10, -10), IRect::MakeLTRB(90, 110, 210, 190));
1293  EXPECT_EQ(rect.Expand(-10, 10), IRect::MakeLTRB(110, 90, 190, 210));
1294  EXPECT_EQ(rect.Expand(-10, -10), IRect::MakeLTRB(110, 110, 190, 190));
1295 
1296  // Expand(amount, amount, amount, amount)
1297  EXPECT_EQ(rect.Expand(10, 20, 30, 40), IRect::MakeLTRB(90, 80, 230, 240));
1298  EXPECT_EQ(rect.Expand(-10, 20, 30, 40), IRect::MakeLTRB(110, 80, 230, 240));
1299  EXPECT_EQ(rect.Expand(10, -20, 30, 40), IRect::MakeLTRB(90, 120, 230, 240));
1300  EXPECT_EQ(rect.Expand(10, 20, -30, 40), IRect::MakeLTRB(90, 80, 170, 240));
1301  EXPECT_EQ(rect.Expand(10, 20, 30, -40), IRect::MakeLTRB(90, 80, 230, 160));
1302 
1303  // Expand(IPoint amount)
1304  EXPECT_EQ(rect.Expand(IPoint{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1305  EXPECT_EQ(rect.Expand(IPoint{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1306  EXPECT_EQ(rect.Expand(IPoint{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1307  EXPECT_EQ(rect.Expand(IPoint{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1308 
1309  // Expand(ISize amount)
1310  EXPECT_EQ(rect.Expand(ISize{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1311  EXPECT_EQ(rect.Expand(ISize{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1312  EXPECT_EQ(rect.Expand(ISize{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1313  EXPECT_EQ(rect.Expand(ISize{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1314 }

References impeller::TRect< T >::MakeLTRB().

◆ TEST() [318/525]

impeller::testing::TEST ( RectTest  ,
IRectFromIRect   
)

Definition at line 661 of file rect_unittests.cc.

661  {
662  EXPECT_EQ(IRect(IRect::MakeXYWH(2, 3, 7, 15)), //
663  IRect::MakeXYWH(2, 3, 7, 15));
664  EXPECT_EQ(IRect(IRect::MakeLTRB(2, 3, 7, 15)), //
665  IRect::MakeLTRB(2, 3, 7, 15));
666 }

References impeller::TRect< T >::MakeLTRB(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [319/525]

impeller::testing::TEST ( RectTest  ,
IRectGetNormalizingTransform   
)

Definition at line 1122 of file rect_unittests.cc.

1122  {
1123  {
1124  // Checks for expected matrix values
1125 
1126  auto r = IRect::MakeXYWH(100, 200, 200, 400);
1127 
1128  EXPECT_EQ(r.GetNormalizingTransform(),
1129  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
1130  Matrix::MakeTranslation({-100, -200}));
1131  }
1132 
1133  {
1134  // Checks for expected transform of points relative to the rect
1135 
1136  auto r = IRect::MakeLTRB(300, 500, 400, 700);
1137  auto m = r.GetNormalizingTransform();
1138 
1139  // The 4 corners of the rect => (0, 0) to (1, 1)
1140  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1141  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1142  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1143  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1144 
1145  // The center => (0.5, 0.5)
1146  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1147 
1148  // Outside the 4 corners => (-1, -1) to (2, 2)
1149  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1150  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1151  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1152  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1153  }
1154 
1155  {
1156  // Checks for behavior with empty rects
1157 
1158  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1159 
1160  // Empty for width and/or height == 0
1161  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1162  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1163  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1164 
1165  // Empty for width and/or height < 0
1166  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1167  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1168  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1169  }
1170 }

References impeller::TRect< T >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [320/525]

impeller::testing::TEST ( RectTest  ,
IRectIntersection   
)

Definition at line 1800 of file rect_unittests.cc.

1800  {
1801  auto check_empty_flips = [](const IRect& a, const IRect& b,
1802  const std::string& label) {
1803  ASSERT_FALSE(a.IsEmpty());
1804  // b is allowed to be empty
1805 
1806  // unflipped a vs flipped (empty) b yields a
1807  EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1808  EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1809  EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1810 
1811  // flipped (empty) a vs unflipped b yields b
1812  EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1813  EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1814  EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1815 
1816  // flipped (empty) a vs flipped (empty) b yields empty
1817  EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1818  EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1819  EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1820  };
1821 
1822  auto test_non_empty = [&check_empty_flips](const IRect& a, const IRect& b,
1823  const IRect& result) {
1824  ASSERT_FALSE(a.IsEmpty()) << a;
1825  // b is allowed to be empty
1826 
1827  std::stringstream stream;
1828  stream << a << " union " << b;
1829  auto label = stream.str();
1830 
1831  EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1832  EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1833  EXPECT_EQ(a.Intersection(b), result) << label;
1834  EXPECT_EQ(b.Intersection(a), result) << label;
1835  check_empty_flips(a, b, label);
1836  };
1837 
1838  auto test_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
1839  ASSERT_FALSE(a.IsEmpty()) << a;
1840  // b is allowed to be empty
1841 
1842  std::stringstream stream;
1843  stream << a << " union " << b;
1844  auto label = stream.str();
1845 
1846  EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1847  EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1848  check_empty_flips(a, b, label);
1849  };
1850 
1851  {
1852  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1853  auto b = IRect::MakeXYWH(0, 0, 0, 0);
1854 
1855  test_empty(a, b);
1856  }
1857 
1858  {
1859  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1860  auto b = IRect::MakeXYWH(10, 10, 0, 0);
1861 
1862  test_empty(a, b);
1863  }
1864 
1865  {
1866  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1867  auto b = IRect::MakeXYWH(10, 10, 100, 100);
1868  auto expected = IRect::MakeXYWH(10, 10, 90, 90);
1869 
1870  test_non_empty(a, b, expected);
1871  }
1872 
1873  {
1874  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1875  auto b = IRect::MakeXYWH(100, 100, 100, 100);
1876 
1877  test_empty(a, b);
1878  }
1879 
1880  {
1881  auto a = IRect::MakeMaximum();
1882  auto b = IRect::MakeXYWH(10, 10, 300, 300);
1883 
1884  test_non_empty(a, b, b);
1885  }
1886 
1887  {
1888  auto a = IRect::MakeMaximum();
1889  auto b = IRect::MakeMaximum();
1890 
1891  test_non_empty(a, b, IRect::MakeMaximum());
1892  }
1893 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::Intersection(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::MakeMaximum(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [321/525]

impeller::testing::TEST ( RectTest  ,
IRectIntersectsWithRect   
)

Definition at line 2065 of file rect_unittests.cc.

2065  {
2066  auto check_empty_flips = [](const IRect& a, const IRect& b,
2067  const std::string& label) {
2068  ASSERT_FALSE(a.IsEmpty());
2069  // b is allowed to be empty
2070 
2071  // unflipped a vs flipped (empty) b yields a
2072  EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
2073  EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
2074  EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
2075 
2076  // flipped (empty) a vs unflipped b yields b
2077  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
2078  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
2079  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
2080 
2081  // flipped (empty) a vs flipped (empty) b yields empty
2082  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
2083  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
2084  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
2085  };
2086 
2087  auto test_non_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
2088  ASSERT_FALSE(a.IsEmpty()) << a;
2089  // b is allowed to be empty
2090 
2091  std::stringstream stream;
2092  stream << a << " union " << b;
2093  auto label = stream.str();
2094 
2095  EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
2096  EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
2097  check_empty_flips(a, b, label);
2098  };
2099 
2100  auto test_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
2101  ASSERT_FALSE(a.IsEmpty()) << a;
2102  // b is allowed to be empty
2103 
2104  std::stringstream stream;
2105  stream << a << " union " << b;
2106  auto label = stream.str();
2107 
2108  EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
2109  EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
2110  check_empty_flips(a, b, label);
2111  };
2112 
2113  {
2114  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2115  auto b = IRect::MakeXYWH(0, 0, 0, 0);
2116 
2117  test_empty(a, b);
2118  }
2119 
2120  {
2121  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2122  auto b = IRect::MakeXYWH(10, 10, 0, 0);
2123 
2124  test_empty(a, b);
2125  }
2126 
2127  {
2128  auto a = IRect::MakeXYWH(0, 0, 100, 100);
2129  auto b = IRect::MakeXYWH(10, 10, 100, 100);
2130 
2131  test_non_empty(a, b);
2132  }
2133 
2134  {
2135  auto a = IRect::MakeXYWH(0, 0, 100, 100);
2136  auto b = IRect::MakeXYWH(100, 100, 100, 100);
2137 
2138  test_empty(a, b);
2139  }
2140 
2141  {
2142  auto a = IRect::MakeMaximum();
2143  auto b = IRect::MakeXYWH(10, 10, 100, 100);
2144 
2145  test_non_empty(a, b);
2146  }
2147 
2148  {
2149  auto a = IRect::MakeMaximum();
2150  auto b = IRect::MakeMaximum();
2151 
2152  test_non_empty(a, b);
2153  }
2154 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IntersectsWithRect(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::MakeMaximum(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [322/525]

impeller::testing::TEST ( RectTest  ,
IRectMakeMaximum   
)

Definition at line 638 of file rect_unittests.cc.

638  {
639  IRect rect = IRect::MakeMaximum();
640  auto min = std::numeric_limits<int64_t>::min();
641  auto max = std::numeric_limits<int64_t>::max();
642 
643  EXPECT_EQ(rect.GetLeft(), min);
644  EXPECT_EQ(rect.GetTop(), min);
645  EXPECT_EQ(rect.GetRight(), max);
646  EXPECT_EQ(rect.GetBottom(), max);
647  EXPECT_EQ(rect.GetX(), min);
648  EXPECT_EQ(rect.GetY(), min);
649  EXPECT_EQ(rect.GetWidth(), max);
650  EXPECT_EQ(rect.GetHeight(), max);
651  EXPECT_FALSE(rect.IsEmpty());
652 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeMaximum().

◆ TEST() [323/525]

impeller::testing::TEST ( RectTest  ,
IRectOriginSizeXYWHGetters   
)

Definition at line 728 of file rect_unittests.cc.

728  {
729  {
730  IRect r = IRect::MakeOriginSize({10, 20}, {50, 40});
731  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
732  EXPECT_EQ(r.GetSize(), ISize(50, 40));
733  EXPECT_EQ(r.GetX(), 10);
734  EXPECT_EQ(r.GetY(), 20);
735  EXPECT_EQ(r.GetWidth(), 50);
736  EXPECT_EQ(r.GetHeight(), 40);
737  auto expected_array = std::array<int64_t, 4>{10, 20, 50, 40};
738  EXPECT_EQ(r.GetXYWH(), expected_array);
739  }
740 
741  {
742  IRect r = IRect::MakeLTRB(10, 20, 50, 40);
743  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
744  EXPECT_EQ(r.GetSize(), ISize(40, 20));
745  EXPECT_EQ(r.GetX(), 10);
746  EXPECT_EQ(r.GetY(), 20);
747  EXPECT_EQ(r.GetWidth(), 40);
748  EXPECT_EQ(r.GetHeight(), 20);
749  auto expected_array = std::array<int64_t, 4>{10, 20, 40, 20};
750  EXPECT_EQ(r.GetXYWH(), expected_array);
751  }
752 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetOrigin(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetXYWH(), impeller::TRect< T >::GetY(), impeller::TRect< T >::MakeLTRB(), and impeller::TRect< T >::MakeOriginSize().

◆ TEST() [324/525]

impeller::testing::TEST ( RectTest  ,
IRectOverflowLTRB   
)

Definition at line 523 of file rect_unittests.cc.

523  {
524  auto min = std::numeric_limits<int64_t>::min();
525  auto max = std::numeric_limits<int64_t>::max();
526 
527  // 4 cases
528  // negative l, r near max takes width past max
529  // positive l, r near min takes width below min
530  // negative t, b near max takes width past max
531  // positive t, b near min takes width below min
532 
533  {
534  IRect rect = IRect::MakeLTRB(-10, 10, max - 5, 26);
535 
536  EXPECT_EQ(rect.GetLeft(), -10);
537  EXPECT_EQ(rect.GetTop(), 10);
538  EXPECT_EQ(rect.GetRight(), max - 5);
539  EXPECT_EQ(rect.GetBottom(), 26);
540  EXPECT_EQ(rect.GetX(), -10);
541  EXPECT_EQ(rect.GetY(), 10);
542  EXPECT_EQ(rect.GetWidth(), max);
543  EXPECT_EQ(rect.GetHeight(), 16);
544  EXPECT_FALSE(rect.IsEmpty());
545  }
546 
547  {
548  IRect rect = IRect::MakeLTRB(10, 10, min + 5, 26);
549 
550  EXPECT_EQ(rect.GetLeft(), 10);
551  EXPECT_EQ(rect.GetTop(), 10);
552  EXPECT_EQ(rect.GetRight(), min + 5);
553  EXPECT_EQ(rect.GetBottom(), 26);
554  EXPECT_EQ(rect.GetX(), 10);
555  EXPECT_EQ(rect.GetY(), 10);
556  EXPECT_EQ(rect.GetWidth(), min);
557  EXPECT_EQ(rect.GetHeight(), 16);
558  EXPECT_TRUE(rect.IsEmpty());
559  }
560 
561  {
562  IRect rect = IRect::MakeLTRB(5, -10, 15, max - 5);
563 
564  EXPECT_EQ(rect.GetLeft(), 5);
565  EXPECT_EQ(rect.GetTop(), -10);
566  EXPECT_EQ(rect.GetRight(), 15);
567  EXPECT_EQ(rect.GetBottom(), max - 5);
568  EXPECT_EQ(rect.GetX(), 5);
569  EXPECT_EQ(rect.GetY(), -10);
570  EXPECT_EQ(rect.GetWidth(), 10);
571  EXPECT_EQ(rect.GetHeight(), max);
572  EXPECT_FALSE(rect.IsEmpty());
573  }
574 
575  {
576  IRect rect = IRect::MakeLTRB(5, 10, 15, min + 5);
577 
578  EXPECT_EQ(rect.GetLeft(), 5);
579  EXPECT_EQ(rect.GetTop(), 10);
580  EXPECT_EQ(rect.GetRight(), 15);
581  EXPECT_EQ(rect.GetBottom(), min + 5);
582  EXPECT_EQ(rect.GetX(), 5);
583  EXPECT_EQ(rect.GetY(), 10);
584  EXPECT_EQ(rect.GetWidth(), 10);
585  EXPECT_EQ(rect.GetHeight(), min);
586  EXPECT_TRUE(rect.IsEmpty());
587  }
588 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeLTRB().

◆ TEST() [325/525]

impeller::testing::TEST ( RectTest  ,
IRectOverflowXYWH   
)

Definition at line 317 of file rect_unittests.cc.

317  {
318  auto min = std::numeric_limits<int64_t>::min();
319  auto max = std::numeric_limits<int64_t>::max();
320 
321  // 4 cases
322  // x near max, positive w takes it past max
323  // x near min, negative w takes it below min
324  // y near max, positive h takes it past max
325  // y near min, negative h takes it below min
326 
327  {
328  IRect rect = IRect::MakeXYWH(max - 5, 10, 10, 16);
329 
330  EXPECT_EQ(rect.GetLeft(), max - 5);
331  EXPECT_EQ(rect.GetTop(), 10);
332  EXPECT_EQ(rect.GetRight(), max);
333  EXPECT_EQ(rect.GetBottom(), 26);
334  EXPECT_EQ(rect.GetX(), max - 5);
335  EXPECT_EQ(rect.GetY(), 10);
336  EXPECT_EQ(rect.GetWidth(), 5);
337  EXPECT_EQ(rect.GetHeight(), 16);
338  EXPECT_FALSE(rect.IsEmpty());
339  }
340 
341  {
342  IRect rect = IRect::MakeXYWH(min + 5, 10, -10, 16);
343 
344  EXPECT_EQ(rect.GetLeft(), min + 5);
345  EXPECT_EQ(rect.GetTop(), 10);
346  EXPECT_EQ(rect.GetRight(), min);
347  EXPECT_EQ(rect.GetBottom(), 26);
348  EXPECT_EQ(rect.GetX(), min + 5);
349  EXPECT_EQ(rect.GetY(), 10);
350  EXPECT_EQ(rect.GetWidth(), -5);
351  EXPECT_EQ(rect.GetHeight(), 16);
352  EXPECT_TRUE(rect.IsEmpty());
353  }
354 
355  {
356  IRect rect = IRect::MakeXYWH(5, max - 10, 10, 16);
357 
358  EXPECT_EQ(rect.GetLeft(), 5);
359  EXPECT_EQ(rect.GetTop(), max - 10);
360  EXPECT_EQ(rect.GetRight(), 15);
361  EXPECT_EQ(rect.GetBottom(), max);
362  EXPECT_EQ(rect.GetX(), 5);
363  EXPECT_EQ(rect.GetY(), max - 10);
364  EXPECT_EQ(rect.GetWidth(), 10);
365  EXPECT_EQ(rect.GetHeight(), 10);
366  EXPECT_FALSE(rect.IsEmpty());
367  }
368 
369  {
370  IRect rect = IRect::MakeXYWH(5, min + 10, 10, -16);
371 
372  EXPECT_EQ(rect.GetLeft(), 5);
373  EXPECT_EQ(rect.GetTop(), min + 10);
374  EXPECT_EQ(rect.GetRight(), 15);
375  EXPECT_EQ(rect.GetBottom(), min);
376  EXPECT_EQ(rect.GetX(), 5);
377  EXPECT_EQ(rect.GetY(), min + 10);
378  EXPECT_EQ(rect.GetWidth(), 10);
379  EXPECT_EQ(rect.GetHeight(), -10);
380  EXPECT_TRUE(rect.IsEmpty());
381  }
382 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [326/525]

impeller::testing::TEST ( RectTest  ,
IRectRound   
)

Definition at line 3098 of file rect_unittests.cc.

3098  {
3099  {
3100  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3101  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3102  EXPECT_EQ(IRect::Round(r), ir);
3103  }
3104  {
3105  auto r = Rect::MakeLTRB(-100.4, -200.4, 300.4, 400.4);
3106  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3107  EXPECT_EQ(IRect::Round(r), ir);
3108  }
3109  {
3110  auto r = Rect::MakeLTRB(-100.5, -200.5, 300.5, 400.5);
3111  auto ir = IRect::MakeLTRB(-101, -201, 301, 401);
3112  EXPECT_EQ(IRect::Round(r), ir);
3113  }
3114 }

References impeller::TRect< T >::MakeLTRB(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< T >::Round().

◆ TEST() [327/525]

impeller::testing::TEST ( RectTest  ,
IRectRoundOut   
)

Definition at line 3070 of file rect_unittests.cc.

3070  {
3071  {
3072  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3073  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3074  EXPECT_EQ(IRect::RoundOut(r), ir);
3075  }
3076  {
3077  auto r = Rect::MakeLTRB(-100.1, -200.1, 300.1, 400.1);
3078  auto ir = IRect::MakeLTRB(-101, -201, 301, 401);
3079  EXPECT_EQ(IRect::RoundOut(r), ir);
3080  }
3081 }

References impeller::TRect< T >::MakeLTRB(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< T >::RoundOut().

◆ TEST() [328/525]

impeller::testing::TEST ( RectTest  ,
IRectScale   
)

Definition at line 974 of file rect_unittests.cc.

974  {
975  auto test1 = [](IRect rect, int64_t scale) {
976  IRect expected = IRect::MakeXYWH(rect.GetX() * scale, //
977  rect.GetY() * scale, //
978  rect.GetWidth() * scale, //
979  rect.GetHeight() * scale);
980 
981  EXPECT_EQ(rect.Scale(scale), expected) //
982  << rect << " * " << scale;
983  EXPECT_EQ(rect.Scale(scale, scale), expected) //
984  << rect << " * " << scale;
985  EXPECT_EQ(rect.Scale(IPoint(scale, scale)), expected) //
986  << rect << " * " << scale;
987  EXPECT_EQ(rect.Scale(ISize(scale, scale)), expected) //
988  << rect << " * " << scale;
989  };
990 
991  auto test2 = [&test1](IRect rect, int64_t scale_x, int64_t scale_y) {
992  IRect expected = IRect::MakeXYWH(rect.GetX() * scale_x, //
993  rect.GetY() * scale_y, //
994  rect.GetWidth() * scale_x, //
995  rect.GetHeight() * scale_y);
996 
997  EXPECT_EQ(rect.Scale(scale_x, scale_y), expected) //
998  << rect << " * " << scale_x << ", " << scale_y;
999  EXPECT_EQ(rect.Scale(IPoint(scale_x, scale_y)), expected) //
1000  << rect << " * " << scale_x << ", " << scale_y;
1001  EXPECT_EQ(rect.Scale(ISize(scale_x, scale_y)), expected) //
1002  << rect << " * " << scale_x << ", " << scale_y;
1003 
1004  test1(rect, scale_x);
1005  test1(rect, scale_y);
1006  };
1007 
1008  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, 3);
1009  test2(IRect::MakeLTRB(10, 15, 100, 150), 3, 2);
1010  test2(IRect::MakeLTRB(10, 15, -100, 150), 2, 3);
1011  test2(IRect::MakeLTRB(10, 15, 100, -150), 2, 3);
1012  test2(IRect::MakeLTRB(10, 15, 100, 150), -2, 3);
1013  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, -3);
1014 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::MakeLTRB(), impeller::TRect< T >::MakeXYWH(), and impeller::TRect< T >::Scale().

◆ TEST() [329/525]

impeller::testing::TEST ( RectTest  ,
IRectSimpleLTRB   
)

Definition at line 89 of file rect_unittests.cc.

89  {
90  IRect rect = IRect::MakeLTRB(5, 10, 20, 25);
91 
92  EXPECT_EQ(rect.GetLeft(), 5);
93  EXPECT_EQ(rect.GetTop(), 10);
94  EXPECT_EQ(rect.GetRight(), 20);
95  EXPECT_EQ(rect.GetBottom(), 25);
96  EXPECT_EQ(rect.GetX(), 5);
97  EXPECT_EQ(rect.GetY(), 10);
98  EXPECT_EQ(rect.GetWidth(), 15);
99  EXPECT_EQ(rect.GetHeight(), 15);
100  EXPECT_FALSE(rect.IsEmpty());
101 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeLTRB().

◆ TEST() [330/525]

impeller::testing::TEST ( RectTest  ,
IRectSimpleWH   
)

Definition at line 149 of file rect_unittests.cc.

149  {
150  // Using fractional-power-of-2 friendly values for equality tests
151  IRect rect = IRect::MakeWH(15, 25);
152 
153  EXPECT_EQ(rect.GetLeft(), 0);
154  EXPECT_EQ(rect.GetTop(), 0);
155  EXPECT_EQ(rect.GetRight(), 15);
156  EXPECT_EQ(rect.GetBottom(), 25);
157  EXPECT_EQ(rect.GetX(), 0);
158  EXPECT_EQ(rect.GetY(), 0);
159  EXPECT_EQ(rect.GetWidth(), 15);
160  EXPECT_EQ(rect.GetHeight(), 25);
161  EXPECT_FALSE(rect.IsEmpty());
162 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeWH().

◆ TEST() [331/525]

impeller::testing::TEST ( RectTest  ,
IRectSimpleXYWH   
)

Definition at line 119 of file rect_unittests.cc.

119  {
120  IRect rect = IRect::MakeXYWH(5, 10, 15, 16);
121 
122  EXPECT_EQ(rect.GetLeft(), 5);
123  EXPECT_EQ(rect.GetTop(), 10);
124  EXPECT_EQ(rect.GetRight(), 20);
125  EXPECT_EQ(rect.GetBottom(), 26);
126  EXPECT_EQ(rect.GetX(), 5);
127  EXPECT_EQ(rect.GetY(), 10);
128  EXPECT_EQ(rect.GetWidth(), 15);
129  EXPECT_EQ(rect.GetHeight(), 16);
130  EXPECT_FALSE(rect.IsEmpty());
131 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [332/525]

impeller::testing::TEST ( RectTest  ,
IRectUnion   
)

Definition at line 1497 of file rect_unittests.cc.

1497  {
1498  auto check_empty_flips = [](const IRect& a, const IRect& b,
1499  const std::string& label) {
1500  ASSERT_FALSE(a.IsEmpty());
1501  // b is allowed to be empty
1502 
1503  // unflipped a vs flipped (empty) b yields a
1504  EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1505  EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1506  EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1507 
1508  // flipped (empty) a vs unflipped b yields b
1509  EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1510  EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1511  EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1512 
1513  // flipped (empty) a vs flipped (empty) b yields empty
1514  EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1515  EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1516  EXPECT_TRUE(flip_lrtb(a).Union(flip_lrtb(b)).IsEmpty()) << label;
1517  };
1518 
1519  auto test = [&check_empty_flips](const IRect& a, const IRect& b,
1520  const IRect& result) {
1521  ASSERT_FALSE(a.IsEmpty()) << a;
1522  // b is allowed to be empty
1523 
1524  std::stringstream stream;
1525  stream << a << " union " << b;
1526  auto label = stream.str();
1527 
1528  EXPECT_EQ(a.Union(b), result) << label;
1529  EXPECT_EQ(b.Union(a), result) << label;
1530  check_empty_flips(a, b, label);
1531  };
1532 
1533  {
1534  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1535  auto b = IRect::MakeXYWH(0, 0, 0, 0);
1536  auto expected = IRect::MakeXYWH(100, 100, 100, 100);
1537  test(a, b, expected);
1538  }
1539 
1540  {
1541  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1542  auto b = IRect::MakeXYWH(0, 0, 1, 1);
1543  auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1544  test(a, b, expected);
1545  }
1546 
1547  {
1548  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1549  auto b = IRect::MakeXYWH(10, 10, 1, 1);
1550  auto expected = IRect::MakeXYWH(10, 10, 190, 190);
1551  test(a, b, expected);
1552  }
1553 
1554  {
1555  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1556  auto b = IRect::MakeXYWH(10, 10, 100, 100);
1557  auto expected = IRect::MakeXYWH(0, 0, 110, 110);
1558  test(a, b, expected);
1559  }
1560 
1561  {
1562  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1563  auto b = IRect::MakeXYWH(100, 100, 100, 100);
1564  auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1565  test(a, b, expected);
1566  }
1567 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::MakeXYWH(), and impeller::TRect< T >::Union().

◆ TEST() [333/525]

impeller::testing::TEST ( RectTest  ,
IRectXYWHIsEmpty   
)

Definition at line 1196 of file rect_unittests.cc.

1196  {
1197  // Non-empty
1198  EXPECT_FALSE(IRect::MakeXYWH(1, 2, 10, 7).IsEmpty());
1199 
1200  // Empty both width and height both 0 or negative, in all combinations
1201  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 0).IsEmpty());
1202  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, -1).IsEmpty());
1203  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 0).IsEmpty());
1204  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, -1).IsEmpty());
1205 
1206  // Empty for 0 or negative width or height (but not both at the same time)
1207  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, 0).IsEmpty());
1208  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, -1).IsEmpty());
1209  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 7).IsEmpty());
1210  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 7).IsEmpty());
1211 }

References impeller::TRect< T >::MakeXYWH().

◆ TEST() [334/525]

impeller::testing::TEST ( RectTest  ,
IsSquare   
)

Definition at line 1227 of file rect_unittests.cc.

1227  {
1228  EXPECT_TRUE(Rect::MakeXYWH(10, 30, 20, 20).IsSquare());
1229  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 20, 19).IsSquare());
1230  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 19, 20).IsSquare());
1231  EXPECT_TRUE(Rect::MakeMaximum().IsSquare());
1232 
1233  EXPECT_TRUE(IRect::MakeXYWH(10, 30, 20, 20).IsSquare());
1234  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 20, 19).IsSquare());
1235  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 19, 20).IsSquare());
1236  EXPECT_TRUE(IRect::MakeMaximum().IsSquare());
1237 }

References impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< T >::MakeMaximum(), impeller::TRect< T >::MakeXYWH(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [335/525]

impeller::testing::TEST ( RectTest  ,
MakePointBoundsQuad   
)

Definition at line 1213 of file rect_unittests.cc.

1213  {
1214  Quad quad = {
1215  Point(10, 10),
1216  Point(20, 10),
1217  Point(10, 20),
1218  Point(20, 20),
1219  };
1220  std::optional<Rect> bounds = Rect::MakePointBounds(quad);
1221  EXPECT_TRUE(bounds.has_value());
1222  if (bounds.has_value()) {
1223  EXPECT_TRUE(RectNear(bounds.value(), Rect::MakeLTRB(10, 10, 20, 20)));
1224  }
1225 }
inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b)

References impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakePointBounds(), and RectNear().

◆ TEST() [336/525]

impeller::testing::TEST ( RectTest  ,
OptIRectIntersection   
)

Definition at line 1895 of file rect_unittests.cc.

1895  {
1896  auto a = IRect::MakeLTRB(0, 0, 110, 110);
1897  auto b = IRect::MakeLTRB(100, 100, 200, 200);
1898  auto c = IRect::MakeLTRB(100, 0, 200, 110);
1899 
1900  // NullOpt, NullOpt
1901  EXPECT_FALSE(IRect::Intersection(std::nullopt, std::nullopt).has_value());
1902  EXPECT_EQ(IRect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1903 
1904  auto test1 = [](const IRect& r) {
1905  // Rect, NullOpt
1906  EXPECT_TRUE(IRect::Intersection(r, std::nullopt).has_value());
1907  EXPECT_EQ(IRect::Intersection(r, std::nullopt).value(), r);
1908 
1909  // OptRect, NullOpt
1910  EXPECT_TRUE(
1911  IRect::Intersection(std::optional(r), std::nullopt).has_value());
1912  EXPECT_EQ(IRect::Intersection(std::optional(r), std::nullopt).value(), r);
1913 
1914  // NullOpt, Rect
1915  EXPECT_TRUE(IRect::Intersection(std::nullopt, r).has_value());
1916  EXPECT_EQ(IRect::Intersection(std::nullopt, r).value(), r);
1917 
1918  // NullOpt, OptRect
1919  EXPECT_TRUE(
1920  IRect::Intersection(std::nullopt, std::optional(r)).has_value());
1921  EXPECT_EQ(IRect::Intersection(std::nullopt, std::optional(r)).value(), r);
1922  };
1923 
1924  test1(a);
1925  test1(b);
1926  test1(c);
1927 
1928  auto test2 = [](const IRect& a, const IRect& b, const IRect& i) {
1929  ASSERT_EQ(a.Intersection(b), i);
1930 
1931  // Rect, OptRect
1932  EXPECT_TRUE(IRect::Intersection(a, std::optional(b)).has_value());
1933  EXPECT_EQ(IRect::Intersection(a, std::optional(b)).value(), i);
1934 
1935  // OptRect, Rect
1936  EXPECT_TRUE(IRect::Intersection(std::optional(a), b).has_value());
1937  EXPECT_EQ(IRect::Intersection(std::optional(a), b).value(), i);
1938 
1939  // OptRect, OptRect
1940  EXPECT_TRUE(
1941  IRect::Intersection(std::optional(a), std::optional(b)).has_value());
1942  EXPECT_EQ(IRect::Intersection(std::optional(a), std::optional(b)).value(),
1943  i);
1944  };
1945 
1946  test2(a, b, IRect::MakeLTRB(100, 100, 110, 110));
1947  test2(a, c, IRect::MakeLTRB(100, 0, 110, 110));
1948  test2(b, c, IRect::MakeLTRB(100, 100, 200, 110));
1949 }

References impeller::saturated::b, impeller::TRect< T >::Intersection(), impeller::TRect< T >::MakeLTRB(), and value.

◆ TEST() [337/525]

impeller::testing::TEST ( RectTest  ,
OptIRectUnion   
)

Definition at line 1569 of file rect_unittests.cc.

1569  {
1570  auto a = IRect::MakeLTRB(0, 0, 100, 100);
1571  auto b = IRect::MakeLTRB(100, 100, 200, 200);
1572  auto c = IRect::MakeLTRB(100, 0, 200, 100);
1573 
1574  // NullOpt, NullOpt
1575  EXPECT_FALSE(IRect::Union(std::nullopt, std::nullopt).has_value());
1576  EXPECT_EQ(IRect::Union(std::nullopt, std::nullopt), std::nullopt);
1577 
1578  auto test1 = [](const IRect& r) {
1579  // Rect, NullOpt
1580  EXPECT_EQ(IRect::Union(r, std::nullopt), r);
1581 
1582  // OptRect, NullOpt
1583  EXPECT_TRUE(IRect::Union(std::optional(r), std::nullopt).has_value());
1584  EXPECT_EQ(IRect::Union(std::optional(r), std::nullopt).value(), r);
1585 
1586  // NullOpt, Rect
1587  EXPECT_EQ(IRect::Union(std::nullopt, r), r);
1588 
1589  // NullOpt, OptRect
1590  EXPECT_TRUE(IRect::Union(std::nullopt, std::optional(r)).has_value());
1591  EXPECT_EQ(IRect::Union(std::nullopt, std::optional(r)).value(), r);
1592  };
1593 
1594  test1(a);
1595  test1(b);
1596  test1(c);
1597 
1598  auto test2 = [](const IRect& a, const IRect& b, const IRect& u) {
1599  ASSERT_EQ(a.Union(b), u);
1600 
1601  // Rect, OptRect
1602  EXPECT_EQ(IRect::Union(a, std::optional(b)), u);
1603 
1604  // OptRect, Rect
1605  EXPECT_EQ(IRect::Union(std::optional(a), b), u);
1606 
1607  // OptRect, OptRect
1608  EXPECT_TRUE(IRect::Union(std::optional(a), std::optional(b)).has_value());
1609  EXPECT_EQ(IRect::Union(std::optional(a), std::optional(b)).value(), u);
1610  };
1611 
1612  test2(a, b, IRect::MakeLTRB(0, 0, 200, 200));
1613  test2(a, c, IRect::MakeLTRB(0, 0, 200, 100));
1614  test2(b, c, IRect::MakeLTRB(100, 0, 200, 200));
1615 }

References impeller::saturated::b, impeller::TRect< T >::MakeLTRB(), impeller::TRect< T >::Union(), and value.

◆ TEST() [338/525]

impeller::testing::TEST ( RectTest  ,
OptRectIntersection   
)

Definition at line 1746 of file rect_unittests.cc.

1746  {
1747  auto a = Rect::MakeLTRB(0, 0, 110, 110);
1748  auto b = Rect::MakeLTRB(100, 100, 200, 200);
1749  auto c = Rect::MakeLTRB(100, 0, 200, 110);
1750 
1751  // NullOpt, NullOpt
1752  EXPECT_FALSE(Rect::Intersection(std::nullopt, std::nullopt).has_value());
1753  EXPECT_EQ(Rect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1754 
1755  auto test1 = [](const Rect& r) {
1756  // Rect, NullOpt
1757  EXPECT_TRUE(Rect::Intersection(r, std::nullopt).has_value());
1758  EXPECT_EQ(Rect::Intersection(r, std::nullopt).value(), r);
1759 
1760  // OptRect, NullOpt
1761  EXPECT_TRUE(Rect::Intersection(std::optional(r), std::nullopt).has_value());
1762  EXPECT_EQ(Rect::Intersection(std::optional(r), std::nullopt).value(), r);
1763 
1764  // NullOpt, Rect
1765  EXPECT_TRUE(Rect::Intersection(std::nullopt, r).has_value());
1766  EXPECT_EQ(Rect::Intersection(std::nullopt, r).value(), r);
1767 
1768  // NullOpt, OptRect
1769  EXPECT_TRUE(Rect::Intersection(std::nullopt, std::optional(r)).has_value());
1770  EXPECT_EQ(Rect::Intersection(std::nullopt, std::optional(r)).value(), r);
1771  };
1772 
1773  test1(a);
1774  test1(b);
1775  test1(c);
1776 
1777  auto test2 = [](const Rect& a, const Rect& b, const Rect& i) {
1778  ASSERT_EQ(a.Intersection(b), i);
1779 
1780  // Rect, OptRect
1781  EXPECT_TRUE(Rect::Intersection(a, std::optional(b)).has_value());
1782  EXPECT_EQ(Rect::Intersection(a, std::optional(b)).value(), i);
1783 
1784  // OptRect, Rect
1785  EXPECT_TRUE(Rect::Intersection(std::optional(a), b).has_value());
1786  EXPECT_EQ(Rect::Intersection(std::optional(a), b).value(), i);
1787 
1788  // OptRect, OptRect
1789  EXPECT_TRUE(
1790  Rect::Intersection(std::optional(a), std::optional(b)).has_value());
1791  EXPECT_EQ(Rect::Intersection(std::optional(a), std::optional(b)).value(),
1792  i);
1793  };
1794 
1795  test2(a, b, Rect::MakeLTRB(100, 100, 110, 110));
1796  test2(a, c, Rect::MakeLTRB(100, 0, 110, 110));
1797  test2(b, c, Rect::MakeLTRB(100, 100, 200, 110));
1798 }

References impeller::saturated::b, impeller::TRect< T >::Intersection(), impeller::TRect< Scalar >::Intersection(), impeller::TRect< Scalar >::MakeLTRB(), and value.

◆ TEST() [339/525]

impeller::testing::TEST ( RectTest  ,
OptRectUnion   
)

Definition at line 1449 of file rect_unittests.cc.

1449  {
1450  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1451  auto b = Rect::MakeLTRB(100, 100, 200, 200);
1452  auto c = Rect::MakeLTRB(100, 0, 200, 100);
1453 
1454  // NullOpt, NullOpt
1455  EXPECT_FALSE(Rect::Union(std::nullopt, std::nullopt).has_value());
1456  EXPECT_EQ(Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1457 
1458  auto test1 = [](const Rect& r) {
1459  // Rect, NullOpt
1460  EXPECT_EQ(Rect::Union(r, std::nullopt), r);
1461 
1462  // OptRect, NullOpt
1463  EXPECT_TRUE(Rect::Union(std::optional(r), std::nullopt).has_value());
1464  EXPECT_EQ(Rect::Union(std::optional(r), std::nullopt).value(), r);
1465 
1466  // NullOpt, Rect
1467  EXPECT_EQ(Rect::Union(std::nullopt, r), r);
1468 
1469  // NullOpt, OptRect
1470  EXPECT_TRUE(Rect::Union(std::nullopt, std::optional(r)).has_value());
1471  EXPECT_EQ(Rect::Union(std::nullopt, std::optional(r)).value(), r);
1472  };
1473 
1474  test1(a);
1475  test1(b);
1476  test1(c);
1477 
1478  auto test2 = [](const Rect& a, const Rect& b, const Rect& u) {
1479  ASSERT_EQ(a.Union(b), u);
1480 
1481  // Rect, OptRect
1482  EXPECT_EQ(Rect::Union(a, std::optional(b)), u);
1483 
1484  // OptRect, Rect
1485  EXPECT_EQ(Rect::Union(std::optional(a), b), u);
1486 
1487  // OptRect, OptRect
1488  EXPECT_TRUE(Rect::Union(std::optional(a), std::optional(b)).has_value());
1489  EXPECT_EQ(Rect::Union(std::optional(a), std::optional(b)).value(), u);
1490  };
1491 
1492  test2(a, b, Rect::MakeLTRB(0, 0, 200, 200));
1493  test2(a, c, Rect::MakeLTRB(0, 0, 200, 100));
1494  test2(b, c, Rect::MakeLTRB(100, 0, 200, 200));
1495 }

References impeller::saturated::b, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< T >::Union(), impeller::TRect< Scalar >::Union(), and value.

◆ TEST() [340/525]

impeller::testing::TEST ( RectTest  ,
RectArea   
)

Definition at line 1016 of file rect_unittests.cc.

1016  {
1017  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
1018  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
1019  EXPECT_EQ(Rect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
1020  EXPECT_EQ(Rect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
1021  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
1022  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
1023 }

References impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [341/525]

impeller::testing::TEST ( RectTest  ,
RectContainsInclusivePoint   
)

Definition at line 2311 of file rect_unittests.cc.

2311  {
2312  auto check_nans = [](const Rect& rect, const Point& point,
2313  const std::string& label) {
2314  ASSERT_TRUE(rect.IsFinite()) << label;
2315  ASSERT_TRUE(point.IsFinite()) << label;
2316 
2317  for (int i = 1; i < 16; i++) {
2318  EXPECT_FALSE(swap_nan(rect, i).ContainsInclusive(point))
2319  << label << ", index = " << i;
2320  for (int j = 1; j < 4; j++) {
2321  EXPECT_FALSE(swap_nan(rect, i).ContainsInclusive(swap_nan(point, j)))
2322  << label << ", indices = " << i << ", " << j;
2323  }
2324  }
2325  };
2326 
2327  auto check_empty_flips = [](const Rect& rect, const Point& point,
2328  const std::string& label) {
2329  ASSERT_FALSE(rect.IsEmpty());
2330 
2331  EXPECT_FALSE(flip_lr(rect).ContainsInclusive(point)) << label;
2332  EXPECT_FALSE(flip_tb(rect).ContainsInclusive(point)) << label;
2333  EXPECT_FALSE(flip_lrtb(rect).ContainsInclusive(point)) << label;
2334  };
2335 
2336  auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2337  const Point& point) {
2338  ASSERT_FALSE(rect.IsEmpty()) << rect;
2339 
2340  std::stringstream stream;
2341  stream << rect << " contains " << point;
2342  auto label = stream.str();
2343 
2344  EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2345  check_empty_flips(rect, point, label);
2346  check_nans(rect, point, label);
2347  };
2348 
2349  auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2350  const Point& point) {
2351  ASSERT_FALSE(rect.IsEmpty()) << rect;
2352 
2353  std::stringstream stream;
2354  stream << rect << " contains " << point;
2355  auto label = stream.str();
2356 
2357  EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2358  check_empty_flips(rect, point, label);
2359  check_nans(rect, point, label);
2360  };
2361 
2362  {
2363  // Origin is inclusive
2364  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2365  auto p = Point(100, 100);
2366 
2367  test_inside(r, p);
2368  }
2369  {
2370  // Size is inclusive
2371  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2372  auto p = Point(200, 200);
2373 
2374  test_inside(r, p);
2375  }
2376  {
2377  // Size + epsilon is exclusive
2378  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2379  auto p = Point(200 + kEhCloseEnough, 200 + kEhCloseEnough);
2380 
2381  test_outside(r, p);
2382  }
2383  {
2384  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2385  auto p = Point(99, 99);
2386 
2387  test_outside(r, p);
2388  }
2389  {
2390  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2391  auto p = Point(199, 199);
2392 
2393  test_inside(r, p);
2394  }
2395 
2396  {
2397  auto r = Rect::MakeMaximum();
2398  auto p = Point(199, 199);
2399 
2400  test_inside(r, p);
2401  }
2402 }
static constexpr Point swap_nan(const Point &point, int index)

References impeller::TRect< T >::ContainsInclusive(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::kEhCloseEnough, impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [342/525]

impeller::testing::TEST ( RectTest  ,
RectContainsPoint   
)

Definition at line 2156 of file rect_unittests.cc.

2156  {
2157  auto check_nans = [](const Rect& rect, const Point& point,
2158  const std::string& label) {
2159  ASSERT_TRUE(rect.IsFinite()) << label;
2160  ASSERT_TRUE(point.IsFinite()) << label;
2161 
2162  for (int i = 1; i < 16; i++) {
2163  EXPECT_FALSE(swap_nan(rect, i).Contains(point))
2164  << label << ", index = " << i;
2165  for (int j = 1; j < 4; j++) {
2166  EXPECT_FALSE(swap_nan(rect, i).Contains(swap_nan(point, j)))
2167  << label << ", indices = " << i << ", " << j;
2168  }
2169  }
2170  };
2171 
2172  auto check_empty_flips = [](const Rect& rect, const Point& point,
2173  const std::string& label) {
2174  ASSERT_FALSE(rect.IsEmpty());
2175 
2176  EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2177  EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2178  EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2179  };
2180 
2181  auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2182  const Point& point) {
2183  ASSERT_FALSE(rect.IsEmpty()) << rect;
2184 
2185  std::stringstream stream;
2186  stream << rect << " contains " << point;
2187  auto label = stream.str();
2188 
2189  EXPECT_TRUE(rect.Contains(point)) << label;
2190  check_empty_flips(rect, point, label);
2191  check_nans(rect, point, label);
2192  };
2193 
2194  auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2195  const Point& point) {
2196  ASSERT_FALSE(rect.IsEmpty()) << rect;
2197 
2198  std::stringstream stream;
2199  stream << rect << " contains " << point;
2200  auto label = stream.str();
2201 
2202  EXPECT_FALSE(rect.Contains(point)) << label;
2203  check_empty_flips(rect, point, label);
2204  check_nans(rect, point, label);
2205  };
2206 
2207  {
2208  // Origin is inclusive
2209  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2210  auto p = Point(100, 100);
2211 
2212  test_inside(r, p);
2213  }
2214  {
2215  // Size is exclusive
2216  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2217  auto p = Point(200, 200);
2218 
2219  test_outside(r, p);
2220  }
2221  {
2222  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2223  auto p = Point(99, 99);
2224 
2225  test_outside(r, p);
2226  }
2227  {
2228  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2229  auto p = Point(199, 199);
2230 
2231  test_inside(r, p);
2232  }
2233 
2234  {
2235  auto r = Rect::MakeMaximum();
2236  auto p = Point(199, 199);
2237 
2238  test_inside(r, p);
2239  }
2240 }

References impeller::TRect< T >::Contains(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [343/525]

impeller::testing::TEST ( RectTest  ,
RectContainsRect   
)

Definition at line 2480 of file rect_unittests.cc.

2480  {
2481  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
2482  ASSERT_TRUE(a.IsFinite()) << label;
2483  ASSERT_TRUE(b.IsFinite()) << label;
2484  ASSERT_FALSE(a.IsEmpty());
2485 
2486  for (int i = 1; i < 16; i++) {
2487  // NaN in a produces false
2488  EXPECT_FALSE(swap_nan(a, i).Contains(b)) << label << ", index = " << i;
2489  // NaN in b produces false
2490  EXPECT_TRUE(a.Contains(swap_nan(b, i))) << label << ", index = " << i;
2491  // NaN in both is false
2492  for (int j = 1; j < 16; j++) {
2493  EXPECT_FALSE(swap_nan(a, i).Contains(swap_nan(b, j)))
2494  << label << ", indices = " << i << ", " << j;
2495  }
2496  }
2497  };
2498 
2499  auto check_empty_flips = [](const Rect& a, const Rect& b,
2500  const std::string& label) {
2501  ASSERT_FALSE(a.IsEmpty());
2502  // test b rects are allowed to have 0 w/h, but not be backwards
2503  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2504 
2505  // unflipped a vs flipped (empty) b yields false
2506  EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2507  EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2508  EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2509 
2510  // flipped (empty) a vs unflipped b yields false
2511  EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2512  EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2513  EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2514 
2515  // flipped (empty) a vs flipped (empty) b yields empty
2516  EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2517  EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2518  EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2519  };
2520 
2521  auto test_inside = [&check_nans, &check_empty_flips](const Rect& a,
2522  const Rect& b) {
2523  ASSERT_FALSE(a.IsEmpty()) << a;
2524  // test b rects are allowed to have 0 w/h, but not be backwards
2525  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2526 
2527  std::stringstream stream;
2528  stream << a << " contains " << b;
2529  auto label = stream.str();
2530 
2531  EXPECT_TRUE(a.Contains(b)) << label;
2532  check_empty_flips(a, b, label);
2533  check_nans(a, b, label);
2534  };
2535 
2536  auto test_not_inside = [&check_nans, &check_empty_flips](const Rect& a,
2537  const Rect& b) {
2538  ASSERT_FALSE(a.IsEmpty()) << a;
2539  // If b was empty, it would be contained and should not be tested with
2540  // this function - use |test_inside| instead.
2541  ASSERT_FALSE(b.IsEmpty()) << b;
2542 
2543  std::stringstream stream;
2544  stream << a << " contains " << b;
2545  auto label = stream.str();
2546 
2547  EXPECT_FALSE(a.Contains(b)) << label;
2548  check_empty_flips(a, b, label);
2549  check_nans(a, b, label);
2550  };
2551 
2552  {
2553  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2554 
2555  test_inside(a, a);
2556  }
2557  {
2558  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2559  auto b = Rect::MakeXYWH(0, 0, 0, 0);
2560 
2561  test_inside(a, b);
2562  }
2563  {
2564  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2565  auto b = Rect::MakeXYWH(150, 150, 20, 20);
2566 
2567  test_inside(a, b);
2568  }
2569  {
2570  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2571  auto b = Rect::MakeXYWH(150, 150, 100, 100);
2572 
2573  test_not_inside(a, b);
2574  }
2575  {
2576  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2577  auto b = Rect::MakeXYWH(50, 50, 100, 100);
2578 
2579  test_not_inside(a, b);
2580  }
2581  {
2582  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2583  auto b = Rect::MakeXYWH(0, 0, 300, 300);
2584 
2585  test_not_inside(a, b);
2586  }
2587  {
2588  auto a = Rect::MakeMaximum();
2589  auto b = Rect::MakeXYWH(0, 0, 300, 300);
2590 
2591  test_inside(a, b);
2592  }
2593 }

References impeller::saturated::b, impeller::TRect< T >::Contains(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [344/525]

impeller::testing::TEST ( RectTest  ,
RectCopy   
)

Definition at line 668 of file rect_unittests.cc.

668  {
669  // Using fractional-power-of-2 friendly values for equality tests
670  Rect rect = Rect::MakeLTRB(5.125f, 10.25f, 20.625f, 25.375f);
671  Rect copy = rect;
672 
673  EXPECT_EQ(rect, copy);
674  EXPECT_EQ(copy.GetLeft(), 5.125f);
675  EXPECT_EQ(copy.GetTop(), 10.25f);
676  EXPECT_EQ(copy.GetRight(), 20.625f);
677  EXPECT_EQ(copy.GetBottom(), 25.375f);
678  EXPECT_EQ(copy.GetX(), 5.125f);
679  EXPECT_EQ(copy.GetY(), 10.25f);
680  EXPECT_EQ(copy.GetWidth(), 15.5f);
681  EXPECT_EQ(copy.GetHeight(), 15.125f);
682  EXPECT_FALSE(copy.IsEmpty());
683  EXPECT_TRUE(copy.IsFinite());
684 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [345/525]

impeller::testing::TEST ( RectTest  ,
RectCutOut   
)

Definition at line 2688 of file rect_unittests.cc.

2688  {
2689  Rect cull_rect = Rect::MakeLTRB(20, 20, 40, 40);
2690 
2691  auto check_nans = [&cull_rect](const Rect& diff_rect,
2692  const std::string& label) {
2693  EXPECT_TRUE(cull_rect.IsFinite()) << label;
2694  EXPECT_TRUE(diff_rect.IsFinite()) << label;
2695 
2696  for (int i = 1; i < 16; i++) {
2697  // NaN in cull_rect produces empty
2698  EXPECT_FALSE(swap_nan(cull_rect, i).Cutout(diff_rect).has_value())
2699  << label << ", index " << i;
2700  EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(diff_rect), Rect())
2701  << label << ", index " << i;
2702 
2703  // NaN in diff_rect is nop
2704  EXPECT_TRUE(cull_rect.Cutout(swap_nan(diff_rect, i)).has_value())
2705  << label << ", index " << i;
2706  EXPECT_EQ(cull_rect.CutoutOrEmpty(swap_nan(diff_rect, i)), cull_rect)
2707  << label << ", index " << i;
2708 
2709  for (int j = 1; j < 16; j++) {
2710  // NaN in both is also empty
2711  EXPECT_FALSE(
2712  swap_nan(cull_rect, i).Cutout(swap_nan(diff_rect, j)).has_value())
2713  << label << ", indices " << i << ", " << j;
2714  EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(swap_nan(diff_rect, j)),
2715  Rect())
2716  << label << ", indices " << i << ", " << j;
2717  }
2718  }
2719  };
2720 
2721  auto check_empty_flips = [&cull_rect](const Rect& diff_rect,
2722  const std::string& label) {
2723  EXPECT_FALSE(cull_rect.IsEmpty()) << label;
2724  EXPECT_FALSE(diff_rect.IsEmpty()) << label;
2725 
2726  // unflipped cull_rect vs flipped(empty) diff_rect
2727  // == cull_rect
2728  EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2729  EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2730  EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2731  EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2732  EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2733  EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2734 
2735  // flipped(empty) cull_rect vs unflipped diff_rect
2736  // == empty
2737  EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2738  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2739  EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2740  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2741  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2742  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2743 
2744  // flipped(empty) cull_rect vs flipped(empty) diff_rect
2745  // == empty
2746  EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2747  << label;
2748  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), Rect())
2749  << label;
2750  EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2751  << label;
2752  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), Rect())
2753  << label;
2754  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2755  << label;
2756  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), Rect())
2757  << label;
2758  };
2759 
2760  auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2761  const Rect& diff_rect, const std::string& label) {
2762  EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2763  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2764  check_empty_flips(diff_rect, label);
2765  check_nans(diff_rect, label);
2766  };
2767 
2768  auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2769  const Rect& diff_rect, const Rect& result_rect,
2770  const std::string& label) {
2771  EXPECT_TRUE(!result_rect.IsEmpty());
2772  EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2773  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2774  check_empty_flips(diff_rect, label);
2775  check_nans(diff_rect, label);
2776  };
2777 
2778  auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2779  const Rect& diff_rect, const std::string& label) {
2780  EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2781  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), Rect()) << label;
2782  check_empty_flips(diff_rect, label);
2783  check_nans(diff_rect, label);
2784  };
2785 
2786  // Skim the corners and edge
2787  non_reducing(Rect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2788  non_reducing(Rect::MakeLTRB(20, 10, 40, 20), "Above");
2789  non_reducing(Rect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2790  non_reducing(Rect::MakeLTRB(40, 20, 50, 40), "Right");
2791  non_reducing(Rect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2792  non_reducing(Rect::MakeLTRB(20, 40, 40, 50), "Below");
2793  non_reducing(Rect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2794  non_reducing(Rect::MakeLTRB(10, 20, 20, 40), "Left");
2795 
2796  // Overlap corners
2797  non_reducing(Rect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2798  non_reducing(Rect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2799  non_reducing(Rect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2800  non_reducing(Rect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2801 
2802  // Overlap edges, but not across an entire side
2803  non_reducing(Rect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2804  non_reducing(Rect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2805  non_reducing(Rect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2806  non_reducing(Rect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2807  non_reducing(Rect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2808  non_reducing(Rect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2809  non_reducing(Rect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2810  non_reducing(Rect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2811 
2812  // Slice all the way through the middle
2813  non_reducing(Rect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2814  non_reducing(Rect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2815 
2816  // Slice off each edge
2817  reducing(Rect::MakeLTRB(20, 15, 40, 25), //
2818  Rect::MakeLTRB(20, 25, 40, 40), //
2819  "Slice off top");
2820  reducing(Rect::MakeLTRB(35, 20, 45, 40), //
2821  Rect::MakeLTRB(20, 20, 35, 40), //
2822  "Slice off right");
2823  reducing(Rect::MakeLTRB(20, 35, 40, 45), //
2824  Rect::MakeLTRB(20, 20, 40, 35), //
2825  "Slice off bottom");
2826  reducing(Rect::MakeLTRB(15, 20, 25, 40), //
2827  Rect::MakeLTRB(25, 20, 40, 40), //
2828  "Slice off left");
2829 
2830  // cull rect contains diff rect
2831  non_reducing(Rect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2832 
2833  // cull rect equals diff rect
2834  emptying(cull_rect, "Perfectly covering");
2835 
2836  // diff rect contains cull rect
2837  emptying(Rect::MakeLTRB(15, 15, 45, 45), "Smothering");
2838 }

References impeller::TRect< T >::Cutout(), impeller::TRect< T >::CutoutOrEmpty(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeLTRB(), and swap_nan().

◆ TEST() [346/525]

impeller::testing::TEST ( RectTest  ,
RectDefaultConstructor   
)

Definition at line 44 of file rect_unittests.cc.

44  {
45  Rect rect = Rect();
46 
47  EXPECT_EQ(rect.GetLeft(), 0.0f);
48  EXPECT_EQ(rect.GetTop(), 0.0f);
49  EXPECT_EQ(rect.GetRight(), 0.0f);
50  EXPECT_EQ(rect.GetBottom(), 0.0f);
51  EXPECT_EQ(rect.GetX(), 0.0f);
52  EXPECT_EQ(rect.GetY(), 0.0f);
53  EXPECT_EQ(rect.GetWidth(), 0.0f);
54  EXPECT_EQ(rect.GetHeight(), 0.0f);
55  EXPECT_TRUE(rect.IsEmpty());
56  EXPECT_TRUE(rect.IsFinite());
57 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::IsFinite().

◆ TEST() [347/525]

impeller::testing::TEST ( RectTest  ,
RectDirections   
)

Definition at line 3030 of file rect_unittests.cc.

3030  {
3031  auto r = Rect::MakeLTRB(1, 2, 3, 4);
3032 
3033  EXPECT_EQ(r.GetLeft(), 1);
3034  EXPECT_EQ(r.GetTop(), 2);
3035  EXPECT_EQ(r.GetRight(), 3);
3036  EXPECT_EQ(r.GetBottom(), 4);
3037 
3038  EXPECT_POINT_NEAR(r.GetLeftTop(), Point(1, 2));
3039  EXPECT_POINT_NEAR(r.GetRightTop(), Point(3, 2));
3040  EXPECT_POINT_NEAR(r.GetLeftBottom(), Point(1, 4));
3041  EXPECT_POINT_NEAR(r.GetRightBottom(), Point(3, 4));
3042 }

References EXPECT_POINT_NEAR, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [348/525]

impeller::testing::TEST ( RectTest  ,
RectDoesNotIntersectEmpty   
)

Definition at line 809 of file rect_unittests.cc.

809  {
810  Rect rect = Rect::MakeLTRB(50, 50, 100, 100);
811 
812  auto test = [&rect](Scalar l, Scalar t, Scalar r, Scalar b,
813  const std::string& label) {
814  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(l, b, r, t)))
815  << label << " with Top/Bottom swapped";
816  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(r, b, l, t)))
817  << label << " with Left/Right swapped";
818  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(r, t, l, b)))
819  << label << " with all sides swapped";
820  };
821 
822  test(20, 20, 30, 30, "Above and Left");
823  test(70, 20, 80, 30, "Above");
824  test(120, 20, 130, 30, "Above and Right");
825  test(120, 70, 130, 80, "Right");
826  test(120, 120, 130, 130, "Below and Right");
827  test(70, 120, 80, 130, "Below");
828  test(20, 120, 30, 130, "Below and Left");
829  test(20, 70, 30, 80, "Left");
830 
831  test(70, 70, 80, 80, "Inside");
832 
833  test(40, 70, 60, 80, "Straddling Left");
834  test(70, 40, 80, 60, "Straddling Top");
835  test(90, 70, 110, 80, "Straddling Right");
836  test(70, 90, 80, 110, "Straddling Bottom");
837 }

References impeller::saturated::b, impeller::TRect< T >::IntersectsWithRect(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [349/525]

impeller::testing::TEST ( RectTest  ,
RectEmptyDeclaration   
)

Definition at line 14 of file rect_unittests.cc.

14  {
15  Rect rect;
16 
17  EXPECT_EQ(rect.GetLeft(), 0.0f);
18  EXPECT_EQ(rect.GetTop(), 0.0f);
19  EXPECT_EQ(rect.GetRight(), 0.0f);
20  EXPECT_EQ(rect.GetBottom(), 0.0f);
21  EXPECT_EQ(rect.GetX(), 0.0f);
22  EXPECT_EQ(rect.GetY(), 0.0f);
23  EXPECT_EQ(rect.GetWidth(), 0.0f);
24  EXPECT_EQ(rect.GetHeight(), 0.0f);
25  EXPECT_TRUE(rect.IsEmpty());
26  EXPECT_TRUE(rect.IsFinite());
27 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::IsFinite().

◆ TEST() [350/525]

impeller::testing::TEST ( RectTest  ,
RectExpand   
)

Definition at line 1250 of file rect_unittests.cc.

1250  {
1251  auto rect = Rect::MakeLTRB(100, 100, 200, 200);
1252 
1253  // Expand(T amount)
1254  EXPECT_EQ(rect.Expand(10), Rect::MakeLTRB(90, 90, 210, 210));
1255  EXPECT_EQ(rect.Expand(-10), Rect::MakeLTRB(110, 110, 190, 190));
1256 
1257  // Expand(amount, amount)
1258  EXPECT_EQ(rect.Expand(10, 10), Rect::MakeLTRB(90, 90, 210, 210));
1259  EXPECT_EQ(rect.Expand(10, -10), Rect::MakeLTRB(90, 110, 210, 190));
1260  EXPECT_EQ(rect.Expand(-10, 10), Rect::MakeLTRB(110, 90, 190, 210));
1261  EXPECT_EQ(rect.Expand(-10, -10), Rect::MakeLTRB(110, 110, 190, 190));
1262 
1263  // Expand(amount, amount, amount, amount)
1264  EXPECT_EQ(rect.Expand(10, 20, 30, 40), Rect::MakeLTRB(90, 80, 230, 240));
1265  EXPECT_EQ(rect.Expand(-10, 20, 30, 40), Rect::MakeLTRB(110, 80, 230, 240));
1266  EXPECT_EQ(rect.Expand(10, -20, 30, 40), Rect::MakeLTRB(90, 120, 230, 240));
1267  EXPECT_EQ(rect.Expand(10, 20, -30, 40), Rect::MakeLTRB(90, 80, 170, 240));
1268  EXPECT_EQ(rect.Expand(10, 20, 30, -40), Rect::MakeLTRB(90, 80, 230, 160));
1269 
1270  // Expand(Point amount)
1271  EXPECT_EQ(rect.Expand(Point{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
1272  EXPECT_EQ(rect.Expand(Point{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
1273  EXPECT_EQ(rect.Expand(Point{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
1274  EXPECT_EQ(rect.Expand(Point{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
1275 
1276  // Expand(Size amount)
1277  EXPECT_EQ(rect.Expand(Size{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
1278  EXPECT_EQ(rect.Expand(Size{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
1279  EXPECT_EQ(rect.Expand(Size{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
1280  EXPECT_EQ(rect.Expand(Size{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
1281 }

References impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [351/525]

impeller::testing::TEST ( RectTest  ,
RectFromIRect   
)

Definition at line 164 of file rect_unittests.cc.

164  {
165  IRect irect = IRect::MakeLTRB(10, 20, 30, 40);
166  Rect rect = Rect::Make(irect);
167 
168  EXPECT_EQ(rect.GetLeft(), 10);
169  EXPECT_EQ(rect.GetTop(), 20);
170  EXPECT_EQ(rect.GetRight(), 30);
171  EXPECT_EQ(rect.GetBottom(), 40);
172 
173  // The following do not compile
174  // IRect irect2 = IRect::Make(rect);
175  // IRect irect2 = IRect::Make(irect);
176 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< Scalar >::Make(), and impeller::TRect< T >::MakeLTRB().

◆ TEST() [352/525]

impeller::testing::TEST ( RectTest  ,
RectFromRect   
)

Definition at line 654 of file rect_unittests.cc.

654  {
655  EXPECT_EQ(Rect(Rect::MakeXYWH(2, 3, 7, 15)),
656  Rect::MakeXYWH(2.0, 3.0, 7.0, 15.0));
657  EXPECT_EQ(Rect(Rect::MakeLTRB(2, 3, 7, 15)),
658  Rect::MakeLTRB(2.0, 3.0, 7.0, 15.0));
659 }

References impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [353/525]

impeller::testing::TEST ( RectTest  ,
RectGetNormalizingTransform   
)

Definition at line 1034 of file rect_unittests.cc.

1034  {
1035  {
1036  // Checks for expected matrix values
1037 
1038  auto r = Rect::MakeXYWH(100, 200, 200, 400);
1039 
1040  EXPECT_EQ(r.GetNormalizingTransform(),
1041  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
1042  Matrix::MakeTranslation({-100, -200}));
1043  }
1044 
1045  {
1046  // Checks for expected transform of points relative to the rect
1047 
1048  auto r = Rect::MakeLTRB(300, 500, 400, 700);
1049  auto m = r.GetNormalizingTransform();
1050 
1051  // The 4 corners of the rect => (0, 0) to (1, 1)
1052  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1053  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1054  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1055  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1056 
1057  // The center => (0.5, 0.5)
1058  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1059 
1060  // Outside the 4 corners => (-1, -1) to (2, 2)
1061  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1062  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1063  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1064  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1065  }
1066 
1067  {
1068  // Checks for behavior with empty rects
1069 
1070  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1071 
1072  // Empty for width and/or height == 0
1073  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1074  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1075  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1076 
1077  // Empty for width and/or height < 0
1078  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1079  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1080  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1081  }
1082 
1083  {
1084  // Checks for behavior with non-finite rects
1085 
1086  auto z = Matrix::MakeScale({0.0, 0.0, 1.0});
1087  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1088  auto inf = std::numeric_limits<Scalar>::infinity();
1089 
1090  // Non-finite for width and/or height == nan
1091  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
1092  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
1093  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
1094 
1095  // Non-finite for width and/or height == inf
1096  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
1097  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
1098  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
1099 
1100  // Non-finite for width and/or height == -inf
1101  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
1102  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
1103  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
1104 
1105  // Non-finite for origin X and/or Y == nan
1106  EXPECT_EQ(Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
1107  EXPECT_EQ(Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
1108  EXPECT_EQ(Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
1109 
1110  // Non-finite for origin X and/or Y == inf
1111  EXPECT_EQ(Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
1112  EXPECT_EQ(Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
1113  EXPECT_EQ(Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
1114 
1115  // Non-finite for origin X and/or Y == -inf
1116  EXPECT_EQ(Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
1117  EXPECT_EQ(Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
1118  EXPECT_EQ(Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
1119  }
1120 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [354/525]

impeller::testing::TEST ( RectTest  ,
RectGetPoints   
)

Definition at line 2959 of file rect_unittests.cc.

2959  {
2960  {
2961  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2962  auto points = r.GetPoints();
2963  EXPECT_POINT_NEAR(points[0], Point(100, 200));
2964  EXPECT_POINT_NEAR(points[1], Point(400, 200));
2965  EXPECT_POINT_NEAR(points[2], Point(100, 600));
2966  EXPECT_POINT_NEAR(points[3], Point(400, 600));
2967  }
2968 
2969  {
2970  Rect r = Rect::MakeMaximum();
2971  auto points = r.GetPoints();
2972  EXPECT_EQ(points[0], Point(std::numeric_limits<float>::lowest(),
2973  std::numeric_limits<float>::lowest()));
2974  EXPECT_EQ(points[1], Point(std::numeric_limits<float>::max(),
2975  std::numeric_limits<float>::lowest()));
2976  EXPECT_EQ(points[2], Point(std::numeric_limits<float>::lowest(),
2977  std::numeric_limits<float>::max()));
2978  EXPECT_EQ(points[3], Point(std::numeric_limits<float>::max(),
2979  std::numeric_limits<float>::max()));
2980  }
2981 }

References EXPECT_POINT_NEAR, impeller::TRect< T >::GetPoints(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and points.

◆ TEST() [355/525]

impeller::testing::TEST ( RectTest  ,
RectGetPositive   
)

Definition at line 3016 of file rect_unittests.cc.

3016  {
3017  {
3018  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
3019  auto actual = r.GetPositive();
3020  EXPECT_RECT_NEAR(r, actual);
3021  }
3022  {
3023  Rect r = Rect::MakeXYWH(100, 200, -100, -100);
3024  auto actual = r.GetPositive();
3025  Rect expected = Rect::MakeXYWH(0, 100, 100, 100);
3026  EXPECT_RECT_NEAR(expected, actual);
3027  }
3028 }

References EXPECT_RECT_NEAR, impeller::TRect< T >::GetPositive(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [356/525]

impeller::testing::TEST ( RectTest  ,
RectGetTransformedPoints   
)

Definition at line 2990 of file rect_unittests.cc.

2990  {
2991  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2992  auto points = r.GetTransformedPoints(Matrix::MakeTranslation({10, 20}));
2993  EXPECT_POINT_NEAR(points[0], Point(110, 220));
2994  EXPECT_POINT_NEAR(points[1], Point(410, 220));
2995  EXPECT_POINT_NEAR(points[2], Point(110, 620));
2996  EXPECT_POINT_NEAR(points[3], Point(410, 620));
2997 }

References EXPECT_POINT_NEAR, impeller::TRect< T >::GetTransformedPoints(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), and points.

◆ TEST() [357/525]

impeller::testing::TEST ( RectTest  ,
RectIntersection   
)

Definition at line 1617 of file rect_unittests.cc.

1617  {
1618  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1619  ASSERT_TRUE(a.IsFinite()) << label;
1620  ASSERT_TRUE(b.IsFinite()) << label;
1621 
1622  for (int i = 1; i < 16; i++) {
1623  // NaN in a produces empty
1624  EXPECT_FALSE(swap_nan(a, i).Intersection(b).has_value())
1625  << label << ", index = " << i;
1626  // NaN in b produces empty
1627  EXPECT_FALSE(a.Intersection(swap_nan(b, i)).has_value())
1628  << label << ", index = " << i;
1629  // NaN in both is empty
1630  for (int j = 1; j < 16; j++) {
1631  EXPECT_FALSE(swap_nan(a, i).Intersection(swap_nan(b, j)).has_value())
1632  << label << ", indices = " << i << ", " << j;
1633  }
1634  }
1635  };
1636 
1637  auto check_empty_flips = [](const Rect& a, const Rect& b,
1638  const std::string& label) {
1639  ASSERT_FALSE(a.IsEmpty());
1640  // b is allowed to be empty
1641 
1642  // unflipped a vs flipped (empty) b yields a
1643  EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1644  EXPECT_TRUE(a.IntersectionOrEmpty(flip_lr(b)).IsEmpty()) << label;
1645  EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1646  EXPECT_TRUE(a.IntersectionOrEmpty(flip_tb(b)).IsEmpty()) << label;
1647  EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1648  EXPECT_TRUE(a.IntersectionOrEmpty(flip_lrtb(b)).IsEmpty()) << label;
1649 
1650  // flipped (empty) a vs unflipped b yields b
1651  EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1652  EXPECT_TRUE(flip_lr(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1653  EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1654  EXPECT_TRUE(flip_tb(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1655  EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1656  EXPECT_TRUE(flip_lrtb(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1657 
1658  // flipped (empty) a vs flipped (empty) b yields empty
1659  EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1660  EXPECT_TRUE(flip_lr(a).IntersectionOrEmpty(flip_lr(b)).IsEmpty()) << label;
1661  EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1662  EXPECT_TRUE(flip_tb(a).IntersectionOrEmpty(flip_tb(b)).IsEmpty()) << label;
1663  EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1664  EXPECT_TRUE(flip_lrtb(a).IntersectionOrEmpty(flip_lrtb(b)).IsEmpty())
1665  << label;
1666  };
1667 
1668  auto test_non_empty = [&check_nans, &check_empty_flips](
1669  const Rect& a, const Rect& b, const Rect& result) {
1670  ASSERT_FALSE(a.IsEmpty()) << a;
1671  // b is allowed to be empty
1672 
1673  std::stringstream stream;
1674  stream << a << " union " << b;
1675  auto label = stream.str();
1676 
1677  EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1678  EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1679  EXPECT_EQ(a.Intersection(b), result) << label;
1680  EXPECT_EQ(b.Intersection(a), result) << label;
1681  check_empty_flips(a, b, label);
1682  check_nans(a, b, label);
1683  };
1684 
1685  auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
1686  const Rect& b) {
1687  ASSERT_FALSE(a.IsEmpty()) << a;
1688  // b is allowed to be empty
1689 
1690  std::stringstream stream;
1691  stream << a << " union " << b;
1692  auto label = stream.str();
1693 
1694  EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1695  EXPECT_TRUE(a.IntersectionOrEmpty(b).IsEmpty()) << label;
1696  EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1697  EXPECT_TRUE(b.IntersectionOrEmpty(a).IsEmpty()) << label;
1698  check_empty_flips(a, b, label);
1699  check_nans(a, b, label);
1700  };
1701 
1702  {
1703  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1704  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1705 
1706  test_empty(a, b);
1707  }
1708 
1709  {
1710  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1711  auto b = Rect::MakeXYWH(10, 10, 0, 0);
1712 
1713  test_empty(a, b);
1714  }
1715 
1716  {
1717  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1718  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1719  auto expected = Rect::MakeXYWH(10, 10, 90, 90);
1720 
1721  test_non_empty(a, b, expected);
1722  }
1723 
1724  {
1725  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1726  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1727 
1728  test_empty(a, b);
1729  }
1730 
1731  {
1732  auto a = Rect::MakeMaximum();
1733  auto b = Rect::MakeXYWH(10, 10, 300, 300);
1734 
1735  test_non_empty(a, b, b);
1736  }
1737 
1738  {
1739  auto a = Rect::MakeMaximum();
1740  auto b = Rect::MakeMaximum();
1741 
1742  test_non_empty(a, b, Rect::MakeMaximum());
1743  }
1744 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::Intersection(), impeller::TRect< T >::IntersectionOrEmpty(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [358/525]

impeller::testing::TEST ( RectTest  ,
RectIntersectsWithRect   
)

Definition at line 1951 of file rect_unittests.cc.

1951  {
1952  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1953  ASSERT_TRUE(a.IsFinite()) << label;
1954  ASSERT_TRUE(b.IsFinite()) << label;
1955 
1956  for (int i = 1; i < 16; i++) {
1957  // NaN in a produces b
1958  EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(b))
1959  << label << ", index = " << i;
1960  // NaN in b produces a
1961  EXPECT_FALSE(a.IntersectsWithRect(swap_nan(b, i)))
1962  << label << ", index = " << i;
1963  // NaN in both is empty
1964  for (int j = 1; j < 16; j++) {
1965  EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(swap_nan(b, j)))
1966  << label << ", indices = " << i << ", " << j;
1967  }
1968  }
1969  };
1970 
1971  auto check_empty_flips = [](const Rect& a, const Rect& b,
1972  const std::string& label) {
1973  ASSERT_FALSE(a.IsEmpty());
1974  // b is allowed to be empty
1975 
1976  // unflipped a vs flipped (empty) b yields a
1977  EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
1978  EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
1979  EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
1980 
1981  // flipped (empty) a vs unflipped b yields b
1982  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
1983  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
1984  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
1985 
1986  // flipped (empty) a vs flipped (empty) b yields empty
1987  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
1988  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
1989  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
1990  };
1991 
1992  auto test_non_empty = [&check_nans, &check_empty_flips](const Rect& a,
1993  const Rect& b) {
1994  ASSERT_FALSE(a.IsEmpty()) << a;
1995  // b is allowed to be empty
1996 
1997  std::stringstream stream;
1998  stream << a << " union " << b;
1999  auto label = stream.str();
2000 
2001  EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
2002  EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
2003  check_empty_flips(a, b, label);
2004  check_nans(a, b, label);
2005  };
2006 
2007  auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
2008  const Rect& b) {
2009  ASSERT_FALSE(a.IsEmpty()) << a;
2010  // b is allowed to be empty
2011 
2012  std::stringstream stream;
2013  stream << a << " union " << b;
2014  auto label = stream.str();
2015 
2016  EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
2017  EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
2018  check_empty_flips(a, b, label);
2019  check_nans(a, b, label);
2020  };
2021 
2022  {
2023  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2024  auto b = Rect::MakeXYWH(0, 0, 0, 0);
2025 
2026  test_empty(a, b);
2027  }
2028 
2029  {
2030  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2031  auto b = Rect::MakeXYWH(10, 10, 0, 0);
2032 
2033  test_empty(a, b);
2034  }
2035 
2036  {
2037  auto a = Rect::MakeXYWH(0, 0, 100, 100);
2038  auto b = Rect::MakeXYWH(10, 10, 100, 100);
2039 
2040  test_non_empty(a, b);
2041  }
2042 
2043  {
2044  auto a = Rect::MakeXYWH(0, 0, 100, 100);
2045  auto b = Rect::MakeXYWH(100, 100, 100, 100);
2046 
2047  test_empty(a, b);
2048  }
2049 
2050  {
2051  auto a = Rect::MakeMaximum();
2052  auto b = Rect::MakeXYWH(10, 10, 100, 100);
2053 
2054  test_non_empty(a, b);
2055  }
2056 
2057  {
2058  auto a = Rect::MakeMaximum();
2059  auto b = Rect::MakeMaximum();
2060 
2061  test_non_empty(a, b);
2062  }
2063 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IntersectsWithRect(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [359/525]

impeller::testing::TEST ( RectTest  ,
RectMakeMaximum   
)

Definition at line 620 of file rect_unittests.cc.

620  {
621  Rect rect = Rect::MakeMaximum();
622  auto inf = std::numeric_limits<Scalar>::infinity();
623  auto min = std::numeric_limits<Scalar>::lowest();
624  auto max = std::numeric_limits<Scalar>::max();
625 
626  EXPECT_EQ(rect.GetLeft(), min);
627  EXPECT_EQ(rect.GetTop(), min);
628  EXPECT_EQ(rect.GetRight(), max);
629  EXPECT_EQ(rect.GetBottom(), max);
630  EXPECT_EQ(rect.GetX(), min);
631  EXPECT_EQ(rect.GetY(), min);
632  EXPECT_EQ(rect.GetWidth(), inf);
633  EXPECT_EQ(rect.GetHeight(), inf);
634  EXPECT_FALSE(rect.IsEmpty());
635  EXPECT_TRUE(rect.IsFinite());
636 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeMaximum().

◆ TEST() [360/525]

impeller::testing::TEST ( RectTest  ,
RectMakePointBounds   
)

Definition at line 2999 of file rect_unittests.cc.

2999  {
3000  {
3001  std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
3002  auto r = Rect::MakePointBounds(points.begin(), points.end());
3003  auto expected = Rect::MakeXYWH(0, -1, 4, 7);
3004  EXPECT_TRUE(r.has_value());
3005  if (r.has_value()) {
3006  EXPECT_RECT_NEAR(r.value(), expected);
3007  }
3008  }
3009  {
3010  std::vector<Point> points;
3011  std::optional<Rect> r = Rect::MakePointBounds(points.begin(), points.end());
3012  EXPECT_FALSE(r.has_value());
3013  }
3014 }

References EXPECT_RECT_NEAR, impeller::TRect< Scalar >::MakePointBounds(), impeller::TRect< Scalar >::MakeXYWH(), and points.

◆ TEST() [361/525]

impeller::testing::TEST ( RectTest  ,
RectMakeSize   
)

Definition at line 590 of file rect_unittests.cc.

590  {
591  {
592  Size s(100, 200);
593  Rect r = Rect::MakeSize(s);
594  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
595  EXPECT_RECT_NEAR(r, expected);
596  }
597 
598  {
599  ISize s(100, 200);
600  Rect r = Rect::MakeSize(s);
601  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
602  EXPECT_RECT_NEAR(r, expected);
603  }
604 
605  {
606  Size s(100, 200);
607  IRect r = IRect::MakeSize(s);
608  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
609  EXPECT_EQ(r, expected);
610  }
611 
612  {
613  ISize s(100, 200);
614  IRect r = IRect::MakeSize(s);
615  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
616  EXPECT_EQ(r, expected);
617  }
618 }

References EXPECT_RECT_NEAR, impeller::TRect< T >::MakeLTRB(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< T >::MakeSize(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST() [362/525]

impeller::testing::TEST ( RectTest  ,
RectOriginSizeXYWHGetters   
)

Definition at line 702 of file rect_unittests.cc.

702  {
703  {
704  Rect r = Rect::MakeOriginSize({10, 20}, {50, 40});
705  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
706  EXPECT_EQ(r.GetSize(), Size(50, 40));
707  EXPECT_EQ(r.GetX(), 10);
708  EXPECT_EQ(r.GetY(), 20);
709  EXPECT_EQ(r.GetWidth(), 50);
710  EXPECT_EQ(r.GetHeight(), 40);
711  auto expected_array = std::array<Scalar, 4>{10, 20, 50, 40};
712  EXPECT_EQ(r.GetXYWH(), expected_array);
713  }
714 
715  {
716  Rect r = Rect::MakeLTRB(10, 20, 50, 40);
717  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
718  EXPECT_EQ(r.GetSize(), Size(40, 20));
719  EXPECT_EQ(r.GetX(), 10);
720  EXPECT_EQ(r.GetY(), 20);
721  EXPECT_EQ(r.GetWidth(), 40);
722  EXPECT_EQ(r.GetHeight(), 20);
723  auto expected_array = std::array<Scalar, 4>{10, 20, 40, 20};
724  EXPECT_EQ(r.GetXYWH(), expected_array);
725  }
726 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetOrigin(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetXYWH(), impeller::TRect< T >::GetY(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeOriginSize().

◆ TEST() [363/525]

impeller::testing::TEST ( RectTest  ,
RectOverflowLTRB   
)

Definition at line 384 of file rect_unittests.cc.

384  {
385  auto min = std::numeric_limits<Scalar>::lowest();
386  auto max = std::numeric_limits<Scalar>::max();
387  auto inf = std::numeric_limits<Scalar>::infinity();
388 
389  // 8 cases:
390  // finite negative X, max W
391  // ~min X, ~max W
392  // finite negative Y, max H
393  // ~min Y, ~max H
394  // finite positive X, min W
395  // ~min X, ~min W
396  // finite positive Y, min H
397  // ~min Y, ~min H
398 
399  // a small finite value subtracted from a max value will remain max
400  // a very large finite value (like min) subtracted from max will go to inf
401 
402  {
403  Rect rect = Rect::MakeLTRB(-5.0f, 10.0f, max, 25.0f);
404 
405  EXPECT_EQ(rect.GetLeft(), -5.0f);
406  EXPECT_EQ(rect.GetTop(), 10.0f);
407  EXPECT_EQ(rect.GetRight(), max);
408  EXPECT_EQ(rect.GetBottom(), 25.0f);
409  EXPECT_EQ(rect.GetX(), -5.0f);
410  EXPECT_EQ(rect.GetY(), 10.0f);
411  EXPECT_EQ(rect.GetWidth(), max);
412  EXPECT_EQ(rect.GetHeight(), 15.0f);
413  EXPECT_FALSE(rect.IsEmpty());
414  EXPECT_TRUE(rect.IsFinite());
415  }
416 
417  {
418  Rect rect = Rect::MakeLTRB(min + 5.0f, 10.0f, max - 5.0f, 25.0f);
419 
420  EXPECT_EQ(rect.GetLeft(), min + 5.0f);
421  EXPECT_EQ(rect.GetTop(), 10.0f);
422  EXPECT_EQ(rect.GetRight(), max - 5.0f);
423  EXPECT_EQ(rect.GetBottom(), 25.0f);
424  EXPECT_EQ(rect.GetX(), min + 5.0f);
425  EXPECT_EQ(rect.GetY(), 10.0f);
426  EXPECT_EQ(rect.GetWidth(), inf);
427  EXPECT_EQ(rect.GetHeight(), 15.0f);
428  EXPECT_FALSE(rect.IsEmpty());
429  EXPECT_TRUE(rect.IsFinite());
430  }
431 
432  {
433  Rect rect = Rect::MakeLTRB(5.0f, -10.0f, 20.0f, max);
434 
435  EXPECT_EQ(rect.GetLeft(), 5.0f);
436  EXPECT_EQ(rect.GetTop(), -10.0f);
437  EXPECT_EQ(rect.GetRight(), 20.0f);
438  EXPECT_EQ(rect.GetBottom(), max);
439  EXPECT_EQ(rect.GetX(), 5.0f);
440  EXPECT_EQ(rect.GetY(), -10.0f);
441  EXPECT_EQ(rect.GetWidth(), 15.0f);
442  EXPECT_EQ(rect.GetHeight(), max);
443  EXPECT_FALSE(rect.IsEmpty());
444  EXPECT_TRUE(rect.IsFinite());
445  }
446 
447  {
448  Rect rect = Rect::MakeLTRB(5.0f, min + 10.0f, 20.0f, max - 15.0f);
449 
450  EXPECT_EQ(rect.GetLeft(), 5.0f);
451  EXPECT_EQ(rect.GetTop(), min + 10.0f);
452  EXPECT_EQ(rect.GetRight(), 20.0f);
453  EXPECT_EQ(rect.GetBottom(), max - 15.0f);
454  EXPECT_EQ(rect.GetX(), 5.0f);
455  EXPECT_EQ(rect.GetY(), min + 10.0f);
456  EXPECT_EQ(rect.GetWidth(), 15.0f);
457  EXPECT_EQ(rect.GetHeight(), inf);
458  EXPECT_FALSE(rect.IsEmpty());
459  EXPECT_TRUE(rect.IsFinite());
460  }
461 
462  {
463  Rect rect = Rect::MakeLTRB(5.0f, 10.0f, min, 25.0f);
464 
465  EXPECT_EQ(rect.GetLeft(), 5.0f);
466  EXPECT_EQ(rect.GetTop(), 10.0f);
467  EXPECT_EQ(rect.GetRight(), min);
468  EXPECT_EQ(rect.GetBottom(), 25.0f);
469  EXPECT_EQ(rect.GetX(), 5.0f);
470  EXPECT_EQ(rect.GetY(), 10.0f);
471  EXPECT_EQ(rect.GetWidth(), min);
472  EXPECT_EQ(rect.GetHeight(), 15.0f);
473  EXPECT_TRUE(rect.IsEmpty());
474  EXPECT_TRUE(rect.IsFinite());
475  }
476 
477  {
478  Rect rect = Rect::MakeLTRB(max - 5.0f, 10.0f, min + 10.0f, 25.0f);
479 
480  EXPECT_EQ(rect.GetLeft(), max - 5.0f);
481  EXPECT_EQ(rect.GetTop(), 10.0f);
482  EXPECT_EQ(rect.GetRight(), min + 10.0f);
483  EXPECT_EQ(rect.GetBottom(), 25.0f);
484  EXPECT_EQ(rect.GetX(), max - 5.0f);
485  EXPECT_EQ(rect.GetY(), 10.0f);
486  EXPECT_EQ(rect.GetWidth(), -inf);
487  EXPECT_EQ(rect.GetHeight(), 15.0f);
488  EXPECT_TRUE(rect.IsEmpty());
489  EXPECT_TRUE(rect.IsFinite());
490  }
491 
492  {
493  Rect rect = Rect::MakeLTRB(5.0f, 10.0f, 20.0f, min);
494 
495  EXPECT_EQ(rect.GetLeft(), 5.0f);
496  EXPECT_EQ(rect.GetTop(), 10.0f);
497  EXPECT_EQ(rect.GetRight(), 20.0f);
498  EXPECT_EQ(rect.GetBottom(), min);
499  EXPECT_EQ(rect.GetX(), 5.0f);
500  EXPECT_EQ(rect.GetY(), 10.0f);
501  EXPECT_EQ(rect.GetWidth(), 15.0f);
502  EXPECT_EQ(rect.GetHeight(), min);
503  EXPECT_TRUE(rect.IsEmpty());
504  EXPECT_TRUE(rect.IsFinite());
505  }
506 
507  {
508  Rect rect = Rect::MakeLTRB(5.0f, max - 5.0f, 20.0f, min + 10.0f);
509 
510  EXPECT_EQ(rect.GetLeft(), 5.0f);
511  EXPECT_EQ(rect.GetTop(), max - 5.0f);
512  EXPECT_EQ(rect.GetRight(), 20.0f);
513  EXPECT_EQ(rect.GetBottom(), min + 10.0f);
514  EXPECT_EQ(rect.GetX(), 5.0f);
515  EXPECT_EQ(rect.GetY(), max - 5.0f);
516  EXPECT_EQ(rect.GetWidth(), 15.0f);
517  EXPECT_EQ(rect.GetHeight(), -inf);
518  EXPECT_TRUE(rect.IsEmpty());
519  EXPECT_TRUE(rect.IsFinite());
520  }
521 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [364/525]

impeller::testing::TEST ( RectTest  ,
RectOverflowXYWH   
)

Definition at line 178 of file rect_unittests.cc.

178  {
179  auto min = std::numeric_limits<Scalar>::lowest();
180  auto max = std::numeric_limits<Scalar>::max();
181  auto inf = std::numeric_limits<Scalar>::infinity();
182 
183  // 8 cases:
184  // finite X, max W
185  // max X, max W
186  // finite Y, max H
187  // max Y, max H
188  // finite X, min W
189  // min X, min W
190  // finite Y, min H
191  // min Y, min H
192 
193  // a small finite value added to a max value will remain max
194  // a very large finite value (like max) added to max will go to infinity
195 
196  {
197  Rect rect = Rect::MakeXYWH(5.0, 10.0f, max, 15.0f);
198 
199  EXPECT_EQ(rect.GetLeft(), 5.0f);
200  EXPECT_EQ(rect.GetTop(), 10.0f);
201  EXPECT_EQ(rect.GetRight(), max);
202  EXPECT_EQ(rect.GetBottom(), 25.0f);
203  EXPECT_EQ(rect.GetX(), 5.0f);
204  EXPECT_EQ(rect.GetY(), 10.0f);
205  EXPECT_EQ(rect.GetWidth(), max);
206  EXPECT_EQ(rect.GetHeight(), 15.0f);
207  EXPECT_FALSE(rect.IsEmpty());
208  EXPECT_TRUE(rect.IsFinite());
209  }
210 
211  {
212  Rect rect = Rect::MakeXYWH(max, 10.0f, max, 15.0f);
213 
214  EXPECT_EQ(rect.GetLeft(), max);
215  EXPECT_EQ(rect.GetTop(), 10.0f);
216  EXPECT_EQ(rect.GetRight(), inf);
217  EXPECT_EQ(rect.GetBottom(), 25.0f);
218  EXPECT_EQ(rect.GetX(), max);
219  EXPECT_EQ(rect.GetY(), 10.0f);
220  EXPECT_EQ(rect.GetWidth(), inf);
221  EXPECT_EQ(rect.GetHeight(), 15.0f);
222  EXPECT_FALSE(rect.IsEmpty());
223  EXPECT_FALSE(rect.IsFinite());
224  }
225 
226  {
227  Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, max);
228 
229  EXPECT_EQ(rect.GetLeft(), 5.0f);
230  EXPECT_EQ(rect.GetTop(), 10.0f);
231  EXPECT_EQ(rect.GetRight(), 25.0f);
232  EXPECT_EQ(rect.GetBottom(), max);
233  EXPECT_EQ(rect.GetX(), 5.0f);
234  EXPECT_EQ(rect.GetY(), 10.0f);
235  EXPECT_EQ(rect.GetWidth(), 20.0f);
236  EXPECT_EQ(rect.GetHeight(), max);
237  EXPECT_FALSE(rect.IsEmpty());
238  EXPECT_TRUE(rect.IsFinite());
239  }
240 
241  {
242  Rect rect = Rect::MakeXYWH(5.0f, max, 20.0f, max);
243 
244  EXPECT_EQ(rect.GetLeft(), 5.0f);
245  EXPECT_EQ(rect.GetTop(), max);
246  EXPECT_EQ(rect.GetRight(), 25.0f);
247  EXPECT_EQ(rect.GetBottom(), inf);
248  EXPECT_EQ(rect.GetX(), 5.0f);
249  EXPECT_EQ(rect.GetY(), max);
250  EXPECT_EQ(rect.GetWidth(), 20.0f);
251  EXPECT_EQ(rect.GetHeight(), inf);
252  EXPECT_FALSE(rect.IsEmpty());
253  EXPECT_FALSE(rect.IsFinite());
254  }
255 
256  {
257  Rect rect = Rect::MakeXYWH(5.0, 10.0f, min, 15.0f);
258 
259  EXPECT_EQ(rect.GetLeft(), 5.0f);
260  EXPECT_EQ(rect.GetTop(), 10.0f);
261  EXPECT_EQ(rect.GetRight(), min);
262  EXPECT_EQ(rect.GetBottom(), 25.0f);
263  EXPECT_EQ(rect.GetX(), 5.0f);
264  EXPECT_EQ(rect.GetY(), 10.0f);
265  EXPECT_EQ(rect.GetWidth(), min);
266  EXPECT_EQ(rect.GetHeight(), 15.0f);
267  EXPECT_TRUE(rect.IsEmpty());
268  EXPECT_TRUE(rect.IsFinite());
269  }
270 
271  {
272  Rect rect = Rect::MakeXYWH(min, 10.0f, min, 15.0f);
273 
274  EXPECT_EQ(rect.GetLeft(), min);
275  EXPECT_EQ(rect.GetTop(), 10.0f);
276  EXPECT_EQ(rect.GetRight(), -inf);
277  EXPECT_EQ(rect.GetBottom(), 25.0f);
278  EXPECT_EQ(rect.GetX(), min);
279  EXPECT_EQ(rect.GetY(), 10.0f);
280  EXPECT_EQ(rect.GetWidth(), -inf);
281  EXPECT_EQ(rect.GetHeight(), 15.0f);
282  EXPECT_TRUE(rect.IsEmpty());
283  EXPECT_FALSE(rect.IsFinite());
284  }
285 
286  {
287  Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, min);
288 
289  EXPECT_EQ(rect.GetLeft(), 5.0f);
290  EXPECT_EQ(rect.GetTop(), 10.0f);
291  EXPECT_EQ(rect.GetRight(), 25.0f);
292  EXPECT_EQ(rect.GetBottom(), min);
293  EXPECT_EQ(rect.GetX(), 5.0f);
294  EXPECT_EQ(rect.GetY(), 10.0f);
295  EXPECT_EQ(rect.GetWidth(), 20.0f);
296  EXPECT_EQ(rect.GetHeight(), min);
297  EXPECT_TRUE(rect.IsEmpty());
298  EXPECT_TRUE(rect.IsFinite());
299  }
300 
301  {
302  Rect rect = Rect::MakeXYWH(5.0f, min, 20.0f, min);
303 
304  EXPECT_EQ(rect.GetLeft(), 5.0f);
305  EXPECT_EQ(rect.GetTop(), min);
306  EXPECT_EQ(rect.GetRight(), 25.0f);
307  EXPECT_EQ(rect.GetBottom(), -inf);
308  EXPECT_EQ(rect.GetX(), 5.0f);
309  EXPECT_EQ(rect.GetY(), min);
310  EXPECT_EQ(rect.GetWidth(), 20.0f);
311  EXPECT_EQ(rect.GetHeight(), -inf);
312  EXPECT_TRUE(rect.IsEmpty());
313  EXPECT_FALSE(rect.IsFinite());
314  }
315 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [365/525]

impeller::testing::TEST ( RectTest  ,
RectProject   
)

Definition at line 3044 of file rect_unittests.cc.

3044  {
3045  {
3046  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
3047  auto actual = r.Project(r);
3048  auto expected = Rect::MakeLTRB(0, 0, 1, 1);
3049  EXPECT_RECT_NEAR(expected, actual);
3050  }
3051  {
3052  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
3053  auto actual = r.Project(Rect::MakeLTRB(0, 0, 100, 100));
3054  auto expected = Rect::MakeLTRB(0.5, 0.5, 1, 1);
3055  EXPECT_RECT_NEAR(expected, actual);
3056  }
3057 }

References EXPECT_RECT_NEAR, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [366/525]

impeller::testing::TEST ( RectTest  ,
RectRound   
)

Definition at line 3083 of file rect_unittests.cc.

3083  {
3084  {
3085  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3086  EXPECT_EQ(Rect::Round(r), r);
3087  }
3088  {
3089  auto r = Rect::MakeLTRB(-100.4, -200.4, 300.4, 400.4);
3090  EXPECT_EQ(Rect::Round(r), Rect::MakeLTRB(-100, -200, 300, 400));
3091  }
3092  {
3093  auto r = Rect::MakeLTRB(-100.5, -200.5, 300.5, 400.5);
3094  EXPECT_EQ(Rect::Round(r), Rect::MakeLTRB(-101, -201, 301, 401));
3095  }
3096 }

References impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::Round().

◆ TEST() [367/525]

impeller::testing::TEST ( RectTest  ,
RectRoundOut   
)

Definition at line 3059 of file rect_unittests.cc.

3059  {
3060  {
3061  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3062  EXPECT_EQ(Rect::RoundOut(r), r);
3063  }
3064  {
3065  auto r = Rect::MakeLTRB(-100.1, -200.1, 300.1, 400.1);
3066  EXPECT_EQ(Rect::RoundOut(r), Rect::MakeLTRB(-101, -201, 301, 401));
3067  }
3068 }

References impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::RoundOut().

◆ TEST() [368/525]

impeller::testing::TEST ( RectTest  ,
RectRoundOutEmpty   
)

Definition at line 754 of file rect_unittests.cc.

754  {
755  Rect rect;
756 
757  EXPECT_EQ(Rect::RoundOut(rect), Rect());
758 
759  EXPECT_EQ(IRect::RoundOut(rect), IRect());
760 }

References impeller::TRect< T >::RoundOut(), and impeller::TRect< Scalar >::RoundOut().

◆ TEST() [369/525]

impeller::testing::TEST ( RectTest  ,
RectRoundOutSimple   
)

Definition at line 762 of file rect_unittests.cc.

762  {
763  Rect rect = Rect::MakeLTRB(5.125f, 10.75f, 20.625f, 25.375f);
764 
765  EXPECT_EQ(Rect::RoundOut(rect), Rect::MakeLTRB(5.0f, 10.0f, 21.0f, 26.0f));
766 
767  EXPECT_EQ(IRect::RoundOut(rect), IRect::MakeLTRB(5, 10, 21, 26));
768 }

References impeller::TRect< T >::MakeLTRB(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< T >::RoundOut(), and impeller::TRect< Scalar >::RoundOut().

◆ TEST() [370/525]

impeller::testing::TEST ( RectTest  ,
RectRoundOutToIRectHuge   
)

Definition at line 770 of file rect_unittests.cc.

770  {
771  auto test = [](int corners) {
772  EXPECT_TRUE(corners >= 0 && corners <= 0xf);
773  Scalar l, t, r, b;
774  int64_t il, it, ir, ib;
775  l = il = 50;
776  t = it = 50;
777  r = ir = 80;
778  b = ib = 80;
779  if ((corners & (1 << 0)) != 0) {
780  l = -1E20;
781  il = std::numeric_limits<int64_t>::min();
782  }
783  if ((corners & (1 << 1)) != 0) {
784  t = -1E20;
785  it = std::numeric_limits<int64_t>::min();
786  }
787  if ((corners & (1 << 2)) != 0) {
788  r = +1E20;
789  ir = std::numeric_limits<int64_t>::max();
790  }
791  if ((corners & (1 << 3)) != 0) {
792  b = +1E20;
793  ib = std::numeric_limits<int64_t>::max();
794  }
795 
796  Rect rect = Rect::MakeLTRB(l, t, r, b);
797  IRect irect = IRect::RoundOut(rect);
798  EXPECT_EQ(irect.GetLeft(), il) << corners;
799  EXPECT_EQ(irect.GetTop(), it) << corners;
800  EXPECT_EQ(irect.GetRight(), ir) << corners;
801  EXPECT_EQ(irect.GetBottom(), ib) << corners;
802  };
803 
804  for (int corners = 0; corners <= 15; corners++) {
805  test(corners);
806  }
807 }

References impeller::saturated::b, impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< T >::RoundOut().

◆ TEST() [371/525]

impeller::testing::TEST ( RectTest  ,
RectScale   
)

Definition at line 929 of file rect_unittests.cc.

929  {
930  auto test1 = [](Rect rect, Scalar scale) {
931  Rect expected = Rect::MakeXYWH(rect.GetX() * scale, //
932  rect.GetY() * scale, //
933  rect.GetWidth() * scale, //
934  rect.GetHeight() * scale);
935 
936  EXPECT_RECT_NEAR(rect.Scale(scale), expected) //
937  << rect << " * " << scale;
938  EXPECT_RECT_NEAR(rect.Scale(scale, scale), expected) //
939  << rect << " * " << scale;
940  EXPECT_RECT_NEAR(rect.Scale(Point(scale, scale)), expected) //
941  << rect << " * " << scale;
942  EXPECT_RECT_NEAR(rect.Scale(Size(scale, scale)), expected) //
943  << rect << " * " << scale;
944  };
945 
946  auto test2 = [&test1](Rect rect, Scalar scale_x, Scalar scale_y) {
947  Rect expected = Rect::MakeXYWH(rect.GetX() * scale_x, //
948  rect.GetY() * scale_y, //
949  rect.GetWidth() * scale_x, //
950  rect.GetHeight() * scale_y);
951 
952  EXPECT_RECT_NEAR(rect.Scale(scale_x, scale_y), expected) //
953  << rect << " * " << scale_x << ", " << scale_y;
954  EXPECT_RECT_NEAR(rect.Scale(Point(scale_x, scale_y)), expected) //
955  << rect << " * " << scale_x << ", " << scale_y;
956  EXPECT_RECT_NEAR(rect.Scale(Size(scale_x, scale_y)), expected) //
957  << rect << " * " << scale_x << ", " << scale_y;
958 
959  test1(rect, scale_x);
960  test1(rect, scale_y);
961  };
962 
963  test2(Rect::MakeLTRB(10, 15, 100, 150), 1.0, 0.0);
964  test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 1.0);
965  test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 0.0);
966  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, 3.5);
967  test2(Rect::MakeLTRB(10, 15, 100, 150), 3.5, 2.5);
968  test2(Rect::MakeLTRB(10, 15, -100, 150), 2.5, 3.5);
969  test2(Rect::MakeLTRB(10, 15, 100, -150), 2.5, 3.5);
970  test2(Rect::MakeLTRB(10, 15, 100, 150), -2.5, 3.5);
971  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, -3.5);
972 }

References EXPECT_RECT_NEAR, impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::TRect< T >::Scale().

◆ TEST() [372/525]

impeller::testing::TEST ( RectTest  ,
RectShift   
)

Definition at line 2983 of file rect_unittests.cc.

2983  {
2984  auto r = Rect::MakeLTRB(0, 0, 100, 100);
2985 
2986  EXPECT_EQ(r.Shift(Point(10, 5)), Rect::MakeLTRB(10, 5, 110, 105));
2987  EXPECT_EQ(r.Shift(Point(-10, -5)), Rect::MakeLTRB(-10, -5, 90, 95));
2988 }

References impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [373/525]

impeller::testing::TEST ( RectTest  ,
RectSimpleLTRB   
)

Definition at line 73 of file rect_unittests.cc.

73  {
74  // Using fractional-power-of-2 friendly values for equality tests
75  Rect rect = Rect::MakeLTRB(5.125f, 10.25f, 20.625f, 25.375f);
76 
77  EXPECT_EQ(rect.GetLeft(), 5.125f);
78  EXPECT_EQ(rect.GetTop(), 10.25f);
79  EXPECT_EQ(rect.GetRight(), 20.625f);
80  EXPECT_EQ(rect.GetBottom(), 25.375f);
81  EXPECT_EQ(rect.GetX(), 5.125f);
82  EXPECT_EQ(rect.GetY(), 10.25f);
83  EXPECT_EQ(rect.GetWidth(), 15.5f);
84  EXPECT_EQ(rect.GetHeight(), 15.125f);
85  EXPECT_FALSE(rect.IsEmpty());
86  EXPECT_TRUE(rect.IsFinite());
87 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [374/525]

impeller::testing::TEST ( RectTest  ,
RectSimpleWH   
)

Definition at line 133 of file rect_unittests.cc.

133  {
134  // Using fractional-power-of-2 friendly values for equality tests
135  Rect rect = Rect::MakeWH(15.5f, 15.125f);
136 
137  EXPECT_EQ(rect.GetLeft(), 0.0f);
138  EXPECT_EQ(rect.GetTop(), 0.0f);
139  EXPECT_EQ(rect.GetRight(), 15.5f);
140  EXPECT_EQ(rect.GetBottom(), 15.125f);
141  EXPECT_EQ(rect.GetX(), 0.0f);
142  EXPECT_EQ(rect.GetY(), 0.0f);
143  EXPECT_EQ(rect.GetWidth(), 15.5f);
144  EXPECT_EQ(rect.GetHeight(), 15.125f);
145  EXPECT_FALSE(rect.IsEmpty());
146  EXPECT_TRUE(rect.IsFinite());
147 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeWH().

◆ TEST() [375/525]

impeller::testing::TEST ( RectTest  ,
RectSimpleXYWH   
)

Definition at line 103 of file rect_unittests.cc.

103  {
104  // Using fractional-power-of-2 friendly values for equality tests
105  Rect rect = Rect::MakeXYWH(5.125f, 10.25f, 15.5f, 15.125f);
106 
107  EXPECT_EQ(rect.GetLeft(), 5.125f);
108  EXPECT_EQ(rect.GetTop(), 10.25f);
109  EXPECT_EQ(rect.GetRight(), 20.625f);
110  EXPECT_EQ(rect.GetBottom(), 25.375f);
111  EXPECT_EQ(rect.GetX(), 5.125f);
112  EXPECT_EQ(rect.GetY(), 10.25f);
113  EXPECT_EQ(rect.GetWidth(), 15.5f);
114  EXPECT_EQ(rect.GetHeight(), 15.125f);
115  EXPECT_FALSE(rect.IsEmpty());
116  EXPECT_TRUE(rect.IsFinite());
117 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [376/525]

impeller::testing::TEST ( RectTest  ,
RectUnion   
)

Definition at line 1358 of file rect_unittests.cc.

1358  {
1359  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1360  ASSERT_TRUE(a.IsFinite()) << label;
1361  ASSERT_TRUE(b.IsFinite()) << label;
1362  ASSERT_FALSE(a.Union(b).IsEmpty());
1363 
1364  for (int i = 1; i < 16; i++) {
1365  // NaN in a produces b
1366  EXPECT_EQ(swap_nan(a, i).Union(b), b) << label << ", index = " << i;
1367  // NaN in b produces a
1368  EXPECT_EQ(a.Union(swap_nan(b, i)), a) << label << ", index = " << i;
1369  // NaN in both is empty
1370  for (int j = 1; j < 16; j++) {
1371  EXPECT_TRUE(swap_nan(a, i).Union(swap_nan(b, j)).IsEmpty())
1372  << label << ", indices = " << i << ", " << j;
1373  }
1374  }
1375  };
1376 
1377  auto check_empty_flips = [](const Rect& a, const Rect& b,
1378  const std::string& label) {
1379  ASSERT_FALSE(a.IsEmpty());
1380  // b is allowed to be empty
1381 
1382  // unflipped a vs flipped (empty) b yields a
1383  EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1384  EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1385  EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1386 
1387  // flipped (empty) a vs unflipped b yields b
1388  EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1389  EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1390  EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1391 
1392  // flipped (empty) a vs flipped (empty) b yields empty
1393  EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1394  EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1395  EXPECT_TRUE(flip_lrtb(a).Union(flip_lrtb(b)).IsEmpty()) << label;
1396  };
1397 
1398  auto test = [&check_nans, &check_empty_flips](const Rect& a, const Rect& b,
1399  const Rect& result) {
1400  ASSERT_FALSE(a.IsEmpty()) << a;
1401  // b is allowed to be empty
1402 
1403  std::stringstream stream;
1404  stream << a << " union " << b;
1405  auto label = stream.str();
1406 
1407  EXPECT_EQ(a.Union(b), result) << label;
1408  EXPECT_EQ(b.Union(a), result) << label;
1409  check_empty_flips(a, b, label);
1410  check_nans(a, b, label);
1411  };
1412 
1413  {
1414  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1415  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1416  auto expected = Rect::MakeXYWH(100, 100, 100, 100);
1417  test(a, b, expected);
1418  }
1419 
1420  {
1421  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1422  auto b = Rect::MakeXYWH(0, 0, 1, 1);
1423  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1424  test(a, b, expected);
1425  }
1426 
1427  {
1428  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1429  auto b = Rect::MakeXYWH(10, 10, 1, 1);
1430  auto expected = Rect::MakeXYWH(10, 10, 190, 190);
1431  test(a, b, expected);
1432  }
1433 
1434  {
1435  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1436  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1437  auto expected = Rect::MakeXYWH(0, 0, 110, 110);
1438  test(a, b, expected);
1439  }
1440 
1441  {
1442  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1443  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1444  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1445  test(a, b, expected);
1446  }
1447 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeXYWH(), swap_nan(), and impeller::TRect< T >::Union().

◆ TEST() [377/525]

impeller::testing::TEST ( RectTest  ,
RectXYWHIsEmpty   
)

Definition at line 1172 of file rect_unittests.cc.

1172  {
1173  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1174 
1175  // Non-empty
1176  EXPECT_FALSE(Rect::MakeXYWH(1.5, 2.3, 10.5, 7.2).IsEmpty());
1177 
1178  // Empty both width and height both 0 or negative, in all combinations
1179  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 0.0).IsEmpty());
1180  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, -1.0).IsEmpty());
1181  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, -1.0).IsEmpty());
1182  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 0.0).IsEmpty());
1183 
1184  // Empty for 0 or negative width or height (but not both at the same time)
1185  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, 0.0).IsEmpty());
1186  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, -1.0).IsEmpty());
1187  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 7.2).IsEmpty());
1188  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 7.2).IsEmpty());
1189 
1190  // Empty for NaN in width or height or both
1191  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, nan).IsEmpty());
1192  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, 7.2).IsEmpty());
1193  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, nan).IsEmpty());
1194 }

References impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [378/525]

impeller::testing::TEST ( RectTest  ,
TransformAndClipBounds   
)

Definition at line 3116 of file rect_unittests.cc.

3116  {
3117  {
3118  // This matrix should clip no corners.
3119  auto matrix = impeller::Matrix::MakeColumn(
3120  // clang-format off
3121  2.0f, 0.0f, 0.0f, 0.0f,
3122  0.0f, 4.0f, 0.0f, 0.0f,
3123  0.0f, 0.0f, 1.0f, 0.0f,
3124  0.0f, 0.0f, 0.0f, 8.0f
3125  // clang-format on
3126  );
3127  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3128  // None of these should have a W<0
3129  EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftTop()),
3130  Vector3(200.0f, 400.0f, 8.0f));
3131  EXPECT_EQ(matrix.TransformHomogenous(src.GetRightTop()),
3132  Vector3(400.0f, 400.0f, 8.0f));
3133  EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftBottom()),
3134  Vector3(200.0f, 800.0f, 8.0f));
3135  EXPECT_EQ(matrix.TransformHomogenous(src.GetRightBottom()),
3136  Vector3(400.0f, 800.0f, 8.0f));
3137 
3138  Rect expect = Rect::MakeLTRB(25.0f, 50.0f, 50.0f, 100.0f);
3139  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3140  EXPECT_EQ(src.TransformAndClipBounds(matrix), expect);
3141  }
3142 
3143  {
3144  // This matrix should clip one corner.
3145  auto matrix = impeller::Matrix::MakeColumn(
3146  // clang-format off
3147  2.0f, 0.0f, 0.0f, -0.01f,
3148  0.0f, 2.0f, 0.0f, -0.006f,
3149  0.0f, 0.0f, 1.0f, 0.0f,
3150  0.0f, 0.0f, 0.0f, 3.0f
3151  // clang-format on
3152  );
3153  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3154  // Exactly one of these should have a W<0
3155  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3156  Vector3(200.0f, 200.0f, 1.4f));
3157  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3158  Vector3(400.0f, 200.0f, 0.4f));
3159  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3160  Vector3(200.0f, 400.0f, 0.8f));
3161  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3162  Vector3(400.0f, 400.0f, -0.2f));
3163 
3164  Rect expect = Rect::MakeLTRB(142.85715f, 142.85715f, 6553600.f, 6553600.f);
3165  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3166  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3167  }
3168 
3169  {
3170  // This matrix should clip two corners.
3171  auto matrix = impeller::Matrix::MakeColumn(
3172  // clang-format off
3173  2.0f, 0.0f, 0.0f, -.015f,
3174  0.0f, 2.0f, 0.0f, -.006f,
3175  0.0f, 0.0f, 1.0f, 0.0f,
3176  0.0f, 0.0f, 0.0f, 3.0f
3177  // clang-format on
3178  );
3179  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3180  // Exactly two of these should have a W<0
3181  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3182  Vector3(200.0f, 200.0f, 0.9f));
3183  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3184  Vector3(400.0f, 200.0f, -0.6f));
3185  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3186  Vector3(200.0f, 400.0f, 0.3f));
3187  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3188  Vector3(400.0f, 400.0f, -1.2f));
3189 
3190  Rect expect = Rect::MakeLTRB(222.2222f, 222.2222f, 5898373.f, 6553600.f);
3191  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3192  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3193  }
3194 
3195  {
3196  // This matrix should clip three corners.
3197  auto matrix = impeller::Matrix::MakeColumn(
3198  // clang-format off
3199  2.0f, 0.0f, 0.0f, -.02f,
3200  0.0f, 2.0f, 0.0f, -.006f,
3201  0.0f, 0.0f, 1.0f, 0.0f,
3202  0.0f, 0.0f, 0.0f, 3.0f
3203  // clang-format on
3204  );
3205  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3206  // Exactly three of these should have a W<0
3207  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3208  Vector3(200.0f, 200.0f, 0.4f));
3209  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3210  Vector3(400.0f, 200.0f, -1.6f));
3211  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3212  Vector3(200.0f, 400.0f, -0.2f));
3213  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3214  Vector3(400.0f, 400.0f, -2.2f));
3215 
3216  Rect expect = Rect::MakeLTRB(499.99988f, 499.99988f, 5898340.f, 4369400.f);
3217  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3218  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3219  }
3220 
3221  {
3222  // This matrix should clip all four corners.
3223  auto matrix = impeller::Matrix::MakeColumn(
3224  // clang-format off
3225  2.0f, 0.0f, 0.0f, -.025f,
3226  0.0f, 2.0f, 0.0f, -.006f,
3227  0.0f, 0.0f, 1.0f, 0.0f,
3228  0.0f, 0.0f, 0.0f, 3.0f
3229  // clang-format on
3230  );
3231  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3232  // All of these should have a W<0
3233  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3234  Vector3(200.0f, 200.0f, -0.1f));
3235  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3236  Vector3(400.0f, 200.0f, -2.6f));
3237  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3238  Vector3(200.0f, 400.0f, -0.7f));
3239  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3240  Vector3(400.0f, 400.0f, -3.2f));
3241 
3242  EXPECT_TRUE(src.TransformAndClipBounds(matrix).IsEmpty());
3243  }
3244 }
static constexpr Matrix MakeColumn(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
Definition: matrix.h:69

References EXPECT_RECT_NEAR, EXPECT_VECTOR3_NEAR, impeller::TRect< T >::GetLeftBottom(), impeller::TRect< T >::GetLeftTop(), impeller::TRect< T >::GetRightBottom(), impeller::TRect< T >::GetRightTop(), impeller::TRect< T >::IsEmpty(), impeller::Matrix::MakeColumn(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< T >::TransformAndClipBounds().

◆ TEST() [379/525]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesMSAAResolveWithCorrectStore   
)

Definition at line 133 of file render_pass_builder_vk_unittests.cc.

133  {
134  RenderPassBuilderVK builder = RenderPassBuilderVK();
135  auto const context = MockVulkanContextBuilder().Build();
136 
137  // Create an MSAA color attachment.
138  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
139  SampleCount::kCount4, LoadAction::kClear,
140  StoreAction::kMultisampleResolve);
141 
142  auto render_pass = builder.Build(context->GetDevice());
143 
144  EXPECT_TRUE(!!render_pass);
145 
146  auto maybe_color = builder.GetColor0();
147  ASSERT_TRUE(maybe_color.has_value());
148  if (!maybe_color.has_value()) {
149  return;
150  }
151  vk::AttachmentDescription color = maybe_color.value();
152 
153  // MSAA Texture.
154  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eUndefined);
155  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
156  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
157  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eDontCare);
158 
159  auto maybe_resolve = builder.GetColor0Resolve();
160  ASSERT_TRUE(maybe_resolve.has_value());
161  if (!maybe_resolve.has_value()) {
162  return;
163  }
164  vk::AttachmentDescription resolve = maybe_resolve.value();
165 
166  // MSAA Resolve Texture.
167  EXPECT_EQ(resolve.initialLayout, vk::ImageLayout::eUndefined);
168  EXPECT_EQ(resolve.finalLayout, vk::ImageLayout::eShaderReadOnlyOptimal);
169  EXPECT_EQ(resolve.loadOp, vk::AttachmentLoadOp::eClear);
170  EXPECT_EQ(resolve.storeOp, vk::AttachmentStoreOp::eStore);
171 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetColor0(), impeller::RenderPassBuilderVK::GetColor0Resolve(), impeller::kClear, impeller::kCount4, impeller::kMultisampleResolve, impeller::kR8G8B8A8UNormInt, and impeller::RenderPassBuilderVK::SetColorAttachment().

◆ TEST() [380/525]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithCombinedDepthStencil   
)

Definition at line 56 of file render_pass_builder_vk_unittests.cc.

56  {
57  RenderPassBuilderVK builder = RenderPassBuilderVK();
58  auto const context = MockVulkanContextBuilder().Build();
59 
60  // Create a single color attachment with a transient depth stencil.
61  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
62  SampleCount::kCount1, LoadAction::kClear,
63  StoreAction::kStore, vk::ImageLayout::eGeneral);
64  builder.SetDepthStencilAttachment(PixelFormat::kD24UnormS8Uint,
65  SampleCount::kCount1, LoadAction::kDontCare,
66  StoreAction::kDontCare);
67 
68  auto render_pass = builder.Build(context->GetDevice());
69 
70  EXPECT_TRUE(!!render_pass);
71 
72  std::optional<vk::AttachmentDescription> maybe_color = builder.GetColor0();
73  ASSERT_TRUE(maybe_color.has_value());
74  if (!maybe_color.has_value()) {
75  return;
76  }
77  vk::AttachmentDescription color = maybe_color.value();
78 
79  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eUndefined);
80  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eShaderReadOnlyOptimal);
81  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
82  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eStore);
83 
84  std::optional<vk::AttachmentDescription> maybe_depth_stencil =
85  builder.GetDepthStencil();
86  ASSERT_TRUE(maybe_depth_stencil.has_value());
87  if (!maybe_depth_stencil.has_value()) {
88  return;
89  }
90  vk::AttachmentDescription depth_stencil = maybe_depth_stencil.value();
91 
92  EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
93  EXPECT_EQ(depth_stencil.finalLayout,
94  vk::ImageLayout::eDepthStencilAttachmentOptimal);
95  EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
96  EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
97  EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
98  EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
99 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetColor0(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kD24UnormS8Uint, impeller::kDontCare, impeller::kR8G8B8A8UNormInt, impeller::kStore, impeller::RenderPassBuilderVK::SetColorAttachment(), and impeller::RenderPassBuilderVK::SetDepthStencilAttachment().

◆ TEST() [381/525]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithNoDepthStencil   
)

Definition at line 15 of file render_pass_builder_vk_unittests.cc.

15  {
16  RenderPassBuilderVK builder = RenderPassBuilderVK();
17  auto const context = MockVulkanContextBuilder().Build();
18 
19  // Create a single color attachment with a transient depth stencil.
20  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
21  SampleCount::kCount1, LoadAction::kClear,
22  StoreAction::kStore);
23 
24  auto render_pass = builder.Build(context->GetDevice());
25 
26  EXPECT_TRUE(!!render_pass);
27  EXPECT_FALSE(builder.GetDepthStencil().has_value());
28 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kR8G8B8A8UNormInt, impeller::kStore, and impeller::RenderPassBuilderVK::SetColorAttachment().

◆ TEST() [382/525]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithOnlyStencil   
)

Definition at line 101 of file render_pass_builder_vk_unittests.cc.

101  {
102  RenderPassBuilderVK builder = RenderPassBuilderVK();
103  auto const context = MockVulkanContextBuilder().Build();
104 
105  // Create a single color attachment with a transient depth stencil.
106  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
107  SampleCount::kCount1, LoadAction::kClear,
108  StoreAction::kStore);
109  builder.SetStencilAttachment(PixelFormat::kS8UInt, SampleCount::kCount1,
110  LoadAction::kDontCare, StoreAction::kDontCare);
111 
112  auto render_pass = builder.Build(context->GetDevice());
113 
114  EXPECT_TRUE(!!render_pass);
115 
116  std::optional<vk::AttachmentDescription> maybe_depth_stencil =
117  builder.GetDepthStencil();
118  ASSERT_TRUE(maybe_depth_stencil.has_value());
119  if (!maybe_depth_stencil.has_value()) {
120  return;
121  }
122  vk::AttachmentDescription depth_stencil = maybe_depth_stencil.value();
123 
124  EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
125  EXPECT_EQ(depth_stencil.finalLayout,
126  vk::ImageLayout::eDepthStencilAttachmentOptimal);
127  EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
128  EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
129  EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
130  EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
131 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kDontCare, impeller::kR8G8B8A8UNormInt, impeller::kS8UInt, impeller::kStore, impeller::RenderPassBuilderVK::SetColorAttachment(), and impeller::RenderPassBuilderVK::SetStencilAttachment().

◆ TEST() [383/525]

impeller::testing::TEST ( RenderPassBuilder  ,
RenderPassWithLoadOpUsesCurrentLayout   
)

Definition at line 30 of file render_pass_builder_vk_unittests.cc.

30  {
31  RenderPassBuilderVK builder = RenderPassBuilderVK();
32  auto const context = MockVulkanContextBuilder().Build();
33 
34  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
35  SampleCount::kCount1, LoadAction::kLoad,
36  StoreAction::kStore,
37  vk::ImageLayout::eColorAttachmentOptimal);
38 
39  auto render_pass = builder.Build(context->GetDevice());
40 
41  EXPECT_TRUE(!!render_pass);
42 
43  std::optional<vk::AttachmentDescription> maybe_color = builder.GetColor0();
44  ASSERT_TRUE(maybe_color.has_value());
45  if (!maybe_color.has_value()) {
46  return;
47  }
48  vk::AttachmentDescription color = maybe_color.value();
49 
50  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eColorAttachmentOptimal);
51  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eShaderReadOnlyOptimal);
52  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eLoad);
53  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eStore);
54 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetColor0(), impeller::kCount1, impeller::kLoad, impeller::kR8G8B8A8UNormInt, impeller::kStore, and impeller::RenderPassBuilderVK::SetColorAttachment().

◆ TEST() [384/525]

impeller::testing::TEST ( RenderPassVK  ,
DoesNotRedundantlySetStencil   
)

Definition at line 17 of file render_pass_vk_unittests.cc.

17  {
18  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
19  std::shared_ptr<Context> copy = context;
20  auto cmd_buffer = context->CreateCommandBuffer();
21 
22  RenderTargetAllocator allocator(context->GetResourceAllocator());
23  RenderTarget target = allocator.CreateOffscreenMSAA(*copy.get(), {1, 1}, 1);
24 
25  std::shared_ptr<RenderPass> render_pass =
26  cmd_buffer->CreateRenderPass(target);
27 
28  // Stencil reference set once at buffer start.
29  auto called_functions = GetMockVulkanFunctions(context->GetDevice());
30  EXPECT_EQ(std::count(called_functions->begin(), called_functions->end(),
31  "vkCmdSetStencilReference"),
32  1);
33 
34  // Duplicate stencil ref is not replaced.
35  render_pass->SetStencilReference(0);
36  render_pass->SetStencilReference(0);
37  render_pass->SetStencilReference(0);
38 
39  called_functions = GetMockVulkanFunctions(context->GetDevice());
40  EXPECT_EQ(std::count(called_functions->begin(), called_functions->end(),
41  "vkCmdSetStencilReference"),
42  1);
43 
44  // Different stencil value is updated.
45  render_pass->SetStencilReference(1);
46  called_functions = GetMockVulkanFunctions(context->GetDevice());
47  EXPECT_EQ(std::count(called_functions->begin(), called_functions->end(),
48  "vkCmdSetStencilReference"),
49  2);
50 }

References impeller::RenderTargetAllocator::CreateOffscreenMSAA().

◆ TEST() [385/525]

impeller::testing::TEST ( ResourceManagerVKTest  ,
CreatesANewInstance   
)

Definition at line 18 of file resource_manager_vk_unittests.cc.

18  {
19  auto const a = ResourceManagerVK::Create();
20  auto const b = ResourceManagerVK::Create();
21  EXPECT_NE(a, b);
22 }
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:161

References impeller::saturated::b, and impeller::ResourceManagerVK::Create().

◆ TEST() [386/525]

impeller::testing::TEST ( ResourceManagerVKTest  ,
IsThreadSafe   
)

Definition at line 58 of file resource_manager_vk_unittests.cc.

58  {
59  // In a typical app, there is a single ResourceManagerVK per app, shared b/w
60  // threads.
61  //
62  // This test ensures that the ResourceManagerVK is thread-safe.
63  std::weak_ptr<ResourceManagerVK> manager;
64 
65  {
66  auto const manager = ResourceManagerVK::Create();
67 
68  // Spawn two threads, and have them both put resources into the manager.
69  struct MockResource {};
70 
71  std::thread thread1([&manager]() {
72  UniqueResourceVKT<MockResource>(manager, MockResource{});
73  });
74 
75  std::thread thread2([&manager]() {
76  UniqueResourceVKT<MockResource>(manager, MockResource{});
77  });
78 
79  thread1.join();
80  thread2.join();
81  }
82 
83  // The thread should have terminated.
84  EXPECT_EQ(manager.lock(), nullptr);
85 }

References impeller::ResourceManagerVK::Create().

◆ TEST() [387/525]

impeller::testing::TEST ( ResourceManagerVKTest  ,
ReclaimMovesAResourceAndDestroysIt   
)

Definition at line 24 of file resource_manager_vk_unittests.cc.

24  {
25  auto const manager = ResourceManagerVK::Create();
26 
27  auto waiter = fml::AutoResetWaitableEvent();
28  auto dead = false;
29  auto rattle = fml::ScopedCleanupClosure([&waiter]() { waiter.Signal(); });
30 
31  // Not killed immediately.
32  EXPECT_FALSE(waiter.IsSignaledForTest());
33 
34  {
35  auto resource = UniqueResourceVKT<fml::ScopedCleanupClosure>(
36  manager, std::move(rattle));
37  }
38 
39  waiter.Wait();
40 }

References impeller::ResourceManagerVK::Create().

◆ TEST() [388/525]

impeller::testing::TEST ( ResourceManagerVKTest  ,
TerminatesWhenOutOfScope   
)

Definition at line 43 of file resource_manager_vk_unittests.cc.

43  {
44  // Originally, this shared_ptr was never destroyed, and the thread never
45  // terminated. This test ensures that the thread terminates when the
46  // ResourceManagerVK is out of scope.
47  std::weak_ptr<ResourceManagerVK> manager;
48 
49  {
50  auto shared = ResourceManagerVK::Create();
51  manager = shared;
52  }
53 
54  // The thread should have terminated.
55  EXPECT_EQ(manager.lock(), nullptr);
56 }

References impeller::ResourceManagerVK::Create().

◆ TEST() [389/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiCornersSameTolerance   
)

Definition at line 268 of file rounding_radii_unittests.cc.

268  {
269  RoundingRadii radii{
270  .top_left = {10, 20},
271  .top_right = {10.01, 20.01},
272  .bottom_left = {9.99, 19.99},
273  .bottom_right = {9.99, 20.01},
274  };
275 
276  EXPECT_TRUE(radii.AreAllCornersSame(.02));
277 
278  {
279  RoundingRadii different = radii;
280  different.top_left.width = 10.03;
281  EXPECT_FALSE(different.AreAllCornersSame(.02));
282  }
283  {
284  RoundingRadii different = radii;
285  different.top_left.height = 20.03;
286  EXPECT_FALSE(different.AreAllCornersSame(.02));
287  }
288  {
289  RoundingRadii different = radii;
290  different.top_right.width = 10.03;
291  EXPECT_FALSE(different.AreAllCornersSame(.02));
292  }
293  {
294  RoundingRadii different = radii;
295  different.top_right.height = 20.03;
296  EXPECT_FALSE(different.AreAllCornersSame(.02));
297  }
298  {
299  RoundingRadii different = radii;
300  different.bottom_left.width = 9.97;
301  EXPECT_FALSE(different.AreAllCornersSame(.02));
302  }
303  {
304  RoundingRadii different = radii;
305  different.bottom_left.height = 19.97;
306  EXPECT_FALSE(different.AreAllCornersSame(.02));
307  }
308  {
309  RoundingRadii different = radii;
310  different.bottom_right.width = 9.97;
311  EXPECT_FALSE(different.AreAllCornersSame(.02));
312  }
313  {
314  RoundingRadii different = radii;
315  different.bottom_right.height = 20.03;
316  EXPECT_FALSE(different.AreAllCornersSame(.02));
317  }
318 }

References impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::TSize< T >::height, impeller::RoundingRadii::top_left, impeller::RoundingRadii::top_right, and impeller::TSize< T >::width.

◆ TEST() [390/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiDefaultConstructor   
)

Definition at line 34 of file rounding_radii_unittests.cc.

34  {
35  RoundingRadii radii = RoundingRadii();
36 
37  EXPECT_TRUE(radii.AreAllCornersEmpty());
38  EXPECT_TRUE(radii.AreAllCornersSame());
39  EXPECT_TRUE(radii.IsFinite());
40  EXPECT_EQ(radii.top_left, Size());
41  EXPECT_EQ(radii.top_right, Size());
42  EXPECT_EQ(radii.bottom_left, Size());
43  EXPECT_EQ(radii.bottom_right, Size());
44 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [391/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiEmptyDeclaration   
)

Definition at line 14 of file rounding_radii_unittests.cc.

14  {
15  RoundingRadii radii;
16 
17  EXPECT_TRUE(radii.AreAllCornersEmpty());
18  EXPECT_TRUE(radii.AreAllCornersSame());
19  EXPECT_TRUE(radii.IsFinite());
20  EXPECT_EQ(radii.top_left, Size());
21  EXPECT_EQ(radii.top_right, Size());
22  EXPECT_EQ(radii.bottom_left, Size());
23  EXPECT_EQ(radii.bottom_right, Size());
24  EXPECT_EQ(radii.top_left.width, 0.0f);
25  EXPECT_EQ(radii.top_left.height, 0.0f);
26  EXPECT_EQ(radii.top_right.width, 0.0f);
27  EXPECT_EQ(radii.top_right.height, 0.0f);
28  EXPECT_EQ(radii.bottom_left.width, 0.0f);
29  EXPECT_EQ(radii.bottom_left.height, 0.0f);
30  EXPECT_EQ(radii.bottom_right.width, 0.0f);
31  EXPECT_EQ(radii.bottom_right.height, 0.0f);
32 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::TSize< T >::height, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::top_left, impeller::RoundingRadii::top_right, and impeller::TSize< T >::width.

◆ TEST() [392/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiEmptyScalarConstructor   
)

Definition at line 58 of file rounding_radii_unittests.cc.

58  {
59  RoundingRadii radii = RoundingRadii::MakeRadius(-5.0f);
60 
61  EXPECT_TRUE(radii.AreAllCornersEmpty());
62  EXPECT_TRUE(radii.AreAllCornersSame());
63  EXPECT_TRUE(radii.IsFinite());
64  EXPECT_EQ(radii.top_left, Size(-5.0f, -5.0f));
65  EXPECT_EQ(radii.top_right, Size(-5.0f, -5.0f));
66  EXPECT_EQ(radii.bottom_left, Size(-5.0f, -5.0f));
67  EXPECT_EQ(radii.bottom_right, Size(-5.0f, -5.0f));
68 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::MakeRadius(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [393/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiEmptySizeConstructor   
)

Definition at line 82 of file rounding_radii_unittests.cc.

82  {
83  {
84  RoundingRadii radii = RoundingRadii::MakeRadii(Size(-5.0f, 6.0f));
85 
86  EXPECT_TRUE(radii.AreAllCornersEmpty());
87  EXPECT_TRUE(radii.AreAllCornersSame());
88  EXPECT_TRUE(radii.IsFinite());
89  EXPECT_EQ(radii.top_left, Size(-5.0f, 6.0f));
90  EXPECT_EQ(radii.top_right, Size(-5.0f, 6.0f));
91  EXPECT_EQ(radii.bottom_left, Size(-5.0f, 6.0f));
92  EXPECT_EQ(radii.bottom_right, Size(-5.0f, 6.0f));
93  }
94 
95  {
96  RoundingRadii radii = RoundingRadii::MakeRadii(Size(5.0f, -6.0f));
97 
98  EXPECT_TRUE(radii.AreAllCornersEmpty());
99  EXPECT_TRUE(radii.AreAllCornersSame());
100  EXPECT_TRUE(radii.IsFinite());
101  EXPECT_EQ(radii.top_left, Size(5.0f, -6.0f));
102  EXPECT_EQ(radii.top_right, Size(5.0f, -6.0f));
103  EXPECT_EQ(radii.bottom_left, Size(5.0f, -6.0f));
104  EXPECT_EQ(radii.bottom_right, Size(5.0f, -6.0f));
105  }
106 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::MakeRadii(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [394/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiEquals   
)

Definition at line 201 of file rounding_radii_unittests.cc.

201  {
202  RoundingRadii radii = {
203  .top_left = Size(5.0f, 5.5f),
204  .top_right = Size(6.0f, 6.5f),
205  .bottom_left = Size(7.0f, 7.5f),
206  .bottom_right = Size(8.0f, 8.5f),
207  };
208  RoundingRadii other = {
209  .top_left = Size(5.0f, 5.5f),
210  .top_right = Size(6.0f, 6.5f),
211  .bottom_left = Size(7.0f, 7.5f),
212  .bottom_right = Size(8.0f, 8.5f),
213  };
214 
215  EXPECT_EQ(radii, other);
216 }

References impeller::RoundingRadii::top_left.

◆ TEST() [395/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiMultiply   
)

Definition at line 183 of file rounding_radii_unittests.cc.

183  {
184  RoundingRadii radii = {
185  .top_left = Size(5.0f, 5.5f),
186  .top_right = Size(6.0f, 6.5f),
187  .bottom_left = Size(7.0f, 7.5f),
188  .bottom_right = Size(8.0f, 8.5f),
189  };
190  RoundingRadii doubled = radii * 2.0f;
191 
192  EXPECT_FALSE(doubled.AreAllCornersEmpty());
193  EXPECT_FALSE(doubled.AreAllCornersSame());
194  EXPECT_TRUE(doubled.IsFinite());
195  EXPECT_EQ(doubled.top_left, Size(10.0f, 11.0f));
196  EXPECT_EQ(doubled.top_right, Size(12.0f, 13.0f));
197  EXPECT_EQ(doubled.bottom_left, Size(14.0f, 15.0f));
198  EXPECT_EQ(doubled.bottom_right, Size(16.0f, 17.0f));
199 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [396/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiNamedSizesConstructor   
)

Definition at line 108 of file rounding_radii_unittests.cc.

108  {
109  RoundingRadii radii = {
110  .top_left = Size(5.0f, 5.5f),
111  .top_right = Size(6.0f, 6.5f),
112  .bottom_left = Size(7.0f, 7.5f),
113  .bottom_right = Size(8.0f, 8.5f),
114  };
115 
116  EXPECT_FALSE(radii.AreAllCornersEmpty());
117  EXPECT_FALSE(radii.AreAllCornersSame());
118  EXPECT_TRUE(radii.IsFinite());
119  EXPECT_EQ(radii.top_left, Size(5.0f, 5.5f));
120  EXPECT_EQ(radii.top_right, Size(6.0f, 6.5f));
121  EXPECT_EQ(radii.bottom_left, Size(7.0f, 7.5f));
122  EXPECT_EQ(radii.bottom_right, Size(8.0f, 8.5f));
123 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [397/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiNotEquals   
)

Definition at line 218 of file rounding_radii_unittests.cc.

218  {
219  const RoundingRadii radii = {
220  .top_left = Size(5.0f, 5.5f),
221  .top_right = Size(6.0f, 6.5f),
222  .bottom_left = Size(7.0f, 7.5f),
223  .bottom_right = Size(8.0f, 8.5f),
224  };
225 
226  {
227  RoundingRadii different = radii;
228  different.top_left.width = 100.0f;
229  EXPECT_NE(different, radii);
230  }
231  {
232  RoundingRadii different = radii;
233  different.top_left.height = 100.0f;
234  EXPECT_NE(different, radii);
235  }
236  {
237  RoundingRadii different = radii;
238  different.top_right.width = 100.0f;
239  EXPECT_NE(different, radii);
240  }
241  {
242  RoundingRadii different = radii;
243  different.top_right.height = 100.0f;
244  EXPECT_NE(different, radii);
245  }
246  {
247  RoundingRadii different = radii;
248  different.bottom_left.width = 100.0f;
249  EXPECT_NE(different, radii);
250  }
251  {
252  RoundingRadii different = radii;
253  different.bottom_left.height = 100.0f;
254  EXPECT_NE(different, radii);
255  }
256  {
257  RoundingRadii different = radii;
258  different.bottom_right.width = 100.0f;
259  EXPECT_NE(different, radii);
260  }
261  {
262  RoundingRadii different = radii;
263  different.bottom_right.height = 100.0f;
264  EXPECT_NE(different, radii);
265  }
266 }
Type width
Definition: size.h:28

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::TSize< T >::height, impeller::RoundingRadii::top_left, impeller::RoundingRadii::top_right, and impeller::TSize< T >::width.

◆ TEST() [398/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiPartialNamedSizesConstructor   
)

Definition at line 125 of file rounding_radii_unittests.cc.

125  {
126  {
127  RoundingRadii radii = {
128  .top_left = Size(5.0f, 5.5f),
129  };
130 
131  EXPECT_FALSE(radii.AreAllCornersEmpty());
132  EXPECT_FALSE(radii.AreAllCornersSame());
133  EXPECT_TRUE(radii.IsFinite());
134  EXPECT_EQ(radii.top_left, Size(5.0f, 5.5f));
135  EXPECT_EQ(radii.top_right, Size());
136  EXPECT_EQ(radii.bottom_left, Size());
137  EXPECT_EQ(radii.bottom_right, Size());
138  }
139 
140  {
141  RoundingRadii radii = {
142  .top_right = Size(6.0f, 6.5f),
143  };
144 
145  EXPECT_FALSE(radii.AreAllCornersEmpty());
146  EXPECT_FALSE(radii.AreAllCornersSame());
147  EXPECT_TRUE(radii.IsFinite());
148  EXPECT_EQ(radii.top_left, Size());
149  EXPECT_EQ(radii.top_right, Size(6.0f, 6.5f));
150  EXPECT_EQ(radii.bottom_left, Size());
151  EXPECT_EQ(radii.bottom_right, Size());
152  }
153 
154  {
155  RoundingRadii radii = {
156  .bottom_left = Size(7.0f, 7.5f),
157  };
158 
159  EXPECT_FALSE(radii.AreAllCornersEmpty());
160  EXPECT_FALSE(radii.AreAllCornersSame());
161  EXPECT_TRUE(radii.IsFinite());
162  EXPECT_EQ(radii.top_left, Size());
163  EXPECT_EQ(radii.top_right, Size());
164  EXPECT_EQ(radii.bottom_left, Size(7.0f, 7.5f));
165  EXPECT_EQ(radii.bottom_right, Size());
166  }
167 
168  {
169  RoundingRadii radii = {
170  .bottom_right = Size(8.0f, 8.5f),
171  };
172 
173  EXPECT_FALSE(radii.AreAllCornersEmpty());
174  EXPECT_FALSE(radii.AreAllCornersSame());
175  EXPECT_TRUE(radii.IsFinite());
176  EXPECT_EQ(radii.top_left, Size());
177  EXPECT_EQ(radii.top_right, Size());
178  EXPECT_EQ(radii.bottom_left, Size());
179  EXPECT_EQ(radii.bottom_right, Size(8.0f, 8.5f));
180  }
181 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [399/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiScalarConstructor   
)

Definition at line 46 of file rounding_radii_unittests.cc.

46  {
47  RoundingRadii radii = RoundingRadii::MakeRadius(5.0f);
48 
49  EXPECT_FALSE(radii.AreAllCornersEmpty());
50  EXPECT_TRUE(radii.AreAllCornersSame());
51  EXPECT_TRUE(radii.IsFinite());
52  EXPECT_EQ(radii.top_left, Size(5.0f, 5.0f));
53  EXPECT_EQ(radii.top_right, Size(5.0f, 5.0f));
54  EXPECT_EQ(radii.bottom_left, Size(5.0f, 5.0f));
55  EXPECT_EQ(radii.bottom_right, Size(5.0f, 5.0f));
56 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::MakeRadius(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [400/525]

impeller::testing::TEST ( RoudingRadiiTest  ,
RoundingRadiiSizeConstructor   
)

Definition at line 70 of file rounding_radii_unittests.cc.

70  {
71  RoundingRadii radii = RoundingRadii::MakeRadii(Size(5.0f, 6.0f));
72 
73  EXPECT_FALSE(radii.AreAllCornersEmpty());
74  EXPECT_TRUE(radii.AreAllCornersSame());
75  EXPECT_TRUE(radii.IsFinite());
76  EXPECT_EQ(radii.top_left, Size(5.0f, 6.0f));
77  EXPECT_EQ(radii.top_right, Size(5.0f, 6.0f));
78  EXPECT_EQ(radii.bottom_left, Size(5.0f, 6.0f));
79  EXPECT_EQ(radii.bottom_right, Size(5.0f, 6.0f));
80 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::MakeRadii(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [401/525]

impeller::testing::TEST ( RoundRectTest  ,
ContractAndRequireRadiiAdjustment   
)

Definition at line 496 of file round_rect_unittests.cc.

496  {
497  RoundRect round_rect =
498  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
499  {
500  .top_left = Size(1.0f, 2.0f),
501  .top_right = Size(3.0f, 4.0f),
502  .bottom_left = Size(5.0f, 6.0f),
503  .bottom_right = Size(7.0f, 8.0f),
504  });
505  RoundRect expanded = round_rect.Expand(-12.0);
506  // Largest sum of paired radii sizes are the bottom and right edges
507  // both of which sum to 12
508  // Rect was 30x30 reduced by 12 on all sides leaving only 6x6, so all
509  // radii are scaled by half to avoid overflowing the contracted rect
510 
511  EXPECT_FALSE(expanded.IsEmpty());
512  EXPECT_FALSE(expanded.IsRect());
513  EXPECT_FALSE(expanded.IsOval());
514  EXPECT_TRUE(expanded.IsFinite());
515  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
516  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(22.0f, 22.0f, 28.0f, 28.0f));
517  EXPECT_EQ(expanded.GetRadii().top_left, Size(0.5f, 1.0f));
518  EXPECT_EQ(expanded.GetRadii().top_right, Size(1.5f, 2.0f));
519  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(2.5f, 3.0f));
520  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(3.5f, 4.0f));
521 
522  // In this test, the MakeRectRadii constructor will make the same
523  // adjustment to the radii that the Expand method applied.
524  EXPECT_EQ(expanded,
525  RoundRect::MakeRectRadii(Rect::MakeXYWH(22.0f, 22.0f, 6.0f, 6.0f),
526  {
527  .top_left = Size(1.0f, 2.0f),
528  .top_right = Size(3.0f, 4.0f),
529  .bottom_left = Size(5.0f, 6.0f),
530  .bottom_right = Size(7.0f, 8.0f),
531  }));
532 
533  // In this test, the arguments to the constructor supply the correctly
534  // adjusted radii (though there is no real way to tell other than
535  // the result is the same).
536  EXPECT_EQ(expanded,
537  RoundRect::MakeRectRadii(Rect::MakeXYWH(22.0f, 22.0f, 6.0f, 6.0f),
538  {
539  .top_left = Size(0.5f, 1.0f),
540  .top_right = Size(1.5f, 2.0f),
541  .bottom_left = Size(2.5f, 3.0f),
542  .bottom_right = Size(3.5f, 4.0f),
543  }));
544 }

References impeller::RoundRect::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [402/525]

impeller::testing::TEST ( RoundRectTest  ,
ContractFourScalars   
)

Definition at line 464 of file round_rect_unittests.cc.

464  {
465  RoundRect round_rect =
466  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
467  {
468  .top_left = Size(1.0f, 2.0f),
469  .top_right = Size(3.0f, 4.0f),
470  .bottom_left = Size(5.0f, 6.0f),
471  .bottom_right = Size(7.0f, 8.0f),
472  });
473  RoundRect expanded = round_rect.Expand(-1.0, -1.5, -2.0, -2.5);
474 
475  EXPECT_FALSE(expanded.IsEmpty());
476  EXPECT_FALSE(expanded.IsRect());
477  EXPECT_FALSE(expanded.IsOval());
478  EXPECT_TRUE(expanded.IsFinite());
479  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
480  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(11.0f, 11.5f, 38.0f, 37.5f));
481  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
482  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
483  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
484  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
485 
486  EXPECT_EQ(expanded,
487  RoundRect::MakeRectRadii(Rect::MakeXYWH(11.0f, 11.5f, 27.0f, 26.0f),
488  {
489  .top_left = Size(1.0f, 2.0f),
490  .top_right = Size(3.0f, 4.0f),
491  .bottom_left = Size(5.0f, 6.0f),
492  .bottom_right = Size(7.0f, 8.0f),
493  }));
494 }

References impeller::RoundRect::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [403/525]

impeller::testing::TEST ( RoundRectTest  ,
ContractScalar   
)

Definition at line 400 of file round_rect_unittests.cc.

400  {
401  RoundRect round_rect =
402  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
403  {
404  .top_left = Size(1.0f, 2.0f),
405  .top_right = Size(3.0f, 4.0f),
406  .bottom_left = Size(5.0f, 6.0f),
407  .bottom_right = Size(7.0f, 8.0f),
408  });
409  RoundRect expanded = round_rect.Expand(-2.0);
410 
411  EXPECT_FALSE(expanded.IsEmpty());
412  EXPECT_FALSE(expanded.IsRect());
413  EXPECT_FALSE(expanded.IsOval());
414  EXPECT_TRUE(expanded.IsFinite());
415  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
416  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(12.0f, 12.0f, 38.0f, 38.0f));
417  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
418  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
419  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
420  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
421 
422  EXPECT_EQ(expanded,
423  RoundRect::MakeRectRadii(Rect::MakeXYWH(12.0f, 12.0f, 26.0f, 26.0f),
424  {
425  .top_left = Size(1.0f, 2.0f),
426  .top_right = Size(3.0f, 4.0f),
427  .bottom_left = Size(5.0f, 6.0f),
428  .bottom_right = Size(7.0f, 8.0f),
429  }));
430 }

References impeller::RoundRect::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [404/525]

impeller::testing::TEST ( RoundRectTest  ,
ContractTwoScalars   
)

Definition at line 432 of file round_rect_unittests.cc.

432  {
433  RoundRect round_rect =
434  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
435  {
436  .top_left = Size(1.0f, 2.0f),
437  .top_right = Size(3.0f, 4.0f),
438  .bottom_left = Size(5.0f, 6.0f),
439  .bottom_right = Size(7.0f, 8.0f),
440  });
441  RoundRect expanded = round_rect.Expand(-1.0, -2.0);
442 
443  EXPECT_FALSE(expanded.IsEmpty());
444  EXPECT_FALSE(expanded.IsRect());
445  EXPECT_FALSE(expanded.IsOval());
446  EXPECT_TRUE(expanded.IsFinite());
447  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
448  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(11.0f, 12.0f, 39.0f, 38.0f));
449  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
450  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
451  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
452  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
453 
454  EXPECT_EQ(expanded,
455  RoundRect::MakeRectRadii(Rect::MakeXYWH(11.0f, 12.0f, 28.0f, 26.0f),
456  {
457  .top_left = Size(1.0f, 2.0f),
458  .top_right = Size(3.0f, 4.0f),
459  .bottom_left = Size(5.0f, 6.0f),
460  .bottom_right = Size(7.0f, 8.0f),
461  }));
462 }

References impeller::RoundRect::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [405/525]

impeller::testing::TEST ( RoundRectTest  ,
DefaultConstructor   
)

Definition at line 41 of file round_rect_unittests.cc.

41  {
42  RoundRect round_rect = RoundRect();
43 
44  EXPECT_TRUE(round_rect.IsEmpty());
45  EXPECT_FALSE(round_rect.IsRect());
46  EXPECT_FALSE(round_rect.IsOval());
47  EXPECT_TRUE(round_rect.IsFinite());
48  EXPECT_TRUE(round_rect.GetBounds().IsEmpty());
49  EXPECT_EQ(round_rect.GetBounds(), Rect());
50  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
51  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
52  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
53  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
54 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [406/525]

impeller::testing::TEST ( RoundRectTest  ,
DifferingCornersRoundRectContains   
)

Definition at line 652 of file round_rect_unittests.cc.

652  {
653  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
654  auto round_rect =
655  RoundRect::MakeRectRadii(bounds, {
656  .top_left = Size(2.0, 3.0),
657  .top_right = Size(4.0, 5.0),
658  .bottom_left = Size(6.0, 7.0),
659  .bottom_right = Size(8.0, 9.0),
660  });
661 
662  // For a corner with radii {A, B}, the "45 degree point" on the
663  // corner curve will be at an offset of:
664  //
665  // (A * sqrt(2) / 2, B * sqrt(2) / 2)
666  //
667  // And the center(s) of these corners are at:
668  //
669  // (+/-(50 - A), +/-(50 - B))
670  auto coord = [](Scalar radius) {
671  return 50 - radius + radius * kSqrt2 / 2.0f - kEhCloseEnough;
672  };
673  auto coord_in = [&coord](Scalar radius) {
674  return coord(radius) - kEhCloseEnough;
675  };
676  auto coord_out = [&coord](Scalar radius) {
677  // For some reason 1 kEhCloseEnough is not enough to put us outside
678  // in some of the cases, so we use 2x the epsilon.
679  return coord(radius) + 2 * kEhCloseEnough;
680  };
681  // Upper left corner (radii = {2.0, 3.0})
682  EXPECT_TRUE(round_rect.Contains({-coord_in(2.0), -coord_in(3.0)}));
683  EXPECT_FALSE(round_rect.Contains({-coord_out(2.0), -coord_out(3.0)}));
684  // Upper right corner (radii = {4.0, 5.0})
685  EXPECT_TRUE(round_rect.Contains({coord_in(4.0), -coord_in(5.0)}));
686  EXPECT_FALSE(round_rect.Contains({coord_out(4.0), -coord_out(5.0)}));
687  // Lower left corner (radii = {6.0, 7.0})
688  EXPECT_TRUE(round_rect.Contains({-coord_in(6.0), coord_in(7.0)}));
689  EXPECT_FALSE(round_rect.Contains({-coord_out(6.0), coord_out(7.0)}));
690  // Lower right corner (radii = {8.0, 9.0})
691  EXPECT_TRUE(round_rect.Contains({coord_in(8.0), coord_in(9.0)}));
692  EXPECT_FALSE(round_rect.Contains({coord_out(8.0), coord_out(9.0)}));
693 }

References impeller::kEhCloseEnough, impeller::kSqrt2, impeller::TRect< Scalar >::MakeLTRB(), and impeller::RoundRect::MakeRectRadii().

◆ TEST() [407/525]

impeller::testing::TEST ( RoundRectTest  ,
EmptyDeclaration   
)

Definition at line 14 of file round_rect_unittests.cc.

14  {
15  RoundRect round_rect;
16 
17  EXPECT_TRUE(round_rect.IsEmpty());
18  EXPECT_FALSE(round_rect.IsRect());
19  EXPECT_FALSE(round_rect.IsOval());
20  EXPECT_TRUE(round_rect.IsFinite());
21  EXPECT_TRUE(round_rect.GetBounds().IsEmpty());
22  EXPECT_EQ(round_rect.GetBounds(), Rect());
23  EXPECT_EQ(round_rect.GetBounds().GetLeft(), 0.0f);
24  EXPECT_EQ(round_rect.GetBounds().GetTop(), 0.0f);
25  EXPECT_EQ(round_rect.GetBounds().GetRight(), 0.0f);
26  EXPECT_EQ(round_rect.GetBounds().GetBottom(), 0.0f);
27  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
28  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
29  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
30  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
31  EXPECT_EQ(round_rect.GetRadii().top_left.width, 0.0f);
32  EXPECT_EQ(round_rect.GetRadii().top_left.height, 0.0f);
33  EXPECT_EQ(round_rect.GetRadii().top_right.width, 0.0f);
34  EXPECT_EQ(round_rect.GetRadii().top_right.height, 0.0f);
35  EXPECT_EQ(round_rect.GetRadii().bottom_left.width, 0.0f);
36  EXPECT_EQ(round_rect.GetRadii().bottom_left.height, 0.0f);
37  EXPECT_EQ(round_rect.GetRadii().bottom_right.width, 0.0f);
38  EXPECT_EQ(round_rect.GetRadii().bottom_right.height, 0.0f);
39 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::TRect< T >::GetBottom(), impeller::RoundRect::GetBounds(), impeller::TRect< T >::GetLeft(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TSize< T >::height, impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::RoundingRadii::top_left, impeller::RoundingRadii::top_right, and impeller::TSize< T >::width.

◆ TEST() [408/525]

impeller::testing::TEST ( RoundRectTest  ,
EmptyOvalConstruction   
)

Definition at line 104 of file round_rect_unittests.cc.

104  {
105  RoundRect round_rect = RoundRect::MakeRectXY(
106  Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f), 10.0f, 10.0f);
107 
108  EXPECT_TRUE(round_rect.IsEmpty());
109  EXPECT_FALSE(round_rect.IsRect());
110  EXPECT_FALSE(round_rect.IsOval());
111  EXPECT_TRUE(round_rect.IsFinite());
112  EXPECT_TRUE(round_rect.GetBounds().IsEmpty());
113  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
114  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
115  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
116  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
117  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
118 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [409/525]

impeller::testing::TEST ( RoundRectTest  ,
EmptyRectConstruction   
)

Definition at line 56 of file round_rect_unittests.cc.

56  {
57  RoundRect round_rect =
58  RoundRect::MakeRect(Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
59 
60  EXPECT_TRUE(round_rect.IsEmpty());
61  EXPECT_FALSE(round_rect.IsRect());
62  EXPECT_FALSE(round_rect.IsOval());
63  EXPECT_TRUE(round_rect.IsFinite());
64  EXPECT_TRUE(round_rect.GetBounds().IsEmpty());
65  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
66  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
67  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
68  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
69  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
70 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [410/525]

impeller::testing::TEST ( RoundRectTest  ,
ExpandFourScalars   
)

Definition at line 368 of file round_rect_unittests.cc.

368  {
369  RoundRect round_rect =
370  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
371  {
372  .top_left = Size(1.0f, 2.0f),
373  .top_right = Size(3.0f, 4.0f),
374  .bottom_left = Size(5.0f, 6.0f),
375  .bottom_right = Size(7.0f, 8.0f),
376  });
377  RoundRect expanded = round_rect.Expand(5.0, 6.0, 7.0, 8.0);
378 
379  EXPECT_FALSE(expanded.IsEmpty());
380  EXPECT_FALSE(expanded.IsRect());
381  EXPECT_FALSE(expanded.IsOval());
382  EXPECT_TRUE(expanded.IsFinite());
383  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
384  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 4.0f, 47.0f, 48.0f));
385  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
386  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
387  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
388  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
389 
390  EXPECT_EQ(expanded,
391  RoundRect::MakeRectRadii(Rect::MakeXYWH(5.0f, 4.0f, 42.0f, 44.0f),
392  {
393  .top_left = Size(1.0f, 2.0f),
394  .top_right = Size(3.0f, 4.0f),
395  .bottom_left = Size(5.0f, 6.0f),
396  .bottom_right = Size(7.0f, 8.0f),
397  }));
398 }

References impeller::RoundRect::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [411/525]

impeller::testing::TEST ( RoundRectTest  ,
ExpandScalar   
)

Definition at line 304 of file round_rect_unittests.cc.

304  {
305  RoundRect round_rect =
306  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
307  {
308  .top_left = Size(1.0f, 2.0f),
309  .top_right = Size(3.0f, 4.0f),
310  .bottom_left = Size(5.0f, 6.0f),
311  .bottom_right = Size(7.0f, 8.0f),
312  });
313  RoundRect expanded = round_rect.Expand(5.0);
314 
315  EXPECT_FALSE(expanded.IsEmpty());
316  EXPECT_FALSE(expanded.IsRect());
317  EXPECT_FALSE(expanded.IsOval());
318  EXPECT_TRUE(expanded.IsFinite());
319  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
320  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 5.0f, 45.0f, 45.0f));
321  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
322  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
323  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
324  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
325 
326  EXPECT_EQ(expanded,
327  RoundRect::MakeRectRadii(Rect::MakeXYWH(5.0f, 5.0f, 40.0f, 40.0f),
328  {
329  .top_left = Size(1.0f, 2.0f),
330  .top_right = Size(3.0f, 4.0f),
331  .bottom_left = Size(5.0f, 6.0f),
332  .bottom_right = Size(7.0f, 8.0f),
333  }));
334 }

References impeller::RoundRect::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [412/525]

impeller::testing::TEST ( RoundRectTest  ,
ExpandTwoScalars   
)

Definition at line 336 of file round_rect_unittests.cc.

336  {
337  RoundRect round_rect =
338  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
339  {
340  .top_left = Size(1.0f, 2.0f),
341  .top_right = Size(3.0f, 4.0f),
342  .bottom_left = Size(5.0f, 6.0f),
343  .bottom_right = Size(7.0f, 8.0f),
344  });
345  RoundRect expanded = round_rect.Expand(5.0, 6.0);
346 
347  EXPECT_FALSE(expanded.IsEmpty());
348  EXPECT_FALSE(expanded.IsRect());
349  EXPECT_FALSE(expanded.IsOval());
350  EXPECT_TRUE(expanded.IsFinite());
351  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
352  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 4.0f, 45.0f, 46.0f));
353  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
354  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
355  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
356  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
357 
358  EXPECT_EQ(expanded,
359  RoundRect::MakeRectRadii(Rect::MakeXYWH(5.0f, 4.0f, 40.0f, 42.0f),
360  {
361  .top_left = Size(1.0f, 2.0f),
362  .top_right = Size(3.0f, 4.0f),
363  .bottom_left = Size(5.0f, 6.0f),
364  .bottom_right = Size(7.0f, 8.0f),
365  }));
366 }

References impeller::RoundRect::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [413/525]

impeller::testing::TEST ( RoundRectTest  ,
InvertedOvalConstruction   
)

Definition at line 136 of file round_rect_unittests.cc.

136  {
137  RoundRect round_rect = RoundRect::MakeRectXY(
138  Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f), 10.0f, 10.0f);
139 
140  EXPECT_FALSE(round_rect.IsEmpty());
141  EXPECT_FALSE(round_rect.IsRect());
142  EXPECT_TRUE(round_rect.IsOval());
143  EXPECT_TRUE(round_rect.IsFinite());
144  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
145  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
146  EXPECT_EQ(round_rect.GetRadii().top_left, Size(5.0f, 5.0f));
147  EXPECT_EQ(round_rect.GetRadii().top_right, Size(5.0f, 5.0f));
148  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(5.0f, 5.0f));
149  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(5.0f, 5.0f));
150 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [414/525]

impeller::testing::TEST ( RoundRectTest  ,
InvertedRectConstruction   
)

Definition at line 88 of file round_rect_unittests.cc.

88  {
89  RoundRect round_rect =
90  RoundRect::MakeRect(Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f));
91 
92  EXPECT_FALSE(round_rect.IsEmpty());
93  EXPECT_TRUE(round_rect.IsRect());
94  EXPECT_FALSE(round_rect.IsOval());
95  EXPECT_TRUE(round_rect.IsFinite());
96  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
97  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
98  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
99  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
100  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
101  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
102 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [415/525]

impeller::testing::TEST ( RoundRectTest  ,
NoCornerRoundRectContains   
)

Definition at line 546 of file round_rect_unittests.cc.

546  {
547  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
548  // RRect of bounds with no corners contains corners just barely
549  auto no_corners = RoundRect::MakeRectXY(bounds, 0.0f, 0.0f);
550 
551  EXPECT_TRUE(no_corners.Contains({-50, -50}));
552  // Rectangles have half-in, half-out containment so we need
553  // to be careful about testing containment of right/bottom corners.
554  EXPECT_TRUE(no_corners.Contains({-50, 49.99}));
555  EXPECT_TRUE(no_corners.Contains({49.99, -50}));
556  EXPECT_TRUE(no_corners.Contains({49.99, 49.99}));
557  EXPECT_FALSE(no_corners.Contains({-50.01, -50}));
558  EXPECT_FALSE(no_corners.Contains({-50, -50.01}));
559  EXPECT_FALSE(no_corners.Contains({-50.01, 50}));
560  EXPECT_FALSE(no_corners.Contains({-50, 50.01}));
561  EXPECT_FALSE(no_corners.Contains({50.01, -50}));
562  EXPECT_FALSE(no_corners.Contains({50, -50.01}));
563  EXPECT_FALSE(no_corners.Contains({50.01, 50}));
564  EXPECT_FALSE(no_corners.Contains({50, 50.01}));
565 }

References impeller::TRect< Scalar >::MakeLTRB(), and impeller::RoundRect::MakeRectXY().

◆ TEST() [416/525]

impeller::testing::TEST ( RoundRectTest  ,
OvalConstructor   
)

Definition at line 120 of file round_rect_unittests.cc.

120  {
121  RoundRect round_rect =
122  RoundRect::MakeOval(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
123 
124  EXPECT_FALSE(round_rect.IsEmpty());
125  EXPECT_FALSE(round_rect.IsRect());
126  EXPECT_TRUE(round_rect.IsOval());
127  EXPECT_TRUE(round_rect.IsFinite());
128  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
129  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
130  EXPECT_EQ(round_rect.GetRadii().top_left, Size(5.0f, 5.0f));
131  EXPECT_EQ(round_rect.GetRadii().top_right, Size(5.0f, 5.0f));
132  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(5.0f, 5.0f));
133  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(5.0f, 5.0f));
134 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeOval(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [417/525]

impeller::testing::TEST ( RoundRectTest  ,
RectConstructor   
)

Definition at line 72 of file round_rect_unittests.cc.

72  {
73  RoundRect round_rect =
74  RoundRect::MakeRect(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
75 
76  EXPECT_FALSE(round_rect.IsEmpty());
77  EXPECT_TRUE(round_rect.IsRect());
78  EXPECT_FALSE(round_rect.IsOval());
79  EXPECT_TRUE(round_rect.IsFinite());
80  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
81  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
82  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
83  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
84  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
85  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
86 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [418/525]

impeller::testing::TEST ( RoundRectTest  ,
RectRadiiConstructor   
)

Definition at line 200 of file round_rect_unittests.cc.

200  {
201  RoundRect round_rect =
202  RoundRect::MakeRectRadii(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f),
203  {
204  .top_left = Size(1.0, 1.5),
205  .top_right = Size(2.0, 2.5f),
206  .bottom_left = Size(3.0, 3.5f),
207  .bottom_right = Size(4.0, 4.5f),
208  });
209 
210  EXPECT_FALSE(round_rect.IsEmpty());
211  EXPECT_FALSE(round_rect.IsRect());
212  EXPECT_FALSE(round_rect.IsOval());
213  EXPECT_TRUE(round_rect.IsFinite());
214  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
215  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
216  EXPECT_EQ(round_rect.GetRadii().top_left, Size(1.0f, 1.5f));
217  EXPECT_EQ(round_rect.GetRadii().top_right, Size(2.0f, 2.5f));
218  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(3.0f, 3.5f));
219  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(4.0f, 4.5f));
220 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [419/525]

impeller::testing::TEST ( RoundRectTest  ,
RectRadiiOverflowHeightConstructor   
)

Definition at line 247 of file round_rect_unittests.cc.

247  {
248  RoundRect round_rect =
249  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 6.0f),
250  {
251  .top_left = Size(1.0f, 2.0f),
252  .top_right = Size(3.0f, 4.0f),
253  .bottom_left = Size(5.0f, 6.0f),
254  .bottom_right = Size(7.0f, 8.0f),
255  });
256  // Largest sum of paired radii heights is the right edge which sums to 12
257  // Rect is only 6 tall so all radii are scaled by half
258  // Rect is 30 wide so no scaling should happen due to radii widths
259 
260  EXPECT_FALSE(round_rect.IsEmpty());
261  EXPECT_FALSE(round_rect.IsRect());
262  EXPECT_FALSE(round_rect.IsOval());
263  EXPECT_TRUE(round_rect.IsFinite());
264  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
265  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 40.0f, 16.0f));
266  EXPECT_EQ(round_rect.GetRadii().top_left, Size(0.5f, 1.0f));
267  EXPECT_EQ(round_rect.GetRadii().top_right, Size(1.5f, 2.0f));
268  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(2.5f, 3.0f));
269  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(3.5f, 4.0f));
270 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), impeller::TRect< Scalar >::MakeXYWH(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [420/525]

impeller::testing::TEST ( RoundRectTest  ,
RectRadiiOverflowWidthConstructor   
)

Definition at line 222 of file round_rect_unittests.cc.

222  {
223  RoundRect round_rect =
224  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 6.0f, 30.0f),
225  {
226  .top_left = Size(1.0f, 2.0f),
227  .top_right = Size(3.0f, 4.0f),
228  .bottom_left = Size(5.0f, 6.0f),
229  .bottom_right = Size(7.0f, 8.0f),
230  });
231  // Largest sum of paired radii widths is the bottom edge which sums to 12
232  // Rect is only 6 wide so all radii are scaled by half
233  // Rect is 30 tall so no scaling should happen due to radii heights
234 
235  EXPECT_FALSE(round_rect.IsEmpty());
236  EXPECT_FALSE(round_rect.IsRect());
237  EXPECT_FALSE(round_rect.IsOval());
238  EXPECT_TRUE(round_rect.IsFinite());
239  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
240  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 16.0f, 40.0f));
241  EXPECT_EQ(round_rect.GetRadii().top_left, Size(0.5f, 1.0f));
242  EXPECT_EQ(round_rect.GetRadii().top_right, Size(1.5f, 2.0f));
243  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(2.5f, 3.0f));
244  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(3.5f, 4.0f));
245 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), impeller::TRect< Scalar >::MakeXYWH(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [421/525]

impeller::testing::TEST ( RoundRectTest  ,
RectRadiusConstructor   
)

Definition at line 152 of file round_rect_unittests.cc.

152  {
153  RoundRect round_rect = RoundRect::MakeRectRadius(
154  Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), 2.0f);
155 
156  EXPECT_FALSE(round_rect.IsEmpty());
157  EXPECT_FALSE(round_rect.IsRect());
158  EXPECT_FALSE(round_rect.IsOval());
159  EXPECT_TRUE(round_rect.IsFinite());
160  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
161  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
162  EXPECT_EQ(round_rect.GetRadii().top_left, Size(2.0f, 2.0f));
163  EXPECT_EQ(round_rect.GetRadii().top_right, Size(2.0f, 2.0f));
164  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(2.0f, 2.0f));
165  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(2.0f, 2.0f));
166 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadius(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [422/525]

impeller::testing::TEST ( RoundRectTest  ,
RectSizeConstructor   
)

Definition at line 184 of file round_rect_unittests.cc.

184  {
185  RoundRect round_rect = RoundRect::MakeRectXY(
186  Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), Size(2.0f, 3.0f));
187 
188  EXPECT_FALSE(round_rect.IsEmpty());
189  EXPECT_FALSE(round_rect.IsRect());
190  EXPECT_FALSE(round_rect.IsOval());
191  EXPECT_TRUE(round_rect.IsFinite());
192  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
193  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
194  EXPECT_EQ(round_rect.GetRadii().top_left, Size(2.0f, 3.0f));
195  EXPECT_EQ(round_rect.GetRadii().top_right, Size(2.0f, 3.0f));
196  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(2.0f, 3.0f));
197  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(2.0f, 3.0f));
198 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [423/525]

impeller::testing::TEST ( RoundRectTest  ,
RectXYConstructor   
)

Definition at line 168 of file round_rect_unittests.cc.

168  {
169  RoundRect round_rect = RoundRect::MakeRectXY(
170  Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), 2.0f, 3.0f);
171 
172  EXPECT_FALSE(round_rect.IsEmpty());
173  EXPECT_FALSE(round_rect.IsRect());
174  EXPECT_FALSE(round_rect.IsOval());
175  EXPECT_TRUE(round_rect.IsFinite());
176  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
177  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
178  EXPECT_EQ(round_rect.GetRadii().top_left, Size(2.0f, 3.0f));
179  EXPECT_EQ(round_rect.GetRadii().top_right, Size(2.0f, 3.0f));
180  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(2.0f, 3.0f));
181  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(2.0f, 3.0f));
182 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [424/525]

impeller::testing::TEST ( RoundRectTest  ,
Shift   
)

Definition at line 272 of file round_rect_unittests.cc.

272  {
273  RoundRect round_rect =
274  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
275  {
276  .top_left = Size(1.0f, 2.0f),
277  .top_right = Size(3.0f, 4.0f),
278  .bottom_left = Size(5.0f, 6.0f),
279  .bottom_right = Size(7.0f, 8.0f),
280  });
281  RoundRect shifted = round_rect.Shift(5.0, 6.0);
282 
283  EXPECT_FALSE(shifted.IsEmpty());
284  EXPECT_FALSE(shifted.IsRect());
285  EXPECT_FALSE(shifted.IsOval());
286  EXPECT_TRUE(shifted.IsFinite());
287  EXPECT_FALSE(shifted.GetBounds().IsEmpty());
288  EXPECT_EQ(shifted.GetBounds(), Rect::MakeLTRB(15.0f, 16.0f, 45.0f, 46.0f));
289  EXPECT_EQ(shifted.GetRadii().top_left, Size(1.0f, 2.0f));
290  EXPECT_EQ(shifted.GetRadii().top_right, Size(3.0f, 4.0f));
291  EXPECT_EQ(shifted.GetRadii().bottom_left, Size(5.0f, 6.0f));
292  EXPECT_EQ(shifted.GetRadii().bottom_right, Size(7.0f, 8.0f));
293 
294  EXPECT_EQ(shifted,
295  RoundRect::MakeRectRadii(Rect::MakeXYWH(15.0f, 16.0f, 30.0f, 30.0f),
296  {
297  .top_left = Size(1.0f, 2.0f),
298  .top_right = Size(3.0f, 4.0f),
299  .bottom_left = Size(5.0f, 6.0f),
300  .bottom_right = Size(7.0f, 8.0f),
301  }));
302 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::RoundRect::Shift().

◆ TEST() [425/525]

impeller::testing::TEST ( RoundRectTest  ,
TinyCornerRoundRectContains   
)

Definition at line 567 of file round_rect_unittests.cc.

567  {
568  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
569  // RRect of bounds with even the tiniest corners does not contain corners
570  auto tiny_corners = RoundRect::MakeRectXY(bounds, 0.01f, 0.01f);
571 
572  EXPECT_FALSE(tiny_corners.Contains({-50, -50}));
573  EXPECT_FALSE(tiny_corners.Contains({-50, 50}));
574  EXPECT_FALSE(tiny_corners.Contains({50, -50}));
575  EXPECT_FALSE(tiny_corners.Contains({50, 50}));
576 }

References impeller::TRect< Scalar >::MakeLTRB(), and impeller::RoundRect::MakeRectXY().

◆ TEST() [426/525]

impeller::testing::TEST ( RoundRectTest  ,
UniformCircularRoundRectContains   
)

Definition at line 578 of file round_rect_unittests.cc.

578  {
579  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
580  auto expanded_2_r_2 = RoundRect::MakeRectXY(bounds.Expand(2.0), 2.0f, 2.0f);
581 
582  // Expanded by 2.0 and then with a corner of 2.0 obviously still
583  // contains the corners
584  EXPECT_TRUE(expanded_2_r_2.Contains({-50, -50}));
585  EXPECT_TRUE(expanded_2_r_2.Contains({-50, 50}));
586  EXPECT_TRUE(expanded_2_r_2.Contains({50, -50}));
587  EXPECT_TRUE(expanded_2_r_2.Contains({50, 50}));
588 
589  // Now we try to box in the corner containment to exactly where the
590  // rounded corner of the expanded round rect with radii of 2.0 lies.
591  // The 45-degree diagonal point of a circle of radius 2.0 lies at:
592  //
593  // (2 * sqrt(2) / 2, 2 * sqrt(2) / 2)
594  // (sqrt(2), sqrt(2))
595  //
596  // So we test +/- (50 + sqrt(2) +/- epsilon)
597  const auto coord_out = 50 + kSqrt2 + kEhCloseEnough;
598  const auto coord_in = 50 + kSqrt2 - kEhCloseEnough;
599  // Upper left corner
600  EXPECT_TRUE(expanded_2_r_2.Contains({-coord_in, -coord_in}));
601  EXPECT_FALSE(expanded_2_r_2.Contains({-coord_out, -coord_out}));
602  // Upper right corner
603  EXPECT_TRUE(expanded_2_r_2.Contains({coord_in, -coord_in}));
604  EXPECT_FALSE(expanded_2_r_2.Contains({coord_out, -coord_out}));
605  // Lower left corner
606  EXPECT_TRUE(expanded_2_r_2.Contains({-coord_in, coord_in}));
607  EXPECT_FALSE(expanded_2_r_2.Contains({-coord_out, coord_out}));
608  // Lower right corner
609  EXPECT_TRUE(expanded_2_r_2.Contains({coord_in, coord_in}));
610  EXPECT_FALSE(expanded_2_r_2.Contains({coord_out, coord_out}));
611 }

References impeller::TRect< T >::Expand(), impeller::kEhCloseEnough, impeller::kSqrt2, impeller::TRect< Scalar >::MakeLTRB(), and impeller::RoundRect::MakeRectXY().

◆ TEST() [427/525]

impeller::testing::TEST ( RoundRectTest  ,
UniformEllipticalRoundRectContains   
)

Definition at line 613 of file round_rect_unittests.cc.

613  {
614  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
615  auto expanded_2_r_2 = RoundRect::MakeRectXY(bounds.Expand(2.0), 2.0f, 3.0f);
616 
617  // Expanded by 2.0 and then with a corner of 2x3 should still
618  // contain the corners
619  EXPECT_TRUE(expanded_2_r_2.Contains({-50, -50}));
620  EXPECT_TRUE(expanded_2_r_2.Contains({-50, 50}));
621  EXPECT_TRUE(expanded_2_r_2.Contains({50, -50}));
622  EXPECT_TRUE(expanded_2_r_2.Contains({50, 50}));
623 
624  // Now we try to box in the corner containment to exactly where the
625  // rounded corner of the expanded round rect with radii of 2x3 lies.
626  // The "45-degree diagonal point" of an ellipse of radii 2x3 lies at:
627  //
628  // (2 * sqrt(2) / 2, 3 * sqrt(2) / 2)
629  // (sqrt(2), 3 * sqrt(2) / 2)
630  //
631  // And the center(s) of these corners are at:
632  // (+/-(50 + 2 - 2), +/-(50 + 2 - 3))
633  // = (+/-50, +/-49)
634  const auto x_coord_out = 50 + kSqrt2 + kEhCloseEnough;
635  const auto x_coord_in = 50 + kSqrt2 - kEhCloseEnough;
636  const auto y_coord_out = 49 + 3 * kSqrt2 / 2 + kEhCloseEnough;
637  const auto y_coord_in = 49 + 3 * kSqrt2 / 2 - kEhCloseEnough;
638  // Upper left corner
639  EXPECT_TRUE(expanded_2_r_2.Contains({-x_coord_in, -y_coord_in}));
640  EXPECT_FALSE(expanded_2_r_2.Contains({-x_coord_out, -y_coord_out}));
641  // Upper right corner
642  EXPECT_TRUE(expanded_2_r_2.Contains({x_coord_in, -y_coord_in}));
643  EXPECT_FALSE(expanded_2_r_2.Contains({x_coord_out, -y_coord_out}));
644  // Lower left corner
645  EXPECT_TRUE(expanded_2_r_2.Contains({-x_coord_in, y_coord_in}));
646  EXPECT_FALSE(expanded_2_r_2.Contains({-x_coord_out, y_coord_out}));
647  // Lower right corner
648  EXPECT_TRUE(expanded_2_r_2.Contains({x_coord_in, y_coord_in}));
649  EXPECT_FALSE(expanded_2_r_2.Contains({x_coord_out, y_coord_out}));
650 }

References impeller::TRect< T >::Expand(), impeller::kEhCloseEnough, impeller::kSqrt2, impeller::TRect< Scalar >::MakeLTRB(), and impeller::RoundRect::MakeRectXY().

◆ TEST() [428/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
ContractAndRequireRadiiAdjustment   
)

Definition at line 543 of file round_superellipse_unittests.cc.

543  {
544  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
545  Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
546  {
547  .top_left = Size(1.0f, 2.0f),
548  .top_right = Size(3.0f, 4.0f),
549  .bottom_left = Size(5.0f, 6.0f),
550  .bottom_right = Size(7.0f, 8.0f),
551  });
552  RoundSuperellipse expanded = rse.Expand(-12.0);
553  // Largest sum of paired radii sizes are the bottom and right edges
554  // both of which sum to 12
555  // Rect was 30x30 reduced by 12 on all sides leaving only 6x6, so all
556  // radii are scaled by half to avoid overflowing the contracted rect
557 
558  EXPECT_FALSE(expanded.IsEmpty());
559  EXPECT_FALSE(expanded.IsRect());
560  EXPECT_FALSE(expanded.IsOval());
561  EXPECT_TRUE(expanded.IsFinite());
562  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
563  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(22.0f, 22.0f, 28.0f, 28.0f));
564  EXPECT_EQ(expanded.GetRadii().top_left, Size(0.5f, 1.0f));
565  EXPECT_EQ(expanded.GetRadii().top_right, Size(1.5f, 2.0f));
566  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(2.5f, 3.0f));
567  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(3.5f, 4.0f));
568 
569  // In this test, the MakeRectRadii constructor will make the same
570  // adjustment to the radii that the Expand method applied.
571  EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
572  Rect::MakeXYWH(22.0f, 22.0f, 6.0f, 6.0f),
573  {
574  .top_left = Size(1.0f, 2.0f),
575  .top_right = Size(3.0f, 4.0f),
576  .bottom_left = Size(5.0f, 6.0f),
577  .bottom_right = Size(7.0f, 8.0f),
578  }));
579 
580  // In this test, the arguments to the constructor supply the correctly
581  // adjusted radii (though there is no real way to tell other than
582  // the result is the same).
583  EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
584  Rect::MakeXYWH(22.0f, 22.0f, 6.0f, 6.0f),
585  {
586  .top_left = Size(0.5f, 1.0f),
587  .top_right = Size(1.5f, 2.0f),
588  .bottom_left = Size(2.5f, 3.0f),
589  .bottom_right = Size(3.5f, 4.0f),
590  }));
591 }

References impeller::RoundSuperellipse::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [429/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
ContractFourScalars   
)

Definition at line 511 of file round_superellipse_unittests.cc.

511  {
512  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
513  Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
514  {
515  .top_left = Size(1.0f, 2.0f),
516  .top_right = Size(3.0f, 4.0f),
517  .bottom_left = Size(5.0f, 6.0f),
518  .bottom_right = Size(7.0f, 8.0f),
519  });
520  RoundSuperellipse expanded = rse.Expand(-1.0, -1.5, -2.0, -2.5);
521 
522  EXPECT_FALSE(expanded.IsEmpty());
523  EXPECT_FALSE(expanded.IsRect());
524  EXPECT_FALSE(expanded.IsOval());
525  EXPECT_TRUE(expanded.IsFinite());
526  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
527  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(11.0f, 11.5f, 38.0f, 37.5f));
528  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
529  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
530  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
531  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
532 
533  EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
534  Rect::MakeXYWH(11.0f, 11.5f, 27.0f, 26.0f),
535  {
536  .top_left = Size(1.0f, 2.0f),
537  .top_right = Size(3.0f, 4.0f),
538  .bottom_left = Size(5.0f, 6.0f),
539  .bottom_right = Size(7.0f, 8.0f),
540  }));
541 }

References impeller::RoundSuperellipse::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [430/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
ContractScalar   
)

Definition at line 447 of file round_superellipse_unittests.cc.

447  {
448  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
449  Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
450  {
451  .top_left = Size(1.0f, 2.0f),
452  .top_right = Size(3.0f, 4.0f),
453  .bottom_left = Size(5.0f, 6.0f),
454  .bottom_right = Size(7.0f, 8.0f),
455  });
456  RoundSuperellipse expanded = rse.Expand(-2.0);
457 
458  EXPECT_FALSE(expanded.IsEmpty());
459  EXPECT_FALSE(expanded.IsRect());
460  EXPECT_FALSE(expanded.IsOval());
461  EXPECT_TRUE(expanded.IsFinite());
462  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
463  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(12.0f, 12.0f, 38.0f, 38.0f));
464  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
465  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
466  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
467  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
468 
469  EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
470  Rect::MakeXYWH(12.0f, 12.0f, 26.0f, 26.0f),
471  {
472  .top_left = Size(1.0f, 2.0f),
473  .top_right = Size(3.0f, 4.0f),
474  .bottom_left = Size(5.0f, 6.0f),
475  .bottom_right = Size(7.0f, 8.0f),
476  }));
477 }

References impeller::RoundSuperellipse::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [431/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
ContractTwoScalars   
)

Definition at line 479 of file round_superellipse_unittests.cc.

479  {
480  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
481  Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
482  {
483  .top_left = Size(1.0f, 2.0f),
484  .top_right = Size(3.0f, 4.0f),
485  .bottom_left = Size(5.0f, 6.0f),
486  .bottom_right = Size(7.0f, 8.0f),
487  });
488  RoundSuperellipse expanded = rse.Expand(-1.0, -2.0);
489 
490  EXPECT_FALSE(expanded.IsEmpty());
491  EXPECT_FALSE(expanded.IsRect());
492  EXPECT_FALSE(expanded.IsOval());
493  EXPECT_TRUE(expanded.IsFinite());
494  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
495  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(11.0f, 12.0f, 39.0f, 38.0f));
496  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
497  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
498  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
499  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
500 
501  EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
502  Rect::MakeXYWH(11.0f, 12.0f, 28.0f, 26.0f),
503  {
504  .top_left = Size(1.0f, 2.0f),
505  .top_right = Size(3.0f, 4.0f),
506  .bottom_left = Size(5.0f, 6.0f),
507  .bottom_right = Size(7.0f, 8.0f),
508  }));
509 }

References impeller::RoundSuperellipse::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [432/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
DefaultConstructor   
)

Definition at line 88 of file round_superellipse_unittests.cc.

88  {
89  RoundSuperellipse rse = RoundSuperellipse();
90 
91  EXPECT_TRUE(rse.IsEmpty());
92  EXPECT_FALSE(rse.IsRect());
93  EXPECT_FALSE(rse.IsOval());
94  EXPECT_TRUE(rse.IsFinite());
95  EXPECT_TRUE(rse.GetBounds().IsEmpty());
96  EXPECT_EQ(rse.GetBounds(), Rect());
97  EXPECT_EQ(rse.GetRadii().top_left, Size());
98  EXPECT_EQ(rse.GetRadii().top_right, Size());
99  EXPECT_EQ(rse.GetRadii().bottom_left, Size());
100  EXPECT_EQ(rse.GetRadii().bottom_right, Size());
101 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [433/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
EmptyDeclaration   
)

Definition at line 61 of file round_superellipse_unittests.cc.

61  {
62  RoundSuperellipse rse;
63 
64  EXPECT_TRUE(rse.IsEmpty());
65  EXPECT_FALSE(rse.IsRect());
66  EXPECT_FALSE(rse.IsOval());
67  EXPECT_TRUE(rse.IsFinite());
68  EXPECT_TRUE(rse.GetBounds().IsEmpty());
69  EXPECT_EQ(rse.GetBounds(), Rect());
70  EXPECT_EQ(rse.GetBounds().GetLeft(), 0.0f);
71  EXPECT_EQ(rse.GetBounds().GetTop(), 0.0f);
72  EXPECT_EQ(rse.GetBounds().GetRight(), 0.0f);
73  EXPECT_EQ(rse.GetBounds().GetBottom(), 0.0f);
74  EXPECT_EQ(rse.GetRadii().top_left, Size());
75  EXPECT_EQ(rse.GetRadii().top_right, Size());
76  EXPECT_EQ(rse.GetRadii().bottom_left, Size());
77  EXPECT_EQ(rse.GetRadii().bottom_right, Size());
78  EXPECT_EQ(rse.GetRadii().top_left.width, 0.0f);
79  EXPECT_EQ(rse.GetRadii().top_left.height, 0.0f);
80  EXPECT_EQ(rse.GetRadii().top_right.width, 0.0f);
81  EXPECT_EQ(rse.GetRadii().top_right.height, 0.0f);
82  EXPECT_EQ(rse.GetRadii().bottom_left.width, 0.0f);
83  EXPECT_EQ(rse.GetRadii().bottom_left.height, 0.0f);
84  EXPECT_EQ(rse.GetRadii().bottom_right.width, 0.0f);
85  EXPECT_EQ(rse.GetRadii().bottom_right.height, 0.0f);
86 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::TRect< T >::GetBottom(), impeller::RoundSuperellipse::GetBounds(), impeller::TRect< T >::GetLeft(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TSize< T >::height, impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::RoundingRadii::top_left, impeller::RoundingRadii::top_right, and impeller::TSize< T >::width.

◆ TEST() [434/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
EmptyOvalConstruction   
)

Definition at line 151 of file round_superellipse_unittests.cc.

151  {
152  RoundSuperellipse rse = RoundSuperellipse::MakeRectXY(
153  Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f), 10.0f, 10.0f);
154 
155  EXPECT_TRUE(rse.IsEmpty());
156  EXPECT_FALSE(rse.IsRect());
157  EXPECT_FALSE(rse.IsOval());
158  EXPECT_TRUE(rse.IsFinite());
159  EXPECT_TRUE(rse.GetBounds().IsEmpty());
160  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
161  EXPECT_EQ(rse.GetRadii().top_left, Size());
162  EXPECT_EQ(rse.GetRadii().top_right, Size());
163  EXPECT_EQ(rse.GetRadii().bottom_left, Size());
164  EXPECT_EQ(rse.GetRadii().bottom_right, Size());
165 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [435/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
EmptyRectConstruction   
)

Definition at line 103 of file round_superellipse_unittests.cc.

103  {
104  RoundSuperellipse rse =
105  RoundSuperellipse::MakeRect(Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
106 
107  EXPECT_TRUE(rse.IsEmpty());
108  EXPECT_FALSE(rse.IsRect());
109  EXPECT_FALSE(rse.IsOval());
110  EXPECT_TRUE(rse.IsFinite());
111  EXPECT_TRUE(rse.GetBounds().IsEmpty());
112  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
113  EXPECT_EQ(rse.GetRadii().top_left, Size());
114  EXPECT_EQ(rse.GetRadii().top_right, Size());
115  EXPECT_EQ(rse.GetRadii().bottom_left, Size());
116  EXPECT_EQ(rse.GetRadii().bottom_right, Size());
117 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [436/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
ExpandFourScalars   
)

Definition at line 415 of file round_superellipse_unittests.cc.

415  {
416  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
417  Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
418  {
419  .top_left = Size(1.0f, 2.0f),
420  .top_right = Size(3.0f, 4.0f),
421  .bottom_left = Size(5.0f, 6.0f),
422  .bottom_right = Size(7.0f, 8.0f),
423  });
424  RoundSuperellipse expanded = rse.Expand(5.0, 6.0, 7.0, 8.0);
425 
426  EXPECT_FALSE(expanded.IsEmpty());
427  EXPECT_FALSE(expanded.IsRect());
428  EXPECT_FALSE(expanded.IsOval());
429  EXPECT_TRUE(expanded.IsFinite());
430  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
431  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 4.0f, 47.0f, 48.0f));
432  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
433  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
434  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
435  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
436 
437  EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
438  Rect::MakeXYWH(5.0f, 4.0f, 42.0f, 44.0f),
439  {
440  .top_left = Size(1.0f, 2.0f),
441  .top_right = Size(3.0f, 4.0f),
442  .bottom_left = Size(5.0f, 6.0f),
443  .bottom_right = Size(7.0f, 8.0f),
444  }));
445 }

References impeller::RoundSuperellipse::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [437/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
ExpandScalar   
)

Definition at line 351 of file round_superellipse_unittests.cc.

351  {
352  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
353  Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
354  {
355  .top_left = Size(1.0f, 2.0f),
356  .top_right = Size(3.0f, 4.0f),
357  .bottom_left = Size(5.0f, 6.0f),
358  .bottom_right = Size(7.0f, 8.0f),
359  });
360  RoundSuperellipse expanded = rse.Expand(5.0);
361 
362  EXPECT_FALSE(expanded.IsEmpty());
363  EXPECT_FALSE(expanded.IsRect());
364  EXPECT_FALSE(expanded.IsOval());
365  EXPECT_TRUE(expanded.IsFinite());
366  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
367  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 5.0f, 45.0f, 45.0f));
368  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
369  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
370  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
371  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
372 
373  EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
374  Rect::MakeXYWH(5.0f, 5.0f, 40.0f, 40.0f),
375  {
376  .top_left = Size(1.0f, 2.0f),
377  .top_right = Size(3.0f, 4.0f),
378  .bottom_left = Size(5.0f, 6.0f),
379  .bottom_right = Size(7.0f, 8.0f),
380  }));
381 }

References impeller::RoundSuperellipse::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [438/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
ExpandTwoScalars   
)

Definition at line 383 of file round_superellipse_unittests.cc.

383  {
384  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
385  Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
386  {
387  .top_left = Size(1.0f, 2.0f),
388  .top_right = Size(3.0f, 4.0f),
389  .bottom_left = Size(5.0f, 6.0f),
390  .bottom_right = Size(7.0f, 8.0f),
391  });
392  RoundSuperellipse expanded = rse.Expand(5.0, 6.0);
393 
394  EXPECT_FALSE(expanded.IsEmpty());
395  EXPECT_FALSE(expanded.IsRect());
396  EXPECT_FALSE(expanded.IsOval());
397  EXPECT_TRUE(expanded.IsFinite());
398  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
399  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 4.0f, 45.0f, 46.0f));
400  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
401  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
402  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
403  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
404 
405  EXPECT_EQ(expanded, RoundSuperellipse::MakeRectRadii(
406  Rect::MakeXYWH(5.0f, 4.0f, 40.0f, 42.0f),
407  {
408  .top_left = Size(1.0f, 2.0f),
409  .top_right = Size(3.0f, 4.0f),
410  .bottom_left = Size(5.0f, 6.0f),
411  .bottom_right = Size(7.0f, 8.0f),
412  }));
413 }

References impeller::RoundSuperellipse::Expand(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [439/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
InvertedOvalConstruction   
)

Definition at line 183 of file round_superellipse_unittests.cc.

183  {
184  RoundSuperellipse rse = RoundSuperellipse::MakeRectXY(
185  Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f), 10.0f, 10.0f);
186 
187  EXPECT_FALSE(rse.IsEmpty());
188  EXPECT_FALSE(rse.IsRect());
189  EXPECT_TRUE(rse.IsOval());
190  EXPECT_TRUE(rse.IsFinite());
191  EXPECT_FALSE(rse.GetBounds().IsEmpty());
192  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
193  EXPECT_EQ(rse.GetRadii().top_left, Size(5.0f, 5.0f));
194  EXPECT_EQ(rse.GetRadii().top_right, Size(5.0f, 5.0f));
195  EXPECT_EQ(rse.GetRadii().bottom_left, Size(5.0f, 5.0f));
196  EXPECT_EQ(rse.GetRadii().bottom_right, Size(5.0f, 5.0f));
197 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [440/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
InvertedRectConstruction   
)

Definition at line 135 of file round_superellipse_unittests.cc.

135  {
136  RoundSuperellipse rse =
137  RoundSuperellipse::MakeRect(Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f));
138 
139  EXPECT_FALSE(rse.IsEmpty());
140  EXPECT_TRUE(rse.IsRect());
141  EXPECT_FALSE(rse.IsOval());
142  EXPECT_TRUE(rse.IsFinite());
143  EXPECT_FALSE(rse.GetBounds().IsEmpty());
144  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
145  EXPECT_EQ(rse.GetRadii().top_left, Size());
146  EXPECT_EQ(rse.GetRadii().top_right, Size());
147  EXPECT_EQ(rse.GetRadii().bottom_left, Size());
148  EXPECT_EQ(rse.GetRadii().bottom_right, Size());
149 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [441/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
NoCornerRoundSuperellipseContains   
)

Definition at line 593 of file round_superellipse_unittests.cc.

593  {
594  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
595  // Rounded superellipses of bounds with no corners contains corners just
596  // barely.
597  auto no_corners = RoundSuperellipse::MakeRectRadii(
598  bounds, RoundingRadii::MakeRadii({0.0f, 0.0f}));
599 
600  EXPECT_TRUE(no_corners.Contains({-50, -50}));
601  // Rectangles have half-in, half-out containment so we need
602  // to be careful about testing containment of right/bottom corners.
603  EXPECT_TRUE(no_corners.Contains({-50, 49.99}));
604  EXPECT_TRUE(no_corners.Contains({49.99, -50}));
605  EXPECT_TRUE(no_corners.Contains({49.99, 49.99}));
606  EXPECT_FALSE(no_corners.Contains({-50.01, -50}));
607  EXPECT_FALSE(no_corners.Contains({-50, -50.01}));
608  EXPECT_FALSE(no_corners.Contains({-50.01, 50}));
609  EXPECT_FALSE(no_corners.Contains({-50, 50.01}));
610  EXPECT_FALSE(no_corners.Contains({50.01, -50}));
611  EXPECT_FALSE(no_corners.Contains({50, -50.01}));
612  EXPECT_FALSE(no_corners.Contains({50.01, 50}));
613  EXPECT_FALSE(no_corners.Contains({50, 50.01}));
614 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundingRadii::MakeRadii(), and impeller::RoundSuperellipse::MakeRectRadii().

◆ TEST() [442/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
OvalConstructor   
)

Definition at line 167 of file round_superellipse_unittests.cc.

167  {
168  RoundSuperellipse rse =
169  RoundSuperellipse::MakeOval(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
170 
171  EXPECT_FALSE(rse.IsEmpty());
172  EXPECT_FALSE(rse.IsRect());
173  EXPECT_TRUE(rse.IsOval());
174  EXPECT_TRUE(rse.IsFinite());
175  EXPECT_FALSE(rse.GetBounds().IsEmpty());
176  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
177  EXPECT_EQ(rse.GetRadii().top_left, Size(5.0f, 5.0f));
178  EXPECT_EQ(rse.GetRadii().top_right, Size(5.0f, 5.0f));
179  EXPECT_EQ(rse.GetRadii().bottom_left, Size(5.0f, 5.0f));
180  EXPECT_EQ(rse.GetRadii().bottom_right, Size(5.0f, 5.0f));
181 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeOval(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [443/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
PathForRectangularRseWithShapeCornersShouldBeWithinBounds   
)

Definition at line 755 of file round_superellipse_unittests.cc.

756  {
757  Rect bounds = Rect::MakeLTRB(34.0f, 242.0f, 766.0f, 358.0f);
758  // Regression test for https://github.com/flutter/flutter/issues/170593.
759  // The issue was caused by incorrect calculation when building paths for
760  // rounded superellipses with sharp corners and unequal width and height.
761  // Since the most obvious symptom of the issue is some points being
762  // incorrectly placed out of bounds, this test case simply verifies that all
763  // points are within the bounds.
764 
765  auto rr = RoundSuperellipseParam::MakeBoundsRadii(
766  bounds, {
767  .top_left = Size(14.0, 14.0),
768  .top_right = Size(14.0, 14.0),
769  .bottom_left = Size(0.0, 0.0),
770  .bottom_right = Size(0.0, 0.0),
771  });
772  SpyPathReceiver receiver;
773  receiver.SpyLineTo(
774  [&](const Point& p2) { EXPECT_TRUE(bounds.ContainsInclusive(p2)); });
775  receiver.SpyCubicTo([&](const Point& cp1, const Point& cp2, const Point& p2) {
776  EXPECT_TRUE(bounds.ContainsInclusive(p2));
777  });
778 
779  rr.Dispatch(receiver);
780 }

References impeller::TRect< T >::ContainsInclusive(), impeller::RoundSuperellipseParam::Dispatch(), impeller::RoundSuperellipseParam::MakeBoundsRadii(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [444/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
PointsOutsideOfSharpCorner   
)

Definition at line 738 of file round_superellipse_unittests.cc.

738  {
739  Rect bounds = Rect::MakeLTRB(196.0f, 0.0f, 294.0f, 28.0f);
740  // Regression test for a case where RoundSuperellipseParam::Contains
741  // previously failed. Although the bounding rect filter of
742  // `RoundSuperellipse::Contains` would reject this point, this test ensures
743  // the internal logic of RoundSuperellipseParam::Contains is now correct.
744  auto rr = RoundSuperellipseParam::MakeBoundsRadii(
745  bounds, {
746  .top_left = Size(0.0, 0.0),
747  .top_right = Size(3.0, 3.0),
748  .bottom_left = Size(0.0, 0.0),
749  .bottom_right = Size(3.0, 3.0),
750  });
751 
752  EXPECT_FALSE(rr.Contains(Point{147.0, 14.0}));
753 }

References impeller::RoundSuperellipseParam::MakeBoundsRadii(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [445/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
RectConstructor   
)

Definition at line 119 of file round_superellipse_unittests.cc.

119  {
120  RoundSuperellipse rse =
121  RoundSuperellipse::MakeRect(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
122 
123  EXPECT_FALSE(rse.IsEmpty());
124  EXPECT_TRUE(rse.IsRect());
125  EXPECT_FALSE(rse.IsOval());
126  EXPECT_TRUE(rse.IsFinite());
127  EXPECT_FALSE(rse.GetBounds().IsEmpty());
128  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
129  EXPECT_EQ(rse.GetRadii().top_left, Size());
130  EXPECT_EQ(rse.GetRadii().top_right, Size());
131  EXPECT_EQ(rse.GetRadii().bottom_left, Size());
132  EXPECT_EQ(rse.GetRadii().bottom_right, Size());
133 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [446/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
RectRadiiConstructor   
)

Definition at line 247 of file round_superellipse_unittests.cc.

247  {
248  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
249  Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f),
250  {
251  .top_left = Size(1.0, 1.5),
252  .top_right = Size(2.0, 2.5f),
253  .bottom_left = Size(3.0, 3.5f),
254  .bottom_right = Size(4.0, 4.5f),
255  });
256 
257  EXPECT_FALSE(rse.IsEmpty());
258  EXPECT_FALSE(rse.IsRect());
259  EXPECT_FALSE(rse.IsOval());
260  EXPECT_TRUE(rse.IsFinite());
261  EXPECT_FALSE(rse.GetBounds().IsEmpty());
262  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
263  EXPECT_EQ(rse.GetRadii().top_left, Size(1.0f, 1.5f));
264  EXPECT_EQ(rse.GetRadii().top_right, Size(2.0f, 2.5f));
265  EXPECT_EQ(rse.GetRadii().bottom_left, Size(3.0f, 3.5f));
266  EXPECT_EQ(rse.GetRadii().bottom_right, Size(4.0f, 4.5f));
267 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [447/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
RectRadiiOverflowHeightConstructor   
)

Definition at line 294 of file round_superellipse_unittests.cc.

294  {
295  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
296  Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 6.0f),
297  {
298  .top_left = Size(1.0f, 2.0f),
299  .top_right = Size(3.0f, 4.0f),
300  .bottom_left = Size(5.0f, 6.0f),
301  .bottom_right = Size(7.0f, 8.0f),
302  });
303  // Largest sum of paired radii heights is the right edge which sums to 12
304  // Rect is only 6 tall so all radii are scaled by half
305  // Rect is 30 wide so no scaling should happen due to radii widths
306 
307  EXPECT_FALSE(rse.IsEmpty());
308  EXPECT_FALSE(rse.IsRect());
309  EXPECT_FALSE(rse.IsOval());
310  EXPECT_TRUE(rse.IsFinite());
311  EXPECT_FALSE(rse.GetBounds().IsEmpty());
312  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 40.0f, 16.0f));
313  EXPECT_EQ(rse.GetRadii().top_left, Size(0.5f, 1.0f));
314  EXPECT_EQ(rse.GetRadii().top_right, Size(1.5f, 2.0f));
315  EXPECT_EQ(rse.GetRadii().bottom_left, Size(2.5f, 3.0f));
316  EXPECT_EQ(rse.GetRadii().bottom_right, Size(3.5f, 4.0f));
317 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), impeller::TRect< Scalar >::MakeXYWH(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [448/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
RectRadiiOverflowWidthConstructor   
)

Definition at line 269 of file round_superellipse_unittests.cc.

269  {
270  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
271  Rect::MakeXYWH(10.0f, 10.0f, 6.0f, 30.0f),
272  {
273  .top_left = Size(1.0f, 2.0f),
274  .top_right = Size(3.0f, 4.0f),
275  .bottom_left = Size(5.0f, 6.0f),
276  .bottom_right = Size(7.0f, 8.0f),
277  });
278  // Largest sum of paired radii widths is the bottom edge which sums to 12
279  // Rect is only 6 wide so all radii are scaled by half
280  // Rect is 30 tall so no scaling should happen due to radii heights
281 
282  EXPECT_FALSE(rse.IsEmpty());
283  EXPECT_FALSE(rse.IsRect());
284  EXPECT_FALSE(rse.IsOval());
285  EXPECT_TRUE(rse.IsFinite());
286  EXPECT_FALSE(rse.GetBounds().IsEmpty());
287  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 16.0f, 40.0f));
288  EXPECT_EQ(rse.GetRadii().top_left, Size(0.5f, 1.0f));
289  EXPECT_EQ(rse.GetRadii().top_right, Size(1.5f, 2.0f));
290  EXPECT_EQ(rse.GetRadii().bottom_left, Size(2.5f, 3.0f));
291  EXPECT_EQ(rse.GetRadii().bottom_right, Size(3.5f, 4.0f));
292 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), impeller::TRect< Scalar >::MakeXYWH(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [449/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
RectRadiusConstructor   
)

Definition at line 199 of file round_superellipse_unittests.cc.

199  {
200  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadius(
201  Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), 2.0f);
202 
203  EXPECT_FALSE(rse.IsEmpty());
204  EXPECT_FALSE(rse.IsRect());
205  EXPECT_FALSE(rse.IsOval());
206  EXPECT_TRUE(rse.IsFinite());
207  EXPECT_FALSE(rse.GetBounds().IsEmpty());
208  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
209  EXPECT_EQ(rse.GetRadii().top_left, Size(2.0f, 2.0f));
210  EXPECT_EQ(rse.GetRadii().top_right, Size(2.0f, 2.0f));
211  EXPECT_EQ(rse.GetRadii().bottom_left, Size(2.0f, 2.0f));
212  EXPECT_EQ(rse.GetRadii().bottom_right, Size(2.0f, 2.0f));
213 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadius(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [450/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
RectSizeConstructor   
)

Definition at line 231 of file round_superellipse_unittests.cc.

231  {
232  RoundSuperellipse rse = RoundSuperellipse::MakeRectXY(
233  Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), Size(2.0f, 3.0f));
234 
235  EXPECT_FALSE(rse.IsEmpty());
236  EXPECT_FALSE(rse.IsRect());
237  EXPECT_FALSE(rse.IsOval());
238  EXPECT_TRUE(rse.IsFinite());
239  EXPECT_FALSE(rse.GetBounds().IsEmpty());
240  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
241  EXPECT_EQ(rse.GetRadii().top_left, Size(2.0f, 3.0f));
242  EXPECT_EQ(rse.GetRadii().top_right, Size(2.0f, 3.0f));
243  EXPECT_EQ(rse.GetRadii().bottom_left, Size(2.0f, 3.0f));
244  EXPECT_EQ(rse.GetRadii().bottom_right, Size(2.0f, 3.0f));
245 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [451/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
RectXYConstructor   
)

Definition at line 215 of file round_superellipse_unittests.cc.

215  {
216  RoundSuperellipse rse = RoundSuperellipse::MakeRectXY(
217  Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), 2.0f, 3.0f);
218 
219  EXPECT_FALSE(rse.IsEmpty());
220  EXPECT_FALSE(rse.IsRect());
221  EXPECT_FALSE(rse.IsOval());
222  EXPECT_TRUE(rse.IsFinite());
223  EXPECT_FALSE(rse.GetBounds().IsEmpty());
224  EXPECT_EQ(rse.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
225  EXPECT_EQ(rse.GetRadii().top_left, Size(2.0f, 3.0f));
226  EXPECT_EQ(rse.GetRadii().top_right, Size(2.0f, 3.0f));
227  EXPECT_EQ(rse.GetRadii().bottom_left, Size(2.0f, 3.0f));
228  EXPECT_EQ(rse.GetRadii().bottom_right, Size(2.0f, 3.0f));
229 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundSuperellipse::GetBounds(), impeller::RoundSuperellipse::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundSuperellipse::IsEmpty(), impeller::RoundSuperellipse::IsFinite(), impeller::RoundSuperellipse::IsOval(), impeller::RoundSuperellipse::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [452/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
Shift   
)

Definition at line 319 of file round_superellipse_unittests.cc.

319  {
320  RoundSuperellipse rse = RoundSuperellipse::MakeRectRadii(
321  Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
322  {
323  .top_left = Size(1.0f, 2.0f),
324  .top_right = Size(3.0f, 4.0f),
325  .bottom_left = Size(5.0f, 6.0f),
326  .bottom_right = Size(7.0f, 8.0f),
327  });
328  RoundSuperellipse shifted = rse.Shift(5.0, 6.0);
329 
330  EXPECT_FALSE(shifted.IsEmpty());
331  EXPECT_FALSE(shifted.IsRect());
332  EXPECT_FALSE(shifted.IsOval());
333  EXPECT_TRUE(shifted.IsFinite());
334  EXPECT_FALSE(shifted.GetBounds().IsEmpty());
335  EXPECT_EQ(shifted.GetBounds(), Rect::MakeLTRB(15.0f, 16.0f, 45.0f, 46.0f));
336  EXPECT_EQ(shifted.GetRadii().top_left, Size(1.0f, 2.0f));
337  EXPECT_EQ(shifted.GetRadii().top_right, Size(3.0f, 4.0f));
338  EXPECT_EQ(shifted.GetRadii().bottom_left, Size(5.0f, 6.0f));
339  EXPECT_EQ(shifted.GetRadii().bottom_right, Size(7.0f, 8.0f));
340 
341  EXPECT_EQ(shifted, RoundSuperellipse::MakeRectRadii(
342  Rect::MakeXYWH(15.0f, 16.0f, 30.0f, 30.0f),
343  {
344  .top_left = Size(1.0f, 2.0f),
345  .top_right = Size(3.0f, 4.0f),
346  .bottom_left = Size(5.0f, 6.0f),
347  .bottom_right = Size(7.0f, 8.0f),
348  }));
349 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundSuperellipse::MakeRectRadii(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::RoundSuperellipse::Shift().

◆ TEST() [453/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
SlimDiagonalContains   
)

Definition at line 701 of file round_superellipse_unittests.cc.

701  {
702  // This shape has large radii on one diagonal and tiny radii on the other,
703  // resulting in a almond-like shape placed diagonally (NW to SE).
704  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
705  auto rr = RoundSuperellipse::MakeRectRadii(
706  bounds, {
707  .top_left = Size(1.0, 1.0),
708  .top_right = Size(99.0, 99.0),
709  .bottom_left = Size(99.0, 99.0),
710  .bottom_right = Size(1.0, 1.0),
711  });
712 
713  EXPECT_TRUE(rr.Contains(Point{0, 0}));
714  EXPECT_FALSE(rr.Contains(Point{-49.999, -49.999}));
715  EXPECT_FALSE(rr.Contains(Point{-49.999, 49.999}));
716  EXPECT_FALSE(rr.Contains(Point{49.999, 49.999}));
717  EXPECT_FALSE(rr.Contains(Point{49.999, -49.999}));
718 
719  // The pointy ends at the NE and SW corners
720  CHECK_POINT_WITH_OFFSET(rr, Point(-49.70, -49.70), Point(-0.02, -0.02));
721  CHECK_POINT_WITH_OFFSET(rr, Point(49.70, 49.70), Point(0.02, 0.02));
722 
723 // Checks two points symmetrical to the origin.
724 #define CHECK_DIAGONAL_POINTS(p) \
725  CHECK_POINT_WITH_OFFSET(rr, (p), Point(0.02, -0.02)); \
726  CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, -1), Point(-0.02, 0.02));
727 
728  // A few other points along the edge
729  CHECK_DIAGONAL_POINTS(Point(-40.0, -49.59));
730  CHECK_DIAGONAL_POINTS(Point(-20.0, -45.64));
731  CHECK_DIAGONAL_POINTS(Point(0.0, -37.01));
732  CHECK_DIAGONAL_POINTS(Point(20.0, -21.96));
733  CHECK_DIAGONAL_POINTS(Point(21.05, -20.92));
734  CHECK_DIAGONAL_POINTS(Point(40.0, 5.68));
735 #undef CHECK_POINT_AND_MIRRORS
736 }
#define CHECK_DIAGONAL_POINTS(p)
#define CHECK_POINT_WITH_OFFSET(rr, p, outward_offset)

References CHECK_DIAGONAL_POINTS, CHECK_POINT_WITH_OFFSET, impeller::TRect< Scalar >::MakeLTRB(), and impeller::RoundSuperellipse::MakeRectRadii().

◆ TEST() [454/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
TinyCornerContains   
)

Definition at line 616 of file round_superellipse_unittests.cc.

616  {
617  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
618  // Rounded superellipses of bounds with even the tiniest corners does not
619  // contain corners.
620  auto tiny_corners = RoundSuperellipse::MakeRectRadii(
621  bounds, RoundingRadii::MakeRadii({0.01f, 0.01f}));
622 
623  EXPECT_FALSE(tiny_corners.Contains({-50, -50}));
624  EXPECT_FALSE(tiny_corners.Contains({-50, 50}));
625  EXPECT_FALSE(tiny_corners.Contains({50, -50}));
626  EXPECT_FALSE(tiny_corners.Contains({50, 50}));
627 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundingRadii::MakeRadii(), and impeller::RoundSuperellipse::MakeRectRadii().

◆ TEST() [455/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
UniformEllipticalContains   
)

Definition at line 650 of file round_superellipse_unittests.cc.

650  {
651  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
652  auto rr = RoundSuperellipse::MakeRectRadii(
653  bounds, RoundingRadii::MakeRadii({5.0f, 10.0f}));
654 
655 #define CHECK_POINT_AND_MIRRORS(p) \
656  CHECK_POINT_WITH_OFFSET(rr, (p), Point(0.02, 0.02)); \
657  CHECK_POINT_WITH_OFFSET(rr, (p) * Point(1, -1), Point(0.02, -0.02)); \
658  CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, 1), Point(-0.02, 0.02)); \
659  CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, -1), Point(-0.02, -0.02));
660 
661  CHECK_POINT_AND_MIRRORS(Point(0, 49.995)); // Top
662  CHECK_POINT_AND_MIRRORS(Point(44.245, 49.911)); // Top curve start
663  CHECK_POINT_AND_MIRRORS(Point(45.72, 49.75)); // Top joint
664  CHECK_POINT_AND_MIRRORS(Point(48.51, 47.07)); // Circular arc mid
665  CHECK_POINT_AND_MIRRORS(Point(49.87, 41.44)); // Right joint
666  CHECK_POINT_AND_MIRRORS(Point(49.95, 38.49)); // Right curve start
667  CHECK_POINT_AND_MIRRORS(Point(49.995, 0)); // Right
668 #undef CHECK_POINT_AND_MIRRORS
669 }
#define CHECK_POINT_AND_MIRRORS(p)

References CHECK_POINT_AND_MIRRORS, impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundingRadii::MakeRadii(), and impeller::RoundSuperellipse::MakeRectRadii().

◆ TEST() [456/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
UniformRectangularContains   
)

Definition at line 671 of file round_superellipse_unittests.cc.

671  {
672  // The bounds is not centered at the origin and has unequal height and width.
673  Rect bounds = Rect::MakeLTRB(0.0f, 0.0f, 50.0f, 100.0f);
674  auto rr = RoundSuperellipse::MakeRectRadii(
675  bounds, RoundingRadii::MakeRadii({23.0f, 30.0f}));
676 
677  Point center = bounds.GetCenter();
678 #define CHECK_POINT_AND_MIRRORS(p) \
679  CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(1, 1) + center, \
680  Point(0.02, 0.02)); \
681  CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(1, -1) + center, \
682  Point(0.02, -0.02)); \
683  CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(-1, 1) + center, \
684  Point(-0.02, 0.02)); \
685  CHECK_POINT_WITH_OFFSET(rr, (p - center) * Point(-1, -1) + center, \
686  Point(-0.02, -0.02));
687 
688  CHECK_POINT_AND_MIRRORS(Point(24.99, 99.99)); // Bottom mid edge
689  CHECK_POINT_AND_MIRRORS(Point(29.99, 99.64));
690  CHECK_POINT_AND_MIRRORS(Point(34.99, 98.06));
691  CHECK_POINT_AND_MIRRORS(Point(39.99, 94.73));
692  CHECK_POINT_AND_MIRRORS(Point(44.13, 89.99));
693  CHECK_POINT_AND_MIRRORS(Point(48.46, 79.99));
694  CHECK_POINT_AND_MIRRORS(Point(49.70, 69.99));
695  CHECK_POINT_AND_MIRRORS(Point(49.97, 59.99));
696  CHECK_POINT_AND_MIRRORS(Point(49.99, 49.99)); // Right mid edge
697 
698 #undef CHECK_POINT_AND_MIRRORS
699 }

References CHECK_POINT_AND_MIRRORS, impeller::TRect< T >::GetCenter(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundingRadii::MakeRadii(), and impeller::RoundSuperellipse::MakeRectRadii().

◆ TEST() [457/525]

impeller::testing::TEST ( RoundSuperellipseTest  ,
UniformSquareContains   
)

Definition at line 629 of file round_superellipse_unittests.cc.

629  {
630  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
631  auto rr = RoundSuperellipse::MakeRectRadii(
632  bounds, RoundingRadii::MakeRadii({5.0f, 5.0f}));
633 
634 #define CHECK_POINT_AND_MIRRORS(p) \
635  CHECK_POINT_WITH_OFFSET(rr, (p), Point(0.02, 0.02)); \
636  CHECK_POINT_WITH_OFFSET(rr, (p) * Point(1, -1), Point(0.02, -0.02)); \
637  CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, 1), Point(-0.02, 0.02)); \
638  CHECK_POINT_WITH_OFFSET(rr, (p) * Point(-1, -1), Point(-0.02, -0.02));
639 
640  CHECK_POINT_AND_MIRRORS(Point(0, 49.995)); // Top
641  CHECK_POINT_AND_MIRRORS(Point(44.245, 49.95)); // Top curve start
642  CHECK_POINT_AND_MIRRORS(Point(45.72, 49.87)); // Top joint
643  CHECK_POINT_AND_MIRRORS(Point(48.53, 48.53)); // Circular arc mid
644  CHECK_POINT_AND_MIRRORS(Point(49.87, 45.72)); // Right joint
645  CHECK_POINT_AND_MIRRORS(Point(49.95, 44.245)); // Right curve start
646  CHECK_POINT_AND_MIRRORS(Point(49.995, 0)); // Right
647 #undef CHECK_POINT_AND_MIRRORS
648 }

References CHECK_POINT_AND_MIRRORS, impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundingRadii::MakeRadii(), and impeller::RoundSuperellipse::MakeRectRadii().

◆ TEST() [458/525]

impeller::testing::TEST ( RSTransformTest  ,
CompareToMatrix   
)

Definition at line 32 of file rstransform_unittests.cc.

32  {
33  for (int tx = 0; tx <= 100; tx += 10) {
34  for (int ty = 0; ty <= 100; ty += 10) {
35  Point origin(tx, ty);
36  for (int scale = 1; scale <= 20; scale += 5) {
37  // Overshoot a full circle by 30 degrees
38  for (int degrees = 0; degrees <= 390; degrees += 45) {
39  auto matrix = Matrix::MakeTranslation(origin) *
40  Matrix::MakeRotationZ(Degrees(degrees)) *
41  Matrix::MakeScale(Vector2(scale, scale));
42  auto rst = RSTransform::Make(origin, scale, Degrees(degrees));
43  EXPECT_MATRIX_NEAR(rst.GetMatrix(), matrix);
44  for (int w = 10; w <= 100; w += 10) {
45  for (int h = 10; h <= 100; h += 10) {
46  Quad q = rst.GetQuad(w, h);
47  auto points = Rect::MakeWH(w, h).GetTransformedPoints(matrix);
48  for (int i = 0; i < 4; i++) {
49  EXPECT_NEAR(q[i].x, points[i].x, kEhCloseEnough);
50  EXPECT_NEAR(q[i].y, points[i].y, kEhCloseEnough);
51  }
52  }
53  }
54  }
55  }
56  }
57  }
58 }
#define EXPECT_MATRIX_NEAR(a, b)

References EXPECT_MATRIX_NEAR, impeller::TRect< T >::GetTransformedPoints(), impeller::kEhCloseEnough, impeller::RSTransform::Make(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeWH(), points, and x.

◆ TEST() [459/525]

impeller::testing::TEST ( RSTransformTest  ,
Construction   
)

Definition at line 14 of file rstransform_unittests.cc.

14  {
15  RSTransform transform = RSTransform::Make({10.0f, 12.0f}, 2.0f, Degrees(90));
16 
17  EXPECT_EQ(transform.scaled_cos, 0.0f);
18  EXPECT_EQ(transform.scaled_sin, 2.0f);
19  EXPECT_EQ(transform.translate_x, 10.0f);
20  EXPECT_EQ(transform.translate_y, 12.0f);
21 
22  EXPECT_EQ(transform.GetBounds(20.0f, 30.0f),
23  // relative corners are at
24  // 0, 0
25  // 0, 40
26  // -60, 0
27  // -60, 40
28  // then add 10, 12 to all values
29  Rect::MakeLTRB(10 + -2 * 30, 12 + 0, 10 + 0, 12 + 40));
30 }

References impeller::RSTransform::Make(), impeller::TRect< Scalar >::MakeLTRB(), and transform.

◆ TEST() [460/525]

impeller::testing::TEST ( SaturatedMath  ,
CastingFiniteDoubleToFloatStaysFinite   
)

Definition at line 981 of file saturated_math_unittests.cc.

981  {
982  const double d_max = std::numeric_limits<double>::max();
983  const float f_max = std::numeric_limits<float>::max();
984 
985  {
986  const float result = saturated::Cast<double, float>(d_max);
987  EXPECT_EQ(result, f_max);
988  }
989 
990  {
991  const float result = saturated::Cast<double, float>(-d_max);
992  EXPECT_EQ(result, -f_max);
993  }
994 }

◆ TEST() [461/525]

impeller::testing::TEST ( SaturatedMath  ,
CastingInfiniteDoubleToFloatStaysInfinite   
)

Definition at line 996 of file saturated_math_unittests.cc.

996  {
997  const double d_inf = std::numeric_limits<double>::infinity();
998  const float f_max = std::numeric_limits<float>::infinity();
999 
1000  {
1001  const float result = saturated::Cast<double, float>(d_inf);
1002  EXPECT_EQ(result, f_max);
1003  }
1004 
1005  {
1006  const float result = saturated::Cast<double, float>(-d_inf);
1007  EXPECT_EQ(result, -f_max);
1008  }
1009 }

◆ TEST() [462/525]

impeller::testing::TEST ( SaturatedMath  ,
CastingInfiniteScalarToSignedIntProducesLimit   
)

Definition at line 1066 of file saturated_math_unittests.cc.

1066  {
1067  // larger than even any [u]int64_t;
1068  const Scalar inf = std::numeric_limits<Scalar>::infinity();
1069 
1070  {
1071  const auto result = saturated::Cast<Scalar, int8_t>(inf);
1072  EXPECT_EQ(result, int8_t(0x7F));
1073  }
1074  {
1075  const auto result = saturated::Cast<Scalar, int8_t>(-inf);
1076  EXPECT_EQ(result, int8_t(0x80));
1077  }
1078 
1079  {
1080  const auto result = saturated::Cast<Scalar, int16_t>(inf);
1081  EXPECT_EQ(result, int16_t(0x7FFF));
1082  }
1083  {
1084  const auto result = saturated::Cast<Scalar, int16_t>(-inf);
1085  EXPECT_EQ(result, int16_t(0x8000));
1086  }
1087 
1088  {
1089  const auto result = saturated::Cast<Scalar, int32_t>(inf);
1090  EXPECT_EQ(result, int32_t(0x7FFFFFFF));
1091  }
1092  {
1093  const auto result = saturated::Cast<Scalar, int32_t>(-inf);
1094  EXPECT_EQ(result, int32_t(0x80000000));
1095  }
1096 
1097  {
1098  const auto result = saturated::Cast<Scalar, int64_t>(inf);
1099  EXPECT_EQ(result, int64_t(0x7FFFFFFFFFFFFFFF));
1100  }
1101  {
1102  const auto result = saturated::Cast<Scalar, int64_t>(-inf);
1103  EXPECT_EQ(result, int64_t(0x8000000000000000));
1104  }
1105 }

◆ TEST() [463/525]

impeller::testing::TEST ( SaturatedMath  ,
CastingLargeScalarToSignedIntProducesLimit   
)

Definition at line 1025 of file saturated_math_unittests.cc.

1025  {
1026  // larger than even any [u]int64_t;
1027  const Scalar large = 1e20f;
1028 
1029  {
1030  const auto result = saturated::Cast<Scalar, int8_t>(large);
1031  EXPECT_EQ(result, int8_t(0x7F));
1032  }
1033  {
1034  const auto result = saturated::Cast<Scalar, int8_t>(-large);
1035  EXPECT_EQ(result, int8_t(0x80));
1036  }
1037 
1038  {
1039  const auto result = saturated::Cast<Scalar, int16_t>(large);
1040  EXPECT_EQ(result, int16_t(0x7FFF));
1041  }
1042  {
1043  const auto result = saturated::Cast<Scalar, int16_t>(-large);
1044  EXPECT_EQ(result, int16_t(0x8000));
1045  }
1046 
1047  {
1048  const auto result = saturated::Cast<Scalar, int32_t>(large);
1049  EXPECT_EQ(result, int32_t(0x7FFFFFFF));
1050  }
1051  {
1052  const auto result = saturated::Cast<Scalar, int32_t>(-large);
1053  EXPECT_EQ(result, int32_t(0x80000000));
1054  }
1055 
1056  {
1057  const auto result = saturated::Cast<Scalar, int64_t>(large);
1058  EXPECT_EQ(result, int64_t(0x7FFFFFFFFFFFFFFF));
1059  }
1060  {
1061  const auto result = saturated::Cast<Scalar, int64_t>(-large);
1062  EXPECT_EQ(result, int64_t(0x8000000000000000));
1063  }
1064 }

◆ TEST() [464/525]

impeller::testing::TEST ( SaturatedMath  ,
CastingNaNDoubleToFloatStaysNaN   
)

Definition at line 1011 of file saturated_math_unittests.cc.

1011  {
1012  const double d_nan = std::numeric_limits<double>::quiet_NaN();
1013 
1014  {
1015  const float result = saturated::Cast<double, float>(d_nan);
1016  EXPECT_TRUE(std::isnan(result));
1017  }
1018 
1019  {
1020  const float result = saturated::Cast<double, float>(-d_nan);
1021  EXPECT_TRUE(std::isnan(result));
1022  }
1023 }

◆ TEST() [465/525]

impeller::testing::TEST ( SaturatedMath  ,
CastingNaNScalarToSignedIntProducesZero   
)

Definition at line 1107 of file saturated_math_unittests.cc.

1107  {
1108  // larger than even any [u]int64_t;
1109  const Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1110 
1111  {
1112  const auto result = saturated::Cast<Scalar, int8_t>(nan);
1113  EXPECT_EQ(result, int8_t(0));
1114  }
1115 
1116  {
1117  const auto result = saturated::Cast<Scalar, int16_t>(nan);
1118  EXPECT_EQ(result, int16_t(0));
1119  }
1120 
1121  {
1122  const auto result = saturated::Cast<Scalar, int32_t>(nan);
1123  EXPECT_EQ(result, int32_t(0));
1124  }
1125 
1126  {
1127  const auto result = saturated::Cast<Scalar, int64_t>(nan);
1128  EXPECT_EQ(result, int64_t(0));
1129  }
1130 }

◆ TEST() [466/525]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAddOfFloatingPoint   
)

Definition at line 136 of file saturated_math_unittests.cc.

136  {
137  {
138  const float inf = std::numeric_limits<float>::infinity();
139  const float max = std::numeric_limits<float>::max();
140  const float big = max * 0.5f;
141 
142  EXPECT_EQ(saturated::Add<float>(big, big), max);
143  EXPECT_EQ(saturated::Add<float>(max, big), inf);
144  EXPECT_EQ(saturated::Add<float>(big, max), inf);
145  EXPECT_EQ(saturated::Add<float>(max, max), inf);
146  EXPECT_EQ(saturated::Add<float>(max, inf), inf);
147  EXPECT_EQ(saturated::Add<float>(inf, max), inf);
148  EXPECT_EQ(saturated::Add<float>(inf, inf), inf);
149 
150  EXPECT_EQ(saturated::Add<float>(-big, -big), -max);
151  EXPECT_EQ(saturated::Add<float>(-max, -big), -inf);
152  EXPECT_EQ(saturated::Add<float>(-big, -max), -inf);
153  EXPECT_EQ(saturated::Add<float>(-max, -max), -inf);
154  EXPECT_EQ(saturated::Add<float>(-max, -inf), -inf);
155  EXPECT_EQ(saturated::Add<float>(-inf, -max), -inf);
156  EXPECT_EQ(saturated::Add<float>(-inf, -inf), -inf);
157 
158  EXPECT_EQ(saturated::Add<float>(big, -big), 0.0f);
159  EXPECT_EQ(saturated::Add<float>(max, -big), big);
160  EXPECT_EQ(saturated::Add<float>(big, -max), -big);
161  EXPECT_EQ(saturated::Add<float>(max, -max), 0.0f);
162  EXPECT_EQ(saturated::Add<float>(max, -inf), -inf);
163  EXPECT_EQ(saturated::Add<float>(inf, -max), inf);
164  EXPECT_TRUE(std::isnan(saturated::Add<float>(inf, -inf)));
165 
166  EXPECT_EQ(saturated::Add<float>(-big, big), 0.0f);
167  EXPECT_EQ(saturated::Add<float>(-max, big), -big);
168  EXPECT_EQ(saturated::Add<float>(-big, max), big);
169  EXPECT_EQ(saturated::Add<float>(-max, max), 0.0f);
170  EXPECT_EQ(saturated::Add<float>(-max, inf), inf);
171  EXPECT_EQ(saturated::Add<float>(-inf, max), -inf);
172  EXPECT_TRUE(std::isnan(saturated::Add<float>(-inf, inf)));
173  }
174  {
175  const double inf = std::numeric_limits<double>::infinity();
176  const double max = std::numeric_limits<double>::max();
177  const double big = max * 0.5f;
178 
179  EXPECT_EQ(saturated::Add<double>(big, big), max);
180  EXPECT_EQ(saturated::Add<double>(max, big), inf);
181  EXPECT_EQ(saturated::Add<double>(big, max), inf);
182  EXPECT_EQ(saturated::Add<double>(max, max), inf);
183  EXPECT_EQ(saturated::Add<double>(max, inf), inf);
184  EXPECT_EQ(saturated::Add<double>(inf, max), inf);
185  EXPECT_EQ(saturated::Add<double>(inf, inf), inf);
186 
187  EXPECT_EQ(saturated::Add<double>(-big, -big), -max);
188  EXPECT_EQ(saturated::Add<double>(-max, -big), -inf);
189  EXPECT_EQ(saturated::Add<double>(-big, -max), -inf);
190  EXPECT_EQ(saturated::Add<double>(-max, -max), -inf);
191  EXPECT_EQ(saturated::Add<double>(-max, -inf), -inf);
192  EXPECT_EQ(saturated::Add<double>(-inf, -max), -inf);
193  EXPECT_EQ(saturated::Add<double>(-inf, -inf), -inf);
194 
195  EXPECT_EQ(saturated::Add<double>(big, -big), 0.0f);
196  EXPECT_EQ(saturated::Add<double>(max, -big), big);
197  EXPECT_EQ(saturated::Add<double>(big, -max), -big);
198  EXPECT_EQ(saturated::Add<double>(max, -max), 0.0f);
199  EXPECT_EQ(saturated::Add<double>(max, -inf), -inf);
200  EXPECT_EQ(saturated::Add<double>(inf, -max), inf);
201  EXPECT_TRUE(std::isnan(saturated::Add<double>(inf, -inf)));
202 
203  EXPECT_EQ(saturated::Add<double>(-big, big), 0.0f);
204  EXPECT_EQ(saturated::Add<double>(-max, big), -big);
205  EXPECT_EQ(saturated::Add<double>(-big, max), big);
206  EXPECT_EQ(saturated::Add<double>(-max, max), 0.0f);
207  EXPECT_EQ(saturated::Add<double>(-max, inf), inf);
208  EXPECT_EQ(saturated::Add<double>(-inf, max), -inf);
209  EXPECT_TRUE(std::isnan(saturated::Add<double>(-inf, inf)));
210  }
211  {
212  const Scalar inf = std::numeric_limits<Scalar>::infinity();
213  const Scalar max = std::numeric_limits<Scalar>::max();
214  const Scalar big = max * 0.5f;
215 
216  EXPECT_EQ(saturated::Add<Scalar>(big, big), max);
217  EXPECT_EQ(saturated::Add<Scalar>(max, big), inf);
218  EXPECT_EQ(saturated::Add<Scalar>(big, max), inf);
219  EXPECT_EQ(saturated::Add<Scalar>(max, max), inf);
220  EXPECT_EQ(saturated::Add<Scalar>(max, inf), inf);
221  EXPECT_EQ(saturated::Add<Scalar>(inf, max), inf);
222  EXPECT_EQ(saturated::Add<Scalar>(inf, inf), inf);
223 
224  EXPECT_EQ(saturated::Add<Scalar>(-big, -big), -max);
225  EXPECT_EQ(saturated::Add<Scalar>(-max, -big), -inf);
226  EXPECT_EQ(saturated::Add<Scalar>(-big, -max), -inf);
227  EXPECT_EQ(saturated::Add<Scalar>(-max, -max), -inf);
228  EXPECT_EQ(saturated::Add<Scalar>(-max, -inf), -inf);
229  EXPECT_EQ(saturated::Add<Scalar>(-inf, -max), -inf);
230  EXPECT_EQ(saturated::Add<Scalar>(-inf, -inf), -inf);
231 
232  EXPECT_EQ(saturated::Add<Scalar>(big, -big), 0.0f);
233  EXPECT_EQ(saturated::Add<Scalar>(max, -big), big);
234  EXPECT_EQ(saturated::Add<Scalar>(big, -max), -big);
235  EXPECT_EQ(saturated::Add<Scalar>(max, -max), 0.0f);
236  EXPECT_EQ(saturated::Add<Scalar>(max, -inf), -inf);
237  EXPECT_EQ(saturated::Add<Scalar>(inf, -max), inf);
238  EXPECT_TRUE(std::isnan(saturated::Add<Scalar>(inf, -inf)));
239 
240  EXPECT_EQ(saturated::Add<Scalar>(-big, big), 0.0f);
241  EXPECT_EQ(saturated::Add<Scalar>(-max, big), -big);
242  EXPECT_EQ(saturated::Add<Scalar>(-big, max), big);
243  EXPECT_EQ(saturated::Add<Scalar>(-max, max), 0.0f);
244  EXPECT_EQ(saturated::Add<Scalar>(-max, inf), inf);
245  EXPECT_EQ(saturated::Add<Scalar>(-inf, max), -inf);
246  EXPECT_TRUE(std::isnan(saturated::Add<Scalar>(-inf, inf)));
247  }
248 }

◆ TEST() [467/525]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAddOfSignedInts   
)

Definition at line 12 of file saturated_math_unittests.cc.

12  {
13  {
14  EXPECT_EQ(saturated::Add<int8_t>(0x79, 5), int8_t(0x7E));
15  EXPECT_EQ(saturated::Add<int8_t>(0x7A, 5), int8_t(0x7F));
16  EXPECT_EQ(saturated::Add<int8_t>(0x7B, 5), int8_t(0x7F));
17  }
18  {
19  EXPECT_EQ(saturated::Add<int8_t>(0x86, -5), int8_t(0x81));
20  EXPECT_EQ(saturated::Add<int8_t>(0x85, -5), int8_t(0x80));
21  EXPECT_EQ(saturated::Add<int8_t>(0x84, -5), int8_t(0x80));
22  }
23  {
24  EXPECT_EQ(saturated::Add<int16_t>(0x7FF9, 5), int16_t(0x7FFE));
25  EXPECT_EQ(saturated::Add<int16_t>(0x7FFA, 5), int16_t(0x7FFF));
26  EXPECT_EQ(saturated::Add<int16_t>(0x7FFB, 5), int16_t(0x7FFF));
27  }
28  {
29  EXPECT_EQ(saturated::Add<int16_t>(0x8006, -5), int16_t(0x8001));
30  EXPECT_EQ(saturated::Add<int16_t>(0x8005, -5), int16_t(0x8000));
31  EXPECT_EQ(saturated::Add<int16_t>(0x8004, -5), int16_t(0x8000));
32  }
33  {
34  EXPECT_EQ(saturated::Add<int32_t>(0x7FFFFFF9, 5), int32_t(0x7FFFFFFE));
35  EXPECT_EQ(saturated::Add<int32_t>(0x7FFFFFFA, 5), int32_t(0x7FFFFFFF));
36  EXPECT_EQ(saturated::Add<int32_t>(0x7FFFFFFB, 5), int32_t(0x7FFFFFFF));
37  }
38  {
39  EXPECT_EQ(saturated::Add<int32_t>(0x80000006, -5), int32_t(0x80000001));
40  EXPECT_EQ(saturated::Add<int32_t>(0x80000005, -5), int32_t(0x80000000));
41  EXPECT_EQ(saturated::Add<int32_t>(0x80000004, -5), int32_t(0x80000000));
42  }
43  {
44  EXPECT_EQ(saturated::Add<int64_t>(0x7FFFFFFFFFFFFFF9, 5),
45  int64_t(0x7FFFFFFFFFFFFFFE));
46  EXPECT_EQ(saturated::Add<int64_t>(0x7FFFFFFFFFFFFFFA, 5),
47  int64_t(0x7FFFFFFFFFFFFFFF));
48  EXPECT_EQ(saturated::Add<int64_t>(0x7FFFFFFFFFFFFFFB, 5),
49  int64_t(0x7FFFFFFFFFFFFFFF));
50  }
51  {
52  EXPECT_EQ(saturated::Add<int64_t>(0x8000000000000006, -5),
53  int64_t(0x8000000000000001));
54  EXPECT_EQ(saturated::Add<int64_t>(0x8000000000000005, -5),
55  int64_t(0x8000000000000000));
56  EXPECT_EQ(saturated::Add<int64_t>(0x8000000000000004, -5),
57  int64_t(0x8000000000000000));
58  }
59 }

◆ TEST() [468/525]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAverageScalarOfFloatingPoint   
)

Definition at line 828 of file saturated_math_unittests.cc.

828  {
829  const Scalar s_inf = std::numeric_limits<Scalar>::infinity();
830  const Scalar s_max = std::numeric_limits<Scalar>::max();
831  const Scalar s_big = s_max * 0.5f;
832 
833  {
834  const float inf = std::numeric_limits<Scalar>::infinity();
835  const float max = std::numeric_limits<float>::max();
836  const float big = max * 0.5f;
837 
838  EXPECT_EQ(saturated::AverageScalar<float>(big, big), s_big);
839  EXPECT_EQ(saturated::AverageScalar<float>(max, max), s_max);
840  EXPECT_EQ(saturated::AverageScalar<float>(big, -big), 0.0f);
841  EXPECT_EQ(saturated::AverageScalar<float>(max, -max), 0.0f);
842  EXPECT_EQ(saturated::AverageScalar<float>(-big, big), 0.0f);
843  EXPECT_EQ(saturated::AverageScalar<float>(-max, max), 0.0f);
844  EXPECT_EQ(saturated::AverageScalar<float>(-big, -big), -s_big);
845  EXPECT_EQ(saturated::AverageScalar<float>(-max, -max), -s_max);
846 
847  EXPECT_EQ(saturated::AverageScalar<float>(inf, inf), s_inf);
848  EXPECT_EQ(saturated::AverageScalar<float>(-inf, -inf), -s_inf);
849  EXPECT_TRUE(std::isnan(saturated::AverageScalar<float>(-inf, inf)));
850  EXPECT_TRUE(std::isnan(saturated::AverageScalar<float>(inf, -inf)));
851  }
852  {
853  const double inf = std::numeric_limits<Scalar>::infinity();
854  const double max = std::numeric_limits<double>::max();
855  const double big = max * 0.5;
856 
857  // Most of the averages below using the double constants will
858  // overflow the Scalar return value and result in infinity,
859  // so we also test with some Scalar constants (promoted to double)
860  // to verify that they don't overflow in the double template
861  EXPECT_EQ(saturated::AverageScalar<double>(s_big, s_big), s_big);
862  EXPECT_EQ(saturated::AverageScalar<double>(s_max, s_max), s_max);
863  EXPECT_EQ(saturated::AverageScalar<double>(-s_big, -s_big), -s_big);
864  EXPECT_EQ(saturated::AverageScalar<double>(-s_max, -s_max), -s_max);
865 
866  // And now testing continues with the double constants which
867  // mostly overflow
868  EXPECT_EQ(saturated::AverageScalar<double>(big, big), s_inf);
869  EXPECT_EQ(saturated::AverageScalar<double>(max, max), s_inf);
870  EXPECT_EQ(saturated::AverageScalar<double>(big, -big), 0.0f);
871  EXPECT_EQ(saturated::AverageScalar<double>(max, -max), 0.0f);
872  EXPECT_EQ(saturated::AverageScalar<double>(-big, big), 0.0f);
873  EXPECT_EQ(saturated::AverageScalar<double>(-max, max), 0.0f);
874  EXPECT_EQ(saturated::AverageScalar<double>(-big, -big), -s_inf);
875  EXPECT_EQ(saturated::AverageScalar<double>(-max, -max), -s_inf);
876 
877  EXPECT_EQ(saturated::AverageScalar<double>(inf, inf), s_inf);
878  EXPECT_EQ(saturated::AverageScalar<double>(-inf, -inf), -s_inf);
879  EXPECT_TRUE(std::isnan(saturated::AverageScalar<double>(-inf, inf)));
880  EXPECT_TRUE(std::isnan(saturated::AverageScalar<double>(inf, -inf)));
881  }
882  {
883  const Scalar inf = std::numeric_limits<Scalar>::infinity();
884  const Scalar max = std::numeric_limits<Scalar>::max();
885  const Scalar big = max * 0.5f;
886 
887  EXPECT_EQ(saturated::AverageScalar<Scalar>(big, big), s_big);
888  EXPECT_EQ(saturated::AverageScalar<Scalar>(max, max), s_max);
889  EXPECT_EQ(saturated::AverageScalar<Scalar>(big, -big), 0.0f);
890  EXPECT_EQ(saturated::AverageScalar<Scalar>(max, -max), 0.0f);
891  EXPECT_EQ(saturated::AverageScalar<Scalar>(-big, big), 0.0f);
892  EXPECT_EQ(saturated::AverageScalar<Scalar>(-max, max), 0.0f);
893  EXPECT_EQ(saturated::AverageScalar<Scalar>(-big, -big), -s_big);
894  EXPECT_EQ(saturated::AverageScalar<Scalar>(-max, -max), -s_max);
895 
896  EXPECT_EQ(saturated::AverageScalar<Scalar>(inf, inf), s_inf);
897  EXPECT_EQ(saturated::AverageScalar<Scalar>(-inf, -inf), -s_inf);
898  EXPECT_TRUE(std::isnan(saturated::AverageScalar<Scalar>(-inf, s_inf)));
899  EXPECT_TRUE(std::isnan(saturated::AverageScalar<Scalar>(inf, -s_inf)));
900  }
901 }

◆ TEST() [469/525]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAverageScalarOfSignedInts   
)

Definition at line 716 of file saturated_math_unittests.cc.

716  {
717  // For each type try:
718  //
719  // - near the limits, averaging to 0
720  // - at the limits, averaging to 0 or 0.5 depending on precision
721  // - both large enough for the sum to overflow
722  // - both negative enough for the sum to underflow
723  {
724  EXPECT_EQ(saturated::AverageScalar<int8_t>(0x81, 0x7F), -0.0f);
725  EXPECT_EQ(saturated::AverageScalar<int8_t>(0x80, 0x7F), -0.5f);
726  EXPECT_EQ(saturated::AverageScalar<int8_t>(0x70, 0x75), 114.5f);
727  EXPECT_EQ(saturated::AverageScalar<int8_t>(0x85, 0x8A), -120.5f);
728  }
729  {
730  EXPECT_EQ(saturated::AverageScalar<int16_t>(0x8001, 0x7FFF), -0.0f);
731  EXPECT_EQ(saturated::AverageScalar<int16_t>(0x8000, 0x7FFF), -0.5f);
732  EXPECT_EQ(saturated::AverageScalar<int16_t>(0x7000, 0x7005), 28674.5f);
733  EXPECT_EQ(saturated::AverageScalar<int16_t>(0x8005, 0x800A), -32760.5f);
734  }
735  {
736  EXPECT_EQ(saturated::AverageScalar<int32_t>(0x80000001, 0x7FFFFFFF), -0.0f);
737  EXPECT_EQ(saturated::AverageScalar<int32_t>(0x80000000, 0x7FFFFFFF), -0.5f);
738  EXPECT_EQ(saturated::AverageScalar<int32_t>(0x70000000, 0x70000005),
739  1879048195.5f);
740  EXPECT_EQ(saturated::AverageScalar<int32_t>(0x80000005, 0x8000000A),
741  -2147483655.5f);
742  }
743  {
744  EXPECT_EQ(saturated::AverageScalar<int64_t>(0x8000000000000001,
745  0x7FFFFFFFFFFFFFFF),
746  0.0f);
747  // 64-bit integers overflow the ability of a Scalar (float) to
748  // represent discrete integers and so the two numbers we are
749  // averaging here will look like the same number with different
750  // signs and the answer will be "0"
751  EXPECT_EQ(saturated::AverageScalar<int64_t>(0x8000000000000000,
752  0x7FFFFFFFFFFFFFFF),
753  0.0f);
754  EXPECT_NEAR(saturated::AverageScalar<int64_t>(0x7000000000000000,
755  0x7000000000000005),
756  8.07045053e+18, 1e18);
757  EXPECT_NEAR(saturated::AverageScalar<int64_t>(0x8000000000000005,
758  0x800000000000000A),
759  -9.223372e+18, 1e18);
760  }
761 }

◆ TEST() [470/525]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitSubOfFloatingPoint   
)

Definition at line 488 of file saturated_math_unittests.cc.

488  {
489  {
490  const float inf = std::numeric_limits<float>::infinity();
491  const float max = std::numeric_limits<float>::max();
492  const float big = max * 0.5f;
493 
494  EXPECT_EQ(saturated::Sub<float>(big, big), 0.0f);
495  EXPECT_EQ(saturated::Sub<float>(max, big), big);
496  EXPECT_EQ(saturated::Sub<float>(big, max), -big);
497  EXPECT_EQ(saturated::Sub<float>(max, max), 0.0f);
498  EXPECT_EQ(saturated::Sub<float>(max, inf), -inf);
499  EXPECT_EQ(saturated::Sub<float>(inf, max), inf);
500  EXPECT_TRUE(std::isnan(saturated::Sub<float>(inf, inf)));
501 
502  EXPECT_EQ(saturated::Sub<float>(-big, -big), 0.0f);
503  EXPECT_EQ(saturated::Sub<float>(-max, -big), -big);
504  EXPECT_EQ(saturated::Sub<float>(-big, -max), big);
505  EXPECT_EQ(saturated::Sub<float>(-max, -max), 0.0f);
506  EXPECT_EQ(saturated::Sub<float>(-max, -inf), inf);
507  EXPECT_EQ(saturated::Sub<float>(-inf, -max), -inf);
508  EXPECT_TRUE(std::isnan(saturated::Sub<float>(-inf, -inf)));
509 
510  EXPECT_EQ(saturated::Sub<float>(big, -big), max);
511  EXPECT_EQ(saturated::Sub<float>(max, -big), inf);
512  EXPECT_EQ(saturated::Sub<float>(big, -max), inf);
513  EXPECT_EQ(saturated::Sub<float>(max, -max), inf);
514  EXPECT_EQ(saturated::Sub<float>(max, -inf), inf);
515  EXPECT_EQ(saturated::Sub<float>(inf, -max), inf);
516  EXPECT_EQ(saturated::Sub<float>(inf, -inf), inf);
517 
518  EXPECT_EQ(saturated::Sub<float>(-big, big), -max);
519  EXPECT_EQ(saturated::Sub<float>(-max, big), -inf);
520  EXPECT_EQ(saturated::Sub<float>(-big, max), -inf);
521  EXPECT_EQ(saturated::Sub<float>(-max, max), -inf);
522  EXPECT_EQ(saturated::Sub<float>(-max, inf), -inf);
523  EXPECT_EQ(saturated::Sub<float>(-inf, max), -inf);
524  EXPECT_EQ(saturated::Sub<float>(-inf, inf), -inf);
525  }
526  {
527  const double inf = std::numeric_limits<double>::infinity();
528  const double max = std::numeric_limits<double>::max();
529  const double big = max * 0.5f;
530 
531  EXPECT_EQ(saturated::Sub<double>(big, big), 0.0f);
532  EXPECT_EQ(saturated::Sub<double>(max, big), big);
533  EXPECT_EQ(saturated::Sub<double>(big, max), -big);
534  EXPECT_EQ(saturated::Sub<double>(max, max), 0.0f);
535  EXPECT_EQ(saturated::Sub<double>(max, inf), -inf);
536  EXPECT_EQ(saturated::Sub<double>(inf, max), inf);
537  EXPECT_TRUE(std::isnan(saturated::Sub<double>(inf, inf)));
538 
539  EXPECT_EQ(saturated::Sub<double>(-big, -big), 0.0f);
540  EXPECT_EQ(saturated::Sub<double>(-max, -big), -big);
541  EXPECT_EQ(saturated::Sub<double>(-big, -max), big);
542  EXPECT_EQ(saturated::Sub<double>(-max, -max), 0.0f);
543  EXPECT_EQ(saturated::Sub<double>(-max, -inf), inf);
544  EXPECT_EQ(saturated::Sub<double>(-inf, -max), -inf);
545  EXPECT_TRUE(std::isnan(saturated::Sub<double>(-inf, -inf)));
546 
547  EXPECT_EQ(saturated::Sub<double>(big, -big), max);
548  EXPECT_EQ(saturated::Sub<double>(max, -big), inf);
549  EXPECT_EQ(saturated::Sub<double>(big, -max), inf);
550  EXPECT_EQ(saturated::Sub<double>(max, -max), inf);
551  EXPECT_EQ(saturated::Sub<double>(max, -inf), inf);
552  EXPECT_EQ(saturated::Sub<double>(inf, -max), inf);
553  EXPECT_EQ(saturated::Sub<double>(inf, -inf), inf);
554 
555  EXPECT_EQ(saturated::Sub<double>(-big, big), -max);
556  EXPECT_EQ(saturated::Sub<double>(-max, big), -inf);
557  EXPECT_EQ(saturated::Sub<double>(-big, max), -inf);
558  EXPECT_EQ(saturated::Sub<double>(-max, max), -inf);
559  EXPECT_EQ(saturated::Sub<double>(-max, inf), -inf);
560  EXPECT_EQ(saturated::Sub<double>(-inf, max), -inf);
561  EXPECT_EQ(saturated::Sub<double>(-inf, inf), -inf);
562  }
563  {
564  const Scalar inf = std::numeric_limits<Scalar>::infinity();
565  const Scalar max = std::numeric_limits<Scalar>::max();
566  const Scalar big = max * 0.5f;
567 
568  EXPECT_EQ(saturated::Sub<Scalar>(big, big), 0.0f);
569  EXPECT_EQ(saturated::Sub<Scalar>(max, big), big);
570  EXPECT_EQ(saturated::Sub<Scalar>(big, max), -big);
571  EXPECT_EQ(saturated::Sub<Scalar>(max, max), 0.0f);
572  EXPECT_EQ(saturated::Sub<Scalar>(max, inf), -inf);
573  EXPECT_EQ(saturated::Sub<Scalar>(inf, max), inf);
574  EXPECT_TRUE(std::isnan(saturated::Sub<Scalar>(inf, inf)));
575 
576  EXPECT_EQ(saturated::Sub<Scalar>(-big, -big), 0.0f);
577  EXPECT_EQ(saturated::Sub<Scalar>(-max, -big), -big);
578  EXPECT_EQ(saturated::Sub<Scalar>(-big, -max), big);
579  EXPECT_EQ(saturated::Sub<Scalar>(-max, -max), 0.0f);
580  EXPECT_EQ(saturated::Sub<Scalar>(-max, -inf), inf);
581  EXPECT_EQ(saturated::Sub<Scalar>(-inf, -max), -inf);
582  EXPECT_TRUE(std::isnan(saturated::Sub<Scalar>(-inf, -inf)));
583 
584  EXPECT_EQ(saturated::Sub<Scalar>(big, -big), max);
585  EXPECT_EQ(saturated::Sub<Scalar>(max, -big), inf);
586  EXPECT_EQ(saturated::Sub<Scalar>(big, -max), inf);
587  EXPECT_EQ(saturated::Sub<Scalar>(max, -max), inf);
588  EXPECT_EQ(saturated::Sub<Scalar>(max, -inf), inf);
589  EXPECT_EQ(saturated::Sub<Scalar>(inf, -max), inf);
590  EXPECT_EQ(saturated::Sub<Scalar>(inf, -inf), inf);
591 
592  EXPECT_EQ(saturated::Sub<Scalar>(-big, big), -max);
593  EXPECT_EQ(saturated::Sub<Scalar>(-max, big), -inf);
594  EXPECT_EQ(saturated::Sub<Scalar>(-big, max), -inf);
595  EXPECT_EQ(saturated::Sub<Scalar>(-max, max), -inf);
596  EXPECT_EQ(saturated::Sub<Scalar>(-max, inf), -inf);
597  EXPECT_EQ(saturated::Sub<Scalar>(-inf, max), -inf);
598  EXPECT_EQ(saturated::Sub<Scalar>(-inf, inf), -inf);
599  }
600 }

◆ TEST() [471/525]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitSubOfSignedInts   
)

Definition at line 364 of file saturated_math_unittests.cc.

364  {
365  {
366  EXPECT_EQ(saturated::Sub<int8_t>(0x79, -5), int8_t(0x7E));
367  EXPECT_EQ(saturated::Sub<int8_t>(0x7A, -5), int8_t(0x7F));
368  EXPECT_EQ(saturated::Sub<int8_t>(0x7B, -5), int8_t(0x7F));
369  }
370  {
371  EXPECT_EQ(saturated::Sub<int8_t>(0x86, 5), int8_t(0x81));
372  EXPECT_EQ(saturated::Sub<int8_t>(0x85, 5), int8_t(0x80));
373  EXPECT_EQ(saturated::Sub<int8_t>(0x84, 5), int8_t(0x80));
374  }
375  {
376  EXPECT_EQ(saturated::Sub<int16_t>(0x7FF9, -5), int16_t(0x7FFE));
377  EXPECT_EQ(saturated::Sub<int16_t>(0x7FFA, -5), int16_t(0x7FFF));
378  EXPECT_EQ(saturated::Sub<int16_t>(0x7FFB, -5), int16_t(0x7FFF));
379  }
380  {
381  EXPECT_EQ(saturated::Sub<int16_t>(0x8006, 5), int16_t(0x8001));
382  EXPECT_EQ(saturated::Sub<int16_t>(0x8005, 5), int16_t(0x8000));
383  EXPECT_EQ(saturated::Sub<int16_t>(0x8004, 5), int16_t(0x8000));
384  }
385  {
386  EXPECT_EQ(saturated::Sub<int32_t>(0x7FFFFFF9, -5), int32_t(0x7FFFFFFE));
387  EXPECT_EQ(saturated::Sub<int32_t>(0x7FFFFFFA, -5), int32_t(0x7FFFFFFF));
388  EXPECT_EQ(saturated::Sub<int32_t>(0x7FFFFFFB, -5), int32_t(0x7FFFFFFF));
389  }
390  {
391  EXPECT_EQ(saturated::Sub<int32_t>(0x80000006, 5), int32_t(0x80000001));
392  EXPECT_EQ(saturated::Sub<int32_t>(0x80000005, 5), int32_t(0x80000000));
393  EXPECT_EQ(saturated::Sub<int32_t>(0x80000004, 5), int32_t(0x80000000));
394  }
395  {
396  EXPECT_EQ(saturated::Sub<int64_t>(0x7FFFFFFFFFFFFFF9, -5),
397  int64_t(0x7FFFFFFFFFFFFFFE));
398  EXPECT_EQ(saturated::Sub<int64_t>(0x7FFFFFFFFFFFFFFA, -5),
399  int64_t(0x7FFFFFFFFFFFFFFF));
400  EXPECT_EQ(saturated::Sub<int64_t>(0x7FFFFFFFFFFFFFFB, -5),
401  int64_t(0x7FFFFFFFFFFFFFFF));
402  }
403  {
404  EXPECT_EQ(saturated::Sub<int64_t>(0x8000000000000006, 5),
405  int64_t(0x8000000000000001));
406  EXPECT_EQ(saturated::Sub<int64_t>(0x8000000000000005, 5),
407  int64_t(0x8000000000000000));
408  EXPECT_EQ(saturated::Sub<int64_t>(0x8000000000000004, 5),
409  int64_t(0x8000000000000000));
410  }
411 }

◆ TEST() [472/525]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAddOfFloatingPoint   
)

Definition at line 250 of file saturated_math_unittests.cc.

250  {
251  {
252  const float inf = std::numeric_limits<float>::infinity();
253  const float max = std::numeric_limits<float>::max();
254  const float big = max * 0.5f;
255 
256  EXPECT_EQ(saturated::Add(big, big), max);
257  EXPECT_EQ(saturated::Add(max, big), inf);
258  EXPECT_EQ(saturated::Add(big, max), inf);
259  EXPECT_EQ(saturated::Add(max, max), inf);
260  EXPECT_EQ(saturated::Add(max, inf), inf);
261  EXPECT_EQ(saturated::Add(inf, max), inf);
262  EXPECT_EQ(saturated::Add(inf, inf), inf);
263 
264  EXPECT_EQ(saturated::Add(-big, -big), -max);
265  EXPECT_EQ(saturated::Add(-max, -big), -inf);
266  EXPECT_EQ(saturated::Add(-big, -max), -inf);
267  EXPECT_EQ(saturated::Add(-max, -max), -inf);
268  EXPECT_EQ(saturated::Add(-max, -inf), -inf);
269  EXPECT_EQ(saturated::Add(-inf, -max), -inf);
270  EXPECT_EQ(saturated::Add(-inf, -inf), -inf);
271 
272  EXPECT_EQ(saturated::Add(big, -big), 0.0f);
273  EXPECT_EQ(saturated::Add(max, -big), big);
274  EXPECT_EQ(saturated::Add(big, -max), -big);
275  EXPECT_EQ(saturated::Add(max, -max), 0.0f);
276  EXPECT_EQ(saturated::Add(max, -inf), -inf);
277  EXPECT_EQ(saturated::Add(inf, -max), inf);
278  EXPECT_TRUE(std::isnan(saturated::Add(inf, -inf)));
279 
280  EXPECT_EQ(saturated::Add(-big, big), 0.0f);
281  EXPECT_EQ(saturated::Add(-max, big), -big);
282  EXPECT_EQ(saturated::Add(-big, max), big);
283  EXPECT_EQ(saturated::Add(-max, max), 0.0f);
284  EXPECT_EQ(saturated::Add(-max, inf), inf);
285  EXPECT_EQ(saturated::Add(-inf, max), -inf);
286  EXPECT_TRUE(std::isnan(saturated::Add(-inf, inf)));
287  }
288  {
289  const double inf = std::numeric_limits<double>::infinity();
290  const double max = std::numeric_limits<double>::max();
291  const double big = max * 0.5f;
292 
293  EXPECT_EQ(saturated::Add(big, big), max);
294  EXPECT_EQ(saturated::Add(max, big), inf);
295  EXPECT_EQ(saturated::Add(big, max), inf);
296  EXPECT_EQ(saturated::Add(max, max), inf);
297  EXPECT_EQ(saturated::Add(max, inf), inf);
298  EXPECT_EQ(saturated::Add(inf, max), inf);
299  EXPECT_EQ(saturated::Add(inf, inf), inf);
300 
301  EXPECT_EQ(saturated::Add(-big, -big), -max);
302  EXPECT_EQ(saturated::Add(-max, -big), -inf);
303  EXPECT_EQ(saturated::Add(-big, -max), -inf);
304  EXPECT_EQ(saturated::Add(-max, -max), -inf);
305  EXPECT_EQ(saturated::Add(-max, -inf), -inf);
306  EXPECT_EQ(saturated::Add(-inf, -max), -inf);
307  EXPECT_EQ(saturated::Add(-inf, -inf), -inf);
308 
309  EXPECT_EQ(saturated::Add(big, -big), 0.0f);
310  EXPECT_EQ(saturated::Add(max, -big), big);
311  EXPECT_EQ(saturated::Add(big, -max), -big);
312  EXPECT_EQ(saturated::Add(max, -max), 0.0f);
313  EXPECT_EQ(saturated::Add(max, -inf), -inf);
314  EXPECT_EQ(saturated::Add(inf, -max), inf);
315  EXPECT_TRUE(std::isnan(saturated::Add(inf, -inf)));
316 
317  EXPECT_EQ(saturated::Add(-big, big), 0.0f);
318  EXPECT_EQ(saturated::Add(-max, big), -big);
319  EXPECT_EQ(saturated::Add(-big, max), big);
320  EXPECT_EQ(saturated::Add(-max, max), 0.0f);
321  EXPECT_EQ(saturated::Add(-max, inf), inf);
322  EXPECT_EQ(saturated::Add(-inf, max), -inf);
323  EXPECT_TRUE(std::isnan(saturated::Add(-inf, inf)));
324  }
325  {
326  const Scalar inf = std::numeric_limits<Scalar>::infinity();
327  const Scalar max = std::numeric_limits<Scalar>::max();
328  const Scalar big = max * 0.5f;
329 
330  EXPECT_EQ(saturated::Add(big, big), max);
331  EXPECT_EQ(saturated::Add(max, big), inf);
332  EXPECT_EQ(saturated::Add(big, max), inf);
333  EXPECT_EQ(saturated::Add(max, max), inf);
334  EXPECT_EQ(saturated::Add(max, inf), inf);
335  EXPECT_EQ(saturated::Add(inf, max), inf);
336  EXPECT_EQ(saturated::Add(inf, inf), inf);
337 
338  EXPECT_EQ(saturated::Add(-big, -big), -max);
339  EXPECT_EQ(saturated::Add(-max, -big), -inf);
340  EXPECT_EQ(saturated::Add(-big, -max), -inf);
341  EXPECT_EQ(saturated::Add(-max, -max), -inf);
342  EXPECT_EQ(saturated::Add(-max, -inf), -inf);
343  EXPECT_EQ(saturated::Add(-inf, -max), -inf);
344  EXPECT_EQ(saturated::Add(-inf, -inf), -inf);
345 
346  EXPECT_EQ(saturated::Add(big, -big), 0.0f);
347  EXPECT_EQ(saturated::Add(max, -big), big);
348  EXPECT_EQ(saturated::Add(big, -max), -big);
349  EXPECT_EQ(saturated::Add(max, -max), 0.0f);
350  EXPECT_EQ(saturated::Add(max, -inf), -inf);
351  EXPECT_EQ(saturated::Add(inf, -max), inf);
352  EXPECT_TRUE(std::isnan(saturated::Add(inf, -inf)));
353 
354  EXPECT_EQ(saturated::Add(-big, big), 0.0f);
355  EXPECT_EQ(saturated::Add(-max, big), -big);
356  EXPECT_EQ(saturated::Add(-big, max), big);
357  EXPECT_EQ(saturated::Add(-max, max), 0.0f);
358  EXPECT_EQ(saturated::Add(-max, inf), inf);
359  EXPECT_EQ(saturated::Add(-inf, max), -inf);
360  EXPECT_TRUE(std::isnan(saturated::Add(-inf, inf)));
361  }
362 }

◆ TEST() [473/525]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAddOfSignedInts   
)

Definition at line 61 of file saturated_math_unittests.cc.

61  {
62  {
63  int8_t a = 0x79;
64  int8_t b = 5;
65  EXPECT_EQ(saturated::Add(a, b), int8_t(0x7E));
66  a = 0x7A;
67  EXPECT_EQ(saturated::Add(a, b), int8_t(0x7F));
68  a = 0x7B;
69  EXPECT_EQ(saturated::Add(a, b), int8_t(0x7F));
70  }
71  {
72  int8_t a = 0x86;
73  int8_t b = -5;
74  EXPECT_EQ(saturated::Add(a, b), int8_t(0x81));
75  a = 0x85;
76  EXPECT_EQ(saturated::Add(a, b), int8_t(0x80));
77  a = 0x84;
78  EXPECT_EQ(saturated::Add(a, b), int8_t(0x80));
79  }
80  {
81  int16_t a = 0x7FF9;
82  int16_t b = 5;
83  EXPECT_EQ(saturated::Add(a, b), int16_t(0x7FFE));
84  a = 0x7FFA;
85  EXPECT_EQ(saturated::Add(a, b), int16_t(0x7FFF));
86  a = 0x7FFB;
87  EXPECT_EQ(saturated::Add(a, b), int16_t(0x7FFF));
88  }
89  {
90  int16_t a = 0x8006;
91  int16_t b = -5;
92  EXPECT_EQ(saturated::Add(a, b), int16_t(0x8001));
93  a = 0x8005;
94  EXPECT_EQ(saturated::Add(a, b), int16_t(0x8000));
95  a = 0x8004;
96  EXPECT_EQ(saturated::Add(a, b), int16_t(0x8000));
97  }
98  {
99  int32_t a = 0x7FFFFFF9;
100  int32_t b = 5;
101  EXPECT_EQ(saturated::Add(a, b), int32_t(0x7FFFFFFE));
102  a = 0x7FFFFFFA;
103  EXPECT_EQ(saturated::Add(a, b), int32_t(0x7FFFFFFF));
104  a = 0x7FFFFFFB;
105  EXPECT_EQ(saturated::Add(a, b), int32_t(0x7FFFFFFF));
106  }
107  {
108  int32_t a = 0x80000006;
109  int32_t b = -5;
110  EXPECT_EQ(saturated::Add(a, b), int32_t(0x80000001));
111  a = 0x80000005;
112  EXPECT_EQ(saturated::Add(a, b), int32_t(0x80000000));
113  a = 0x80000004;
114  EXPECT_EQ(saturated::Add(a, b), int32_t(0x80000000));
115  }
116  {
117  int64_t a = 0x7FFFFFFFFFFFFFF9;
118  int64_t b = 5;
119  EXPECT_EQ(saturated::Add(a, b), int64_t(0x7FFFFFFFFFFFFFFE));
120  a = 0x7FFFFFFFFFFFFFFA;
121  EXPECT_EQ(saturated::Add(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
122  a = 0x7FFFFFFFFFFFFFFB;
123  EXPECT_EQ(saturated::Add(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
124  }
125  {
126  int64_t a = 0x8000000000000006;
127  int64_t b = -5;
128  EXPECT_EQ(saturated::Add(a, b), int64_t(0x8000000000000001));
129  a = 0x8000000000000005;
130  EXPECT_EQ(saturated::Add(a, b), int64_t(0x8000000000000000));
131  a = 0x8000000000000004;
132  EXPECT_EQ(saturated::Add(a, b), int64_t(0x8000000000000000));
133  }
134 }

References impeller::saturated::b.

◆ TEST() [474/525]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAverageScalarOfFloatingPoint   
)

Definition at line 903 of file saturated_math_unittests.cc.

903  {
904  // All return values are Scalar regardless of the operand types
905  // so these constants are used as the expected answers.
906  const Scalar s_inf = std::numeric_limits<Scalar>::infinity();
907  const Scalar s_max = std::numeric_limits<Scalar>::max();
908  const Scalar s_big = s_max * 0.5f;
909 
910  {
911  const float inf = std::numeric_limits<float>::infinity();
912  const float max = std::numeric_limits<float>::max();
913  const float big = max * 0.5f;
914 
915  EXPECT_EQ(saturated::AverageScalar(big, big), s_big);
916  EXPECT_EQ(saturated::AverageScalar(max, max), s_max);
917  EXPECT_EQ(saturated::AverageScalar(big, -big), 0.0f);
918  EXPECT_EQ(saturated::AverageScalar(max, -max), 0.0f);
919  EXPECT_EQ(saturated::AverageScalar(-big, big), 0.0f);
920  EXPECT_EQ(saturated::AverageScalar(-max, max), 0.0f);
921  EXPECT_EQ(saturated::AverageScalar(-big, -big), -s_big);
922  EXPECT_EQ(saturated::AverageScalar(-max, -max), -s_max);
923 
924  EXPECT_EQ(saturated::AverageScalar(inf, inf), s_inf);
925  EXPECT_EQ(saturated::AverageScalar(-inf, -inf), -s_inf);
926  EXPECT_TRUE(std::isnan(saturated::AverageScalar(-inf, inf)));
927  EXPECT_TRUE(std::isnan(saturated::AverageScalar(inf, -inf)));
928  }
929  {
930  const double inf = std::numeric_limits<double>::infinity();
931  const double max = std::numeric_limits<double>::max();
932  const double big = max * 0.5;
933 
934  // The s_constants converted to double. We should get finite results
935  // from finding the averages of these values, but we'll get a lot of
936  // overflow to infinity when testing the large double constants.
937  const double d_s_max = s_max;
938  const double d_s_big = s_big;
939  EXPECT_EQ(saturated::AverageScalar(d_s_big, d_s_big), s_big);
940  EXPECT_EQ(saturated::AverageScalar(d_s_max, d_s_max), s_max);
941  EXPECT_EQ(saturated::AverageScalar(-d_s_big, -d_s_big), -s_big);
942  EXPECT_EQ(saturated::AverageScalar(-d_s_max, -d_s_max), -s_max);
943 
944  // And now testing continues with the double constants which
945  // mostly overflow
946  EXPECT_EQ(saturated::AverageScalar(big, big), s_inf);
947  EXPECT_EQ(saturated::AverageScalar(max, max), s_inf);
948  EXPECT_EQ(saturated::AverageScalar(big, -big), 0.0f);
949  EXPECT_EQ(saturated::AverageScalar(max, -max), 0.0f);
950  EXPECT_EQ(saturated::AverageScalar(-big, big), 0.0f);
951  EXPECT_EQ(saturated::AverageScalar(-max, max), 0.0f);
952  EXPECT_EQ(saturated::AverageScalar(-big, -big), -s_inf);
953  EXPECT_EQ(saturated::AverageScalar(-max, -max), -s_inf);
954 
955  EXPECT_EQ(saturated::AverageScalar(inf, inf), s_inf);
956  EXPECT_EQ(saturated::AverageScalar(-inf, -inf), -s_inf);
957  EXPECT_TRUE(std::isnan(saturated::AverageScalar(-inf, inf)));
958  EXPECT_TRUE(std::isnan(saturated::AverageScalar(inf, -inf)));
959  }
960  {
961  const Scalar inf = std::numeric_limits<Scalar>::infinity();
962  const Scalar max = std::numeric_limits<Scalar>::max();
963  const Scalar big = max * 0.5f;
964 
965  EXPECT_EQ(saturated::AverageScalar(big, big), s_big);
966  EXPECT_EQ(saturated::AverageScalar(max, max), s_max);
967  EXPECT_EQ(saturated::AverageScalar(big, -big), 0.0f);
968  EXPECT_EQ(saturated::AverageScalar(max, -max), 0.0f);
969  EXPECT_EQ(saturated::AverageScalar(-big, big), 0.0f);
970  EXPECT_EQ(saturated::AverageScalar(-max, max), 0.0f);
971  EXPECT_EQ(saturated::AverageScalar(-big, -big), -s_big);
972  EXPECT_EQ(saturated::AverageScalar(-max, -max), -s_max);
973 
974  EXPECT_EQ(saturated::AverageScalar(inf, inf), s_inf);
975  EXPECT_EQ(saturated::AverageScalar(-inf, -inf), -s_inf);
976  EXPECT_TRUE(std::isnan(saturated::AverageScalar(-inf, s_inf)));
977  EXPECT_TRUE(std::isnan(saturated::AverageScalar(inf, -s_inf)));
978  }
979 }

◆ TEST() [475/525]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAverageScalarOfSignedInts   
)

Definition at line 763 of file saturated_math_unittests.cc.

763  {
764  // For each type try:
765  //
766  // - near the limits, averaging to 0
767  // - at the limits, averaging to 0 or 0.5 depending on precision
768  // - both large enough for the sum to overflow
769  // - both negative enough for the sum to underflow
770  {
771  int8_t a = 0x81;
772  int8_t b = 0x7f;
773  EXPECT_EQ(saturated::AverageScalar(a, b), -0.0f);
774  a = 0x80;
775  EXPECT_EQ(saturated::AverageScalar(a, b), -0.5f);
776  a = 0x70;
777  b = 0x75;
778  EXPECT_EQ(saturated::AverageScalar(a, b), 114.5f);
779  a = 0x85;
780  b = 0x8A;
781  EXPECT_EQ(saturated::AverageScalar(a, b), -120.5f);
782  }
783  {
784  int16_t a = 0x8001;
785  int16_t b = 0x7FFF;
786  EXPECT_EQ(saturated::AverageScalar(a, b), -0.0f);
787  a = 0x8000;
788  EXPECT_EQ(saturated::AverageScalar(a, b), -0.5f);
789  a = 0x7000;
790  b = 0x7005;
791  EXPECT_EQ(saturated::AverageScalar(a, b), 28674.5f);
792  a = 0x8005;
793  b = 0x800A;
794  EXPECT_EQ(saturated::AverageScalar(a, b), -32760.5f);
795  }
796  {
797  int32_t a = 0x80000001;
798  int32_t b = 0x7FFFFFFF;
799  EXPECT_EQ(saturated::AverageScalar(a, b), -0.0f);
800  a = 0x80000000;
801  EXPECT_EQ(saturated::AverageScalar(a, b), -0.5f);
802  a = 0x70000000;
803  b = 0x70000005;
804  EXPECT_EQ(saturated::AverageScalar(a, b), 1879048195.5f);
805  a = 0x80000005;
806  b = 0x8000000A;
807  EXPECT_EQ(saturated::AverageScalar(a, b), -2147483655.5f);
808  }
809  {
810  int64_t a = 0x8000000000000001;
811  int64_t b = 0x7FFFFFFFFFFFFFFF;
812  EXPECT_EQ(saturated::AverageScalar(a, b), 0.0f);
813  // 64-bit integers overflow the ability of a Scalar (float) to
814  // represent discrete integers and so the two numbers we are
815  // averaging here will look like the same number with different
816  // signs and the answer will be "0"
817  a = 0x8000000000000000;
818  EXPECT_EQ(saturated::AverageScalar<int64_t>(a, b), 0.0f);
819  a = 0x7000000000000000;
820  b = 0x7000000000000005;
821  EXPECT_NEAR(saturated::AverageScalar<int64_t>(a, b), 8.0704505e+18, 1e18);
822  a = 0x8000000000000005;
823  b = 0x800000000000000A;
824  EXPECT_NEAR(saturated::AverageScalar<int64_t>(a, b), -9.223372e+18, 1e18);
825  }
826 }

References impeller::saturated::b.

◆ TEST() [476/525]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitSubOfFloatingPoint   
)

Definition at line 602 of file saturated_math_unittests.cc.

602  {
603  {
604  const float inf = std::numeric_limits<float>::infinity();
605  const float max = std::numeric_limits<float>::max();
606  const float big = max * 0.5f;
607 
608  EXPECT_EQ(saturated::Sub(big, big), 0.0f);
609  EXPECT_EQ(saturated::Sub(max, big), big);
610  EXPECT_EQ(saturated::Sub(big, max), -big);
611  EXPECT_EQ(saturated::Sub(max, max), 0.0f);
612  EXPECT_EQ(saturated::Sub(max, inf), -inf);
613  EXPECT_EQ(saturated::Sub(inf, max), inf);
614  EXPECT_TRUE(std::isnan(saturated::Sub(inf, inf)));
615 
616  EXPECT_EQ(saturated::Sub(-big, -big), 0.0f);
617  EXPECT_EQ(saturated::Sub(-max, -big), -big);
618  EXPECT_EQ(saturated::Sub(-big, -max), big);
619  EXPECT_EQ(saturated::Sub(-max, -max), 0.0f);
620  EXPECT_EQ(saturated::Sub(-max, -inf), inf);
621  EXPECT_EQ(saturated::Sub(-inf, -max), -inf);
622  EXPECT_TRUE(std::isnan(saturated::Sub(-inf, -inf)));
623 
624  EXPECT_EQ(saturated::Sub(big, -big), max);
625  EXPECT_EQ(saturated::Sub(max, -big), inf);
626  EXPECT_EQ(saturated::Sub(big, -max), inf);
627  EXPECT_EQ(saturated::Sub(max, -max), inf);
628  EXPECT_EQ(saturated::Sub(max, -inf), inf);
629  EXPECT_EQ(saturated::Sub(inf, -max), inf);
630  EXPECT_EQ(saturated::Sub(inf, -inf), inf);
631 
632  EXPECT_EQ(saturated::Sub(-big, big), -max);
633  EXPECT_EQ(saturated::Sub(-max, big), -inf);
634  EXPECT_EQ(saturated::Sub(-big, max), -inf);
635  EXPECT_EQ(saturated::Sub(-max, max), -inf);
636  EXPECT_EQ(saturated::Sub(-max, inf), -inf);
637  EXPECT_EQ(saturated::Sub(-inf, max), -inf);
638  EXPECT_EQ(saturated::Sub(-inf, inf), -inf);
639  }
640  {
641  const double inf = std::numeric_limits<double>::infinity();
642  const double max = std::numeric_limits<double>::max();
643  const double big = max * 0.5f;
644 
645  EXPECT_EQ(saturated::Sub(big, big), 0.0f);
646  EXPECT_EQ(saturated::Sub(max, big), big);
647  EXPECT_EQ(saturated::Sub(big, max), -big);
648  EXPECT_EQ(saturated::Sub(max, max), 0.0f);
649  EXPECT_EQ(saturated::Sub(max, inf), -inf);
650  EXPECT_EQ(saturated::Sub(inf, max), inf);
651  EXPECT_TRUE(std::isnan(saturated::Sub(inf, inf)));
652 
653  EXPECT_EQ(saturated::Sub(-big, -big), 0.0f);
654  EXPECT_EQ(saturated::Sub(-max, -big), -big);
655  EXPECT_EQ(saturated::Sub(-big, -max), big);
656  EXPECT_EQ(saturated::Sub(-max, -max), 0.0f);
657  EXPECT_EQ(saturated::Sub(-max, -inf), inf);
658  EXPECT_EQ(saturated::Sub(-inf, -max), -inf);
659  EXPECT_TRUE(std::isnan(saturated::Sub(-inf, -inf)));
660 
661  EXPECT_EQ(saturated::Sub(big, -big), max);
662  EXPECT_EQ(saturated::Sub(max, -big), inf);
663  EXPECT_EQ(saturated::Sub(big, -max), inf);
664  EXPECT_EQ(saturated::Sub(max, -max), inf);
665  EXPECT_EQ(saturated::Sub(max, -inf), inf);
666  EXPECT_EQ(saturated::Sub(inf, -max), inf);
667  EXPECT_EQ(saturated::Sub(inf, -inf), inf);
668 
669  EXPECT_EQ(saturated::Sub(-big, big), -max);
670  EXPECT_EQ(saturated::Sub(-max, big), -inf);
671  EXPECT_EQ(saturated::Sub(-big, max), -inf);
672  EXPECT_EQ(saturated::Sub(-max, max), -inf);
673  EXPECT_EQ(saturated::Sub(-max, inf), -inf);
674  EXPECT_EQ(saturated::Sub(-inf, max), -inf);
675  EXPECT_EQ(saturated::Sub(-inf, inf), -inf);
676  }
677  {
678  const Scalar inf = std::numeric_limits<Scalar>::infinity();
679  const Scalar max = std::numeric_limits<Scalar>::max();
680  const Scalar big = max * 0.5f;
681 
682  EXPECT_EQ(saturated::Sub(big, big), 0.0f);
683  EXPECT_EQ(saturated::Sub(max, big), big);
684  EXPECT_EQ(saturated::Sub(big, max), -big);
685  EXPECT_EQ(saturated::Sub(max, max), 0.0f);
686  EXPECT_EQ(saturated::Sub(max, inf), -inf);
687  EXPECT_EQ(saturated::Sub(inf, max), inf);
688  EXPECT_TRUE(std::isnan(saturated::Sub(inf, inf)));
689 
690  EXPECT_EQ(saturated::Sub(-big, -big), 0.0f);
691  EXPECT_EQ(saturated::Sub(-max, -big), -big);
692  EXPECT_EQ(saturated::Sub(-big, -max), big);
693  EXPECT_EQ(saturated::Sub(-max, -max), 0.0f);
694  EXPECT_EQ(saturated::Sub(-max, -inf), inf);
695  EXPECT_EQ(saturated::Sub(-inf, -max), -inf);
696  EXPECT_TRUE(std::isnan(saturated::Sub(-inf, -inf)));
697 
698  EXPECT_EQ(saturated::Sub(big, -big), max);
699  EXPECT_EQ(saturated::Sub(max, -big), inf);
700  EXPECT_EQ(saturated::Sub(big, -max), inf);
701  EXPECT_EQ(saturated::Sub(max, -max), inf);
702  EXPECT_EQ(saturated::Sub(max, -inf), inf);
703  EXPECT_EQ(saturated::Sub(inf, -max), inf);
704  EXPECT_EQ(saturated::Sub(inf, -inf), inf);
705 
706  EXPECT_EQ(saturated::Sub(-big, big), -max);
707  EXPECT_EQ(saturated::Sub(-max, big), -inf);
708  EXPECT_EQ(saturated::Sub(-big, max), -inf);
709  EXPECT_EQ(saturated::Sub(-max, max), -inf);
710  EXPECT_EQ(saturated::Sub(-max, inf), -inf);
711  EXPECT_EQ(saturated::Sub(-inf, max), -inf);
712  EXPECT_EQ(saturated::Sub(-inf, inf), -inf);
713  }
714 }

◆ TEST() [477/525]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitSubOfSignedInts   
)

Definition at line 413 of file saturated_math_unittests.cc.

413  {
414  {
415  int8_t a = 0x79;
416  int8_t b = -5;
417  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x7E));
418  a = 0x7A;
419  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x7F));
420  a = 0x7B;
421  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x7F));
422  }
423  {
424  int8_t a = 0x86;
425  int8_t b = 5;
426  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x81));
427  a = 0x85;
428  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x80));
429  a = 0x84;
430  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x80));
431  }
432  {
433  int16_t a = 0x7FF9;
434  int16_t b = -5;
435  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x7FFE));
436  a = 0x7FFA;
437  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x7FFF));
438  a = 0x7FFB;
439  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x7FFF));
440  }
441  {
442  int16_t a = 0x8006;
443  int16_t b = 5;
444  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x8001));
445  a = 0x8005;
446  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x8000));
447  a = 0x8004;
448  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x8000));
449  }
450  {
451  int32_t a = 0x7FFFFFF9;
452  int32_t b = -5;
453  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x7FFFFFFE));
454  a = 0x7FFFFFFA;
455  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x7FFFFFFF));
456  a = 0x7FFFFFFB;
457  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x7FFFFFFF));
458  }
459  {
460  int32_t a = 0x80000006;
461  int32_t b = 5;
462  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x80000001));
463  a = 0x80000005;
464  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x80000000));
465  a = 0x80000004;
466  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x80000000));
467  }
468  {
469  int64_t a = 0x7FFFFFFFFFFFFFF9;
470  int64_t b = -5;
471  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x7FFFFFFFFFFFFFFE));
472  a = 0x7FFFFFFFFFFFFFFA;
473  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
474  a = 0x7FFFFFFFFFFFFFFB;
475  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
476  }
477  {
478  int64_t a = 0x8000000000000006;
479  int64_t b = 5;
480  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x8000000000000001));
481  a = 0x8000000000000005;
482  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x8000000000000000));
483  a = 0x8000000000000004;
484  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x8000000000000000));
485  }
486 }

References impeller::saturated::b.

◆ TEST() [478/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
BackdropFilterEmptyCoverage   
)

Definition at line 163 of file save_layer_utils_unittests.cc.

163  {
164  // Empty coverage with backdrop filter.
165  auto coverage = ComputeSaveLayerCoverage(
166  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
167  /*effect_transform=*/{}, //
168  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
169  /*image_filter=*/nullptr, //
170  /*flood_output_coverage=*/true //
171  );
172 
173  ASSERT_TRUE(coverage.has_value());
174  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 2400, 1800));
175 }
std::optional< Rect > ComputeSaveLayerCoverage(const Rect &content_coverage, const Matrix &effect_transform, const Rect &coverage_limit, const std::shared_ptr< FilterContents > &image_filter, bool flood_output_coverage, bool flood_input_coverage)
Compute the coverage of a subpass in the global coordinate space.

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [479/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
BackdropFiterComputedCoverage   
)

Definition at line 29 of file save_layer_utils_unittests.cc.

29  {
30  // Backdrop Filter, computed coverage
31  auto coverage = ComputeSaveLayerCoverage(
32  /*content_coverage=*/Rect::MakeLTRB(0, 0, 10, 10), //
33  /*effect_transform=*/{}, //
34  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
35  /*image_filter=*/nullptr,
36  /*flood_output_coverage=*/false, //
37  /*flood_input_coverage=*/true //
38  );
39 
40  ASSERT_TRUE(coverage.has_value());
41  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 2400, 1800));
42 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [480/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
BasicEmptyCoverage   
)

Definition at line 137 of file save_layer_utils_unittests.cc.

137  {
138  auto coverage = ComputeSaveLayerCoverage(
139  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
140  /*effect_transform=*/{}, //
141  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
142  /*image_filter=*/nullptr //
143  );
144 
145  ASSERT_FALSE(coverage.has_value());
146 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [481/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
CoverageLimitIgnoredIfIntersectedValueIsCloseToActualCoverageLargerWithImageFilter   
)

Definition at line 246 of file save_layer_utils_unittests.cc.

248  {
249  // Create an image filter that slightly stretches the coverage limit. Even
250  // without the special logic for using the original content coverage, we
251  // verify that we don't introduce any artifacts from the intersection.
252  auto image_filter = FilterContents::MakeMatrixFilter(
253  FilterInput::Make(Rect()), Matrix::MakeScale({0.9, 0.9, 1}), {});
254 
255  auto coverage = ComputeSaveLayerCoverage(
256  /*content_coverage=*/Rect::MakeLTRB(0, 0, 100, 100), //
257  /*effect_transform=*/{}, //
258  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
259  /*image_filter=*/image_filter //
260  );
261 
262  ASSERT_TRUE(coverage.has_value());
263  // The transfomed coverage limit is ((0, 0), (111.111, 111.111)).
264  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
265 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [482/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
CoverageLimitIgnoredIfIntersectedValueIsCloseToActualCoverageSmallerWithImageFilter   
)

Definition at line 227 of file save_layer_utils_unittests.cc.

229  {
230  // Create an image filter that slightly shrinks the coverage limit
231  auto image_filter = FilterContents::MakeMatrixFilter(
232  FilterInput::Make(Rect()), Matrix::MakeScale({1.1, 1.1, 1}), {});
233 
234  auto coverage = ComputeSaveLayerCoverage(
235  /*content_coverage=*/Rect::MakeLTRB(0, 0, 100, 100), //
236  /*effect_transform=*/{}, //
237  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
238  /*image_filter=*/image_filter //
239  );
240 
241  ASSERT_TRUE(coverage.has_value());
242  // The transfomed coverage limit is ((0, 0), (90.9091, 90.9091)).
243  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
244 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [483/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
CoverageLimitRespectedIfSubstantiallyDifferentFromContentCoverage   
)

Definition at line 267 of file save_layer_utils_unittests.cc.

268  {
269  auto image_filter = FilterContents::MakeMatrixFilter(
270  FilterInput::Make(Rect()), Matrix::MakeScale({2, 2, 1}), {});
271 
272  auto coverage = ComputeSaveLayerCoverage(
273  /*content_coverage=*/Rect::MakeLTRB(0, 0, 1000, 1000), //
274  /*effect_transform=*/{}, //
275  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
276  /*image_filter=*/image_filter //
277  );
278 
279  ASSERT_TRUE(coverage.has_value());
280  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
281 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [484/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DisjointCoverage   
)

Definition at line 94 of file save_layer_utils_unittests.cc.

94  {
95  // No intersection in coverage
96  auto coverage = ComputeSaveLayerCoverage(
97  /*content_coverage=*/Rect::MakeLTRB(200, 200, 210, 210), //
98  /*effect_transform=*/{}, //
99  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
100  /*image_filter=*/nullptr //
101  );
102 
103  EXPECT_FALSE(coverage.has_value());
104 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [485/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DisjointCoverageTransformedByImageFilter   
)

Definition at line 106 of file save_layer_utils_unittests.cc.

106  {
107  // Coverage disjoint from parent coverage but transformed into parent space
108  // with image filter.
109  auto image_filter = FilterContents::MakeMatrixFilter(
110  FilterInput::Make(Rect()), Matrix::MakeTranslation({-200, -200, 0}), {});
111 
112  auto coverage = ComputeSaveLayerCoverage(
113  /*content_coverage=*/Rect::MakeLTRB(200, 200, 210, 210), //
114  /*effect_transform=*/{}, //
115  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
116  /*image_filter=*/image_filter //
117  );
118 
119  ASSERT_TRUE(coverage.has_value());
120  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(200, 200, 210, 210));
121 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeTranslation().

◆ TEST() [486/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DisjointCoveragTransformedByCTM   
)

Definition at line 123 of file save_layer_utils_unittests.cc.

123  {
124  // Coverage disjoint from parent coverage.
125  Matrix ctm = Matrix::MakeTranslation({-200, -200, 0});
126  auto coverage = ComputeSaveLayerCoverage(
127  /*content_coverage=*/Rect::MakeLTRB(200, 200, 210, 210), //
128  /*effect_transform=*/ctm, //
129  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
130  /*image_filter=*/nullptr //
131  );
132 
133  ASSERT_TRUE(coverage.has_value());
134  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 10, 10));
135 }

References impeller::ComputeSaveLayerCoverage(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::Matrix::MakeTranslation().

◆ TEST() [487/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DontRoundUpCoverageWhenNotCloseToCoverageLimitHeight   
)

Definition at line 311 of file save_layer_utils_unittests.cc.

311  {
312  // X varies, translation is performed on coverage.
313  auto coverage = ComputeSaveLayerCoverage(
314  /*content_coverage=*/Rect::MakeLTRB(0, 0, 90, 50), //
315  /*effect_transform=*/{}, //
316  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
317  /*image_filter=*/nullptr //
318  );
319 
320  ASSERT_TRUE(coverage.has_value());
321  // Size that matches coverage limit
322  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 90, 50));
323 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [488/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DontRoundUpCoverageWhenNotCloseToCoverageLimitWidth   
)

Definition at line 297 of file save_layer_utils_unittests.cc.

297  {
298  // X varies, translation is performed on coverage.
299  auto coverage = ComputeSaveLayerCoverage(
300  /*content_coverage=*/Rect::MakeLTRB(0, 0, 50, 90), //
301  /*effect_transform=*/{}, //
302  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
303  /*image_filter=*/nullptr //
304  );
305 
306  ASSERT_TRUE(coverage.has_value());
307  // Size that matches coverage limit
308  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 50, 90));
309 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [489/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DontRoundUpCoverageWhenNotCloseToCoverageLimitWidthHeight   
)

Definition at line 325 of file save_layer_utils_unittests.cc.

326  {
327  // X varies, translation is performed on coverage.
328  auto coverage = ComputeSaveLayerCoverage(
329  /*content_coverage=*/Rect::MakeLTRB(0, 0, 50, 50), //
330  /*effect_transform=*/{}, //
331  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
332  /*image_filter=*/nullptr //
333  );
334 
335  ASSERT_TRUE(coverage.has_value());
336  // Size that matches coverage limit
337  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
338 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [490/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
FloodInputCoverage   
)

Definition at line 177 of file save_layer_utils_unittests.cc.

177  {
178  auto coverage = ComputeSaveLayerCoverage(
179  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
180  /*effect_transform=*/{}, //
181  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
182  /*image_filter=*/nullptr, //
183  /*flood_output_coverage=*/false, //
184  /*flood_input_coverage=*/true //
185  );
186 
187  ASSERT_TRUE(coverage.has_value());
188  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 2400, 1800));
189 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [491/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
FloodInputCoverageWithImageFilter   
)

Definition at line 191 of file save_layer_utils_unittests.cc.

191  {
192  auto image_filter = FilterContents::MakeMatrixFilter(
193  FilterInput::Make(Rect()), Matrix::MakeScale({0.5, 0.5, 1}), {});
194 
195  auto coverage = ComputeSaveLayerCoverage(
196  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
197  /*effect_transform=*/{}, //
198  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
199  /*image_filter=*/image_filter, //
200  /*flood_output_coverage=*/false, //
201  /*flood_input_coverage=*/true //
202  );
203 
204  ASSERT_TRUE(coverage.has_value());
205  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 4800, 3600));
206 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [492/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
FloodInputCoverageWithImageFilterWithNoCoverageProducesNoCoverage   
)

Definition at line 208 of file save_layer_utils_unittests.cc.

209  {
210  // Even if we flood the input coverage due to a bdf, we can still cull out the
211  // layer if the image filter results in no coverage.
212  auto image_filter = FilterContents::MakeMatrixFilter(
213  FilterInput::Make(Rect()), Matrix::MakeScale({1, 1, 0}), {});
214 
215  auto coverage = ComputeSaveLayerCoverage(
216  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
217  /*effect_transform=*/{}, //
218  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
219  /*image_filter=*/image_filter, //
220  /*flood_output_coverage=*/false, //
221  /*flood_input_coverage=*/true //
222  );
223 
224  ASSERT_FALSE(coverage.has_value());
225 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [493/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
ImageFilterEmptyCoverage   
)

Definition at line 148 of file save_layer_utils_unittests.cc.

148  {
149  // Empty coverage with Image Filter
150  auto image_filter = FilterContents::MakeMatrixFilter(
151  FilterInput::Make(Rect()), Matrix::MakeTranslation({-200, -200, 0}), {});
152 
153  auto coverage = ComputeSaveLayerCoverage(
154  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
155  /*effect_transform=*/{}, //
156  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
157  /*image_filter=*/image_filter //
158  );
159 
160  ASSERT_FALSE(coverage.has_value());
161 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeTranslation().

◆ TEST() [494/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
ImageFiterComputedCoverage   
)

Definition at line 44 of file save_layer_utils_unittests.cc.

44  {
45  // Image Filter, computed coverage
46  auto image_filter = FilterContents::MakeMatrixFilter(
47  FilterInput::Make(Rect()), Matrix::MakeScale({2, 2, 1}), {});
48 
49  auto coverage = ComputeSaveLayerCoverage(
50  /*content_coverage=*/Rect::MakeLTRB(0, 0, 10, 10), //
51  /*effect_transform=*/{}, //
52  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
53  /*image_filter=*/image_filter //
54  );
55 
56  ASSERT_TRUE(coverage.has_value());
57  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 10, 10));
58 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [495/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
ImageFiterLargeScaleComputedCoverageLargerThanBoundsLimit   
)

Definition at line 77 of file save_layer_utils_unittests.cc.

78  {
79  // Image Filter scaling small, computed coverage is larger than bounds limit.
80  auto image_filter = FilterContents::MakeMatrixFilter(
81  FilterInput::Make(Rect()), Matrix::MakeScale({0.5, 0.5, 1}), {});
82 
83  auto coverage = ComputeSaveLayerCoverage(
84  /*content_coverage=*/Rect::MakeLTRB(0, 0, 10, 10), //
85  /*effect_transform=*/{}, //
86  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 5, 5), //
87  /*image_filter=*/image_filter //
88  );
89 
90  ASSERT_TRUE(coverage.has_value());
91  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 10, 10));
92 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [496/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
ImageFiterSmallScaleComputedCoverageLargerThanBoundsLimit   
)

Definition at line 60 of file save_layer_utils_unittests.cc.

61  {
62  // Image Filter scaling large, computed coverage is larger than bounds limit.
63  auto image_filter = FilterContents::MakeMatrixFilter(
64  FilterInput::Make(Rect()), Matrix::MakeScale({2, 2, 1}), {});
65 
66  auto coverage = ComputeSaveLayerCoverage(
67  /*content_coverage=*/Rect::MakeLTRB(0, 0, 10, 10), //
68  /*effect_transform=*/{}, //
69  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 5, 5), //
70  /*image_filter=*/image_filter //
71  );
72 
73  ASSERT_TRUE(coverage.has_value());
74  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 2.5, 2.5));
75 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [497/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
RoundUpCoverageWhenCloseToCoverageLimit   
)

Definition at line 283 of file save_layer_utils_unittests.cc.

283  {
284  // X varies, translation is performed on coverage.
285  auto coverage = ComputeSaveLayerCoverage(
286  /*content_coverage=*/Rect::MakeLTRB(0, 0, 90, 90), //
287  /*effect_transform=*/{}, //
288  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
289  /*image_filter=*/nullptr //
290  );
291 
292  ASSERT_TRUE(coverage.has_value());
293  // Size that matches coverage limit
294  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
295 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [498/525]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
SimplePaintComputedCoverage   
)

Definition at line 17 of file save_layer_utils_unittests.cc.

17  {
18  // Basic Case, simple paint, computed coverage
19  auto coverage = ComputeSaveLayerCoverage(
20  /*content_coverage=*/Rect::MakeLTRB(0, 0, 10, 10), //
21  /*effect_transform=*/{}, //
22  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
23  /*image_filter=*/nullptr //
24  );
25  ASSERT_TRUE(coverage.has_value());
26  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 10, 10));
27 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [499/525]

impeller::testing::TEST ( ShaderArchiveTest  ,
CanReadAndWriteBlobs   
)

Definition at line 28 of file shader_archive_unittests.cc.

28  {
29  ShaderArchiveWriter writer;
30  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Hello",
31  CreateMappingFromString("World")));
32  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Foo",
33  CreateMappingFromString("Bar")));
34  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Baz",
35  CreateMappingFromString("Bang")));
36  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Ping",
37  CreateMappingFromString("Pong")));
38  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Pang",
39  CreateMappingFromString("World")));
40 
41  auto mapping = writer.CreateMapping();
42  ASSERT_NE(mapping, nullptr);
43 
44  ShaderArchive library(mapping);
45  ASSERT_TRUE(library.IsValid());
46  ASSERT_EQ(library.GetShaderCount(), 5u);
47 
48  // Wrong type.
49  ASSERT_EQ(library.GetMapping(ArchiveShaderType::kFragment, "Hello"), nullptr);
50 
51  auto hello_vtx = library.GetMapping(ArchiveShaderType::kVertex, "Hello");
52  ASSERT_NE(hello_vtx, nullptr);
53  ASSERT_EQ(CreateStringFromMapping(*hello_vtx), "World");
54 }
const std::string CreateStringFromMapping(const fml::Mapping &mapping)
static std::shared_ptr< fml::Mapping > CreateMappingFromString(std::string p_string)

References impeller::ShaderArchiveWriter::AddShader(), impeller::ShaderArchiveWriter::CreateMapping(), CreateMappingFromString(), CreateStringFromMapping(), impeller::ShaderArchive::GetMapping(), impeller::ShaderArchive::GetShaderCount(), impeller::ShaderArchive::IsValid(), impeller::kFragment, and impeller::kVertex.

◆ TEST() [500/525]

impeller::testing::TEST ( SizeTest  ,
ISizeIsEmpty   
)

Definition at line 36 of file size_unittests.cc.

36  {
37  // Non-empty
38  EXPECT_FALSE(ISize(10, 7).IsEmpty());
39 
40  // Empty both width and height both 0 or negative, in all combinations
41  EXPECT_TRUE(ISize(0, 0).IsEmpty());
42  EXPECT_TRUE(ISize(-1, -1).IsEmpty());
43  EXPECT_TRUE(ISize(-1, 0).IsEmpty());
44  EXPECT_TRUE(ISize(0, -1).IsEmpty());
45 
46  // Empty for 0 or negative width or height (but not both at the same time)
47  EXPECT_TRUE(ISize(10, 0).IsEmpty());
48  EXPECT_TRUE(ISize(10, -1).IsEmpty());
49  EXPECT_TRUE(ISize(0, 7).IsEmpty());
50  EXPECT_TRUE(ISize(-1, 7).IsEmpty());
51 }

◆ TEST() [501/525]

impeller::testing::TEST ( SizeTest  ,
IsSquare   
)

Definition at line 53 of file size_unittests.cc.

53  {
54  EXPECT_TRUE(Size(20, 20).IsSquare());
55  EXPECT_FALSE(Size(20, 19).IsSquare());
56  EXPECT_FALSE(Size(19, 20).IsSquare());
57 
58  EXPECT_TRUE(ISize(20, 20).IsSquare());
59  EXPECT_FALSE(ISize(20, 19).IsSquare());
60  EXPECT_FALSE(ISize(19, 20).IsSquare());
61 }

◆ TEST() [502/525]

impeller::testing::TEST ( SizeTest  ,
MaxDimension   
)

Definition at line 63 of file size_unittests.cc.

63  {
64  EXPECT_EQ(Size(20, 20).MaxDimension(), 20);
65  EXPECT_EQ(Size(20, 19).MaxDimension(), 20);
66  EXPECT_EQ(Size(19, 20).MaxDimension(), 20);
67  EXPECT_EQ(Size(20, 21).MaxDimension(), 21);
68  EXPECT_EQ(Size(21, 20).MaxDimension(), 21);
69 
70  EXPECT_EQ(ISize(20, 20).MaxDimension(), 20);
71  EXPECT_EQ(ISize(20, 19).MaxDimension(), 20);
72  EXPECT_EQ(ISize(19, 20).MaxDimension(), 20);
73  EXPECT_EQ(ISize(20, 21).MaxDimension(), 21);
74  EXPECT_EQ(ISize(21, 20).MaxDimension(), 21);
75 }

◆ TEST() [503/525]

impeller::testing::TEST ( SizeTest  ,
NegationOperator   
)

Definition at line 77 of file size_unittests.cc.

77  {
78  EXPECT_EQ(-Size(10, 20), Size(-10, -20));
79  EXPECT_EQ(-Size(-10, 20), Size(10, -20));
80  EXPECT_EQ(-Size(10, -20), Size(-10, 20));
81  EXPECT_EQ(-Size(-10, -20), Size(10, 20));
82 }

◆ TEST() [504/525]

impeller::testing::TEST ( SizeTest  ,
SizeIsEmpty   
)

Definition at line 12 of file size_unittests.cc.

12  {
13  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
14 
15  // Non-empty
16  EXPECT_FALSE(Size(10.5, 7.2).IsEmpty());
17 
18  // Empty both width and height both 0 or negative, in all combinations
19  EXPECT_TRUE(Size(0.0, 0.0).IsEmpty());
20  EXPECT_TRUE(Size(-1.0, -1.0).IsEmpty());
21  EXPECT_TRUE(Size(-1.0, 0.0).IsEmpty());
22  EXPECT_TRUE(Size(0.0, -1.0).IsEmpty());
23 
24  // Empty for 0 or negative width or height (but not both at the same time)
25  EXPECT_TRUE(Size(10.5, 0.0).IsEmpty());
26  EXPECT_TRUE(Size(10.5, -1.0).IsEmpty());
27  EXPECT_TRUE(Size(0.0, 7.2).IsEmpty());
28  EXPECT_TRUE(Size(-1.0, 7.2).IsEmpty());
29 
30  // Empty for NaN in width or height or both
31  EXPECT_TRUE(Size(10.5, nan).IsEmpty());
32  EXPECT_TRUE(Size(nan, 7.2).IsEmpty());
33  EXPECT_TRUE(Size(nan, nan).IsEmpty());
34 }

◆ TEST() [505/525]

impeller::testing::TEST ( SkiaConversionsTest  ,
ToColor   
)

Definition at line 46 of file skia_conversions_unittests.cc.

46  {
47  // Create a color with alpha, red, green, and blue values that are all
48  // trivially divisible by 255 so that we can test the conversion results in
49  // correct scalar values.
50  // AARRGGBB
51  const flutter::DlColor color = flutter::DlColor(0x8040C020);
52  auto converted_color = skia_conversions::ToColor(color);
53 
54  ASSERT_TRUE(ScalarNearlyEqual(converted_color.alpha, 0x80 * (1.0f / 255)));
55  ASSERT_TRUE(ScalarNearlyEqual(converted_color.red, 0x40 * (1.0f / 255)));
56  ASSERT_TRUE(ScalarNearlyEqual(converted_color.green, 0xC0 * (1.0f / 255)));
57  ASSERT_TRUE(ScalarNearlyEqual(converted_color.blue, 0x20 * (1.0f / 255)));
58 }
Color ToColor(const flutter::DlColor &color)

References impeller::ScalarNearlyEqual(), and impeller::skia_conversions::ToColor().

◆ TEST() [506/525]

impeller::testing::TEST ( SkiaConversionTest  ,
ToSamplerDescriptor   
)

Definition at line 17 of file skia_conversions_unittests.cc.

17  {
19  flutter::DlImageSampling::kNearestNeighbor)
20  .min_filter,
23  flutter::DlImageSampling::kNearestNeighbor)
24  .mip_filter,
26 
27  EXPECT_EQ(
28  skia_conversions::ToSamplerDescriptor(flutter::DlImageSampling::kLinear)
29  .min_filter,
31  EXPECT_EQ(
32  skia_conversions::ToSamplerDescriptor(flutter::DlImageSampling::kLinear)
33  .mip_filter,
35 
37  flutter::DlImageSampling::kMipmapLinear)
38  .min_filter,
41  flutter::DlImageSampling::kMipmapLinear)
42  .mip_filter,
44 }
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
@ kBase
The texture is sampled as if it only had a single mipmap level.
static impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlFilterMode options)
@ kNearest
Select nearest to the sample point. Most widely supported.

References impeller::kBase, impeller::kLinear, impeller::kNearest, and impeller::skia_conversions::ToSamplerDescriptor().

◆ TEST() [507/525]

impeller::testing::TEST ( SurfaceContextVK  ,
TearsDownSwapchain   
)

Definition at line 31 of file surface_context_vk_unittests.cc.

31  {
32  SetSwapchainImageSize({100, 100});
33  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
34 
35  vk::UniqueSurfaceKHR surface = CreateSurface(*context);
36  SurfaceContextVK surface_context(context);
37 
38  EXPECT_TRUE(surface_context.SetWindowSurface(std::move(surface), {100, 100}));
39  EXPECT_NE(surface_context.AcquireNextSurface(), nullptr);
40 
41  surface_context.TeardownSwapchain();
42 
43  EXPECT_EQ(surface_context.AcquireNextSurface(), nullptr);
44 }

References impeller::SurfaceContextVK::AcquireNextSurface(), impeller::SurfaceContextVK::SetWindowSurface(), and impeller::SurfaceContextVK::TeardownSwapchain().

◆ TEST() [508/525]

impeller::testing::TEST ( TessellatorTest  ,
CircleVertexCounts   
)

Definition at line 153 of file tessellator_unittests.cc.

153  {
154  auto tessellator = std::make_shared<Tessellator>();
155 
156  auto test = [&tessellator](const Matrix& transform, Scalar radius) {
157  auto generator = tessellator->FilledCircle(transform, {}, radius);
158  size_t quadrant_divisions = generator.GetVertexCount() / 4;
159 
160  // Confirm the approximation error is within the currently accepted
161  // |kCircleTolerance| value advertised by |CircleTessellator|.
162  // (With an additional 1% tolerance for floating point rounding.)
163  double angle = kPiOver2 / quadrant_divisions;
164  Point first = {radius, 0};
165  Point next = {static_cast<Scalar>(cos(angle) * radius),
166  static_cast<Scalar>(sin(angle) * radius)};
167  Point midpoint = (first + next) * 0.5;
168  EXPECT_GE(midpoint.GetLength(),
169  radius - Tessellator::kCircleTolerance * 1.01)
170  << ", transform = " << transform << ", radius = " << radius
171  << ", divisions = " << quadrant_divisions;
172  };
173 
174  test({}, 0.0);
175  test({}, 0.9);
176  test({}, 1.0);
177  test({}, 1.9);
178  test(Matrix::MakeScale(Vector2(2.0, 2.0)), 0.95);
179  test({}, 2.0);
180  test(Matrix::MakeScale(Vector2(2.0, 2.0)), 1.0);
181  test({}, 11.9);
182  test({}, 12.0);
183  test({}, 35.9);
184  for (int i = 36; i < 10000; i += 4) {
185  test({}, i);
186  }
187 }

References impeller::TPoint< T >::GetLength(), impeller::Tessellator::kCircleTolerance, impeller::kPiOver2, impeller::Matrix::MakeScale(), and transform.

◆ TEST() [509/525]

impeller::testing::TEST ( TessellatorTest  ,
EarlyReturnEmptyConvexShape   
)

Definition at line 513 of file tessellator_unittests.cc.

513  {
514  // This path is not technically empty (it has a size in one dimension), but
515  // it contains only move commands and no actual path segment definitions.
516  flutter::DlPathBuilder builder;
517  builder.MoveTo({0, 0});
518  builder.MoveTo({10, 10});
519 
520  std::vector<Point> points;
521  std::vector<uint16_t> indices;
522  Tessellator::TessellateConvexInternal(builder.TakePath(), points, indices,
523  3.0f);
524 
525  EXPECT_TRUE(points.empty());
526  EXPECT_TRUE(indices.empty());
527 }

References points, and impeller::Tessellator::TessellateConvexInternal().

◆ TEST() [510/525]

impeller::testing::TEST ( TessellatorTest  ,
FilledCircleTessellationVertices   
)

Definition at line 189 of file tessellator_unittests.cc.

189  {
190  auto tessellator = std::make_shared<Tessellator>();
191 
192  auto test = [&tessellator](const Matrix& transform, const Point& center,
193  Scalar radius) {
194  auto generator = tessellator->FilledCircle(transform, center, radius);
195  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
196 
197  auto vertex_count = generator.GetVertexCount();
198  auto vertices = std::vector<Point>();
199  generator.GenerateVertices([&vertices](const Point& p) { //
200  vertices.push_back(p);
201  });
202  EXPECT_EQ(vertices.size(), vertex_count);
203  ASSERT_EQ(vertex_count % 4, 0u);
204 
205  auto quadrant_count = vertex_count / 4;
206  for (size_t i = 0; i < quadrant_count; i++) {
207  double angle = kPiOver2 * i / (quadrant_count - 1);
208  double degrees = angle * 180.0 / kPi;
209  double rsin = sin(angle) * radius;
210  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
211  double rcos = (i == quadrant_count - 1) ? 0.0f : cos(angle) * radius;
212  EXPECT_POINT_NEAR(vertices[i * 2],
213  Point(center.x - rcos, center.y + rsin))
214  << "vertex " << i << ", angle = " << degrees << std::endl;
215  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
216  Point(center.x - rcos, center.y - rsin))
217  << "vertex " << i << ", angle = " << degrees << std::endl;
218  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
219  Point(center.x + rcos, center.y - rsin))
220  << "vertex " << i << ", angle = " << degrees << std::endl;
221  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
222  Point(center.x + rcos, center.y + rsin))
223  << "vertex " << i << ", angle = " << degrees << std::endl;
224  }
225  };
226 
227  test({}, {}, 2.0);
228  test({}, {10, 10}, 2.0);
229  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0);
230  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0);
231 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), and transform.

◆ TEST() [511/525]

impeller::testing::TEST ( TessellatorTest  ,
FilledEllipseTessellationVertices   
)

Definition at line 378 of file tessellator_unittests.cc.

378  {
379  auto tessellator = std::make_shared<Tessellator>();
380 
381  auto test = [&tessellator](const Matrix& transform, const Rect& bounds) {
382  auto center = bounds.GetCenter();
383  auto half_size = bounds.GetSize() * 0.5f;
384 
385  auto generator = tessellator->FilledEllipse(transform, bounds);
386  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
387 
388  auto vertex_count = generator.GetVertexCount();
389  auto vertices = std::vector<Point>();
390  generator.GenerateVertices([&vertices](const Point& p) { //
391  vertices.push_back(p);
392  });
393  EXPECT_EQ(vertices.size(), vertex_count);
394  ASSERT_EQ(vertex_count % 4, 0u);
395 
396  auto quadrant_count = vertex_count / 4;
397  for (size_t i = 0; i < quadrant_count; i++) {
398  double angle = kPiOver2 * i / (quadrant_count - 1);
399  double degrees = angle * 180.0 / kPi;
400  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
401  double rcos =
402  (i == quadrant_count - 1) ? 0.0f : cos(angle) * half_size.width;
403  double rsin = sin(angle) * half_size.height;
404  EXPECT_POINT_NEAR(vertices[i * 2],
405  Point(center.x - rcos, center.y + rsin))
406  << "vertex " << i << ", angle = " << degrees << ", " //
407  << "bounds = " << bounds << std::endl;
408  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
409  Point(center.x - rcos, center.y - rsin))
410  << "vertex " << i << ", angle = " << degrees << ", " //
411  << "bounds = " << bounds << std::endl;
412  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
413  Point(center.x + rcos, center.y - rsin))
414  << "vertex " << i << ", angle = " << degrees << ", " //
415  << "bounds = " << bounds << std::endl;
416  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
417  Point(center.x + rcos, center.y + rsin))
418  << "vertex " << i << ", angle = " << degrees << ", " //
419  << "bounds = " << bounds << std::endl;
420  }
421  };
422 
423  // Square bounds should actually use the circle generator, but its
424  // results should match the same math as the ellipse generator.
425  test({}, Rect::MakeXYWH(0, 0, 2, 2));
426 
427  test({}, Rect::MakeXYWH(0, 0, 2, 3));
428  test({}, Rect::MakeXYWH(0, 0, 3, 2));
429  test({}, Rect::MakeXYWH(5, 10, 2, 3));
430  test({}, Rect::MakeXYWH(16, 7, 3, 2));
431  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 3, 2));
432  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 2, 3));
433  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
434  Rect::MakeXYWH(5000, 10000, 3000, 2000));
435  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
436  Rect::MakeXYWH(5000, 10000, 2000, 3000));
437 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), and transform.

◆ TEST() [512/525]

impeller::testing::TEST ( TessellatorTest  ,
FilledRoundRectTessellationVertices   
)

Definition at line 439 of file tessellator_unittests.cc.

439  {
440  auto tessellator = std::make_shared<Tessellator>();
441 
442  auto test = [&tessellator](const Matrix& transform, const Rect& bounds,
443  const Size& radii) {
444  FML_DCHECK(radii.width * 2 <= bounds.GetWidth()) << radii << bounds;
445  FML_DCHECK(radii.height * 2 <= bounds.GetHeight()) << radii << bounds;
446 
447  Scalar middle_left = bounds.GetX() + radii.width;
448  Scalar middle_top = bounds.GetY() + radii.height;
449  Scalar middle_right = bounds.GetX() + bounds.GetWidth() - radii.width;
450  Scalar middle_bottom = bounds.GetY() + bounds.GetHeight() - radii.height;
451 
452  auto generator = tessellator->FilledRoundRect(transform, bounds, radii);
453  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
454 
455  auto vertex_count = generator.GetVertexCount();
456  auto vertices = std::vector<Point>();
457  generator.GenerateVertices([&vertices](const Point& p) { //
458  vertices.push_back(p);
459  });
460  EXPECT_EQ(vertices.size(), vertex_count);
461  ASSERT_EQ(vertex_count % 4, 0u);
462 
463  auto quadrant_count = vertex_count / 4;
464  for (size_t i = 0; i < quadrant_count; i++) {
465  double angle = kPiOver2 * i / (quadrant_count - 1);
466  double degrees = angle * 180.0 / kPi;
467  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
468  double rcos = (i == quadrant_count - 1) ? 0.0f : cos(angle) * radii.width;
469  double rsin = sin(angle) * radii.height;
470  EXPECT_POINT_NEAR(vertices[i * 2],
471  Point(middle_left - rcos, middle_bottom + rsin))
472  << "vertex " << i << ", angle = " << degrees << ", " //
473  << "bounds = " << bounds << std::endl;
474  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
475  Point(middle_left - rcos, middle_top - rsin))
476  << "vertex " << i << ", angle = " << degrees << ", " //
477  << "bounds = " << bounds << std::endl;
478  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
479  Point(middle_right + rcos, middle_top - rsin))
480  << "vertex " << i << ", angle = " << degrees << ", " //
481  << "bounds = " << bounds << std::endl;
482  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
483  Point(middle_right + rcos, middle_bottom + rsin))
484  << "vertex " << i << ", angle = " << degrees << ", " //
485  << "bounds = " << bounds << std::endl;
486  }
487  };
488 
489  // Both radii spanning the bounds should actually use the circle/ellipse
490  // generator, but their results should match the same math as the round
491  // rect generator.
492  test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 10});
493 
494  // One radius spanning the bounds, but not the other will not match the
495  // round rect math if the generator transfers to circle/ellipse
496  test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 5});
497  test({}, Rect::MakeXYWH(0, 0, 20, 20), {5, 10});
498 
499  test({}, Rect::MakeXYWH(0, 0, 20, 30), {2, 2});
500  test({}, Rect::MakeXYWH(0, 0, 30, 20), {2, 2});
501  test({}, Rect::MakeXYWH(5, 10, 20, 30), {2, 3});
502  test({}, Rect::MakeXYWH(16, 7, 30, 20), {2, 3});
503  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 30, 20),
504  {2, 3});
505  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 20, 30),
506  {2, 3});
507  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
508  Rect::MakeXYWH(5000, 10000, 3000, 2000), {50, 70});
509  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
510  Rect::MakeXYWH(5000, 10000, 2000, 3000), {50, 70});
511 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), and transform.

◆ TEST() [513/525]

impeller::testing::TEST ( TessellatorTest  ,
RoundCapLineTessellationVertices   
)

Definition at line 305 of file tessellator_unittests.cc.

305  {
306  auto tessellator = std::make_shared<Tessellator>();
307 
308  auto test = [&tessellator](const Matrix& transform, const Point& p0,
309  const Point& p1, Scalar radius) {
310  auto generator = tessellator->RoundCapLine(transform, p0, p1, radius);
311  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
312 
313  auto vertex_count = generator.GetVertexCount();
314  auto vertices = std::vector<Point>();
315  generator.GenerateVertices([&vertices](const Point& p) { //
316  vertices.push_back(p);
317  });
318  EXPECT_EQ(vertices.size(), vertex_count);
319  ASSERT_EQ(vertex_count % 4, 0u);
320 
321  Point along = p1 - p0;
322  Scalar length = along.GetLength();
323  if (length > 0) {
324  along *= radius / length;
325  } else {
326  along = {radius, 0};
327  }
328  Point across = {-along.y, along.x};
329 
330  auto quadrant_count = vertex_count / 4;
331  for (size_t i = 0; i < quadrant_count; i++) {
332  double angle = kPiOver2 * i / (quadrant_count - 1);
333  double degrees = angle * 180.0 / kPi;
334  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
335  Point relative_along =
336  along * ((i == quadrant_count - 1) ? 0.0f : cos(angle));
337  Point relative_across = across * sin(angle);
338  EXPECT_POINT_NEAR(vertices[i * 2], //
339  p0 - relative_along + relative_across)
340  << "vertex " << i << ", angle = " << degrees << ", " //
341  << "line = " << p0 << " => " << p1 << ", " //
342  << "radius = " << radius << std::endl;
343  EXPECT_POINT_NEAR(vertices[i * 2 + 1], //
344  p0 - relative_along - relative_across)
345  << "vertex " << i << ", angle = " << degrees << ", " //
346  << "line = " << p0 << " => " << p1 << ", " //
347  << "radius = " << radius << std::endl;
348  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1], //
349  p1 + relative_along - relative_across)
350  << "vertex " << i << ", angle = " << degrees << ", " //
351  << "line = " << p0 << " => " << p1 << ", " //
352  << "radius = " << radius << std::endl;
353  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2], //
354  p1 + relative_along + relative_across)
355  << "vertex " << i << ", angle = " << degrees << ", " //
356  << "line = " << p0 << " => " << p1 << ", " //
357  << "radius = " << radius << std::endl;
358  }
359  };
360 
361  // Empty line should actually use the circle generator, but its
362  // results should match the same math as the round cap generator.
363  test({}, {0, 0}, {0, 0}, 10);
364 
365  test({}, {0, 0}, {10, 0}, 2);
366  test({}, {10, 0}, {0, 0}, 2);
367  test({}, {0, 0}, {10, 10}, 2);
368 
369  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 0}, 2);
370  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {10, 0}, {0, 0}, 2);
371  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 10}, 2);
372 
373  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 0}, 2);
374  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {10, 0}, {0, 0}, 2);
375  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 10}, 2);
376 }

References EXPECT_POINT_NEAR, impeller::TPoint< T >::GetLength(), impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), transform, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [514/525]

impeller::testing::TEST ( TessellatorTest  ,
StrokedCircleTessellationVertices   
)

Definition at line 233 of file tessellator_unittests.cc.

233  {
234  auto tessellator = std::make_shared<Tessellator>();
235 
236  auto test = [&tessellator](const Matrix& transform, const Point& center,
237  Scalar radius, Scalar half_width) {
238  ASSERT_GT(radius, half_width);
239  auto generator =
240  tessellator->StrokedCircle(transform, center, radius, half_width);
241  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
242 
243  auto vertex_count = generator.GetVertexCount();
244  auto vertices = std::vector<Point>();
245  generator.GenerateVertices([&vertices](const Point& p) { //
246  vertices.push_back(p);
247  });
248  EXPECT_EQ(vertices.size(), vertex_count);
249  ASSERT_EQ(vertex_count % 4, 0u);
250 
251  auto quadrant_count = vertex_count / 8;
252 
253  // Test outer points first
254  for (size_t i = 0; i < quadrant_count; i++) {
255  double angle = kPiOver2 * i / (quadrant_count - 1);
256  double degrees = angle * 180.0 / kPi;
257  double rsin = sin(angle) * (radius + half_width);
258  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
259  double rcos =
260  (i == quadrant_count - 1) ? 0.0f : cos(angle) * (radius + half_width);
261  EXPECT_POINT_NEAR(vertices[i * 2],
262  Point(center.x - rcos, center.y - rsin))
263  << "vertex " << i << ", angle = " << degrees << std::endl;
264  EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2],
265  Point(center.x + rsin, center.y - rcos))
266  << "vertex " << i << ", angle = " << degrees << std::endl;
267  EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2],
268  Point(center.x + rcos, center.y + rsin))
269  << "vertex " << i << ", angle = " << degrees << std::endl;
270  EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2],
271  Point(center.x - rsin, center.y + rcos))
272  << "vertex " << i << ", angle = " << degrees << std::endl;
273  }
274 
275  // Then test innerer points
276  for (size_t i = 0; i < quadrant_count; i++) {
277  double angle = kPiOver2 * i / (quadrant_count - 1);
278  double degrees = angle * 180.0 / kPi;
279  double rsin = sin(angle) * (radius - half_width);
280  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
281  double rcos =
282  (i == quadrant_count - 1) ? 0.0f : cos(angle) * (radius - half_width);
283  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
284  Point(center.x - rcos, center.y - rsin))
285  << "vertex " << i << ", angle = " << degrees << std::endl;
286  EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2 + 1],
287  Point(center.x + rsin, center.y - rcos))
288  << "vertex " << i << ", angle = " << degrees << std::endl;
289  EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2 + 1],
290  Point(center.x + rcos, center.y + rsin))
291  << "vertex " << i << ", angle = " << degrees << std::endl;
292  EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2 + 1],
293  Point(center.x - rsin, center.y + rcos))
294  << "vertex " << i << ", angle = " << degrees << std::endl;
295  }
296  };
297 
298  test({}, {}, 2.0, 1.0);
299  test({}, {}, 2.0, 0.5);
300  test({}, {10, 10}, 2.0, 1.0);
301  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0, 1.0);
302  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0, 10.0);
303 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), and transform.

◆ TEST() [515/525]

impeller::testing::TEST ( TessellatorTest  ,
TessellateConvex   
)

Definition at line 96 of file tessellator_unittests.cc.

96  {
97  {
98  std::vector<Point> points;
99  std::vector<uint16_t> indices;
100  // Sanity check simple rectangle.
101  Tessellator::TessellateConvexInternal(
102  flutter::DlPath::MakeRect(Rect::MakeLTRB(0, 0, 10, 10)), points,
103  indices, 1.0);
104 
105  // Note: the origin point is repeated but not referenced in the indices
106  // below
107  std::vector<Point> expected = {{0, 0}, {10, 0}, {10, 10}, {0, 10}, {0, 0}};
108  std::vector<uint16_t> expected_indices = {0, 1, 3, 2};
109  EXPECT_EQ(points, expected);
110  EXPECT_EQ(indices, expected_indices);
111  }
112 
113  {
114  std::vector<Point> points;
115  std::vector<uint16_t> indices;
116  Tessellator::TessellateConvexInternal(
117  flutter::DlPath(flutter::DlPathBuilder{}
118  .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
119  .AddRect(Rect::MakeLTRB(20, 20, 30, 30))
120  .TakePath()),
121  points, indices, 1.0);
122 
123  std::vector<Point> expected = {{0, 0}, {10, 0}, {10, 10}, {0, 10},
124  {0, 0}, {20, 20}, {30, 20}, {30, 30},
125  {20, 30}, {20, 20}};
126  std::vector<uint16_t> expected_indices = {0, 1, 3, 2, 2, 5, 5, 6, 8, 7};
127  EXPECT_EQ(points, expected);
128  EXPECT_EQ(indices, expected_indices);
129  }
130 }

References impeller::TRect< Scalar >::MakeLTRB(), points, and impeller::Tessellator::TessellateConvexInternal().

◆ TEST() [516/525]

impeller::testing::TEST ( TessellatorTest  ,
TessellateConvexUnclosedPath   
)

Definition at line 133 of file tessellator_unittests.cc.

133  {
134  std::vector<Point> points;
135  std::vector<uint16_t> indices;
136 
137  // Create a rectangle that lacks an explicit close.
138  flutter::DlPath path = flutter::DlPathBuilder{}
139  .LineTo({100, 0})
140  .LineTo({100, 100})
141  .LineTo({0, 100})
142  .TakePath();
143  Tessellator::TessellateConvexInternal(flutter::DlPath(path), points, indices,
144  1.0);
145 
146  std::vector<Point> expected = {
147  {0, 0}, {100, 0}, {100, 100}, {0, 100}, {0, 0}};
148  std::vector<uint16_t> expected_indices = {0, 1, 3, 2};
149  EXPECT_EQ(points, expected);
150  EXPECT_EQ(indices, expected_indices);
151 }

References impeller::LineTo(), points, and impeller::Tessellator::TessellateConvexInternal().

◆ TEST() [517/525]

impeller::testing::TEST ( TessellatorTest  ,
TessellatorBuilderReturnsCorrectResultStatus   
)

Definition at line 16 of file tessellator_unittests.cc.

16  {
17  // Zero points.
18  {
19  TessellatorLibtess t;
20  auto path = flutter::DlPathBuilder{} //
21  .SetFillType(FillType::kOdd)
22  .TakePath();
23  TessellatorLibtess::Result result = t.Tessellate(
24  path, 1.0f,
25  [](const float* vertices, size_t vertices_count,
26  const uint16_t* indices, size_t indices_count) { return true; });
27 
28  ASSERT_EQ(result, TessellatorLibtess::Result::kInputError);
29  }
30 
31  // One point.
32  {
33  TessellatorLibtess t;
34  auto path = flutter::DlPathBuilder{}
35  .LineTo({0, 0})
36  .SetFillType(FillType::kOdd)
37  .TakePath();
38  TessellatorLibtess::Result result = t.Tessellate(
39  path, 1.0f,
40  [](const float* vertices, size_t vertices_count,
41  const uint16_t* indices, size_t indices_count) { return true; });
42 
43  ASSERT_EQ(result, TessellatorLibtess::Result::kSuccess);
44  }
45 
46  // Two points.
47  {
48  TessellatorLibtess t;
49  auto path = flutter::DlPathBuilder{}
50  .MoveTo({0, 0})
51  .LineTo({0, 1})
52  .SetFillType(FillType::kOdd)
53  .TakePath();
54  TessellatorLibtess::Result result = t.Tessellate(
55  path, 1.0f,
56  [](const float* vertices, size_t vertices_count,
57  const uint16_t* indices, size_t indices_count) { return true; });
58 
59  ASSERT_EQ(result, TessellatorLibtess::Result::kSuccess);
60  }
61 
62  // Many points.
63  {
64  TessellatorLibtess t;
65  flutter::DlPathBuilder builder;
66  for (int i = 0; i < 1000; i++) {
67  auto coord = i * 1.0f;
68  builder.MoveTo({coord, coord}).LineTo({coord + 1, coord + 1});
69  }
70  auto path = builder.SetFillType(FillType::kOdd).TakePath();
71  TessellatorLibtess::Result result = t.Tessellate(
72  path, 1.0f,
73  [](const float* vertices, size_t vertices_count,
74  const uint16_t* indices, size_t indices_count) { return true; });
75 
76  ASSERT_EQ(result, TessellatorLibtess::Result::kSuccess);
77  }
78 
79  // Closure fails.
80  {
81  TessellatorLibtess t;
82  auto path = flutter::DlPathBuilder{}
83  .MoveTo({0, 0})
84  .LineTo({0, 1})
85  .SetFillType(FillType::kOdd)
86  .TakePath();
87  TessellatorLibtess::Result result = t.Tessellate(
88  path, 1.0f,
89  [](const float* vertices, size_t vertices_count,
90  const uint16_t* indices, size_t indices_count) { return false; });
91 
92  ASSERT_EQ(result, TessellatorLibtess::Result::kInputError);
93  }
94 }

References impeller::TessellatorLibtess::kInputError, impeller::kOdd, impeller::TessellatorLibtess::kSuccess, impeller::LineTo(), and impeller::TessellatorLibtess::Tessellate().

◆ TEST() [518/525]

impeller::testing::TEST ( ThreadTest  ,
CanCreateMutex   
)

Definition at line 36 of file base_unittests.cc.

36  {
37  Foo f = {};
38 
39  // f.a = 100; <--- Static analysis error.
40  f.mtx.Lock();
41  f.a = 100;
42  f.mtx.Unlock();
43 }

References impeller::testing::Foo::mtx.

◆ TEST() [519/525]

impeller::testing::TEST ( ThreadTest  ,
CanCreateMutexLock   
)

Definition at line 45 of file base_unittests.cc.

45  {
46  Foo f = {};
47 
48  // f.a = 100; <--- Static analysis error.
49  auto a = Lock(f.mtx);
50  f.a = 100;
51 }

References impeller::testing::Foo::mtx.

◆ TEST() [520/525]

impeller::testing::TEST ( ThreadTest  ,
CanCreateRWMutex   
)

Definition at line 53 of file base_unittests.cc.

53  {
54  RWFoo f = {};
55 
56  // f.a = 100; <--- Static analysis error.
57  f.mtx.LockWriter();
58  f.a = 100;
59  f.mtx.UnlockWriter();
60  // int b = f.a; <--- Static analysis error.
61  f.mtx.LockReader();
62  [[maybe_unused]] int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
63  f.mtx.UnlockReader();
64 }

References impeller::saturated::b, and impeller::testing::RWFoo::mtx.

◆ TEST() [521/525]

impeller::testing::TEST ( ThreadTest  ,
CanCreateRWMutexLock   
)

Definition at line 66 of file base_unittests.cc.

66  {
67  RWFoo f = {};
68 
69  // f.a = 100; <--- Static analysis error.
70  {
71  auto write_lock = WriterLock{f.mtx};
72  f.a = 100;
73  }
74 
75  // int b = f.a; <--- Static analysis error.
76  {
77  auto read_lock = ReaderLock(f.mtx);
78  [[maybe_unused]] int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
79  }
80 
81  // f.mtx.UnlockReader(); <--- Static analysis error.
82 }

References impeller::saturated::b, and impeller::testing::RWFoo::mtx.

◆ TEST() [522/525]

impeller::testing::TEST ( TrigTest  ,
MultiplyByScalarRadius   
)

Definition at line 65 of file trig_unittests.cc.

65  {
66  for (int i = 0; i <= 360; i++) {
67  for (int i = 1; i <= 10; i++) {
68  Scalar radius = i * 5.0f;
69  EXPECT_EQ(Trig(Degrees(i)) * radius,
70  Point(radius * std::cos(i * kPi / 180),
71  radius * std::sin(i * kPi / 180)))
72  << "at " << i << " degrees and radius " << radius;
73  }
74  }
75 }

References impeller::kPi.

◆ TEST() [523/525]

impeller::testing::TEST ( TrigTest  ,
TrigAngles   
)

Definition at line 15 of file trig_unittests.cc.

15  {
16  {
17  Trig trig(Degrees(0.0));
18  EXPECT_EQ(trig.cos, 1.0);
19  EXPECT_EQ(trig.sin, 0.0);
20  }
21 
22  {
23  Trig trig(Radians(0.0));
24  EXPECT_EQ(trig.cos, 1.0);
25  EXPECT_EQ(trig.sin, 0.0);
26  }
27 
28  {
29  Trig trig(Degrees(30.0));
30  EXPECT_NEAR(trig.cos, sqrt(0.75), kEhCloseEnough);
31  EXPECT_NEAR(trig.sin, 0.5, kEhCloseEnough);
32  }
33 
34  {
35  Trig trig(Radians(kPi / 6.0));
36  EXPECT_NEAR(trig.cos, sqrt(0.75), kEhCloseEnough);
37  EXPECT_NEAR(trig.sin, 0.5, kEhCloseEnough);
38  }
39 
40  {
41  Trig trig(Degrees(60.0));
42  EXPECT_NEAR(trig.cos, 0.5, kEhCloseEnough);
43  EXPECT_NEAR(trig.sin, sqrt(0.75), kEhCloseEnough);
44  }
45 
46  {
47  Trig trig(Radians(kPi / 3.0));
48  EXPECT_NEAR(trig.cos, 0.5, kEhCloseEnough);
49  EXPECT_NEAR(trig.sin, sqrt(0.75), kEhCloseEnough);
50  }
51 
52  {
53  Trig trig(Degrees(90.0));
54  EXPECT_NEAR(trig.cos, 0.0, kEhCloseEnough);
55  EXPECT_NEAR(trig.sin, 1.0, kEhCloseEnough);
56  }
57 
58  {
59  Trig trig(Radians(kPi / 2.0));
60  EXPECT_NEAR(trig.cos, 0.0, kEhCloseEnough);
61  EXPECT_NEAR(trig.sin, 1.0, kEhCloseEnough);
62  }
63 }

References impeller::Trig::cos, impeller::kEhCloseEnough, impeller::kPi, and impeller::Trig::sin.

◆ TEST() [524/525]

impeller::testing::TEST ( TypographerTest  ,
RectanglePackerFillsRows   
)

Definition at line 413 of file typographer_unittests.cc.

413  {
414  auto skyline = RectanglePacker::Factory(257, 256);
415 
416  // Fill up the first row.
417  IPoint16 loc;
418  for (auto i = 0u; i < 16; i++) {
419  skyline->AddRect(16, 16, &loc);
420  }
421  // Last rectangle still in first row.
422  EXPECT_EQ(loc.x(), 256 - 16);
423  EXPECT_EQ(loc.y(), 0);
424 
425  // Fill up second row.
426  for (auto i = 0u; i < 16; i++) {
427  skyline->AddRect(16, 16, &loc);
428  }
429 
430  EXPECT_EQ(loc.x(), 256 - 16);
431  EXPECT_EQ(loc.y(), 16);
432 }

References impeller::RectanglePacker::Factory(), impeller::IPoint16::x(), and impeller::IPoint16::y().

◆ TEST() [525/525]

impeller::testing::TEST ( UniqueHandleGLES  ,
MakeUntracked   
)

Definition at line 26 of file unique_handle_gles_unittests.cc.

26  {
27  auto mock_gles_impl = std::make_unique<MockGLESImpl>();
28 
29  EXPECT_CALL(*mock_gles_impl, GenTextures(1, _)).Times(1);
30 
31  std::shared_ptr<MockGLES> mock_gled =
32  MockGLES::Init(std::move(mock_gles_impl));
33  ProcTableGLES::Resolver resolver = kMockResolverGLES;
34  auto proc_table = std::make_unique<ProcTableGLES>(resolver);
35  auto worker = std::make_shared<TestWorker>();
36  auto reactor = std::make_shared<ReactorGLES>(std::move(proc_table));
37  reactor->AddWorker(worker);
38 
39  UniqueHandleGLES handle =
40  UniqueHandleGLES::MakeUntracked(reactor, HandleType::kTexture);
41  EXPECT_FALSE(handle.Get().IsDead());
42 }

References impeller::UniqueHandleGLES::Get(), impeller::HandleGLES::IsDead(), impeller::kTexture, and impeller::UniqueHandleGLES::MakeUntracked().

◆ TEST_F()

impeller::testing::TEST_F ( GoldenTests  ,
ConicalGradient   
)

Definition at line 80 of file golden_tests.cc.

80  {
81  flutter::DisplayListBuilder builder;
82  flutter::DlPaint paint;
83  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
84 
85  flutter::DlColor colors[2] = {flutter::DlColor::RGBA(1, 0, 0, 1),
86  flutter::DlColor::RGBA(0, 0, 1, 1)};
87  Scalar stops[2] = {0, 1};
88 
89  paint.setColorSource(flutter::DlColorSource::MakeConical(
90  /*start_center=*/{125, 125}, //
91  /*start_radius=*/125, {180, 180}, //
92  /*end_radius=*/0, //
93  /*stop_count=*/2, //
94  /*colors=*/colors, //
95  /*stops=*/stops, //
96  /*tile_mode=*/flutter::DlTileMode::kClamp //
97  ));
98 
99  builder.DrawRect(DlRect::MakeXYWH(10, 10, 250, 250), paint);
100 
101  auto aiks_context =
102  AiksContext(Screenshotter().GetPlayground().GetContext(), nullptr);
103  auto screenshot = Screenshotter().MakeScreenshot(
104  aiks_context,
105  DisplayListToTexture(builder.Build(), {240, 240}, aiks_context));
106  ASSERT_TRUE(SaveScreenshot(std::move(screenshot)));
107 }
std::shared_ptr< Texture > DisplayListToTexture(const sk_sp< flutter::DisplayList > &display_list, ISize size, AiksContext &context, bool reset_host_buffer, bool generate_mips)
Render the provided display list to a texture with the given size.

References impeller::DisplayListToTexture(), and impeller::testing::Screenshotter::MakeScreenshot().

◆ TEST_P() [1/549]

impeller::testing::TEST_P ( AiksTest  ,
AdvancedBlendColorFilterWithDestinationOpacity   
)

Definition at line 907 of file aiks_dl_blend_unittests.cc.

907  {
908  DisplayListBuilder builder;
909 
910  builder.DrawPaint(DlPaint(DlColor::kWhite()));
911 
912  DlPaint save_paint;
913  save_paint.setOpacity(0.3);
914  save_paint.setColorFilter(DlColorFilter::MakeBlend(DlColor::kTransparent(),
915  DlBlendMode::kSaturation));
916  builder.SaveLayer(std::nullopt, &save_paint);
917  builder.DrawRect(DlRect::MakeXYWH(100, 100, 300, 300),
918  DlPaint(DlColor::kMaroon()));
919  builder.DrawRect(DlRect::MakeXYWH(200, 200, 300, 300),
920  DlPaint(DlColor::kBlue()));
921  builder.Restore();
922 
923  // Should be solid red as the destructive color filter floods the clip.
924  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
925 }

◆ TEST_P() [2/549]

impeller::testing::TEST_P ( AiksTest  ,
ArcWithZeroSweepAndBlur   
)

Definition at line 839 of file aiks_dl_path_unittests.cc.

839  {
840  DisplayListBuilder builder;
841  builder.Scale(GetContentScale().x, GetContentScale().y);
842 
843  DlPaint paint;
844  paint.setColor(DlColor::kRed());
845 
846  std::vector<DlColor> colors = {DlColor::RGBA(1.0, 0.0, 0.0, 1.0),
847  DlColor::RGBA(0.0, 0.0, 0.0, 1.0)};
848  std::vector<Scalar> stops = {0.0, 1.0};
849 
850  paint.setColorSource(
851  DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
852  stops.data(), DlTileMode::kMirror));
853  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
854 
855  DlPathBuilder path_builder;
856  path_builder.AddArc(DlRect::MakeXYWH(10, 10, 100, 100), //
857  DlDegrees(0), DlDegrees(0));
858  builder.DrawPath(path_builder.TakePath(), paint);
859 
860  // Check that this empty picture can be created without crashing.
861  builder.Build();
862 }

References x.

◆ TEST_P() [3/549]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownBackdropId   
)

Definition at line 176 of file canvas_unittests.cc.

176  {
177  ContentContext context(GetContext(), nullptr);
178  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
179  GTEST_SKIP() << "Test requires device with framebuffer fetch";
180  }
181  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
182  /*requires_readback=*/true);
183  // 3 backdrop filters all with same id.
184  std::unordered_map<int64_t, BackdropData> data;
185  data[1] = BackdropData{.backdrop_count = 3};
186  canvas->SetBackdropData(data, 3);
187 
188  auto blur =
189  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
190 
191  EXPECT_TRUE(canvas->RequiresReadback());
192  canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
193  {.color = Color::Azure()});
194  canvas->SaveLayer({}, std::nullopt, blur.get(),
195  ContentBoundsPromise::kContainsContents,
196  /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
197  /*backdrop_id=*/1);
198  canvas->Restore();
199  EXPECT_FALSE(canvas->RequiresReadback());
200 
201  canvas->SaveLayer({}, std::nullopt, blur.get(),
202  ContentBoundsPromise::kContainsContents,
203  /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
204  /*backdrop_id=*/1);
205  canvas->Restore();
206  EXPECT_FALSE(canvas->RequiresReadback());
207 
208  canvas->SaveLayer({}, std::nullopt, blur.get(),
209  ContentBoundsPromise::kContainsContents,
210  /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
211  /*backdrop_id=*/1);
212  canvas->Restore();
213  EXPECT_FALSE(canvas->RequiresReadback());
214 }
std::unique_ptr< Canvas > CreateTestCanvas(ContentContext &context, std::optional< Rect > cull_rect=std::nullopt, bool requires_readback=false)

References impeller::Color::Azure(), impeller::BackdropData::backdrop_count, CreateTestCanvas(), data, impeller::ContentContext::GetDeviceCapabilities(), impeller::kContainsContents, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Capabilities::SupportsFramebufferFetch().

◆ TEST_P() [4/549]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownBackdropIdMixed   
)

Definition at line 216 of file canvas_unittests.cc.

216  {
217  ContentContext context(GetContext(), nullptr);
218  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
219  GTEST_SKIP() << "Test requires device with framebuffer fetch";
220  }
221  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
222  /*requires_readback=*/true);
223  // 3 backdrop filters, 2 with same id.
224  std::unordered_map<int64_t, BackdropData> data;
225  data[1] = BackdropData{.backdrop_count = 2};
226  canvas->SetBackdropData(data, 3);
227 
228  auto blur =
229  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
230 
231  EXPECT_TRUE(canvas->RequiresReadback());
232  canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
233  {.color = Color::Azure()});
234  canvas->SaveLayer({}, std::nullopt, blur.get(),
235  ContentBoundsPromise::kContainsContents, 1, false);
236  canvas->Restore();
237  EXPECT_TRUE(canvas->RequiresReadback());
238 
239  canvas->SaveLayer({}, std::nullopt, blur.get(),
240  ContentBoundsPromise::kContainsContents, 1, false, 1);
241  canvas->Restore();
242  EXPECT_FALSE(canvas->RequiresReadback());
243 
244  canvas->SaveLayer({}, std::nullopt, blur.get(),
245  ContentBoundsPromise::kContainsContents, 1, false, 1);
246  canvas->Restore();
247  EXPECT_FALSE(canvas->RequiresReadback());
248 }

References impeller::Color::Azure(), impeller::BackdropData::backdrop_count, CreateTestCanvas(), data, impeller::ContentContext::GetDeviceCapabilities(), impeller::kContainsContents, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Capabilities::SupportsFramebufferFetch().

◆ TEST_P() [5/549]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownNormal   
)

Definition at line 141 of file canvas_unittests.cc.

141  {
142  ContentContext context(GetContext(), nullptr);
143  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
144  GTEST_SKIP() << "Test requires device with framebuffer fetch";
145  }
146  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
147  /*requires_readback=*/true);
148  // 3 backdrop filters
149  canvas->SetBackdropData({}, 3);
150 
151  auto blur =
152  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
153  flutter::DlRect rect = flutter::DlRect::MakeLTRB(0, 0, 50, 50);
154 
155  EXPECT_TRUE(canvas->RequiresReadback());
156  canvas->DrawRect(rect, {.color = Color::Azure()});
157  canvas->SaveLayer({}, rect, blur.get(),
158  ContentBoundsPromise::kContainsContents,
159  /*total_content_depth=*/1);
160  canvas->Restore();
161  EXPECT_TRUE(canvas->RequiresReadback());
162 
163  canvas->SaveLayer({}, rect, blur.get(),
164  ContentBoundsPromise::kContainsContents,
165  /*total_content_depth=*/1);
166  canvas->Restore();
167  EXPECT_TRUE(canvas->RequiresReadback());
168 
169  canvas->SaveLayer({}, rect, blur.get(),
170  ContentBoundsPromise::kContainsContents,
171  /*total_content_depth=*/1);
172  canvas->Restore();
173  EXPECT_FALSE(canvas->RequiresReadback());
174 }
flutter::DlRect DlRect
Definition: dl_dispatcher.h:25

References impeller::Color::Azure(), CreateTestCanvas(), impeller::ContentContext::GetDeviceCapabilities(), impeller::kContainsContents, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Capabilities::SupportsFramebufferFetch().

◆ TEST_P() [6/549]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownWithNestedSaveLayers   
)

Definition at line 253 of file canvas_unittests.cc.

253  {
254  ContentContext context(GetContext(), nullptr);
255  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
256  GTEST_SKIP() << "Test requires device with framebuffer fetch";
257  }
258  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
259  /*requires_readback=*/true);
260 
261  canvas->SetBackdropData({}, 2);
262 
263  auto blur =
264  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
265 
266  EXPECT_TRUE(canvas->RequiresReadback());
267  canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
268  {.color = Color::Azure()});
269  canvas->SaveLayer({}, std::nullopt, blur.get(),
270  ContentBoundsPromise::kContainsContents,
271  /*total_content_depth=*/3);
272 
273  // This filter is nested in the first saveLayer. We cannot restore to onscreen
274  // here.
275  canvas->SaveLayer({}, std::nullopt, blur.get(),
276  ContentBoundsPromise::kContainsContents,
277  /*total_content_depth=*/1);
278  canvas->Restore();
279  EXPECT_TRUE(canvas->RequiresReadback());
280 
281  canvas->Restore();
282  EXPECT_TRUE(canvas->RequiresReadback());
283 }

References impeller::Color::Azure(), CreateTestCanvas(), impeller::ContentContext::GetDeviceCapabilities(), impeller::kContainsContents, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Capabilities::SupportsFramebufferFetch().

◆ TEST_P() [7/549]

impeller::testing::TEST_P ( AiksTest  ,
BackdropFilterOverUnclosedClip   
)

Definition at line 2146 of file aiks_dl_basic_unittests.cc.

2146  {
2147  DisplayListBuilder builder;
2148 
2149  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
2150  builder.Save();
2151  {
2152  builder.ClipRect(DlRect::MakeLTRB(100, 100, 800, 800));
2153 
2154  builder.Save();
2155  {
2156  builder.ClipRect(DlRect::MakeLTRB(600, 600, 800, 800));
2157  builder.DrawPaint(DlPaint().setColor(DlColor::kRed()));
2158  builder.DrawPaint(DlPaint().setColor(DlColor::kBlue().withAlphaF(0.5)));
2159  builder.ClipRect(DlRect::MakeLTRB(700, 700, 750, 800));
2160  builder.DrawPaint(DlPaint().setColor(DlColor::kRed().withAlphaF(0.5)));
2161  }
2162  builder.Restore();
2163 
2164  auto image_filter = DlImageFilter::MakeBlur(10, 10, DlTileMode::kDecal);
2165  builder.SaveLayer(std::nullopt, nullptr, image_filter.get());
2166  }
2167  builder.Restore();
2168  builder.DrawCircle(DlPoint(100, 100), 100,
2169  DlPaint().setColor(DlColor::kAqua()));
2170 
2171  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
2172 }

◆ TEST_P() [8/549]

impeller::testing::TEST_P ( AiksTest  ,
BackdropRestoreUsesCorrectCoverageForFirstRestoredClip   
)

Definition at line 902 of file aiks_dl_unittests.cc.

902  {
903  DisplayListBuilder builder;
904 
905  DlPaint paint;
906  // Add a difference clip that cuts out the bottom right corner
907  builder.ClipRect(DlRect::MakeLTRB(50, 50, 100, 100), DlClipOp::kDifference);
908 
909  // Draw a red rectangle that's going to be completely covered by green later.
910  paint.setColor(DlColor::kRed());
911  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), paint);
912 
913  // Add a clip restricting the backdrop filter to the top right corner.
914  auto count = builder.GetSaveCount();
915  builder.Save();
916  {
917  builder.ClipRect(DlRect::MakeLTRB(0, 0, 100, 100));
918  {
919  // Create a save layer with a backdrop blur filter.
920  auto backdrop_filter =
921  DlImageFilter::MakeBlur(10.0, 10.0, DlTileMode::kDecal);
922  builder.SaveLayer(std::nullopt, nullptr, backdrop_filter.get());
923  }
924  }
925  builder.RestoreToCount(count);
926 
927  // Finally, overwrite all the previous stuff with green.
928  paint.setColor(DlColor::kGreen());
929  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), paint);
930 
931  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
932 }

◆ TEST_P() [9/549]

impeller::testing::TEST_P ( AiksTest  ,
BlendModePlusAlphaColorFilterWideGamut   
)

Definition at line 432 of file aiks_dl_blend_unittests.cc.

432  {
433  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
434  PixelFormat::kB10G10R10A10XR);
435  auto texture = CreateTextureForFixture("airplane.jpg",
436  /*enable_mipmapping=*/true);
437 
438  DisplayListBuilder builder;
439  builder.Scale(GetContentScale().x, GetContentScale().y);
440 
441  DlPaint paint;
442  paint.setColor(DlColor::RGBA(0.1, 0.2, 0.1, 1.0));
443  builder.DrawPaint(paint);
444 
445  DlPaint save_paint;
446  save_paint.setColorFilter(
447  DlColorFilter::MakeBlend(DlColor::RGBA(1, 0, 0, 1), DlBlendMode::kPlus));
448  builder.SaveLayer(std::nullopt, &save_paint);
449 
450  paint.setColor(DlColor::kRed());
451  builder.DrawRect(DlRect::MakeXYWH(100, 100, 400, 400), paint);
452 
453  paint.setColor(DlColor::kWhite());
454 
455  auto rect = Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100);
456  builder.DrawImageRect(
457  DlImageImpeller::Make(texture),
458  DlRect::MakeWH(texture->GetSize().width, texture->GetSize().height),
459  DlRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), //
460  rect.GetRight(), rect.GetBottom()),
461  DlImageSampling::kMipmapLinear, &paint);
462  builder.Restore();
463 
464  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
465 }

References impeller::TRect< T >::Expand(), impeller::kB10G10R10A10XR, impeller::DlImageImpeller::Make(), impeller::TRect< Scalar >::MakeXYWH(), and x.

◆ TEST_P() [10/549]

impeller::testing::TEST_P ( AiksTest  ,
BlendModePlusAlphaWideGamut   
)

Definition at line 400 of file aiks_dl_blend_unittests.cc.

400  {
401  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
402  PixelFormat::kB10G10R10A10XR);
403  auto texture = CreateTextureForFixture("airplane.jpg",
404  /*enable_mipmapping=*/true);
405 
406  DisplayListBuilder builder;
407  DlPaint paint;
408  builder.Scale(GetContentScale().x, GetContentScale().y);
409 
410  paint.setColor(DlColor::RGBA(0.9, 1, 0.9, 1.0));
411  builder.DrawPaint(paint);
412  builder.SaveLayer(std::nullopt);
413 
414  paint.setBlendMode(DlBlendMode::kPlus);
415  paint.setColor(DlColor::kRed());
416 
417  builder.DrawRect(DlRect::MakeXYWH(100, 100, 400, 400), paint);
418  paint.setColor(DlColor::kWhite());
419 
420  auto rect = Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100);
421  builder.DrawImageRect(
422  DlImageImpeller::Make(texture),
423  DlRect::MakeWH(texture->GetSize().width, texture->GetSize().height),
424  DlRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), //
425  rect.GetRight(), rect.GetBottom()),
426  DlImageSampling::kMipmapLinear, &paint);
427  builder.Restore();
428  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
429 }

References impeller::TRect< T >::Expand(), impeller::kB10G10R10A10XR, impeller::DlImageImpeller::Make(), impeller::TRect< Scalar >::MakeXYWH(), and x.

◆ TEST_P() [11/549]

impeller::testing::TEST_P ( AiksTest  ,
BlendModeShouldCoverWholeScreen   
)

Definition at line 82 of file aiks_dl_blend_unittests.cc.

82  {
83  DisplayListBuilder builder;
84  DlPaint paint;
85 
86  paint.setColor(DlColor::kRed());
87  builder.DrawPaint(paint);
88 
89  paint.setBlendMode(DlBlendMode::kSrcOver);
90  builder.SaveLayer(std::nullopt, &paint);
91 
92  paint.setColor(DlColor::kWhite());
93  builder.DrawRect(DlRect::MakeXYWH(100, 100, 400, 400), paint);
94 
95  paint.setBlendMode(DlBlendMode::kSrc);
96  builder.SaveLayer(std::nullopt, &paint);
97 
98  paint.setColor(DlColor::kBlue());
99  builder.DrawRect(DlRect::MakeXYWH(200, 200, 200, 200), paint);
100 
101  builder.Restore();
102  builder.Restore();
103 
104  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
105 }

◆ TEST_P() [12/549]

impeller::testing::TEST_P ( AiksTest  ,
BlurGradientWithOpacity   
)

Definition at line 1343 of file aiks_dl_blur_unittests.cc.

1343  {
1344  DisplayListBuilder builder;
1345  builder.Scale(GetContentScale().x, GetContentScale().y);
1346 
1347  std::vector<DlColor> colors = {DlColor(0xFFFF0000), DlColor(0xFF00FF00)};
1348  std::vector<Scalar> stops = {0.0, 1.0};
1349 
1350  auto gradient = DlColorSource::MakeLinear(
1351  {0, 0}, {400, 400}, 2, colors.data(), stops.data(), DlTileMode::kClamp);
1352 
1353  DlPaint save_paint;
1354  save_paint.setOpacity(0.5);
1355  builder.SaveLayer(std::nullopt, &save_paint);
1356 
1357  DlPaint paint;
1358  paint.setColorSource(gradient);
1359  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1));
1360  builder.DrawRect(DlRect::MakeXYWH(100, 100, 200, 200), paint);
1361 
1362  builder.Restore();
1363 
1364  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1365 }

References x.

◆ TEST_P() [13/549]

impeller::testing::TEST_P ( AiksTest  ,
BlurHasNoEdge   
)

Definition at line 438 of file aiks_dl_blur_unittests.cc.

438  {
439  Scalar sigma = 47.6;
440  auto callback = [&]() -> sk_sp<DisplayList> {
441  if (AiksTest::ImGuiBegin("Controls", nullptr,
442  ImGuiWindowFlags_AlwaysAutoResize)) {
443  ImGui::SliderFloat("Sigma", &sigma, 0, 50);
444  ImGui::End();
445  }
446  DisplayListBuilder builder;
447  builder.Scale(GetContentScale().x, GetContentScale().y);
448  builder.DrawPaint({});
449 
450  DlPaint paint;
451  paint.setColor(DlColor::kGreen());
452  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
453 
454  builder.DrawRect(DlRect::MakeXYWH(300, 300, 200, 200), paint);
455  return builder.Build();
456  };
457 
458  ASSERT_TRUE(OpenPlaygroundHere(callback));
459 }

References impeller::AiksPlayground::ImGuiBegin(), and x.

◆ TEST_P() [14/549]

impeller::testing::TEST_P ( AiksTest  ,
BlurredCircleWithStrokeWidth   
)

Definition at line 1083 of file aiks_dl_path_unittests.cc.

1083  {
1084  DisplayListBuilder builder;
1085  DlPaint paint;
1086  paint.setColor(DlColor::kGreen());
1087  paint.setDrawStyle(DlDrawStyle::kStroke);
1088  paint.setStrokeWidth(30);
1089  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 5));
1090 
1091  builder.DrawCircle(DlPoint(200, 200), 100, paint);
1092 
1093  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1094 }

◆ TEST_P() [15/549]

impeller::testing::TEST_P ( AiksTest  ,
BlurredRectangleWithShader   
)

Definition at line 1196 of file aiks_dl_blur_unittests.cc.

1196  {
1197  DisplayListBuilder builder;
1198  builder.Scale(GetContentScale().x, GetContentScale().y);
1199 
1200  auto paint_lines = [&builder](Scalar dx, Scalar dy, DlPaint paint) {
1201  auto draw_line = [&builder, &paint](DlPoint a, DlPoint b) {
1202  DlPath line = DlPath::MakeLine(a, b);
1203  builder.DrawPath(line, paint);
1204  };
1205  paint.setStrokeWidth(5);
1206  paint.setDrawStyle(DlDrawStyle::kStroke);
1207  draw_line(DlPoint(dx + 100, dy + 100), DlPoint(dx + 200, dy + 200));
1208  draw_line(DlPoint(dx + 100, dy + 200), DlPoint(dx + 200, dy + 100));
1209  draw_line(DlPoint(dx + 150, dy + 100), DlPoint(dx + 200, dy + 150));
1210  draw_line(DlPoint(dx + 100, dy + 150), DlPoint(dx + 150, dy + 200));
1211  };
1212 
1213  AiksContext renderer(GetContext(), nullptr);
1214  DisplayListBuilder recorder_builder;
1215  for (int x = 0; x < 5; ++x) {
1216  for (int y = 0; y < 5; ++y) {
1217  DlRect rect = DlRect::MakeXYWH(x * 20, y * 20, 20, 20);
1218  DlPaint paint;
1219  paint.setColor(((x + y) & 1) == 0 ? DlColor::kYellow()
1220  : DlColor::kBlue());
1221 
1222  recorder_builder.DrawRect(rect, paint);
1223  }
1224  }
1225  auto texture =
1226  DisplayListToTexture(recorder_builder.Build(), {100, 100}, renderer);
1227 
1228  auto image_source = DlColorSource::MakeImage(
1229  DlImageImpeller::Make(texture), DlTileMode::kRepeat, DlTileMode::kRepeat);
1230  auto blur_filter = DlImageFilter::MakeBlur(5, 5, DlTileMode::kDecal);
1231 
1232  DlPaint paint;
1233  paint.setColor(DlColor::kDarkGreen());
1234  builder.DrawRect(DlRect::MakeLTRB(0, 0, 300, 600), paint);
1235 
1236  paint.setColorSource(image_source);
1237  builder.DrawRect(DlRect::MakeLTRB(100, 100, 200, 200), paint);
1238 
1239  paint.setColorSource(nullptr);
1240  paint.setColor(DlColor::kRed());
1241  builder.DrawRect(DlRect::MakeLTRB(300, 0, 600, 600), paint);
1242 
1243  paint.setColorSource(image_source);
1244  paint.setImageFilter(blur_filter);
1245  builder.DrawRect(DlRect::MakeLTRB(400, 100, 500, 200), paint);
1246 
1247  paint.setImageFilter(nullptr);
1248  paint_lines(0, 300, paint);
1249 
1250  paint.setImageFilter(blur_filter);
1251  paint_lines(300, 300, paint);
1252 
1253  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1254 }

References impeller::saturated::b, impeller::DisplayListToTexture(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [16/549]

impeller::testing::TEST_P ( AiksTest  ,
CanConvertTriangleFanToTriangles   
)

Definition at line 158 of file aiks_dl_vertices_unittests.cc.

158  {
159  constexpr Scalar hexagon_radius = 125;
160  auto hex_start = Point(200.0, -hexagon_radius + 200.0);
161  auto center_to_flat = 1.73 / 2 * hexagon_radius;
162 
163  // clang-format off
164  std::vector<DlPoint> vertices = {
165  DlPoint(hex_start.x, hex_start.y),
166  DlPoint(hex_start.x + center_to_flat, hex_start.y + 0.5 * hexagon_radius),
167  DlPoint(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
168  DlPoint(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
169  DlPoint(hex_start.x, hex_start.y + 2 * hexagon_radius),
170  DlPoint(hex_start.x, hex_start.y + 2 * hexagon_radius),
171  DlPoint(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
172  DlPoint(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
173  DlPoint(hex_start.x - center_to_flat, hex_start.y + 0.5 * hexagon_radius)
174  };
175  // clang-format on
176  auto paint = flutter::DlPaint(flutter::DlColor::kDarkGrey());
177  auto dl_vertices = flutter::DlVertices::Make(
178  flutter::DlVertexMode::kTriangleFan, vertices.size(), vertices.data(),
179  nullptr, nullptr);
180  flutter::DisplayListBuilder builder;
181  builder.DrawVertices(dl_vertices, flutter::DlBlendMode::kSrcOver, paint);
182  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
183 }

◆ TEST_P() [17/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawAnOpenPath   
)

Definition at line 428 of file aiks_dl_path_unittests.cc.

428  {
429  DisplayListBuilder builder;
430 
431  // Starting at (50, 50), draw lines from:
432  // 1. (50, height)
433  // 2. (width, height)
434  // 3. (width, 50)
435  DlPathBuilder path_builder;
436  path_builder.MoveTo(DlPoint(50, 50));
437  path_builder.LineTo(DlPoint(50, 100));
438  path_builder.LineTo(DlPoint(100, 100));
439  path_builder.LineTo(DlPoint(100, 50));
440 
441  DlPaint paint;
442  paint.setColor(DlColor::kRed());
443  paint.setDrawStyle(DlDrawStyle::kStroke);
444  paint.setStrokeWidth(10);
445 
446  builder.DrawPath(path_builder.TakePath(), paint);
447 
448  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
449 }

◆ TEST_P() [18/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawAnOpenPathThatIsntARect   
)

Definition at line 451 of file aiks_dl_path_unittests.cc.

451  {
452  DisplayListBuilder builder;
453 
454  // Draw a stroked path that is explicitly closed to verify
455  // It doesn't become a rectangle.
456  DlPathBuilder path_builder;
457  path_builder.MoveTo(DlPoint(50, 50));
458  path_builder.LineTo(DlPoint(520, 120));
459  path_builder.LineTo(DlPoint(300, 310));
460  path_builder.LineTo(DlPoint(100, 50));
461  path_builder.Close();
462 
463  DlPaint paint;
464  paint.setColor(DlColor::kRed());
465  paint.setDrawStyle(DlDrawStyle::kStroke);
466  paint.setStrokeWidth(10);
467 
468  builder.DrawPath(path_builder.TakePath(), paint);
469 
470  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
471 }

◆ TEST_P() [19/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawMultiContourConvexPath   
)

Definition at line 811 of file aiks_dl_path_unittests.cc.

811  {
812  DlPathBuilder path_builder;
813  for (auto i = 0; i < 10; i++) {
814  if (i % 2 == 0) {
815  // We use the factory method to convert the circle to a path so that it
816  // uses the legacy conics for legacy golden output.
817  DlPath circle =
818  DlPath::MakeCircle(DlPoint(100 + 50 * i, 100 + 50 * i), 100);
819  path_builder.AddPath(circle);
820  path_builder.Close();
821  } else {
822  path_builder.MoveTo(DlPoint(100.f + 50.f * i - 100, 100.f + 50.f * i));
823  path_builder.LineTo(DlPoint(100.f + 50.f * i, 100.f + 50.f * i - 100));
824  path_builder.LineTo(DlPoint(100.f + 50.f * i - 100, //
825  100.f + 50.f * i - 100));
826  path_builder.Close();
827  }
828  }
829  DlPath path = path_builder.TakePath();
830 
831  DisplayListBuilder builder;
832  DlPaint paint;
833  paint.setColor(DlColor::kRed().withAlpha(102));
834  builder.DrawPath(path, paint);
835 
836  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
837 }

◆ TEST_P() [20/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaint   
)

Definition at line 470 of file aiks_dl_basic_unittests.cc.

470  {
471  auto medium_turquoise =
472  DlColor::RGBA(72.0f / 255.0f, 209.0f / 255.0f, 204.0f / 255.0f, 1.0f);
473 
474  DisplayListBuilder builder;
475  builder.Scale(0.2, 0.2);
476  builder.DrawPaint(DlPaint().setColor(medium_turquoise));
477  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
478 }

◆ TEST_P() [21/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintMultipleTimes   
)

Definition at line 480 of file aiks_dl_basic_unittests.cc.

480  {
481  auto medium_turquoise =
482  DlColor::RGBA(72.0f / 255.0f, 209.0f / 255.0f, 204.0f / 255.0f, 1.0f);
483  auto orange_red =
484  DlColor::RGBA(255.0f / 255.0f, 69.0f / 255.0f, 0.0f / 255.0f, 1.0f);
485 
486  DisplayListBuilder builder;
487  builder.Scale(0.2, 0.2);
488  builder.DrawPaint(DlPaint().setColor(medium_turquoise));
489  builder.DrawPaint(DlPaint().setColor(orange_red.modulateOpacity(0.5f)));
490  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
491 }

◆ TEST_P() [22/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintMultipleTimesInteractive   
)

Definition at line 682 of file aiks_dl_blend_unittests.cc.

682  {
683  auto modes = GetBlendModeSelection();
684 
685  auto callback = [&]() -> sk_sp<DisplayList> {
686  static Color background = Color::MediumTurquoise();
687  static Color foreground = Color::Color::OrangeRed().WithAlpha(0.5);
688  static int current_blend_index = 3;
689 
690  if (AiksTest::ImGuiBegin("Controls", nullptr,
691  ImGuiWindowFlags_AlwaysAutoResize)) {
692  ImGui::ColorEdit4("Background", reinterpret_cast<float*>(&background));
693  ImGui::ColorEdit4("Foreground", reinterpret_cast<float*>(&foreground));
694  ImGui::ListBox("Blend mode", &current_blend_index,
695  modes.blend_mode_names.data(),
696  modes.blend_mode_names.size());
697  ImGui::End();
698  }
699 
700  DisplayListBuilder builder;
701  builder.Scale(0.2, 0.2);
702  DlPaint paint;
703  paint.setColor(DlColor(background.ToARGB()));
704  builder.DrawPaint(paint);
705 
706  paint.setColor(DlColor(foreground.ToARGB()));
707  paint.setBlendMode(static_cast<DlBlendMode>(current_blend_index));
708  builder.DrawPaint(paint);
709  return builder.Build();
710  };
711  ASSERT_TRUE(OpenPlaygroundHere(callback));
712 }
static BlendModeSelection GetBlendModeSelection()

References GetBlendModeSelection(), impeller::AiksPlayground::ImGuiBegin(), impeller::Color::MediumTurquoise(), impeller::Color::ToARGB(), and impeller::Color::WithAlpha().

◆ TEST_P() [23/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintWithAdvancedBlend   
)

Definition at line 107 of file aiks_dl_blend_unittests.cc.

107  {
108  DisplayListBuilder builder;
109 
110  builder.Scale(0.2, 0.2);
111  DlPaint paint;
112  paint.setColor(DlColor::RGBA(
113  Color::MediumTurquoise().red, Color::MediumTurquoise().green,
114  Color::MediumTurquoise().blue, Color::MediumTurquoise().alpha));
115  builder.DrawPaint(paint);
116 
117  paint.setColor(DlColor::RGBA(Color::OrangeRed().red, Color::OrangeRed().green,
118  Color::OrangeRed().blue, 0.5));
119  paint.setBlendMode(DlBlendMode::kHue);
120  builder.DrawPaint(paint);
121 
122  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
123 }

References impeller::Color::MediumTurquoise(), and impeller::Color::OrangeRed().

◆ TEST_P() [24/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPerspectiveTransformWithClips   
)

Definition at line 1373 of file aiks_dl_basic_unittests.cc.

1373  {
1374  // Avoiding `GetSecondsElapsed()` to reduce risk of golden flakiness.
1375  int time = 0;
1376  auto callback = [&]() -> sk_sp<DisplayList> {
1377  DisplayListBuilder builder;
1378 
1379  builder.Save();
1380  {
1381  builder.Translate(300, 300);
1382 
1383  // 1. Draw/restore a clip before drawing the image, which will get drawn
1384  // to the depth buffer behind the image.
1385  builder.Save();
1386  {
1387  DlPaint paint;
1388  paint.setColor(DlColor::kGreen());
1389  builder.DrawPaint(paint);
1390  builder.ClipRect(DlRect::MakeLTRB(-180, -180, 180, 180),
1391  DlClipOp::kDifference);
1392 
1393  paint.setColor(DlColor::kBlack());
1394  builder.DrawPaint(paint);
1395  }
1396  builder.Restore(); // Restore rectangle difference clip.
1397 
1398  builder.Save();
1399  {
1400  // 2. Draw an oval clip that applies to the image, which will get drawn
1401  // in front of the image on the depth buffer.
1402  builder.ClipOval(DlRect::MakeLTRB(-200, -200, 200, 200));
1403 
1404  Matrix result =
1405  Matrix(1.0, 0.0, 0.0, 0.0, //
1406  0.0, 1.0, 0.0, 0.0, //
1407  0.0, 0.0, 1.0, 0.003, //
1408  0.0, 0.0, 0.0, 1.0) *
1409  Matrix::MakeRotationY({Radians{-1.0f + (time++ / 60.0f)}});
1410 
1411  // 3. Draw the rotating image with a perspective transform.
1412  builder.Transform(result);
1413 
1414  auto image =
1415  DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
1416  auto position =
1417  -DlPoint(image->GetSize().width, image->GetSize().height) * 0.5;
1418  builder.DrawImage(image, position, {});
1419  }
1420  builder.Restore(); // Restore oval intersect clip.
1421 
1422  // 4. Draw a semi-translucent blue circle atop all previous draws.
1423  DlPaint paint;
1424  paint.setColor(DlColor::kBlue().modulateOpacity(0.4));
1425  builder.DrawCircle(DlPoint(), 230, paint);
1426  }
1427  builder.Restore(); // Restore translation.
1428 
1429  return builder.Build();
1430  };
1431  ASSERT_TRUE(OpenPlaygroundHere(callback));
1432 }

References impeller::DlImageImpeller::Make(), impeller::Matrix::MakeRotationY(), and impeller::Matrix::Transform().

◆ TEST_P() [25/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPoints   
)

Definition at line 405 of file aiks_dl_unittests.cc.

405  {
406  std::vector<DlPoint> points = {
407  {0, 0}, //
408  {100, 100}, //
409  {100, 0}, //
410  {0, 100}, //
411  {0, 0}, //
412  {48, 48}, //
413  {52, 52}, //
414  };
415  DlPaint paint_round;
416  paint_round.setColor(DlColor::kYellow().withAlpha(128));
417  paint_round.setStrokeCap(DlStrokeCap::kRound);
418  paint_round.setStrokeWidth(20);
419 
420  DlPaint paint_square;
421  paint_square.setColor(DlColor::kYellow().withAlpha(128));
422  paint_square.setStrokeCap(DlStrokeCap::kSquare);
423  paint_square.setStrokeWidth(20);
424 
425  DlPaint background;
426  background.setColor(DlColor::kBlack());
427 
428  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
429  builder.DrawPaint(background);
430  builder.Translate(200, 200);
431 
432  builder.DrawPoints(DlPointMode::kPoints, points.size(), points.data(),
433  paint_round);
434  builder.Translate(150, 0);
435  builder.DrawPoints(DlPointMode::kPoints, points.size(), points.data(),
436  paint_square);
437 
438  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
439 }

References points.

◆ TEST_P() [26/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPointsWithTextureMap   
)

Definition at line 441 of file aiks_dl_unittests.cc.

441  {
442  auto texture = DlImageImpeller::Make(
443  CreateTextureForFixture("table_mountain_nx.png",
444  /*enable_mipmapping=*/true));
445 
446  std::vector<DlPoint> points = {
447  {0, 0}, //
448  {100, 100}, //
449  {100, 0}, //
450  {0, 100}, //
451  {0, 0}, //
452  {48, 48}, //
453  {52, 52}, //
454  };
455 
456  auto image_src =
457  DlColorSource::MakeImage(texture, DlTileMode::kClamp, DlTileMode::kClamp);
458 
459  DlPaint paint_round;
460  paint_round.setStrokeCap(DlStrokeCap::kRound);
461  paint_round.setColorSource(image_src);
462  paint_round.setStrokeWidth(200);
463 
464  DlPaint paint_square;
465  paint_square.setStrokeCap(DlStrokeCap::kSquare);
466  paint_square.setColorSource(image_src);
467  paint_square.setStrokeWidth(200);
468 
469  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
470  builder.Translate(200, 200);
471 
472  builder.DrawPoints(DlPointMode::kPoints, points.size(), points.data(),
473  paint_round);
474  builder.Translate(150, 0);
475  builder.DrawPoints(DlPointMode::kPoints, points.size(), points.data(),
476  paint_square);
477 
478  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
479 }

References impeller::DlImageImpeller::Make(), and points.

◆ TEST_P() [27/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawScaledPointsLargeScaleSmallRadius   
)

Definition at line 840 of file aiks_dl_unittests.cc.

840  {
841  std::vector<DlPoint> point = {
842  {0, 0}, //
843  };
844 
845  DlPaint paint;
846  paint.setStrokeCap(DlStrokeCap::kRound);
847  paint.setColor(DlColor::kRed());
848  paint.setStrokeWidth(100 * 0.000001);
849 
850  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
851  builder.Translate(200, 200);
852  builder.Scale(1000000, 1000000);
853 
854  builder.DrawPoints(DlPointMode::kPoints, point.size(), point.data(), paint);
855  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
856 }

◆ TEST_P() [28/549]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawScaledPointsSmallScaleLargeRadius   
)

Definition at line 820 of file aiks_dl_unittests.cc.

820  {
821  std::vector<DlPoint> point = {
822  {0, 0}, //
823  };
824 
825  DlPaint paint;
826  paint.setStrokeCap(DlStrokeCap::kRound);
827  paint.setColor(DlColor::kRed());
828  paint.setStrokeWidth(100 * 1000000);
829 
830  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
831  builder.Translate(200, 200);
832  builder.Scale(0.000001, 0.000001);
833 
834  builder.DrawPoints(DlPointMode::kPoints, point.size(), point.data(), paint);
835 
836  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
837 }

◆ TEST_P() [29/549]

impeller::testing::TEST_P ( AiksTest  ,
CanEmptyPictureConvertToImage   
)

Definition at line 961 of file aiks_dl_unittests.cc.

961  {
962  DisplayListBuilder recorder_builder;
963 
964  DisplayListBuilder builder;
965  AiksContext renderer(GetContext(), nullptr);
966 
967  DlPaint paint;
968  paint.setColor(DlColor::kTransparent());
969  builder.DrawPaint(paint);
970 
971  auto result_image =
972  DisplayListToTexture(builder.Build(), ISize{1000, 1000}, renderer);
973  if (result_image) {
974  recorder_builder.DrawImage(DlImageImpeller::Make(result_image), DlPoint(),
975  {});
976 
977  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 0.2));
978  recorder_builder.DrawRect(DlRect::MakeWH(1000, 1000), paint);
979  }
980 
981  ASSERT_TRUE(OpenPlaygroundHere(recorder_builder.Build()));
982 }

References impeller::DisplayListToTexture(), and impeller::DlImageImpeller::Make().

◆ TEST_P() [30/549]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformFullScreenMSAA   
)

Definition at line 1714 of file aiks_dl_basic_unittests.cc.

1714  {
1715  DisplayListBuilder builder;
1716 
1717  DlPaint paint;
1718  paint.setColor(DlColor::kRed());
1719  builder.DrawCircle(DlPoint(250, 250), 125, paint);
1720 
1721  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1722 }

◆ TEST_P() [31/549]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSaveLayerWithBounds   
)

Definition at line 1735 of file aiks_dl_basic_unittests.cc.

1735  {
1736  DisplayListBuilder builder;
1737 
1738  DlPaint save;
1739  save.setColor(DlColor::kBlack());
1740 
1741  DlRect save_bounds = DlRect::MakeXYWH(0, 0, 50, 50);
1742  builder.SaveLayer(save_bounds, &save);
1743 
1744  DlPaint paint;
1745  paint.setColor(DlColor::kRed());
1746  builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), paint);
1747  paint.setColor(DlColor::kGreen());
1748  builder.DrawRect(DlRect::MakeXYWH(10, 10, 100, 100), paint);
1749  paint.setColor(DlColor::kBlue());
1750  builder.DrawRect(DlRect::MakeXYWH(20, 20, 100, 100), paint);
1751 
1752  builder.Restore();
1753 
1754  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1755 }

◆ TEST_P() [32/549]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated   
)

Definition at line 1636 of file aiks_dl_basic_unittests.cc.

1637  {
1638  DisplayListBuilder builder;
1639 
1640  DlPaint red;
1641  red.setColor(DlColor::kRed());
1642 
1643  DlPaint green;
1644  green.setColor(DlColor::kGreen());
1645 
1646  DlPaint blue;
1647  blue.setColor(DlColor::kBlue());
1648 
1649  DlPaint save;
1650  save.setColor(DlColor::kBlack().modulateOpacity(0.5));
1651 
1652  DlRect huge_bounds = DlRect::MakeXYWH(0, 0, 100000, 100000);
1653  builder.SaveLayer(huge_bounds, &save);
1654 
1655  builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), red);
1656  builder.DrawRect(DlRect::MakeXYWH(10, 10, 100, 100), green);
1657  builder.DrawRect(DlRect::MakeXYWH(20, 20, 100, 100), blue);
1658 
1659  builder.Restore();
1660 
1661  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1662 }

◆ TEST_P() [33/549]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSkew   
)

Definition at line 1724 of file aiks_dl_basic_unittests.cc.

1724  {
1725  DisplayListBuilder builder;
1726 
1727  DlPaint red;
1728  red.setColor(DlColor::kRed());
1729  builder.Skew(2, 5);
1730  builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), red);
1731 
1732  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1733 }

◆ TEST_P() [34/549]

impeller::testing::TEST_P ( AiksTest  ,
CanPictureConvertToImage   
)

Definition at line 934 of file aiks_dl_unittests.cc.

934  {
935  DisplayListBuilder recorder_canvas;
936  DlPaint paint;
937  paint.setColor(DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0));
938  recorder_canvas.DrawRect(DlRect::MakeXYWH(100.0, 100.0, 600, 600), paint);
939  paint.setColor(DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0));
940  recorder_canvas.DrawRect(DlRect::MakeXYWH(200.0, 200.0, 600, 600), paint);
941 
942  DisplayListBuilder canvas;
943  AiksContext renderer(GetContext(), nullptr);
944  paint.setColor(DlColor::kTransparent());
945  canvas.DrawPaint(paint);
946 
947  auto image =
948  DisplayListToTexture(recorder_canvas.Build(), {1000, 1000}, renderer);
949  if (image) {
950  canvas.DrawImage(DlImageImpeller::Make(image), DlPoint(), {});
951  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 0.2));
952  canvas.DrawRect(DlRect::MakeWH(1000, 1000), paint);
953  }
954 
955  ASSERT_TRUE(OpenPlaygroundHere(canvas.Build()));
956 }

References impeller::DisplayListToTexture(), and impeller::DlImageImpeller::Make().

◆ TEST_P() [35/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderAdvancedBlendColorFilterWithSaveLayer   
)

Definition at line 61 of file aiks_dl_blend_unittests.cc.

61  {
62  DisplayListBuilder builder;
63 
64  DlRect layer_rect = DlRect::MakeXYWH(0, 0, 500, 500);
65  builder.ClipRect(layer_rect);
66 
67  DlPaint save_paint;
68  save_paint.setColorFilter(DlColorFilter::MakeBlend(
69  DlColor::RGBA(0, 1, 0, 0.5), DlBlendMode::kDifference));
70  builder.SaveLayer(layer_rect, &save_paint);
71 
72  DlPaint paint;
73  paint.setColor(DlColor::kBlack());
74  builder.DrawPaint(paint);
75  paint.setColor(DlColor::kWhite());
76  builder.DrawRect(DlRect::MakeXYWH(100, 100, 300, 300), paint);
77  builder.Restore();
78 
79  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
80 }

◆ TEST_P() [36/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlur   
)

Definition at line 241 of file aiks_dl_blur_unittests.cc.

241  {
242  DisplayListBuilder builder;
243 
244  DlPaint paint;
245  paint.setColor(DlColor::kCornflowerBlue());
246  builder.DrawCircle(DlPoint(100, 100), 50, paint);
247 
248  paint.setColor(DlColor::kGreenYellow());
249  builder.DrawCircle(DlPoint(300, 200), 100, paint);
250 
251  paint.setColor(DlColor::kDarkMagenta());
252  builder.DrawCircle(DlPoint(140, 170), 75, paint);
253 
254  paint.setColor(DlColor::kOrangeRed());
255  builder.DrawCircle(DlPoint(180, 120), 100, paint);
256 
257  DlRoundRect rrect =
258  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(75, 50, 375, 275), 20, 20);
259  builder.ClipRoundRect(rrect);
260 
261  DlPaint save_paint;
262  save_paint.setBlendMode(DlBlendMode::kSrc);
263  auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
264  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
265  builder.Restore();
266 
267  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
268 }

◆ TEST_P() [37/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlurHugeSigma   
)

Definition at line 351 of file aiks_dl_blur_unittests.cc.

351  {
352  DisplayListBuilder builder;
353 
354  DlPaint paint;
355  paint.setColor(DlColor::kGreen());
356  builder.DrawCircle(DlPoint(400, 400), 300, paint);
357 
358  DlPaint save_paint;
359  save_paint.setBlendMode(DlBlendMode::kSrc);
360 
361  auto backdrop_filter =
362  DlImageFilter::MakeBlur(999999, 999999, DlTileMode::kClamp);
363  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
364  builder.Restore();
365 
366  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
367 }

◆ TEST_P() [38/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlurInteractive   
)

Definition at line 204 of file aiks_dl_blur_unittests.cc.

204  {
205  auto callback = [&]() -> sk_sp<DisplayList> {
206  static PlaygroundPoint point_a(Point(50, 50), 30, Color::White());
207  static PlaygroundPoint point_b(Point(300, 200), 30, Color::White());
208  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
209 
210  DisplayListBuilder builder;
211  DlPaint paint;
212  paint.setColor(DlColor::kCornflowerBlue());
213  builder.DrawCircle(DlPoint(100, 100), 50, paint);
214 
215  paint.setColor(DlColor::kGreenYellow());
216  builder.DrawCircle(DlPoint(300, 200), 100, paint);
217 
218  paint.setColor(DlColor::kDarkMagenta());
219  builder.DrawCircle(DlPoint(140, 170), 75, paint);
220 
221  paint.setColor(DlColor::kOrangeRed());
222  builder.DrawCircle(DlPoint(180, 120), 100, paint);
223 
224  DlRoundRect rrect =
225  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(a.x, a.y, b.x, b.y), 20, 20);
226  builder.ClipRoundRect(rrect);
227 
228  DlPaint save_paint;
229  save_paint.setBlendMode(DlBlendMode::kSrc);
230 
231  auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
232  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
233  builder.Restore();
234 
235  return builder.Build();
236  };
237 
238  ASSERT_TRUE(OpenPlaygroundHere(callback));
239 }
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
Definition: widgets.cc:51

References impeller::saturated::b, impeller::DrawPlaygroundLine(), and impeller::Color::White().

◆ TEST_P() [39/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlurWithSingleBackdropId   
)

Definition at line 270 of file aiks_dl_blur_unittests.cc.

270  {
271  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
272 
273  DisplayListBuilder builder;
274 
275  DlPaint paint;
276  builder.DrawImage(image, DlPoint(50.0, 50.0),
277  DlImageSampling::kNearestNeighbor, &paint);
278 
279  DlRoundRect rrect =
280  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(50, 250, 100, 100), 20, 20);
281  builder.Save();
282  builder.ClipRoundRect(rrect);
283 
284  DlPaint save_paint;
285  save_paint.setBlendMode(DlBlendMode::kSrc);
286  auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
287  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get(),
288  /*backdrop_id=*/1);
289  builder.Restore();
290  builder.Restore();
291 
292  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
293 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [40/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedBackdropFilter   
)

Definition at line 1334 of file aiks_dl_basic_unittests.cc.

1334  {
1335  DisplayListBuilder builder;
1336 
1337  builder.Scale(GetContentScale().x, GetContentScale().y);
1338 
1339  // Draw something interesting in the background.
1340  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
1341  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
1342  std::vector<Scalar> stops = {
1343  0.0,
1344  1.0,
1345  };
1346  DlPaint paint;
1347  paint.setColorSource(DlColorSource::MakeLinear(
1348  /*start_point=*/DlPoint(0, 0), //
1349  /*end_point=*/DlPoint(100, 100), //
1350  /*stop_count=*/2, //
1351  /*colors=*/colors.data(), //
1352  /*stops=*/stops.data(), //
1353  /*tile_mode=*/DlTileMode::kRepeat //
1354  ));
1355 
1356  builder.DrawPaint(paint);
1357 
1358  DlRect clip_rect = DlRect::MakeLTRB(50, 50, 400, 300);
1359  DlRoundRect clip_rrect = DlRoundRect::MakeRectXY(clip_rect, 100, 100);
1360 
1361  // Draw a clipped SaveLayer, where the clip coverage and SaveLayer size are
1362  // the same.
1363  builder.ClipRoundRect(clip_rrect, DlClipOp::kIntersect);
1364 
1365  DlPaint save_paint;
1366  auto backdrop_filter = DlImageFilter::MakeColorFilter(
1367  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kExclusion));
1368  builder.SaveLayer(clip_rect, &save_paint, backdrop_filter.get());
1369 
1370  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1371 }

References x.

◆ TEST_P() [41/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedBlur   
)

Definition at line 369 of file aiks_dl_blur_unittests.cc.

369  {
370  DisplayListBuilder builder;
371  builder.ClipRect(DlRect::MakeXYWH(100, 150, 400, 400));
372 
373  DlPaint paint;
374  paint.setColor(DlColor::kGreen());
375  paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
376  builder.DrawCircle(DlPoint(400, 400), 200, paint);
377  builder.Restore();
378 
379  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
380 }

◆ TEST_P() [42/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedLayers   
)

Definition at line 1969 of file aiks_dl_basic_unittests.cc.

1969  {
1970  DisplayListBuilder builder;
1971 
1972  DlPaint paint;
1973  paint.setColor(DlColor::kWhite());
1974  builder.DrawPaint(paint);
1975 
1976  // Draw a green circle on the screen.
1977  {
1978  // Increase the clip depth for the savelayer to contend with.
1979  DlPath path = DlPath::MakeCircle(DlPoint(100, 100), 50);
1980  builder.ClipPath(path);
1981 
1982  DlRect bounds = DlRect::MakeXYWH(50, 50, 100, 100);
1983  DlPaint save_paint;
1984  builder.SaveLayer(bounds, &save_paint);
1985 
1986  // Fill the layer with white.
1987  paint.setColor(DlColor::kWhite());
1988  builder.DrawRect(DlRect::MakeSize(DlSize(400, 400)), paint);
1989  // Fill the layer with green, but do so with a color blend that can't be
1990  // collapsed into the parent pass.
1991  paint.setColor(DlColor::kGreen());
1992  paint.setBlendMode(DlBlendMode::kHardLight);
1993  builder.DrawRect(DlRect::MakeSize(DlSize(400, 400)), paint);
1994  }
1995 
1996  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1997 }

◆ TEST_P() [43/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedRuntimeEffects   
)

Definition at line 40 of file aiks_dl_runtime_effect_unittests.cc.

40  {
41  struct FragUniforms {
42  Vector2 iResolution;
43  Scalar iTime;
44  } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
45  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
46  uniform_data->resize(sizeof(FragUniforms));
47  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
48 
49  DlPaint paint;
50  paint.setColorSource(
51  MakeRuntimeEffect(this, "runtime_stage_example.frag.iplr", uniform_data));
52 
53  DisplayListBuilder builder;
54  builder.Save();
55  builder.ClipRoundRect(
56  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 400, 400), 10.0, 10.0),
57  DlClipOp::kIntersect);
58  builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
59  builder.Restore();
60 
61  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
62 }

◆ TEST_P() [44/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClips   
)

Definition at line 864 of file aiks_dl_path_unittests.cc.

864  {
865  DisplayListBuilder builder;
866  DlPaint paint;
867  paint.setColor(DlColor::kFuchsia());
868 
869  builder.ClipPath(DlPath::MakeRect(DlRect::MakeXYWH(0, 0, 500, 500)));
870  builder.DrawPath(DlPath::MakeCircle(DlPoint(500, 500), 250), paint);
871 
872  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
873 }

◆ TEST_P() [45/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColoredRect   
)

Definition at line 30 of file aiks_dl_basic_unittests.cc.

30  {
31  DisplayListBuilder builder;
32  DlPaint paint;
33  paint.setColor(DlColor::kBlue());
34  builder.DrawPath(DlPath::MakeRectXYWH(100.0f, 100.0f, 100.0f, 100.0f), paint);
35  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
36 }

◆ TEST_P() [46/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColorFilterWithInvertColors   
)

Definition at line 131 of file aiks_dl_basic_unittests.cc.

131  {
132  DisplayListBuilder builder;
133  DlPaint paint;
134  paint.setColor(DlColor::kRed());
135  paint.setColorFilter(
136  DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
137  paint.setInvertColors(true);
138 
139  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), paint);
140  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
141 }

◆ TEST_P() [47/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColorFilterWithInvertColorsDrawPaint   
)

Definition at line 143 of file aiks_dl_basic_unittests.cc.

143  {
144  DisplayListBuilder builder;
145  DlPaint paint;
146  paint.setColor(DlColor::kRed());
147  paint.setColorFilter(
148  DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
149  paint.setInvertColors(true);
150 
151  builder.DrawPaint(paint);
152  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
153 }

◆ TEST_P() [48/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradient   
)

Definition at line 655 of file aiks_dl_gradient_unittests.cc.

655  {
656  Scalar size = 256;
657  DisplayListBuilder builder;
658  DlPaint paint;
659  paint.setColor(DlColor::kWhite());
660  builder.DrawRect(DlRect::MakeXYWH(0, 0, size * 3, size * 3), paint);
661  std::vector<DlColor> colors = {
662  DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
663  DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
664  DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
665  DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
666  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
667  std::array<std::tuple<DlPoint, float, DlPoint, float>, 8> array{
668  std::make_tuple(DlPoint(size / 2.f, size / 2.f), 0.f,
669  DlPoint(size / 2.f, size / 2.f), size / 2.f),
670  std::make_tuple(DlPoint(size / 2.f, size / 2.f), size / 4.f,
671  DlPoint(size / 2.f, size / 2.f), size / 2.f),
672  std::make_tuple(DlPoint(size / 4.f, size / 4.f), 0.f,
673  DlPoint(size / 2.f, size / 2.f), size / 2.f),
674  std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 2.f,
675  DlPoint(size / 2.f, size / 2.f), 0),
676  std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 4.f,
677  DlPoint(size / 2.f, size / 2.f), size / 2.f),
678  std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 16.f,
679  DlPoint(size / 2.f, size / 2.f), size / 8.f),
680  std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 8.f,
681  DlPoint(size / 2.f, size / 2.f), size / 16.f),
682  std::make_tuple(DlPoint(size / 8.f, size / 8.f), size / 8.f,
683  DlPoint(size / 2.f, size / 2.f), size / 8.f),
684  };
685  for (int i = 0; i < 8; i++) {
686  builder.Save();
687  builder.Translate((i % 3) * size, i / 3 * size);
688  paint.setColorSource(DlColorSource::MakeConical(
689  /*start_center=*/std::get<2>(array[i]),
690  /*start_radius=*/std::get<3>(array[i]),
691  /*end_center=*/std::get<0>(array[i]),
692  /*end_radius=*/std::get<1>(array[i]),
693  /*stop_count=*/stops.size(),
694  /*colors=*/colors.data(),
695  /*stops=*/stops.data(),
696  /*tile_mode=*/DlTileMode::kClamp));
697  builder.DrawRect(DlRect::MakeXYWH(0, 0, size, size), paint);
698  builder.Restore();
699  }
700  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
701 }

◆ TEST_P() [49/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradientWithDitheringEnabled   
)

Definition at line 174 of file aiks_dl_gradient_unittests.cc.

174  {
176 }
static void CanRenderConicalGradientWithDithering(AiksTest *aiks_test)

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [50/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradientWithIncompleteStops   
)

Definition at line 316 of file aiks_dl_gradient_unittests.cc.

316  {
317  CanRenderGradientWithIncompleteStops(this,
318  DlColorSourceType::kConicalGradient);
319 }

◆ TEST_P() [51/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderCurvedStrokes   
)

Definition at line 71 of file aiks_dl_path_unittests.cc.

71  {
72  DisplayListBuilder builder;
73  DlPaint paint;
74  paint.setColor(DlColor::kRed());
75  paint.setStrokeWidth(25);
76  paint.setDrawStyle(DlDrawStyle::kStroke);
77 
78  builder.DrawPath(DlPath::MakeCircle(DlPoint(500, 500), 250), paint);
79 
80  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
81 }

◆ TEST_P() [52/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDestructiveSaveLayer   
)

Definition at line 383 of file aiks_dl_unittests.cc.

383  {
384  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
385 
386  DlPaint paint;
387  paint.setColor(DlColor::kRed());
388  builder.DrawPaint(paint);
389  // Draw an empty savelayer with a destructive blend mode, which will replace
390  // the entire red screen with fully transparent black, except for the green
391  // circle drawn within the layer.
392 
393  DlPaint save_paint;
394  save_paint.setBlendMode(DlBlendMode::kSrc);
395  builder.SaveLayer(std::nullopt, &save_paint);
396 
397  DlPaint draw_paint;
398  draw_paint.setColor(DlColor::kGreen());
399  builder.DrawCircle(DlPoint(300, 300), 100, draw_paint);
400  builder.Restore();
401 
402  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
403 }

◆ TEST_P() [53/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferenceClips   
)

Definition at line 35 of file aiks_dl_clip_unittests.cc.

35  {
36  DisplayListBuilder builder;
37  builder.Translate(400, 400);
38 
39  // Limit drawing to face circle with a clip.
40  builder.ClipPath(DlPath::MakeCircle(DlPoint(0, 0), 200));
41  builder.Save();
42 
43  // Cut away eyes/mouth using difference clips.
44  builder.ClipPath(DlPath::MakeCircle(DlPoint(-100, -50), 30),
45  DlClipOp::kDifference);
46  builder.ClipPath(DlPath::MakeCircle(DlPoint(100, -50), 30),
47  DlClipOp::kDifference);
48 
49  DlPathBuilder path_builder;
50  path_builder.MoveTo(DlPoint(-100, 50));
51  path_builder.QuadraticCurveTo(DlPoint(0, 150), DlPoint(100, 50));
52  builder.ClipPath(path_builder.TakePath(), DlClipOp::kDifference);
53 
54  // Draw a huge yellow rectangle to prove the clipping works.
55  DlPaint paint;
56  paint.setColor(DlColor::kYellow());
57  builder.DrawRect(DlRect::MakeXYWH(-1000, -1000, 2000, 2000), paint);
58 
59  // Remove the difference clips and draw hair that partially covers the eyes.
60  builder.Restore();
61  paint.setColor(DlColor::kMaroon());
62  DlPathBuilder path_builder_2;
63  path_builder_2.MoveTo(DlPoint(200, -200));
64  path_builder_2.LineTo(DlPoint(-200, -200));
65  path_builder_2.LineTo(DlPoint(-200, -40));
66  path_builder_2.CubicCurveTo(DlPoint(0, -40), DlPoint(0, -80),
67  DlPoint(200, -80));
68 
69  builder.DrawPath(path_builder_2.TakePath(), paint);
70 
71  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
72 }

◆ TEST_P() [54/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferencePaths   
)

Definition at line 395 of file aiks_dl_path_unittests.cc.

395  {
396  DisplayListBuilder builder;
397 
398  DlPaint paint;
399  paint.setColor(DlColor::kRed());
400 
401  RoundingRadii radii = {
402  .top_left = {50, 25},
403  .top_right = {25, 50},
404  .bottom_left = {25, 50},
405  .bottom_right = {50, 25},
406  };
407  DlPathBuilder path_builder;
408  DlRoundRect rrect =
409  DlRoundRect::MakeRectRadii(DlRect::MakeXYWH(100, 100, 200, 200), radii);
410  // We use the factory method to convert the rrect and circle to a path so
411  // that they use the legacy conics for legacy golden output.
412  path_builder.AddPath(DlPath::MakeRoundRect(rrect));
413  path_builder.AddPath(DlPath::MakeCircle(DlPoint(200, 200), 50));
414  path_builder.SetFillType(DlPathFillType::kOdd);
415  DlPath path = path_builder.TakePath();
416 
417  builder.DrawImage(
418  DlImageImpeller::Make(CreateTextureForFixture("boston.jpg")),
419  DlPoint{10, 10}, {});
420  builder.DrawPath(path, paint);
421 
422  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
423 }

References impeller::DlImageImpeller::Make(), and impeller::RoundingRadii::top_left.

◆ TEST_P() [55/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferentShapesWithSameColorSource   
)

Definition at line 417 of file aiks_dl_basic_unittests.cc.

417  {
418  DisplayListBuilder builder;
419  DlPaint paint;
420 
421  DlColor colors[2] = {
422  DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
423  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0),
424  };
425  DlScalar stops[2] = {
426  0.0,
427  1.0,
428  };
429 
430  paint.setColorSource(DlColorSource::MakeLinear(
431  /*start_point=*/DlPoint(0, 0), //
432  /*end_point=*/DlPoint(100, 100), //
433  /*stop_count=*/2, //
434  /*colors=*/colors, //
435  /*stops=*/stops, //
436  /*tile_mode=*/DlTileMode::kRepeat //
437  ));
438 
439  builder.Save();
440  builder.Translate(100, 100);
441  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), paint);
442  builder.Restore();
443 
444  builder.Save();
445  builder.Translate(100, 400);
446  builder.DrawCircle(DlPoint(100, 100), 100, paint);
447  builder.Restore();
448  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
449 }
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:23

◆ TEST_P() [56/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrame   
)

Definition at line 383 of file aiks_dl_text_unittests.cc.

383  {
384  DisplayListBuilder builder;
385 
386  DlPaint paint;
387  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
388  builder.DrawPaint(paint);
389 
390  ASSERT_TRUE(RenderTextInCanvasSkia(
391  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
392  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
393 }
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string_view &font_fixture, const TextRenderOptions &options={}, const std::optional< SkFont > &font=std::nullopt)
static constexpr std::string_view kFontFixture

References kFontFixture, and RenderTextInCanvasSkia().

◆ TEST_P() [57/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrameWithAlpha   
)

Definition at line 411 of file aiks_dl_text_unittests.cc.

411  {
412  DisplayListBuilder builder;
413 
414  DlPaint paint;
415  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
416  builder.DrawPaint(paint);
417 
418  ASSERT_TRUE(RenderTextInCanvasSkia(
419  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
420  {.color = DlColor::kBlack().modulateOpacity(0.5)}));
421  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
422 }

References kFontFixture, and RenderTextInCanvasSkia().

◆ TEST_P() [58/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrameWithBlur   
)

Definition at line 395 of file aiks_dl_text_unittests.cc.

395  {
396  DisplayListBuilder builder;
397 
398  builder.Scale(GetContentScale().x, GetContentScale().y);
399  DlPaint paint;
400  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
401  builder.DrawPaint(paint);
402 
403  ASSERT_TRUE(RenderTextInCanvasSkia(
404  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
405  TextRenderOptions{
406  .color = DlColor::kBlue(),
407  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
408  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
409 }

References impeller::testing::TextRenderOptions::color, kFontFixture, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [59/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderFilledConicPaths   
)

Definition at line 159 of file aiks_dl_path_unittests.cc.

159  {
160  DisplayListBuilder builder;
161  builder.Scale(GetContentScale().x, GetContentScale().y);
162 
163  DlPaint paint;
164  paint.setColor(DlColor::kRed());
165  paint.setDrawStyle(DlDrawStyle::kFill);
166 
167  DlPaint reference_paint;
168  reference_paint.setColor(DlColor::kGreen());
169  reference_paint.setDrawStyle(DlDrawStyle::kFill);
170 
171  DlPathBuilder path_builder;
172  DlPathBuilder reference_builder;
173 
174  // weight of 1.0 is just a quadratic bezier
175  path_builder.MoveTo(DlPoint(100, 100));
176  path_builder.ConicCurveTo(DlPoint(150, 150), DlPoint(200, 100), 1.0f);
177  reference_builder.MoveTo(DlPoint(300, 100));
178  reference_builder.QuadraticCurveTo(DlPoint(350, 150), DlPoint(400, 100));
179 
180  // weight of sqrt(2)/2 is a circular section
181  path_builder.MoveTo(DlPoint(100, 200));
182  path_builder.ConicCurveTo(DlPoint(150, 250), DlPoint(200, 200), kSqrt2Over2);
183  reference_builder.MoveTo(DlPoint(300, 200));
184  auto magic = DlPathBuilder::kArcApproximationMagic;
185  reference_builder.CubicCurveTo(DlPoint(300, 200) + DlPoint(50, 50) * magic,
186  DlPoint(400, 200) + DlPoint(-50, 50) * magic,
187  DlPoint(400, 200));
188 
189  // weight of .01 is nearly a straight line
190  path_builder.MoveTo(DlPoint(100, 300));
191  path_builder.ConicCurveTo(DlPoint(150, 350), DlPoint(200, 300), 0.01f);
192  reference_builder.MoveTo(DlPoint(300, 300));
193  reference_builder.LineTo(DlPoint(350, 300.5));
194  reference_builder.LineTo(DlPoint(400, 300));
195 
196  // weight of 100.0 is nearly a triangle
197  path_builder.MoveTo(DlPoint(100, 400));
198  path_builder.ConicCurveTo(DlPoint(150, 450), DlPoint(200, 400), 100.0f);
199  reference_builder.MoveTo(DlPoint(300, 400));
200  reference_builder.LineTo(DlPoint(350, 450));
201  reference_builder.LineTo(DlPoint(400, 400));
202 
203  builder.DrawPath(path_builder.TakePath(), paint);
204  builder.DrawPath(reference_builder.TakePath(), reference_paint);
205 
206  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
207 }

References impeller::kSqrt2Over2, and x.

◆ TEST_P() [60/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderForegroundAdvancedBlendWithMaskBlur   
)

Definition at line 183 of file aiks_dl_blur_unittests.cc.

183  {
184  // This case triggers the ForegroundAdvancedBlend path. The color filter
185  // should apply to the color only, and respect the alpha mask.
186  DisplayListBuilder builder;
187  builder.ClipRect(DlRect::MakeXYWH(100, 150, 400, 400));
188 
189  DlPaint paint;
190  paint.setColor(
191  DlColor::RGBA(128.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f, 1.0f));
192 
193  Sigma sigma = Radius(20);
194  paint.setMaskFilter(
195  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma));
196  paint.setColorFilter(
197  DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kColor));
198  builder.DrawCircle(DlPoint(400, 400), 200, paint);
199  builder.Restore();
200 
201  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
202 }

References impeller::Sigma::sigma.

◆ TEST_P() [61/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderForegroundBlendWithMaskBlur   
)

Definition at line 164 of file aiks_dl_blur_unittests.cc.

164  {
165  // This case triggers the ForegroundPorterDuffBlend path. The color filter
166  // should apply to the color only, and respect the alpha mask.
167  DisplayListBuilder builder;
168  builder.ClipRect(DlRect::MakeXYWH(100, 150, 400, 400));
169 
170  DlPaint paint;
171  paint.setColor(DlColor::kWhite());
172 
173  Sigma sigma = Radius(20);
174  paint.setMaskFilter(
175  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma));
176  paint.setColorFilter(
177  DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kSrc));
178  builder.DrawCircle(DlPoint(400, 400), 200, paint);
179 
180  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
181 }

References impeller::Sigma::sigma.

◆ TEST_P() [62/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderGradientDecalWithBackground   
)

Definition at line 703 of file aiks_dl_gradient_unittests.cc.

703  {
704  std::vector<DlColor> colors = {
705  DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
706  DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
707  DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
708  DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
709  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
710 
711  std::array<std::shared_ptr<DlColorSource>, 3> color_sources = {
712  DlColorSource::MakeLinear({0, 0}, {100, 100}, stops.size(), colors.data(),
713  stops.data(), DlTileMode::kDecal),
714  DlColorSource::MakeRadial({100, 100}, 100, stops.size(), colors.data(),
715  stops.data(), DlTileMode::kDecal),
716  DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
717  stops.data(), DlTileMode::kDecal),
718  };
719 
720  DisplayListBuilder builder;
721  DlPaint paint;
722  paint.setColor(DlColor::kWhite());
723  builder.DrawRect(DlRect::MakeLTRB(0, 0, 605, 205), paint);
724  for (int i = 0; i < 3; i++) {
725  builder.Save();
726  builder.Translate(i * 200.0f, 0);
727  paint.setColorSource(color_sources[i]);
728  builder.DrawRect(DlRect::MakeLTRB(0, 0, 200, 200), paint);
729  builder.Restore();
730  }
731  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
732 }

◆ TEST_P() [63/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderGroupOpacity   
)

Definition at line 34 of file aiks_dl_opacity_unittests.cc.

34  {
35  DisplayListBuilder builder;
36 
37  DlPaint red;
38  red.setColor(DlColor::kRed());
39  DlPaint green;
40  green.setColor(DlColor::kGreen().modulateOpacity(0.5));
41  DlPaint blue;
42  blue.setColor(DlColor::kBlue());
43 
44  DlPaint alpha;
45  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
46 
47  builder.SaveLayer(std::nullopt, &alpha);
48  builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), red);
49  builder.DrawRect(DlRect::MakeXYWH(200, 200, 100, 100), green);
50  builder.DrawRect(DlRect::MakeXYWH(400, 400, 100, 100), blue);
51  builder.Restore();
52 
53  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
54 }

◆ TEST_P() [64/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderGroupOpacityToSavelayer   
)

Definition at line 56 of file aiks_dl_opacity_unittests.cc.

56  {
57  DisplayListBuilder builder;
58 
59  DlPaint red;
60  red.setColor(DlColor::kRed());
61 
62  DlPaint alpha;
63  alpha.setColor(DlColor::kRed().modulateOpacity(0.7));
64 
65  // Create a saveLayer that will forward its opacity to another
66  // saveLayer, to verify that we correctly distribute opacity.
67  DlRect bounds = DlRect::MakeLTRB(0, 0, 500, 500);
68  builder.SaveLayer(bounds, &alpha);
69  builder.SaveLayer(bounds, &alpha);
70  builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), red);
71  builder.DrawRect(DlRect::MakeXYWH(0, 0, 450, 450), red);
72  builder.Restore();
73  builder.Restore();
74 
75  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
76 }

◆ TEST_P() [65/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderImage   
)

Definition at line 107 of file aiks_dl_basic_unittests.cc.

107  {
108  DisplayListBuilder builder;
109  DlPaint paint;
110  paint.setColor(DlColor::kRed());
111  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
112  builder.DrawImage(image, DlPoint(100.0, 100.0),
113  DlImageSampling::kNearestNeighbor, &paint);
114  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
115 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [66/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderImageRect   
)

Definition at line 277 of file aiks_dl_basic_unittests.cc.

277  {
278  DisplayListBuilder builder;
279  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
280 
281  DlISize image_half_size =
282  DlISize(image->GetSize().width * 0.5f, image->GetSize().height * 0.5f);
283 
284  // Render the bottom right quarter of the source image in a stretched rect.
285  auto source_rect = DlRect::MakeSize(image_half_size);
286  source_rect =
287  source_rect.Shift(image_half_size.width, image_half_size.height);
288 
289  builder.DrawImageRect(image, source_rect,
290  DlRect::MakeXYWH(100, 100, 600, 600),
291  DlImageSampling::kNearestNeighbor);
292  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
293 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [67/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderInvertedImageWithColorFilter   
)

Definition at line 117 of file aiks_dl_basic_unittests.cc.

117  {
118  DisplayListBuilder builder;
119  DlPaint paint;
120  paint.setColor(DlColor::kRed());
121  paint.setColorFilter(
122  DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
123  paint.setInvertColors(true);
124  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
125 
126  builder.DrawImage(image, DlPoint(100.0, 100.0),
127  DlImageSampling::kNearestNeighbor, &paint);
128  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
129 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [68/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderItalicizedText   
)

Definition at line 363 of file aiks_dl_text_unittests.cc.

363  {
364  DisplayListBuilder builder;
365 
366  DlPaint paint;
367  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
368  builder.DrawPaint(paint);
369 
370  ASSERT_TRUE(RenderTextInCanvasSkia(
371  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
372  "HomemadeApple.ttf"));
373  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
374 }

References RenderTextInCanvasSkia().

◆ TEST_P() [69/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientClamp   
)

Definition at line 55 of file aiks_dl_gradient_unittests.cc.

55  {
56  CanRenderLinearGradient(this, DlTileMode::kClamp);
57 }

◆ TEST_P() [70/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientDecal   
)

Definition at line 64 of file aiks_dl_gradient_unittests.cc.

64  {
65  CanRenderLinearGradient(this, DlTileMode::kDecal);
66 }

◆ TEST_P() [71/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientDecalWithColorFilter   
)

Definition at line 68 of file aiks_dl_gradient_unittests.cc.

68  {
69  DisplayListBuilder builder;
70  Point scale = GetContentScale();
71  builder.Scale(scale.x, scale.y);
72  DlPaint paint;
73  builder.Translate(100.0f, 0);
74 
75  std::vector<DlColor> colors = {
76  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
77  DlColor(Color{0.1294, 0.5882, 0.9529, 0.0}.ToARGB())};
78  std::vector<Scalar> stops = {0.0, 1.0};
79 
80  paint.setColorSource(DlColorSource::MakeLinear(
81  {0, 0}, {200, 200}, 2, colors.data(), stops.data(), DlTileMode::kDecal));
82  // Overlay the gradient with 25% green. This should appear as the entire
83  // rectangle being drawn with 25% green, including the border area outside the
84  // decal gradient.
85  paint.setColorFilter(DlColorFilter::MakeBlend(DlColor::kGreen().withAlpha(64),
86  DlBlendMode::kSrcOver));
87  paint.setColor(DlColor::kWhite());
88  builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
89  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
90 }

References impeller::Color::ToARGB(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [72/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsClamp   
)

Definition at line 361 of file aiks_dl_gradient_unittests.cc.

361  {
362  CanRenderLinearGradientManyColors(this, DlTileMode::kClamp);
363 }

◆ TEST_P() [73/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsDecal   
)

Definition at line 370 of file aiks_dl_gradient_unittests.cc.

370  {
371  CanRenderLinearGradientManyColors(this, DlTileMode::kDecal);
372 }

◆ TEST_P() [74/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsMirror   
)

Definition at line 367 of file aiks_dl_gradient_unittests.cc.

367  {
368  CanRenderLinearGradientManyColors(this, DlTileMode::kMirror);
369 }

◆ TEST_P() [75/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsRepeat   
)

Definition at line 364 of file aiks_dl_gradient_unittests.cc.

364  {
365  CanRenderLinearGradientManyColors(this, DlTileMode::kRepeat);
366 }

◆ TEST_P() [76/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsUnevenStops   
)

Definition at line 405 of file aiks_dl_gradient_unittests.cc.

405  {
406  auto callback = [&]() -> sk_sp<DisplayList> {
407  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
408  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
409  DlTileMode::kMirror, DlTileMode::kDecal};
410 
411  static int selected_tile_mode = 0;
412  static Matrix matrix;
413  if (AiksTest::ImGuiBegin("Controls", nullptr,
414  ImGuiWindowFlags_AlwaysAutoResize)) {
415  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
416  sizeof(tile_mode_names) / sizeof(char*));
417  std::string label = "##1";
418  for (int i = 0; i < 4; i++) {
419  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
420  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
421  label[2]++;
422  }
423  ImGui::End();
424  }
425 
426  DisplayListBuilder builder;
427  DlPaint paint;
428  builder.Translate(100.0, 100.0);
429  auto tile_mode = tile_modes[selected_tile_mode];
430 
431  std::vector<DlColor> colors = {
432  DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
433  DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
434  DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
435  DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
436  DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
437  DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
438  DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
439  std::vector<Scalar> stops = {
440  0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
441  };
442 
443  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
444  stops.size(), colors.data(),
445  stops.data(), tile_mode));
446 
447  builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
448  return builder.Build();
449  };
450  ASSERT_TRUE(OpenPlaygroundHere(callback));
451 }

References impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [77/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientMaskBlur   
)

Definition at line 453 of file aiks_dl_gradient_unittests.cc.

453  {
454  DisplayListBuilder builder;
455 
456  std::vector<DlColor> colors = {
457  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed(), DlColor::kWhite(),
458  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed(), DlColor::kWhite(),
459  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed()};
460  std::vector<Scalar> stops = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5,
461  0.6, 0.7, 0.8, 0.9, 1.0};
462 
463  DlPaint paint;
464  paint.setColor(DlColor::kWhite());
465  paint.setColorSource(DlColorSource::MakeLinear(
466  {200, 200}, {400, 400}, stops.size(), colors.data(), stops.data(),
467  DlTileMode::kClamp));
468  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
469 
470  builder.DrawCircle(DlPoint(300, 300), 200, paint);
471  builder.DrawRect(DlRect::MakeLTRB(100, 300, 500, 600), paint);
472 
473  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
474 }

◆ TEST_P() [78/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientMirror   
)

Definition at line 61 of file aiks_dl_gradient_unittests.cc.

61  {
62  CanRenderLinearGradient(this, DlTileMode::kMirror);
63 }

◆ TEST_P() [79/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientRepeat   
)

Definition at line 58 of file aiks_dl_gradient_unittests.cc.

58  {
59  CanRenderLinearGradient(this, DlTileMode::kRepeat);
60 }

◆ TEST_P() [80/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWayManyColorsClamp   
)

Definition at line 401 of file aiks_dl_gradient_unittests.cc.

401  {
402  CanRenderLinearGradientWayManyColors(this, DlTileMode::kClamp);
403 }

◆ TEST_P() [81/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWithDitheringEnabled   
)

Definition at line 108 of file aiks_dl_gradient_unittests.cc.

108  {
110 }
static void CanRenderLinearGradientWithDithering(AiksTest *aiks_test)

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [82/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWithIncompleteStops   
)

Definition at line 308 of file aiks_dl_gradient_unittests.cc.

308  {
309  CanRenderGradientWithIncompleteStops(this,
310  DlColorSourceType::kLinearGradient);
311 }

◆ TEST_P() [83/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWithOverlappingStopsClamp   
)

Definition at line 203 of file aiks_dl_gradient_unittests.cc.

203  {
204  CanRenderLinearGradientWithOverlappingStops(this, DlTileMode::kClamp);
205 }

◆ TEST_P() [84/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMaskBlurHugeSigma   
)

Definition at line 152 of file aiks_dl_blur_unittests.cc.

152  {
153  DisplayListBuilder builder;
154 
155  DlPaint paint;
156  paint.setColor(DlColor::kGreen());
157  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 99999));
158  builder.DrawCircle(DlPoint(400, 400), 300, paint);
159  builder.Restore();
160 
161  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
162 }

◆ TEST_P() [85/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMultipleBackdropBlurWithSingleBackdropId   
)

Definition at line 295 of file aiks_dl_blur_unittests.cc.

295  {
296  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
297 
298  DisplayListBuilder builder;
299 
300  DlPaint paint;
301  builder.DrawImage(image, DlPoint(50.0, 50.0),
302  DlImageSampling::kNearestNeighbor, &paint);
303 
304  for (int i = 0; i < 6; i++) {
305  DlRoundRect rrect = DlRoundRect::MakeRectXY(
306  DlRect::MakeXYWH(50 + (i * 100), 250, 100, 100), 20, 20);
307  builder.Save();
308  builder.ClipRoundRect(rrect);
309 
310  DlPaint save_paint;
311  save_paint.setBlendMode(DlBlendMode::kSrc);
312  auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
313  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get(),
314  /*backdrop_id=*/1);
315  builder.Restore();
316  builder.Restore();
317  }
318 
319  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
320 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [86/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMultipleBackdropBlurWithSingleBackdropIdAndDistinctFilters   
)

Definition at line 322 of file aiks_dl_blur_unittests.cc.

323  {
324  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
325 
326  DisplayListBuilder builder;
327 
328  DlPaint paint;
329  builder.DrawImage(image, DlPoint(50.0, 50.0),
330  DlImageSampling::kNearestNeighbor, &paint);
331 
332  for (int i = 0; i < 6; i++) {
333  DlRoundRect rrect = DlRoundRect::MakeRectXY(
334  DlRect::MakeXYWH(50 + (i * 100), 250, 100, 100), 20, 20);
335  builder.Save();
336  builder.ClipRoundRect(rrect);
337 
338  DlPaint save_paint;
339  save_paint.setBlendMode(DlBlendMode::kSrc);
340  auto backdrop_filter =
341  DlImageFilter::MakeBlur(30 + i, 30, DlTileMode::kClamp);
342  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get(),
343  /*backdrop_id=*/1);
344  builder.Restore();
345  builder.Restore();
346  }
347 
348  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
349 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [87/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMultipleBackdropBlurWithSingleBackdropIdDifferentLayers   
)

Definition at line 1307 of file aiks_dl_blur_unittests.cc.

1308  {
1309  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
1310 
1311  DisplayListBuilder builder;
1312 
1313  DlPaint paint;
1314  builder.DrawImage(image, DlPoint(50.0, 50.0),
1315  DlImageSampling::kNearestNeighbor, &paint);
1316 
1317  for (int i = 0; i < 6; i++) {
1318  if (i != 0) {
1319  DlPaint paint;
1320  paint.setColor(DlColor::kWhite().withAlphaF(0.95));
1321  builder.SaveLayer(std::nullopt, &paint);
1322  }
1323  DlRoundRect rrect = DlRoundRect::MakeRectXY(
1324  DlRect::MakeXYWH(50 + (i * 100), 250, 100, 100), 20, 20);
1325  builder.Save();
1326  builder.ClipRoundRect(rrect);
1327 
1328  DlPaint save_paint;
1329  save_paint.setBlendMode(DlBlendMode::kSrc);
1330  auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
1331  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get(),
1332  /*backdrop_id=*/1);
1333  builder.Restore();
1334  builder.Restore();
1335  if (i != 0) {
1336  builder.Restore();
1337  }
1338  }
1339 
1340  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1341 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [88/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderNestedBackdropBlur   
)

Definition at line 1371 of file aiks_dl_blur_unittests.cc.

1371  {
1372  int64_t count = 0;
1373  auto callback = [&]() -> sk_sp<DisplayList> {
1374  DisplayListBuilder builder;
1375 
1376  Scalar freq = 1.0;
1377  Scalar amp = 50.0;
1378  Scalar offset = amp * sin(freq * 2.0 * M_PI * count / 60.0);
1379 
1380  // Draw some background content to be blurred.
1381  DlPaint paint;
1382  paint.setColor(DlColor::kCornflowerBlue());
1383  builder.DrawCircle(DlPoint(100 + offset, 100), 50, paint);
1384  paint.setColor(DlColor::kGreenYellow());
1385  builder.DrawCircle(DlPoint(300, 200 + offset), 100, paint);
1386  paint.setColor(DlColor::kDarkMagenta());
1387  builder.DrawCircle(DlPoint(140, 170), 75, paint);
1388  paint.setColor(DlColor::kOrangeRed());
1389  builder.DrawCircle(DlPoint(180 + offset, 120 + offset), 100, paint);
1390 
1391  // This is the first backdrop blur, simulating the navigation transition.
1392  auto backdrop_filter1 = DlImageFilter::MakeBlur(15, 15, DlTileMode::kClamp);
1393  builder.SaveLayer(std::nullopt, nullptr, backdrop_filter1.get());
1394 
1395  // Draw the semi-transparent container from the second screen.
1396  DlPaint transparent_paint;
1397  transparent_paint.setColor(DlColor::kWhite().withAlpha(0.1 * 255));
1398  builder.DrawPaint(transparent_paint);
1399 
1400  {
1401  // This is the second, nested backdrop blur.
1402  auto backdrop_filter2 =
1403  DlImageFilter::MakeBlur(10, 10, DlTileMode::kClamp);
1404  builder.Save();
1405  builder.ClipRect(DlRect::MakeXYWH(150, 150, 300, 300));
1406  builder.SaveLayer(std::nullopt, nullptr, backdrop_filter2.get());
1407  builder.Restore(); // Restore from SaveLayer
1408  builder.Restore(); // Restore from ClipRect
1409  }
1410 
1411  builder.Restore(); // Restore from the first SaveLayer
1412 
1413  count++;
1414  return builder.Build();
1415  };
1416  ASSERT_TRUE(OpenPlaygroundHere(callback));
1417 }

◆ TEST_P() [89/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderNestedClips   
)

Definition at line 20 of file aiks_dl_clip_unittests.cc.

20  {
21  DisplayListBuilder builder;
22  DlPaint paint;
23  paint.setColor(DlColor::kFuchsia());
24 
25  builder.Save();
26  builder.ClipPath(DlPath::MakeCircle(DlPoint(200, 400), 300));
27  builder.Restore();
28  builder.ClipPath(DlPath::MakeCircle(DlPoint(600, 400), 300));
29  builder.ClipPath(DlPath::MakeCircle(DlPoint(400, 600), 300));
30  builder.DrawRect(DlRect::MakeXYWH(200, 200, 400, 400), paint);
31 
32  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
33 }

◆ TEST_P() [90/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderOverlappingMultiContourPath   
)

Definition at line 914 of file aiks_dl_path_unittests.cc.

914  {
915  DisplayListBuilder builder;
916 
917  DlPaint paint;
918  paint.setColor(DlColor::kRed());
919 
920  RoundingRadii radii = {
921  .top_left = DlSize(50, 50),
922  .top_right = DlSize(50, 50),
923  .bottom_left = DlSize(50, 50),
924  .bottom_right = DlSize(50, 50),
925  };
926 
927  const Scalar kTriangleHeight = 100;
928  DlRoundRect rrect = DlRoundRect::MakeRectRadii(
929  DlRect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
930  kTriangleHeight, kTriangleHeight),
931  radii //
932  );
933  // We use the factory method to convert the rrect to a path so that it
934  // uses the legacy conics for legacy golden output.
935  DlPath rrect_path = DlPath::MakeRoundRect(rrect);
936 
937  builder.Translate(200, 200);
938  // Form a path similar to the Material drop slider value indicator. Both
939  // shapes should render identically side-by-side.
940  {
941  DlPathBuilder path_builder;
942  path_builder.MoveTo(DlPoint(0, kTriangleHeight));
943  path_builder.LineTo(DlPoint(-kTriangleHeight / 2.0f, 0));
944  path_builder.LineTo(DlPoint(kTriangleHeight / 2.0f, 0));
945  path_builder.Close();
946  path_builder.AddPath(rrect_path);
947 
948  builder.DrawPath(path_builder.TakePath(), paint);
949  }
950  builder.Translate(100, 0);
951 
952  {
953  DlPathBuilder path_builder;
954  path_builder.MoveTo(DlPoint(0, kTriangleHeight));
955  path_builder.LineTo(DlPoint(-kTriangleHeight / 2.0f, 0));
956  path_builder.LineTo(DlPoint(0, -10));
957  path_builder.LineTo(DlPoint(kTriangleHeight / 2.0f, 0));
958  path_builder.Close();
959  path_builder.AddPath(rrect_path);
960 
961  builder.DrawPath(path_builder.TakePath(), paint);
962  }
963 
964  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
965 }

References impeller::RoundingRadii::top_left.

◆ TEST_P() [91/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderQuadraticStrokeWithInstantTurn   
)

Definition at line 139 of file aiks_dl_path_unittests.cc.

139  {
140  DisplayListBuilder builder;
141 
142  DlPaint paint;
143  paint.setColor(DlColor::kRed());
144  paint.setStrokeWidth(50);
145  paint.setDrawStyle(DlDrawStyle::kStroke);
146  paint.setStrokeCap(DlStrokeCap::kRound);
147 
148  // Should draw a diagonal pill shape. If flat on either end, the stroke is
149  // rendering wrong.
150  DlPathBuilder path_builder;
151  path_builder.MoveTo(DlPoint(250, 250));
152  path_builder.QuadraticCurveTo(DlPoint(100, 100), DlPoint(250, 250));
153 
154  builder.DrawPath(path_builder.TakePath(), paint);
155 
156  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
157 }

◆ TEST_P() [92/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradient   
)

Definition at line 476 of file aiks_dl_gradient_unittests.cc.

476  {
477  auto callback = [&]() -> sk_sp<DisplayList> {
478  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
479  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
480  DlTileMode::kMirror, DlTileMode::kDecal};
481 
482  static int selected_tile_mode = 0;
483  static Matrix matrix;
484  if (AiksTest::ImGuiBegin("Controls", nullptr,
485  ImGuiWindowFlags_AlwaysAutoResize)) {
486  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
487  sizeof(tile_mode_names) / sizeof(char*));
488  std::string label = "##1";
489  for (int i = 0; i < 4; i++) {
490  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
491  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
492  label[2]++;
493  }
494  ImGui::End();
495  }
496 
497  DisplayListBuilder builder;
498  DlPaint paint;
499  builder.Translate(100.0, 100.0);
500  auto tile_mode = tile_modes[selected_tile_mode];
501 
502  std::vector<DlColor> colors = {
503  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
504  DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
505  std::vector<Scalar> stops = {0.0, 1.0};
506 
507  paint.setColorSource(DlColorSource::MakeRadial(
508  {100, 100}, 100, 2, colors.data(), stops.data(), tile_mode));
509 
510  builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
511  return builder.Build();
512  };
513  ASSERT_TRUE(OpenPlaygroundHere(callback));
514 }

References impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [93/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientManyColors   
)

Definition at line 516 of file aiks_dl_gradient_unittests.cc.

516  {
517  auto callback = [&]() -> sk_sp<DisplayList> {
518  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
519  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
520  DlTileMode::kMirror, DlTileMode::kDecal};
521 
522  static int selected_tile_mode = 0;
523  static Matrix matrix = {
524  1, 0, 0, 0, //
525  0, 1, 0, 0, //
526  0, 0, 1, 0, //
527  0, 0, 0, 1 //
528  };
529  if (AiksTest::ImGuiBegin("Controls", nullptr,
530  ImGuiWindowFlags_AlwaysAutoResize)) {
531  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
532  sizeof(tile_mode_names) / sizeof(char*));
533  std::string label = "##1";
534  for (int i = 0; i < 4; i++) {
535  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
536  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
537  label[2]++;
538  }
539  ImGui::End();
540  }
541 
542  DisplayListBuilder builder;
543  DlPaint paint;
544  builder.Translate(100.0, 100.0);
545  auto tile_mode = tile_modes[selected_tile_mode];
546 
547  std::vector<DlColor> colors = {
548  DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
549  DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
550  DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
551  DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
552  DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
553  DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
554  DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
555  std::vector<Scalar> stops = {
556  0.0,
557  (1.0 / 6.0) * 1,
558  (1.0 / 6.0) * 2,
559  (1.0 / 6.0) * 3,
560  (1.0 / 6.0) * 4,
561  (1.0 / 6.0) * 5,
562  1.0,
563  };
564 
565  paint.setColorSource(DlColorSource::MakeRadial(
566  {100, 100}, 100, stops.size(), colors.data(), stops.data(), tile_mode));
567 
568  builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
569  return builder.Build();
570  };
571  ASSERT_TRUE(OpenPlaygroundHere(callback));
572 }

References impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [94/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientWithDitheringEnabled   
)

Definition at line 128 of file aiks_dl_gradient_unittests.cc.

128  {
130 }
static void CanRenderRadialGradientWithDithering(AiksTest *aiks_test)

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [95/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientWithIncompleteStops   
)

Definition at line 312 of file aiks_dl_gradient_unittests.cc.

312  {
313  CanRenderGradientWithIncompleteStops(this,
314  DlColorSourceType::kRadialGradient);
315 }

◆ TEST_P() [96/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRoundedRectWithNonUniformRadii   
)

Definition at line 451 of file aiks_dl_basic_unittests.cc.

451  {
452  DisplayListBuilder builder;
453  DlPaint paint;
454  paint.setColor(DlColor::kRed());
455 
456  RoundingRadii radii = {
457  .top_left = DlSize(50, 25),
458  .top_right = DlSize(25, 50),
459  .bottom_left = DlSize(25, 50),
460  .bottom_right = DlSize(50, 25),
461  };
462  DlRoundRect rrect =
463  DlRoundRect::MakeRectRadii(DlRect::MakeXYWH(100, 100, 500, 500), radii);
464 
465  builder.DrawRoundRect(rrect, paint);
466 
467  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
468 }

References impeller::RoundingRadii::top_left.

◆ TEST_P() [97/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRuntimeEffectFilter   
)

Definition at line 85 of file aiks_dl_runtime_effect_unittests.cc.

85  {
86  auto runtime_stages =
87  OpenAssetAsRuntimeStage("runtime_stage_filter_example.frag.iplr");
88 
89  std::shared_ptr<RuntimeStage> runtime_stage =
90  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
91  ASSERT_TRUE(runtime_stage);
92  ASSERT_TRUE(runtime_stage->IsDirty());
93 
94  std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
95  nullptr,
96  };
97  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
98  uniform_data->resize(sizeof(Vector2));
99 
100  DlPaint paint;
101  paint.setColor(DlColor::kAqua());
102  paint.setImageFilter(DlImageFilter::MakeRuntimeEffect(
103  DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
104  uniform_data));
105 
106  DisplayListBuilder builder;
107  builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
108 
109  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
110 }
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition: playground.h:33

References flutter::DlRuntimeEffectImpeller::Make(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [98/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSimpleClips   
)

Definition at line 315 of file aiks_dl_basic_unittests.cc.

315  {
316  DisplayListBuilder builder;
317  builder.Scale(GetContentScale().x, GetContentScale().y);
318  DlPaint paint;
319 
320  paint.setColor(DlColor::kWhite());
321  builder.DrawPaint(paint);
322 
323  auto draw = [&builder](const DlPaint& paint, Scalar x, Scalar y) {
324  builder.Save();
325  builder.Translate(x, y);
326  {
327  builder.Save();
328  builder.ClipRect(DlRect::MakeLTRB(50, 50, 150, 150));
329  builder.DrawPaint(paint);
330  builder.Restore();
331  }
332  {
333  builder.Save();
334  builder.ClipOval(DlRect::MakeLTRB(200, 50, 300, 150));
335  builder.DrawPaint(paint);
336  builder.Restore();
337  }
338  {
339  builder.Save();
340  builder.ClipRoundRect(
341  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(50, 200, 150, 300), 20, 20));
342  builder.DrawPaint(paint);
343  builder.Restore();
344  }
345  {
346  builder.Save();
347  builder.ClipRoundRect(DlRoundRect::MakeRectXY(
348  DlRect::MakeLTRB(200, 230, 300, 270), 20, 20));
349  builder.DrawPaint(paint);
350  builder.Restore();
351  }
352  {
353  builder.Save();
354  builder.ClipRoundRect(DlRoundRect::MakeRectXY(
355  DlRect::MakeLTRB(230, 200, 270, 300), 20, 20));
356  builder.DrawPaint(paint);
357  builder.Restore();
358  }
359  builder.Restore();
360  };
361 
362  paint.setColor(DlColor::kBlue());
363  draw(paint, 0, 0);
364 
365  DlColor gradient_colors[7] = {
366  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
367  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
368  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
369  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
370  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
371  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
372  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
373  };
374  Scalar stops[7] = {
375  0.0,
376  (1.0 / 6.0) * 1,
377  (1.0 / 6.0) * 2,
378  (1.0 / 6.0) * 3,
379  (1.0 / 6.0) * 4,
380  (1.0 / 6.0) * 5,
381  1.0,
382  };
383  auto texture = CreateTextureForFixture("airplane.jpg",
384  /*enable_mipmapping=*/true);
385  auto image = DlImageImpeller::Make(texture);
386 
387  paint.setColorSource(DlColorSource::MakeRadial(
388  DlPoint(500, 600), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
389  draw(paint, 0, 300);
390 
391  paint.setColorSource(
392  DlColorSource::MakeImage(image, DlTileMode::kRepeat, DlTileMode::kRepeat,
393  DlImageSampling::kNearestNeighbor));
394  draw(paint, 300, 0);
395 
396  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
397 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [99/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokedConicPaths   
)

Definition at line 209 of file aiks_dl_path_unittests.cc.

209  {
210  DisplayListBuilder builder;
211  builder.Scale(GetContentScale().x, GetContentScale().y);
212 
213  DlPaint paint;
214  paint.setColor(DlColor::kRed());
215  paint.setStrokeWidth(10);
216  paint.setDrawStyle(DlDrawStyle::kStroke);
217  paint.setStrokeCap(DlStrokeCap::kRound);
218  paint.setStrokeJoin(DlStrokeJoin::kRound);
219 
220  DlPaint reference_paint;
221  reference_paint.setColor(DlColor::kGreen());
222  reference_paint.setStrokeWidth(10);
223  reference_paint.setDrawStyle(DlDrawStyle::kStroke);
224  reference_paint.setStrokeCap(DlStrokeCap::kRound);
225  reference_paint.setStrokeJoin(DlStrokeJoin::kRound);
226 
227  DlPathBuilder path_builder;
228  DlPathBuilder reference_builder;
229 
230  // weight of 1.0 is just a quadratic bezier
231  path_builder.MoveTo(DlPoint(100, 100));
232  path_builder.ConicCurveTo(DlPoint(150, 150), DlPoint(200, 100), 1.0f);
233  reference_builder.MoveTo(DlPoint(300, 100));
234  reference_builder.QuadraticCurveTo(DlPoint(350, 150), DlPoint(400, 100));
235 
236  // weight of sqrt(2)/2 is a circular section
237  path_builder.MoveTo(DlPoint(100, 200));
238  path_builder.ConicCurveTo(DlPoint(150, 250), DlPoint(200, 200), kSqrt2Over2);
239  reference_builder.MoveTo(DlPoint(300, 200));
240  auto magic = DlPathBuilder::kArcApproximationMagic;
241  reference_builder.CubicCurveTo(DlPoint(300, 200) + DlPoint(50, 50) * magic,
242  DlPoint(400, 200) + DlPoint(-50, 50) * magic,
243  DlPoint(400, 200));
244 
245  // weight of .0 is a straight line
246  path_builder.MoveTo(DlPoint(100, 300));
247  path_builder.ConicCurveTo(DlPoint(150, 350), DlPoint(200, 300), 0.0f);
248  reference_builder.MoveTo(DlPoint(300, 300));
249  reference_builder.LineTo(DlPoint(400, 300));
250 
251  // weight of 100.0 is nearly a triangle
252  path_builder.MoveTo(DlPoint(100, 400));
253  path_builder.ConicCurveTo(DlPoint(150, 450), DlPoint(200, 400), 100.0f);
254  reference_builder.MoveTo(DlPoint(300, 400));
255  reference_builder.LineTo(DlPoint(350, 450));
256  reference_builder.LineTo(DlPoint(400, 400));
257 
258  builder.DrawPath(path_builder.TakePath(), paint);
259  builder.DrawPath(reference_builder.TakePath(), reference_paint);
260 
261  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
262 }

References impeller::kSqrt2Over2, and x.

◆ TEST_P() [100/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokedTextFrame   
)

Definition at line 127 of file aiks_dl_text_unittests.cc.

127  {
128  DisplayListBuilder builder;
129 
130  DlPaint paint;
131  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
132  builder.DrawPaint(paint);
133 
134  ASSERT_TRUE(RenderTextInCanvasSkia(
135  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
136  "Roboto-Regular.ttf",
137  {
138  .stroke = true,
139  }));
140  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
141 }

References RenderTextInCanvasSkia().

◆ TEST_P() [101/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokePathThatEndsAtSharpTurn   
)

Definition at line 107 of file aiks_dl_path_unittests.cc.

107  {
108  DisplayListBuilder builder;
109  DlPaint paint;
110  paint.setColor(DlColor::kRed());
111  paint.setStrokeWidth(200);
112  paint.setDrawStyle(DlDrawStyle::kStroke);
113 
114  DlPath path = DlPath::MakeArc(DlRect::MakeXYWH(100, 100, 200, 200), //
115  DlDegrees(0), DlDegrees(90), false);
116 
117  builder.DrawPath(path, paint);
118 
119  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
120 }

◆ TEST_P() [102/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokePathWithCubicLine   
)

Definition at line 122 of file aiks_dl_path_unittests.cc.

122  {
123  DisplayListBuilder builder;
124 
125  DlPaint paint;
126  paint.setColor(DlColor::kRed());
127  paint.setStrokeWidth(20);
128  paint.setDrawStyle(DlDrawStyle::kStroke);
129 
130  DlPathBuilder path_builder;
131  path_builder.MoveTo(DlPoint(0, 200));
132  path_builder.CubicCurveTo(DlPoint(50, 400), DlPoint(350, 0),
133  DlPoint(400, 200));
134 
135  builder.DrawPath(path_builder.TakePath(), paint);
136  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
137 }

◆ TEST_P() [103/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokes   
)

Definition at line 58 of file aiks_dl_path_unittests.cc.

58  {
59  DisplayListBuilder builder;
60  DlPaint paint;
61  paint.setColor(DlColor::kRed());
62  paint.setStrokeWidth(20);
63  paint.setDrawStyle(DlDrawStyle::kStroke);
64 
65  builder.DrawPath(DlPath::MakeLine(DlPoint(200, 100), DlPoint(800, 100)),
66  paint);
67 
68  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
69 }

◆ TEST_P() [104/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientClamp   
)

Definition at line 595 of file aiks_dl_gradient_unittests.cc.

595  {
596  CanRenderSweepGradient(this, DlTileMode::kClamp);
597 }

◆ TEST_P() [105/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientDecal   
)

Definition at line 604 of file aiks_dl_gradient_unittests.cc.

604  {
605  CanRenderSweepGradient(this, DlTileMode::kDecal);
606 }

◆ TEST_P() [106/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsClamp   
)

Definition at line 642 of file aiks_dl_gradient_unittests.cc.

642  {
643  CanRenderSweepGradientManyColors(this, DlTileMode::kClamp);
644 }

◆ TEST_P() [107/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsDecal   
)

Definition at line 651 of file aiks_dl_gradient_unittests.cc.

651  {
652  CanRenderSweepGradientManyColors(this, DlTileMode::kDecal);
653 }

◆ TEST_P() [108/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsMirror   
)

Definition at line 648 of file aiks_dl_gradient_unittests.cc.

648  {
649  CanRenderSweepGradientManyColors(this, DlTileMode::kMirror);
650 }

◆ TEST_P() [109/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsRepeat   
)

Definition at line 645 of file aiks_dl_gradient_unittests.cc.

645  {
646  CanRenderSweepGradientManyColors(this, DlTileMode::kRepeat);
647 }

◆ TEST_P() [110/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientMirror   
)

Definition at line 601 of file aiks_dl_gradient_unittests.cc.

601  {
602  CanRenderSweepGradient(this, DlTileMode::kMirror);
603 }

◆ TEST_P() [111/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientRepeat   
)

Definition at line 598 of file aiks_dl_gradient_unittests.cc.

598  {
599  CanRenderSweepGradient(this, DlTileMode::kRepeat);
600 }

◆ TEST_P() [112/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientWithDitheringEnabled   
)

Definition at line 151 of file aiks_dl_gradient_unittests.cc.

151  {
153 }
static void CanRenderSweepGradientWithDithering(AiksTest *aiks_test)

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [113/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientWithIncompleteStops   
)

Definition at line 320 of file aiks_dl_gradient_unittests.cc.

320  {
321  CanRenderGradientWithIncompleteStops(this, DlColorSourceType::kSweepGradient);
322 }

◆ TEST_P() [114/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrame   
)

Definition at line 98 of file aiks_dl_text_unittests.cc.

98  {
99  DisplayListBuilder builder;
100 
101  DlPaint paint;
102  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
103  builder.DrawPaint(paint);
104  ASSERT_TRUE(RenderTextInCanvasSkia(
105  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
106  "Roboto-Regular.ttf"));
107 
108  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
109 }

References RenderTextInCanvasSkia().

◆ TEST_P() [115/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithFractionScaling   
)

Definition at line 252 of file aiks_dl_text_unittests.cc.

252  {
253  Scalar fine_scale = 0.f;
254  bool is_subpixel = false;
255  auto callback = [&]() -> sk_sp<DisplayList> {
256  if (AiksTest::ImGuiBegin("Controls", nullptr,
257  ImGuiWindowFlags_AlwaysAutoResize)) {
258  ImGui::SliderFloat("Fine Scale", &fine_scale, -1, 1);
259  ImGui::Checkbox("subpixel", &is_subpixel);
260  ImGui::End();
261  }
262 
263  DisplayListBuilder builder;
264  DlPaint paint;
265  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
266  builder.DrawPaint(paint);
267  Scalar scale = 2.625 + fine_scale;
268  builder.Scale(scale, scale);
269  RenderTextInCanvasSkia(GetContext(), builder,
270  "the quick brown fox jumped over the lazy dog!.?",
271  "Roboto-Regular.ttf",
272  TextRenderOptions{.is_subpixel = is_subpixel});
273  return builder.Build();
274  };
275 
276  ASSERT_TRUE(OpenPlaygroundHere(callback));
277 }
bool is_subpixel

References impeller::testing::TextRenderOptions::is_subpixel, is_subpixel, and RenderTextInCanvasSkia().

◆ TEST_P() [116/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithHalfScaling   
)

Definition at line 159 of file aiks_dl_text_unittests.cc.

159  {
160  DisplayListBuilder builder;
161 
162  DlPaint paint;
163  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
164  builder.DrawPaint(paint);
165  builder.Scale(0.5, 0.5);
166 
167  ASSERT_TRUE(RenderTextInCanvasSkia(
168  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
169  "Roboto-Regular.ttf"));
170  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
171 }

References RenderTextInCanvasSkia().

◆ TEST_P() [117/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithInvertedTransform   
)

Definition at line 111 of file aiks_dl_text_unittests.cc.

111  {
112  DisplayListBuilder builder;
113 
114  DlPaint paint;
115  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
116  builder.DrawPaint(paint);
117  builder.Translate(1000, 0);
118  builder.Scale(-1, 1);
119 
120  ASSERT_TRUE(RenderTextInCanvasSkia(
121  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
122  "Roboto-Regular.ttf"));
123 
124  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
125 }

References RenderTextInCanvasSkia().

◆ TEST_P() [118/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithScalingOverflow   
)

Definition at line 223 of file aiks_dl_text_unittests.cc.

223  {
224  Scalar scale = 60.0;
225  Scalar offsetx = -500.0;
226  Scalar offsety = 700.0;
227  auto callback = [&]() -> sk_sp<DisplayList> {
228  if (AiksTest::ImGuiBegin("Controls", nullptr,
229  ImGuiWindowFlags_AlwaysAutoResize)) {
230  ImGui::SliderFloat("scale", &scale, 1.f, 300.f);
231  ImGui::SliderFloat("offsetx", &offsetx, -600.f, 100.f);
232  ImGui::SliderFloat("offsety", &offsety, 600.f, 2048.f);
233  ImGui::End();
234  }
235  DisplayListBuilder builder;
236  builder.Scale(GetContentScale().x, GetContentScale().y);
237  DlPaint paint;
238  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
239  builder.DrawPaint(paint);
240  builder.Scale(scale, scale);
241 
243  GetContext(), builder, "test", "Roboto-Regular.ttf",
244  TextRenderOptions{
245  .position = DlPoint(offsetx / scale, offsety / scale),
246  });
247  return builder.Build();
248  };
249  ASSERT_TRUE(OpenPlaygroundHere(callback));
250 }

References impeller::testing::TextRenderOptions::position, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [119/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextInSaveLayer   
)

Definition at line 424 of file aiks_dl_text_unittests.cc.

424  {
425  DisplayListBuilder builder;
426 
427  DlPaint paint;
428  paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
429  builder.DrawPaint(paint);
430 
431  builder.Translate(100, 100);
432  builder.Scale(0.5, 0.5);
433 
434  // Blend the layer with the parent pass using kClear to expose the coverage.
435  paint.setBlendMode(DlBlendMode::kClear);
436  builder.SaveLayer(std::nullopt, &paint);
437  ASSERT_TRUE(RenderTextInCanvasSkia(
438  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
439  "Roboto-Regular.ttf"));
440  builder.Restore();
441 
442  // Render the text again over the cleared coverage rect.
443  ASSERT_TRUE(RenderTextInCanvasSkia(
444  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
445  "Roboto-Regular.ttf"));
446 
447  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
448 }

References RenderTextInCanvasSkia().

◆ TEST_P() [120/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextOutsideBoundaries   
)

Definition at line 450 of file aiks_dl_text_unittests.cc.

450  {
451  DisplayListBuilder builder;
452  builder.Translate(200, 150);
453 
454  // Construct the text blob.
455  auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
456  ASSERT_NE(mapping, nullptr);
457 
458  Scalar font_size = 80;
459  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
460  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
461 
462  DlPaint text_paint;
463  text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
464 
465  struct {
466  DlPoint position;
467  const char* text;
468  } text[] = {{DlPoint(0, 0), "0F0F0F0"},
469  {DlPoint(1, 2), "789"},
470  {DlPoint(1, 3), "456"},
471  {DlPoint(1, 4), "123"},
472  {DlPoint(0, 6), "0F0F0F0"}};
473  for (auto& t : text) {
474  builder.Save();
475  builder.Translate(t.position.x * font_size * 2,
476  t.position.y * font_size * 1.1);
477  {
478  auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
479  ASSERT_NE(blob, nullptr);
480  auto frame = MakeTextFrameFromTextBlobSkia(blob);
481  builder.DrawText(DlTextImpeller::Make(frame), 0, 0, text_paint);
482  }
483  builder.Restore();
484  }
485 
486  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
487 }
Scalar font_size

References font_size, flutter::DlTextImpeller::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [121/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextStrokeWidth   
)

Definition at line 143 of file aiks_dl_text_unittests.cc.

143  {
144  DisplayListBuilder builder;
145 
146  DlPaint paint;
147  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
148  builder.DrawPaint(paint);
149 
150  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "LMNOP VWXYZ",
151  "Roboto-Medium.ttf",
152  {
153  .stroke = true,
154  .stroke_width = 4,
155  }));
156  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
157 }

References RenderTextInCanvasSkia().

◆ TEST_P() [122/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextWithLargePerspectiveTransform   
)

Definition at line 547 of file aiks_dl_text_unittests.cc.

547  {
548  // Verifies that text scales are clamped to work around
549  // https://github.com/flutter/flutter/issues/136112 .
550 
551  DisplayListBuilder builder;
552 
553  DlPaint save_paint;
554  builder.SaveLayer(std::nullopt, &save_paint);
555  builder.Transform(Matrix(2000, 0, 0, 0, //
556  0, 2000, 0, 0, //
557  0, 0, -1, 9000, //
558  0, 0, -1, 7000 //
559  ));
560 
561  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
562  "Roboto-Regular.ttf"));
563  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
564 }

References RenderTextInCanvasSkia().

◆ TEST_P() [123/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextWithPerspectiveTransformInSublist   
)

Definition at line 566 of file aiks_dl_text_unittests.cc.

566  {
567  DisplayListBuilder text_builder;
568  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), text_builder, "Hello world",
569  "Roboto-Regular.ttf"));
570  auto text_display_list = text_builder.Build();
571 
572  DisplayListBuilder builder;
573 
574  Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0, //
575  0.0, 2.0, 0.0, 0.0, //
576  0.0, 0.0, 1.0, 0.0, //
577  0.0, 0.002, 0.0, 1.0);
578 
579  DlPaint save_paint;
580  DlRect window_bounds =
581  DlRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
582  builder.SaveLayer(window_bounds, &save_paint);
583  builder.Transform(matrix);
584  builder.DrawDisplayList(text_display_list, 1.0f);
585  builder.Restore();
586 
587  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
588 }

References RenderTextInCanvasSkia().

◆ TEST_P() [124/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderThickCurvedStrokes   
)

Definition at line 83 of file aiks_dl_path_unittests.cc.

83  {
84  DisplayListBuilder builder;
85  DlPaint paint;
86  paint.setColor(DlColor::kRed());
87  paint.setStrokeWidth(100);
88  paint.setDrawStyle(DlDrawStyle::kStroke);
89 
90  builder.DrawPath(DlPath::MakeCircle(DlPoint(100, 100), 50), paint);
91 
92  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
93 }

◆ TEST_P() [125/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderThinCurvedStrokes   
)

Definition at line 95 of file aiks_dl_path_unittests.cc.

95  {
96  DisplayListBuilder builder;
97  DlPaint paint;
98  paint.setColor(DlColor::kRed());
99  paint.setStrokeWidth(0.01);
100  paint.setDrawStyle(DlDrawStyle::kStroke);
101 
102  builder.DrawPath(DlPath::MakeCircle(DlPoint(100, 100), 50), paint);
103 
104  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
105 }

◆ TEST_P() [126/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTightConicPath   
)

Definition at line 346 of file aiks_dl_path_unittests.cc.

346  {
347  DisplayListBuilder builder;
348  builder.Scale(GetContentScale().x, GetContentScale().y);
349 
350  DlPaint paint;
351  paint.setColor(DlColor::kRed());
352  paint.setDrawStyle(DlDrawStyle::kFill);
353 
354  DlPaint reference_paint;
355  reference_paint.setColor(DlColor::kGreen());
356  reference_paint.setDrawStyle(DlDrawStyle::kFill);
357 
358  DlPathBuilder path_builder;
359 
360  path_builder.MoveTo(DlPoint(100, 100));
361  path_builder.ConicCurveTo(DlPoint(150, 450), DlPoint(200, 100), 5.0f);
362 
363  DlPathBuilder reference_builder;
364  PathTessellator::Conic component{DlPoint(300, 100), //
365  DlPoint(350, 450), //
366  DlPoint(400, 100), //
367  5.0f};
368  reference_builder.MoveTo(component.p1);
369  constexpr int N = 100;
370  for (int i = 1; i < N; i++) {
371  reference_builder.LineTo(component.Solve(static_cast<Scalar>(i) / N));
372  }
373  reference_builder.LineTo(component.p2);
374 
375  DlPaint line_paint;
376  line_paint.setColor(DlColor::kYellow());
377  line_paint.setDrawStyle(DlDrawStyle::kStroke);
378  line_paint.setStrokeWidth(1.0f);
379 
380  // Draw some lines to provide a spacial reference for the curvature of
381  // the tips of the direct rendering and the manually tessellated versions.
382  builder.DrawLine(DlPoint(145, 100), DlPoint(145, 450), line_paint);
383  builder.DrawLine(DlPoint(155, 100), DlPoint(155, 450), line_paint);
384  builder.DrawLine(DlPoint(345, 100), DlPoint(345, 450), line_paint);
385  builder.DrawLine(DlPoint(355, 100), DlPoint(355, 450), line_paint);
386  builder.DrawLine(DlPoint(100, 392.5f), DlPoint(400, 392.5f), line_paint);
387 
388  // Draw the two paths (direct and manually tessellated) on top of the lines.
389  builder.DrawPath(path_builder.TakePath(), paint);
390  builder.DrawPath(reference_builder.TakePath(), reference_paint);
391 
392  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
393 }

References x.

◆ TEST_P() [127/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureClamp   
)

Definition at line 256 of file aiks_dl_basic_unittests.cc.

256  {
257  CanRenderTiledTexture(this, DlTileMode::kClamp);
258 }

◆ TEST_P() [128/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureClampWithTranslate   
)

Definition at line 272 of file aiks_dl_basic_unittests.cc.

272  {
273  CanRenderTiledTexture(this, DlTileMode::kClamp,
274  Matrix::MakeTranslation({172.f, 172.f, 0.f}));
275 }

References impeller::Matrix::MakeTranslation().

◆ TEST_P() [129/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureDecal   
)

Definition at line 268 of file aiks_dl_basic_unittests.cc.

268  {
269  CanRenderTiledTexture(this, DlTileMode::kDecal);
270 }

◆ TEST_P() [130/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureMirror   
)

Definition at line 264 of file aiks_dl_basic_unittests.cc.

264  {
265  CanRenderTiledTexture(this, DlTileMode::kMirror);
266 }

◆ TEST_P() [131/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureRepeat   
)

Definition at line 260 of file aiks_dl_basic_unittests.cc.

260  {
261  CanRenderTiledTexture(this, DlTileMode::kRepeat);
262 }

◆ TEST_P() [132/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTinyOverlappingSubpasses   
)

This is a regression check for https://github.com/flutter/engine/pull/41129 The entire screen is green if successful. If failing, no frames will render, or the entire screen will be transparent black.

Definition at line 358 of file aiks_dl_unittests.cc.

358  {
359  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
360 
361  DlPaint paint;
362  paint.setColor(DlColor::kRed());
363  builder.DrawPaint(paint);
364 
365  // Draw two overlapping subpixel circles.
366  builder.SaveLayer(std::nullopt);
367 
368  DlPaint yellow_paint;
369  yellow_paint.setColor(DlColor::kYellow());
370  builder.DrawCircle(DlPoint(100, 100), 0.1, yellow_paint);
371  builder.Restore();
372  builder.SaveLayer(std::nullopt);
373  builder.DrawCircle(DlPoint(100, 100), 0.1, yellow_paint);
374  builder.Restore();
375 
376  DlPaint draw_paint;
377  draw_paint.setColor(DlColor::kGreen());
378  builder.DrawPaint(draw_paint);
379 
380  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
381 }

◆ TEST_P() [133/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderWideStrokedRectPathWithoutOverlap   
)

Definition at line 98 of file aiks_dl_basic_unittests.cc.

98  {
99  ASSERT_TRUE(OpenPlaygroundHere(MakeWideStrokedRects(
100  GetContentScale(), [](DisplayListBuilder& builder, const DlRect& rect,
101  const DlPaint& paint) {
102  // Draw the rect as a Path
103  builder.DrawPath(DlPath::MakeRect(rect), paint);
104  })));
105 }

◆ TEST_P() [134/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderWideStrokedRectWithoutOverlap   
)

Definition at line 89 of file aiks_dl_basic_unittests.cc.

89  {
90  ASSERT_TRUE(OpenPlaygroundHere(MakeWideStrokedRects(
91  GetContentScale(), [](DisplayListBuilder& builder, const DlRect& rect,
92  const DlPaint& paint) {
93  // Draw the rect directly
94  builder.DrawRect(rect, paint);
95  })));
96 }

◆ TEST_P() [135/549]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderWithContiguousClipRestores   
)

Definition at line 74 of file aiks_dl_clip_unittests.cc.

74  {
75  DisplayListBuilder builder;
76 
77  // Cover the whole canvas with red.
78  DlPaint paint;
79  paint.setColor(DlColor::kRed());
80  builder.DrawPaint(paint);
81 
82  builder.Save();
83 
84  // Append two clips, the second resulting in empty coverage.
85  builder.ClipRect(DlRect::MakeXYWH(100, 100, 100, 100));
86  builder.ClipRect(DlRect::MakeXYWH(300, 300, 100, 100));
87 
88  // Restore to no clips.
89  builder.Restore();
90 
91  // Replace the whole canvas with green.
92  paint.setColor(DlColor::kGreen());
93  builder.DrawPaint(paint);
94 
95  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
96 }

◆ TEST_P() [136/549]

impeller::testing::TEST_P ( AiksTest  ,
CanSaveLayerStandalone   
)

Definition at line 399 of file aiks_dl_basic_unittests.cc.

399  {
400  DisplayListBuilder builder;
401 
402  DlPaint red;
403  red.setColor(DlColor::kRed());
404 
405  DlPaint alpha;
406  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
407 
408  builder.SaveLayer(std::nullopt, &alpha);
409 
410  builder.DrawCircle(DlPoint(125, 125), 125, red);
411 
412  builder.Restore();
413 
414  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
415 }

◆ TEST_P() [137/549]

impeller::testing::TEST_P ( AiksTest  ,
CanvasCanPushPopCTM   
)

Definition at line 112 of file canvas_unittests.cc.

112  {
113  ContentContext context(GetContext(), nullptr);
114  auto canvas = CreateTestCanvas(context);
115 
116  ASSERT_EQ(canvas->GetSaveCount(), 1u);
117  ASSERT_EQ(canvas->Restore(), false);
118 
119  canvas->Translate(Size{100, 100});
120  canvas->Save(10);
121  ASSERT_EQ(canvas->GetSaveCount(), 2u);
122  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
123  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
124  ASSERT_TRUE(canvas->Restore());
125  ASSERT_EQ(canvas->GetSaveCount(), 1u);
126  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
127  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
128 }

References ASSERT_MATRIX_NEAR, CreateTestCanvas(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [138/549]

impeller::testing::TEST_P ( AiksTest  ,
CanvasCTMCanBeUpdated   
)

Definition at line 130 of file canvas_unittests.cc.

130  {
131  ContentContext context(GetContext(), nullptr);
132  auto canvas = CreateTestCanvas(context);
133 
134  Matrix identity;
135  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(), identity);
136  canvas->Translate(Size{100, 100});
137  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
138  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
139 }

References ASSERT_MATRIX_NEAR, CreateTestCanvas(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [139/549]

impeller::testing::TEST_P ( AiksTest  ,
ClearBlend   
)

Definition at line 485 of file aiks_dl_blend_unittests.cc.

485  {
486  DisplayListBuilder builder;
487 
488  DlPaint blue;
489  blue.setColor(DlColor::kBlue());
490  builder.DrawRect(DlRect::MakeXYWH(0, 0, 600.0, 600.0), blue);
491 
492  DlPaint clear;
493  clear.setBlendMode(DlBlendMode::kClear);
494 
495  builder.DrawCircle(DlPoint(300.0, 300.0), 200.0, clear);
496 
497  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
498 }

◆ TEST_P() [140/549]

impeller::testing::TEST_P ( AiksTest  ,
ClearBlendWithBlur   
)

Definition at line 423 of file aiks_dl_blur_unittests.cc.

423  {
424  DisplayListBuilder builder;
425  DlPaint paint;
426  paint.setColor(DlColor::kBlue());
427  builder.DrawRect(DlRect::MakeXYWH(0, 0, 600.0, 600.0), paint);
428 
429  DlPaint clear;
430  clear.setBlendMode(DlBlendMode::kClear);
431  clear.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
432 
433  builder.DrawCircle(DlPoint(300.0, 300.0), 200.0, clear);
434 
435  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
436 }

◆ TEST_P() [141/549]

impeller::testing::TEST_P ( AiksTest  ,
ClearColorOptimizationWhenSubpassIsBiggerThanParentPass   
)

Definition at line 1580 of file aiks_dl_basic_unittests.cc.

1580  {
1581  SetWindowSize({400, 400});
1582  DisplayListBuilder builder;
1583 
1584  builder.Scale(GetContentScale().x, GetContentScale().y);
1585 
1586  DlPaint paint;
1587  paint.setColor(DlColor::kRed());
1588  builder.DrawRect(DlRect::MakeLTRB(200, 200, 300, 300), paint);
1589 
1590  paint.setImageFilter(DlImageFilter::MakeMatrix(DlMatrix::MakeScale({2, 2, 1}),
1591  DlImageSampling::kLinear));
1592  builder.SaveLayer(std::nullopt, &paint);
1593  // Draw a rectangle that would fully cover the parent pass size, but not
1594  // the subpass that it is rendered in.
1595  paint.setColor(DlColor::kGreen());
1596  builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 400), paint);
1597  // Draw a bigger rectangle to force the subpass to be bigger.
1598 
1599  paint.setColor(DlColor::kRed());
1600  builder.DrawRect(DlRect::MakeLTRB(0, 0, 800, 800), paint);
1601  builder.Restore();
1602 
1603  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1604 }

References x.

◆ TEST_P() [142/549]

impeller::testing::TEST_P ( AiksTest  ,
ClippedBlurFilterRendersCorrectly   
)

Definition at line 406 of file aiks_dl_blur_unittests.cc.

406  {
407  DisplayListBuilder builder;
408  builder.Translate(0, -400);
409  DlPaint paint;
410 
411  Sigma sigma = Radius{120 * 3};
412  paint.setMaskFilter(
413  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma));
414  paint.setColor(DlColor::kRed());
415 
416  DlPath path = DlPath::MakeRect(DlRect::MakeLTRB(0, 0, 800, 800));
417  path = path + DlPath::MakeCircle(DlPoint(0, 0), 0.5);
418  builder.DrawPath(path, paint);
419 
420  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
421 }

References impeller::Sigma::sigma.

◆ TEST_P() [143/549]

impeller::testing::TEST_P ( AiksTest  ,
ClippedBlurFilterRendersCorrectlyInteractive   
)

Definition at line 382 of file aiks_dl_blur_unittests.cc.

382  {
383  auto callback = [&]() -> sk_sp<DisplayList> {
384  static PlaygroundPoint playground_point(Point(400, 400), 20,
385  Color::Green());
386  auto point = DrawPlaygroundPoint(playground_point);
387 
388  DisplayListBuilder builder;
389  auto location = point - Point(400, 400);
390  builder.Translate(location.x, location.y);
391 
392  DlPaint paint;
393  Sigma sigma = Radius{120 * 3};
394  paint.setMaskFilter(
395  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma));
396  paint.setColor(DlColor::kRed());
397 
398  DlPath path = DlPath::MakeRect(DlRect::MakeLTRB(0, 0, 800, 800));
399  path = path + DlPath::MakeCircle(DlPoint(0, 0), 0.5);
400  builder.DrawPath(path, paint);
401  return builder.Build();
402  };
403  ASSERT_TRUE(OpenPlaygroundHere(callback));
404 }
Point DrawPlaygroundPoint(PlaygroundPoint &point)
Definition: widgets.cc:11

References impeller::DrawPlaygroundPoint(), impeller::Color::Green(), and impeller::Sigma::sigma.

◆ TEST_P() [144/549]

impeller::testing::TEST_P ( AiksTest  ,
ClipsUseCurrentTransform   
)

Definition at line 98 of file aiks_dl_clip_unittests.cc.

98  {
99  std::array<DlColor, 5> colors = {DlColor::kWhite(), DlColor::kBlack(),
100  DlColor::kSkyBlue(), DlColor::kRed(),
101  DlColor::kYellow()};
102  DisplayListBuilder builder;
103  DlPaint paint;
104 
105  builder.Translate(300, 300);
106  for (int i = 0; i < 15; i++) {
107  builder.Scale(0.8, 0.8);
108 
109  paint.setColor(colors[i % colors.size()]);
110  builder.ClipPath(DlPath::MakeCircle(DlPoint(0, 0), 300));
111  builder.DrawRect(DlRect::MakeXYWH(-300, -300, 600, 600), paint);
112  }
113  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
114 }

◆ TEST_P() [145/549]

impeller::testing::TEST_P ( AiksTest  ,
CollapsedDrawPaintInSubpass   
)

Definition at line 41 of file aiks_dl_unittests.cc.

41  {
42  DisplayListBuilder builder;
43 
44  DlPaint paint;
45  paint.setColor(DlColor::kYellow());
46  paint.setBlendMode(DlBlendMode::kSrc);
47  builder.DrawPaint(paint);
48 
49  DlPaint save_paint;
50  save_paint.setBlendMode(DlBlendMode::kMultiply);
51  builder.SaveLayer(std::nullopt, &save_paint);
52 
53  DlPaint draw_paint;
54  draw_paint.setColor(DlColor::kCornflowerBlue().modulateOpacity(0.75f));
55  builder.DrawPaint(draw_paint);
56 
57  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
58 }

◆ TEST_P() [146/549]

impeller::testing::TEST_P ( AiksTest  ,
CollapsedDrawPaintInSubpassBackdropFilter   
)

Definition at line 60 of file aiks_dl_unittests.cc.

60  {
61  // Bug: https://github.com/flutter/flutter/issues/131576
62  DisplayListBuilder builder;
63 
64  DlPaint paint;
65  paint.setColor(DlColor::kYellow());
66  paint.setBlendMode(DlBlendMode::kSrc);
67  builder.DrawPaint(paint);
68 
69  auto filter = DlImageFilter::MakeBlur(20.0, 20.0, DlTileMode::kDecal);
70  builder.SaveLayer(std::nullopt, nullptr, filter.get());
71 
72  DlPaint draw_paint;
73  draw_paint.setColor(DlColor::kCornflowerBlue());
74  builder.DrawPaint(draw_paint);
75 
76  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
77 }

◆ TEST_P() [147/549]

impeller::testing::TEST_P ( AiksTest  ,
ColorFilterAdvancedBlend   
)

Definition at line 250 of file aiks_dl_blend_unittests.cc.

250  {
251  bool has_color_filter = true;
252  auto callback = [&]() -> sk_sp<DisplayList> {
253  if (AiksTest::ImGuiBegin("Controls", nullptr,
254  ImGuiWindowFlags_AlwaysAutoResize)) {
255  ImGui::Checkbox("has color filter", &has_color_filter);
256  ImGui::End();
257  }
258 
259  DisplayListBuilder builder;
260  builder.Scale(GetContentScale().x, GetContentScale().y);
261 
262  auto src_image =
263  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png"));
264  auto dst_image =
265  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png"));
266 
267  std::vector<DlBlendMode> blend_modes = {
268  DlBlendMode::kScreen, DlBlendMode::kOverlay,
269  DlBlendMode::kDarken, DlBlendMode::kLighten,
270  DlBlendMode::kColorDodge, DlBlendMode::kColorBurn,
271  DlBlendMode::kHardLight, DlBlendMode::kSoftLight,
272  DlBlendMode::kDifference, DlBlendMode::kExclusion,
273  DlBlendMode::kMultiply, DlBlendMode::kHue,
274  DlBlendMode::kSaturation, DlBlendMode::kColor,
275  DlBlendMode::kLuminosity,
276  };
277 
278  for (uint32_t i = 0; i < blend_modes.size(); ++i) {
279  builder.Save();
280  builder.Translate((i % 5) * 200, (i / 5) * 200);
281  builder.Scale(0.4, 0.4);
282  {
283  DlPaint dstPaint;
284  builder.DrawImage(dst_image, DlPoint(0, 0),
285  DlImageSampling::kMipmapLinear, &dstPaint);
286  }
287  {
288  DlPaint srcPaint;
289  srcPaint.setBlendMode(blend_modes[i]);
290  if (has_color_filter) {
291  std::shared_ptr<const DlColorFilter> color_filter =
292  DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
293  DlBlendMode::kSrcIn);
294  srcPaint.setColorFilter(color_filter);
295  }
296  builder.DrawImage(src_image, DlPoint(0, 0),
297  DlImageSampling::kMipmapLinear, &srcPaint);
298  }
299  builder.Restore();
300  }
301  return builder.Build();
302  };
303  ASSERT_TRUE(OpenPlaygroundHere(callback));
304 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [148/549]

impeller::testing::TEST_P ( AiksTest  ,
ColorFilterAdvancedBlendNoFbFetch   
)

Definition at line 309 of file aiks_dl_blend_unittests.cc.

309  {
310  if (GetParam() != PlaygroundBackend::kMetal) {
311  GTEST_SKIP()
312  << "This backend doesn't yet support setting device capabilities.";
313  }
314  if (!WillRenderSomething()) {
315  GTEST_SKIP() << "This test requires playgrounds.";
316  }
317 
318  std::shared_ptr<const Capabilities> old_capabilities =
319  GetContext()->GetCapabilities();
320  auto mock_capabilities = std::make_shared<MockCapabilities>();
321  EXPECT_CALL(*mock_capabilities, SupportsFramebufferFetch())
322  .Times(::testing::AtLeast(1))
323  .WillRepeatedly(::testing::Return(false));
324  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
325  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
326  FLT_FORWARD(mock_capabilities, old_capabilities,
327  GetDefaultDepthStencilFormat);
328  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
329  FLT_FORWARD(mock_capabilities, old_capabilities,
330  SupportsImplicitResolvingMSAA);
331  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
332  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
333  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
334  FLT_FORWARD(mock_capabilities, old_capabilities,
335  SupportsTextureToTextureBlits);
336  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
337  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsTriangleFan);
338  FLT_FORWARD(mock_capabilities, old_capabilities,
339  SupportsDecalSamplerAddressMode);
340  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsPrimitiveRestart);
341  FLT_FORWARD(mock_capabilities, old_capabilities, GetMinimumUniformAlignment);
342  ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
343 
344  bool has_color_filter = true;
345  auto callback = [&]() -> sk_sp<DisplayList> {
346  if (AiksTest::ImGuiBegin("Controls", nullptr,
347  ImGuiWindowFlags_AlwaysAutoResize)) {
348  ImGui::Checkbox("has color filter", &has_color_filter);
349  ImGui::End();
350  }
351 
352  DisplayListBuilder builder;
353  builder.Scale(GetContentScale().x, GetContentScale().y);
354 
355  auto src_image =
356  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png"));
357  auto dst_image =
358  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png"));
359 
360  std::vector<DlBlendMode> blend_modes = {
361  DlBlendMode::kScreen, DlBlendMode::kOverlay,
362  DlBlendMode::kDarken, DlBlendMode::kLighten,
363  DlBlendMode::kColorDodge, DlBlendMode::kColorBurn,
364  DlBlendMode::kHardLight, DlBlendMode::kSoftLight,
365  DlBlendMode::kDifference, DlBlendMode::kExclusion,
366  DlBlendMode::kMultiply, DlBlendMode::kHue,
367  DlBlendMode::kSaturation, DlBlendMode::kColor,
368  DlBlendMode::kLuminosity,
369  };
370 
371  for (uint32_t i = 0; i < blend_modes.size(); ++i) {
372  builder.Save();
373  builder.Translate((i % 5) * 200, (i / 5) * 200);
374  builder.Scale(0.4, 0.4);
375  {
376  DlPaint dstPaint;
377  builder.DrawImage(dst_image, DlPoint(0, 0),
378  DlImageSampling::kMipmapLinear, &dstPaint);
379  }
380  {
381  DlPaint srcPaint;
382  srcPaint.setBlendMode(blend_modes[i]);
383  if (has_color_filter) {
384  std::shared_ptr<const DlColorFilter> color_filter =
385  DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
386  DlBlendMode::kMultiply);
387  srcPaint.setColorFilter(color_filter);
388  }
389  builder.DrawImage(src_image, DlPoint(0, 0),
390  DlImageSampling::kMipmapLinear, &srcPaint);
391  }
392  builder.Restore();
393  }
394  return builder.Build();
395  };
396  ASSERT_TRUE(OpenPlaygroundHere(callback));
397 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::kMetal, impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [149/549]

impeller::testing::TEST_P ( AiksTest  ,
ColorFilterBlend   
)

Definition at line 198 of file aiks_dl_blend_unittests.cc.

198  {
199  bool has_color_filter = true;
200  auto callback = [&]() -> sk_sp<DisplayList> {
201  if (AiksTest::ImGuiBegin("Controls", nullptr,
202  ImGuiWindowFlags_AlwaysAutoResize)) {
203  ImGui::Checkbox("has color filter", &has_color_filter);
204  ImGui::End();
205  }
206 
207  DisplayListBuilder builder;
208  builder.Scale(GetContentScale().x, GetContentScale().y);
209 
210  auto src_image =
211  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png"));
212  auto dst_image =
213  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png"));
214 
215  std::vector<DlBlendMode> blend_modes = {
216  DlBlendMode::kSrc, DlBlendMode::kSrcATop, DlBlendMode::kSrcOver,
217  DlBlendMode::kSrcIn, DlBlendMode::kSrcOut, DlBlendMode::kDst,
218  DlBlendMode::kDstATop, DlBlendMode::kDstOver, DlBlendMode::kDstIn,
219  DlBlendMode::kDstOut, DlBlendMode::kClear, DlBlendMode::kXor};
220 
221  for (uint32_t i = 0; i < blend_modes.size(); ++i) {
222  builder.Save();
223  builder.Translate((i % 5) * 200, (i / 5) * 200);
224  builder.Scale(0.4, 0.4);
225  {
226  DlPaint dstPaint;
227  builder.DrawImage(dst_image, DlPoint(0, 0),
228  DlImageSampling::kMipmapLinear, &dstPaint);
229  }
230  {
231  DlPaint srcPaint;
232  srcPaint.setBlendMode(blend_modes[i]);
233  if (has_color_filter) {
234  std::shared_ptr<const DlColorFilter> color_filter =
235  DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
236  DlBlendMode::kSrcIn);
237  srcPaint.setColorFilter(color_filter);
238  }
239  builder.DrawImage(src_image, DlPoint(0, 0),
240  DlImageSampling::kMipmapLinear, &srcPaint);
241  }
242  builder.Restore();
243  }
244  return builder.Build();
245  };
246  ASSERT_TRUE(OpenPlaygroundHere(callback));
247 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [150/549]

impeller::testing::TEST_P ( AiksTest  ,
ColorMatrixFilterSubpassCollapseOptimization   
)

Definition at line 79 of file aiks_dl_unittests.cc.

79  {
80  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
81  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
82 
83  const float matrix[20] = {
84  -1.0, 0, 0, 1.0, 0, //
85  0, -1.0, 0, 1.0, 0, //
86  0, 0, -1.0, 1.0, 0, //
87  1.0, 1.0, 1.0, 1.0, 0 //
88  };
89  auto filter = DlColorFilter::MakeMatrix(matrix);
90 
91  DlPaint paint;
92  paint.setColorFilter(filter);
93  builder.SaveLayer(std::nullopt, &paint);
94 
95  builder.Translate(500, 300);
96  builder.Rotate(120); // 120 deg
97 
98  DlPaint draw_paint;
99  draw_paint.setColor(DlColor::kBlue());
100  builder.DrawRect(DlRect::MakeXYWH(100, 100, 200, 200), draw_paint);
101 
102  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
103 }

◆ TEST_P() [151/549]

impeller::testing::TEST_P ( AiksTest  ,
ColorWheel   
)

color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 -> cyan domain: r >= 0 (because modulo used is non euclidean)

Definition at line 773 of file aiks_dl_blend_unittests.cc.

773  {
774  // Compare with https://fiddle.skia.org/c/@BlendModes
775 
776  BlendModeSelection blend_modes = GetBlendModeSelection();
777 
778  auto draw_color_wheel = [](DisplayListBuilder& builder) -> void {
779  /// color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 ->
780  /// cyan domain: r >= 0 (because modulo used is non euclidean)
781  auto color_wheel_sampler = [](Radians r) {
782  Scalar x = r.radians / k2Pi + 1;
783 
784  // https://www.desmos.com/calculator/6nhjelyoaj
785  auto color_cycle = [](Scalar x) {
786  Scalar cycle = std::fmod(x, 6.0f);
787  return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
788  };
789  return Color(color_cycle(6 * x + 1), //
790  color_cycle(6 * x - 1), //
791  color_cycle(6 * x - 3), //
792  1);
793  };
794 
795  DlPaint paint;
796  paint.setBlendMode(DlBlendMode::kSrcOver);
797 
798  // Draw a fancy color wheel for the backdrop.
799  // https://www.desmos.com/calculator/xw7kafthwd
800  const int max_dist = 900;
801  for (int i = 0; i <= 900; i++) {
802  Radians r(kPhi / k2Pi * i);
803  Scalar distance = r.radians / std::powf(4.12, 0.0026 * r.radians);
804  Scalar normalized_distance = static_cast<Scalar>(i) / max_dist;
805 
806  auto color = color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
807  paint.setColor(
808  DlColor::RGBA(color.red, color.green, color.blue, color.alpha));
809  DlPoint position = DlPoint(distance * std::sin(r.radians),
810  -distance * std::cos(r.radians));
811 
812  builder.DrawCircle(position, 9 + normalized_distance * 3, paint);
813  }
814  };
815 
816  auto callback = [&]() -> sk_sp<DisplayList> {
817  // UI state.
818  static bool cache_the_wheel = true;
819  static int current_blend_index = 3;
820  static float dst_alpha = 1;
821  static float src_alpha = 1;
822  static DlColor color0 = DlColor::kRed();
823  static DlColor color1 = DlColor::kGreen();
824  static DlColor color2 = DlColor::kBlue();
825 
826  if (AiksTest::ImGuiBegin("Controls", nullptr,
827  ImGuiWindowFlags_AlwaysAutoResize)) {
828  ImGui::Checkbox("Cache the wheel", &cache_the_wheel);
829  ImGui::ListBox("Blending mode", &current_blend_index,
830  blend_modes.blend_mode_names.data(),
831  blend_modes.blend_mode_names.size());
832  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
833  ImGui::ColorEdit4("Color A", reinterpret_cast<float*>(&color0));
834  ImGui::ColorEdit4("Color B", reinterpret_cast<float*>(&color1));
835  ImGui::ColorEdit4("Color C", reinterpret_cast<float*>(&color2));
836  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
837  ImGui::End();
838  }
839 
840  DisplayListBuilder builder;
841 
842  DlPaint paint;
843  paint.setColor(DlColor::kWhite().withAlpha(dst_alpha * 255));
844  paint.setBlendMode(DlBlendMode::kSrc);
845  builder.SaveLayer(std::nullopt, &paint);
846  {
847  DlPaint paint;
848  paint.setColor(DlColor::kWhite());
849  builder.DrawPaint(paint);
850 
851  builder.SaveLayer(std::nullopt, nullptr);
852  builder.Scale(GetContentScale().x, GetContentScale().y);
853  builder.Translate(500, 400);
854  builder.Scale(3, 3);
855  draw_color_wheel(builder);
856  builder.Restore();
857  }
858  builder.Restore();
859 
860  builder.Scale(GetContentScale().x, GetContentScale().y);
861  builder.Translate(500, 400);
862  builder.Scale(3, 3);
863 
864  // Draw 3 circles to a subpass and blend it in.
865  DlPaint save_paint;
866  save_paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
867  save_paint.setBlendMode(static_cast<DlBlendMode>(
868  blend_modes.blend_mode_values[current_blend_index]));
869  builder.SaveLayer(std::nullopt, &save_paint);
870  {
871  DlPaint paint;
872  paint.setBlendMode(DlBlendMode::kPlus);
873  const Scalar x = std::sin(k2Pi / 3);
874  const Scalar y = -std::cos(k2Pi / 3);
875  paint.setColor(color0);
876  builder.DrawCircle(DlPoint(-x * 45, y * 45), 65, paint);
877  paint.setColor(color1);
878  builder.DrawCircle(DlPoint(0, -45), 65, paint);
879  paint.setColor(color2);
880  builder.DrawCircle(DlPoint(x * 45, y * 45), 65, paint);
881  }
882  builder.Restore();
883 
884  return builder.Build();
885  };
886 
887  ASSERT_TRUE(OpenPlaygroundHere(callback));
888 }
constexpr float kPhi
Definition: constants.h:54

References impeller::testing::BlendModeSelection::blend_mode_names, impeller::testing::BlendModeSelection::blend_mode_values, impeller::saturated::distance, GetBlendModeSelection(), impeller::AiksPlayground::ImGuiBegin(), impeller::k2Pi, impeller::kPhi, impeller::Radians::radians, and x.

◆ TEST_P() [152/549]

impeller::testing::TEST_P ( AiksTest  ,
CoordinateConversionsAreCorrect   
)

Definition at line 1678 of file aiks_dl_basic_unittests.cc.

1678  {
1679  DisplayListBuilder builder;
1680 
1681  // Render a texture directly.
1682  {
1683  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
1684 
1685  builder.Save();
1686  builder.Translate(100, 200);
1687  builder.Scale(0.5, 0.5);
1688  builder.DrawImage(image, DlPoint(100.0, 100.0),
1689  DlImageSampling::kNearestNeighbor);
1690  builder.Restore();
1691  }
1692 
1693  // Render an offscreen rendered texture.
1694  {
1695  DlPaint alpha;
1696  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
1697 
1698  builder.SaveLayer(std::nullopt, &alpha);
1699 
1700  DlPaint paint;
1701  paint.setColor(DlColor::kRed());
1702  builder.DrawRect(DlRect::MakeXYWH(000, 000, 100, 100), paint);
1703  paint.setColor(DlColor::kGreen());
1704  builder.DrawRect(DlRect::MakeXYWH(020, 020, 100, 100), paint);
1705  paint.setColor(DlColor::kBlue());
1706  builder.DrawRect(DlRect::MakeXYWH(040, 040, 100, 100), paint);
1707 
1708  builder.Restore();
1709  }
1710 
1711  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1712 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [153/549]

impeller::testing::TEST_P ( AiksTest  ,
CoverageOriginShouldBeAccountedForInSubpasses   
)

Definition at line 1859 of file aiks_dl_basic_unittests.cc.

1859  {
1860  auto callback = [&]() -> sk_sp<DisplayList> {
1861  DisplayListBuilder builder;
1862  builder.Scale(GetContentScale().x, GetContentScale().y);
1863 
1864  DlPaint alpha;
1865  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
1866 
1867  auto current = Point{25, 25};
1868  const auto offset = Point{25, 25};
1869  const auto size = Size(100, 100);
1870 
1871  static PlaygroundPoint point_a(Point(40, 40), 10, Color::White());
1872  static PlaygroundPoint point_b(Point(160, 160), 10, Color::White());
1873  auto [b0, b1] = DrawPlaygroundLine(point_a, point_b);
1874  DlRect bounds = DlRect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
1875 
1876  DlPaint stroke_paint;
1877  stroke_paint.setColor(DlColor::kYellow());
1878  stroke_paint.setStrokeWidth(5);
1879  stroke_paint.setDrawStyle(DlDrawStyle::kStroke);
1880  builder.DrawRect(bounds, stroke_paint);
1881 
1882  builder.SaveLayer(bounds, &alpha);
1883 
1884  DlPaint paint;
1885  paint.setColor(DlColor::kRed());
1886  builder.DrawRect(
1887  DlRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1888 
1889  paint.setColor(DlColor::kGreen());
1890  current += offset;
1891  builder.DrawRect(
1892  DlRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1893 
1894  paint.setColor(DlColor::kBlue());
1895  current += offset;
1896  builder.DrawRect(
1897  DlRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1898 
1899  builder.Restore();
1900 
1901  return builder.Build();
1902  };
1903 
1904  ASSERT_TRUE(OpenPlaygroundHere(callback));
1905 }

References impeller::DrawPlaygroundLine(), and impeller::Color::White().

◆ TEST_P() [154/549]

impeller::testing::TEST_P ( AiksTest  ,
DepthValuesForLineMode   
)

Definition at line 984 of file aiks_dl_unittests.cc.

984  {
985  // Ensures that the additional draws created by line/polygon mode all
986  // have the same depth values.
987  DisplayListBuilder builder;
988 
989  DlPath path = DlPath::MakeCircle(DlPoint(100, 100), 100);
990 
991  builder.DrawPath(path, DlPaint()
992  .setColor(DlColor::kRed())
993  .setDrawStyle(DlDrawStyle::kStroke)
994  .setStrokeWidth(5));
995  builder.Save();
996  builder.ClipPath(path);
997 
998  std::vector<DlPoint> points = {
999  DlPoint::MakeXY(0, -200), DlPoint::MakeXY(400, 200),
1000  DlPoint::MakeXY(0, -100), DlPoint::MakeXY(400, 300),
1001  DlPoint::MakeXY(0, 0), DlPoint::MakeXY(400, 400),
1002  DlPoint::MakeXY(0, 100), DlPoint::MakeXY(400, 500),
1003  DlPoint::MakeXY(0, 150), DlPoint::MakeXY(400, 600)};
1004 
1005  builder.DrawPoints(DlPointMode::kLines, points.size(), points.data(),
1006  DlPaint().setColor(DlColor::kBlue()).setStrokeWidth(10));
1007  builder.Restore();
1008 
1009  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1010 }

References points.

◆ TEST_P() [155/549]

impeller::testing::TEST_P ( AiksTest  ,
DepthValuesForPolygonMode   
)

Definition at line 1012 of file aiks_dl_unittests.cc.

1012  {
1013  // Ensures that the additional draws created by line/polygon mode all
1014  // have the same depth values.
1015  DisplayListBuilder builder;
1016 
1017  DlPath path = DlPath::MakeCircle(DlPoint(100, 100), 100);
1018 
1019  builder.DrawPath(path, DlPaint()
1020  .setColor(DlColor::kRed())
1021  .setDrawStyle(DlDrawStyle::kStroke)
1022  .setStrokeWidth(5));
1023  builder.Save();
1024  builder.ClipPath(path);
1025 
1026  std::vector<DlPoint> points = {
1027  DlPoint::MakeXY(0, -200), DlPoint::MakeXY(400, 200),
1028  DlPoint::MakeXY(0, -100), DlPoint::MakeXY(400, 300),
1029  DlPoint::MakeXY(0, 0), DlPoint::MakeXY(400, 400),
1030  DlPoint::MakeXY(0, 100), DlPoint::MakeXY(400, 500),
1031  DlPoint::MakeXY(0, 150), DlPoint::MakeXY(400, 600)};
1032 
1033  builder.DrawPoints(DlPointMode::kPolygon, points.size(), points.data(),
1034  DlPaint().setColor(DlColor::kBlue()).setStrokeWidth(10));
1035  builder.Restore();
1036 
1037  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1038 }

References points.

◆ TEST_P() [156/549]

impeller::testing::TEST_P ( AiksTest  ,
DestructiveBlendColorFilterFloodsClip   
)

Definition at line 890 of file aiks_dl_blend_unittests.cc.

890  {
891  DisplayListBuilder builder;
892 
893  DlPaint paint;
894  paint.setColor(DlColor::kBlue());
895  builder.DrawPaint(paint);
896 
897  DlPaint save_paint;
898  save_paint.setColorFilter(
899  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kSrc));
900  builder.SaveLayer(std::nullopt, &save_paint);
901  builder.Restore();
902 
903  // Should be solid red as the destructive color filter floods the clip.
904  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
905 }

◆ TEST_P() [157/549]

impeller::testing::TEST_P ( AiksTest  ,
DifferenceClipsMustRenderIdenticallyAcrossBackends   
)

Definition at line 632 of file aiks_dl_text_unittests.cc.

632  {
633  DisplayListBuilder builder;
634 
635  DlPaint paint;
636  DlColor clear_color(1.0, 0.5, 0.5, 0.5, DlColorSpace::kSRGB);
637  paint.setColor(clear_color);
638  builder.DrawPaint(paint);
639 
640  DlMatrix identity = {
641  1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
642  0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
643  };
644  builder.Save();
645  builder.Transform(identity);
646 
647  DlRect frame = DlRect::MakeLTRB(1.0, 1.0, 1278.0, 763.0);
648  DlColor white(1.0, 1.0, 1.0, 1.0, DlColorSpace::kSRGB);
649  paint.setColor(white);
650  builder.DrawRect(frame, paint);
651 
652  builder.Save();
653  builder.ClipRect(frame, DlClipOp::kIntersect);
654 
655  DlMatrix rect_xform = {
656  0.8241262, 0.56640625, 0.0, 0.0, -0.56640625, 0.8241262, 0.0, 0.0,
657  0.0, 0.0, 1.0, 0.0, 271.1137, 489.4733, 0.0, 1.0,
658  };
659  builder.Save();
660  builder.Transform(rect_xform);
661 
662  DlRect rect = DlRect::MakeLTRB(0.0, 0.0, 100.0, 100.0);
663  DlColor bluish(1.0, 0.184, 0.501, 0.929, DlColorSpace::kSRGB);
664  paint.setColor(bluish);
665  DlRoundRect rrect = DlRoundRect::MakeRectRadius(rect, 18.0);
666  builder.DrawRoundRect(rrect, paint);
667 
668  builder.Save();
669  builder.ClipRect(rect, DlClipOp::kIntersect);
670  builder.Restore();
671 
672  builder.Restore();
673 
674  DlMatrix path_xform = {
675  1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
676  0.0, 0.0, 1.0, 0.0, 675.0, 279.5, 0.0, 1.0,
677  };
678  builder.Save();
679  builder.Transform(path_xform);
680 
681  DlPathBuilder path_builder;
682  path_builder.MoveTo(DlPoint(87.5, 349.5));
683  path_builder.LineTo(DlPoint(25.0, 29.5));
684  path_builder.LineTo(DlPoint(150.0, 118.0));
685  path_builder.LineTo(DlPoint(25.0, 118.0));
686  path_builder.LineTo(DlPoint(150.0, 29.5));
687  path_builder.Close();
688  DlPath path = path_builder.TakePath();
689 
690  DlColor fill_color(1.0, 1.0, 0.0, 0.0, DlColorSpace::kSRGB);
691  DlColor stroke_color(1.0, 0.0, 0.0, 0.0, DlColorSpace::kSRGB);
692  paint.setColor(fill_color);
693  paint.setDrawStyle(DlDrawStyle::kFill);
694  builder.DrawPath(path, paint);
695 
696  paint.setColor(stroke_color);
697  paint.setStrokeWidth(2.0);
698  paint.setDrawStyle(DlDrawStyle::kStroke);
699  builder.DrawPath(path, paint);
700 
701  builder.Restore();
702  builder.Restore();
703  builder.Restore();
704 
705  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
706 }

◆ TEST_P() [158/549]

impeller::testing::TEST_P ( AiksTest  ,
DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists   
)

Definition at line 871 of file aiks_dl_unittests.cc.

871  {
872  flutter::DisplayListBuilder sub_builder(true);
873  sub_builder.DrawRect(DlRect::MakeXYWH(0, 0, 50, 50),
874  flutter::DlPaint(flutter::DlColor::kRed()));
875  auto display_list = sub_builder.Build();
876 
877  AiksContext context(GetContext(), nullptr);
878  RenderTarget render_target =
879  context.GetContentContext().GetRenderTargetCache()->CreateOffscreen(
880  *context.GetContext(), {2400, 1800}, 1);
881 
882  DisplayListBuilder builder;
883 
884  builder.Scale(2.0, 2.0);
885  builder.Translate(-93.0, 0.0);
886 
887  // clang-format off
888  builder.TransformFullPerspective(
889  0.8, -0.2, -0.1, -0.0,
890  0.0, 1.0, 0.0, 0.0,
891  1.4, 1.3, 1.0, 0.0,
892  63.2, 65.3, 48.6, 1.1
893  );
894  // clang-format on
895  builder.Translate(35.0, 75.0);
896  builder.DrawDisplayList(display_list, 1.0f);
897 
898  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
899 }

References impeller::AiksContext::GetContentContext(), impeller::AiksContext::GetContext(), and impeller::ContentContext::GetRenderTargetCache().

◆ TEST_P() [159/549]

impeller::testing::TEST_P ( AiksTest  ,
DisplayListToTextureAllocationFailure   
)

Definition at line 1112 of file aiks_dl_unittests.cc.

1112  {
1113  ScopedValidationDisable disable_validations;
1114  DisplayListBuilder builder;
1115 
1116  AiksContext aiks_context(GetContext(), nullptr);
1117  // Use intentionally invalid dimensions that would trigger an allocation
1118  // failure.
1119  auto texture =
1120  DisplayListToTexture(builder.Build(), ISize{0, 0}, aiks_context);
1121 
1122  EXPECT_EQ(texture, nullptr);
1123 }

References impeller::DisplayListToTexture().

◆ TEST_P() [160/549]

impeller::testing::TEST_P ( AiksTest  ,
DisplayListToTextureWithMipGeneration   
)

Definition at line 1125 of file aiks_dl_unittests.cc.

1125  {
1126  DisplayListBuilder builder;
1127 
1128  std::shared_ptr<DlImageFilter> filter =
1129  DlImageFilter::MakeBlur(8, 8, DlTileMode::kClamp);
1130  builder.SaveLayer(std::nullopt, nullptr, filter.get());
1131  builder.Restore();
1132 
1133  AiksContext aiks_context(GetContext(), nullptr);
1134  // Use intentionally invalid dimensions that would trigger an allocation
1135  // failure.
1136  auto texture =
1137  DisplayListToTexture(builder.Build(), ISize{10, 10}, aiks_context,
1138  /*reset_host_buffer=*/true, /*generate_mips=*/true);
1139 
1140  EXPECT_FALSE(texture->NeedsMipmapGeneration());
1141 }

References impeller::DisplayListToTexture().

◆ TEST_P() [161/549]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometryBlend   
)

Definition at line 200 of file aiks_dl_atlas_unittests.cc.

200  {
201  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
202 
203  std::vector<DlColor> colors;
204  colors.reserve(texture_coordinates.size());
205  for (auto i = 0u; i < texture_coordinates.size(); i++) {
206  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
207  }
208  DlAtlasGeometry geom(
209  atlas->impeller_texture(), transforms.data(), texture_coordinates.data(),
210  colors.data(), transforms.size(), BlendMode::kSrcOver, {}, std::nullopt);
211 
212  EXPECT_TRUE(geom.ShouldUseBlend());
213  EXPECT_FALSE(geom.ShouldSkip());
214 
215  ContentContext context(GetContext(), nullptr);
216  auto vertex_buffer =
217  geom.CreateBlendVertexBuffer(context.GetTransientsDataBuffer());
218 
219  EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
220  EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
221 }

References impeller::DlAtlasGeometry::CreateBlendVertexBuffer(), impeller::ContentContext::GetTransientsDataBuffer(), impeller::kNone, impeller::kSrcOver, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [162/549]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometryColorButNoBlend   
)

Definition at line 223 of file aiks_dl_atlas_unittests.cc.

223  {
224  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
225 
226  std::vector<DlColor> colors;
227  colors.reserve(texture_coordinates.size());
228  for (auto i = 0u; i < texture_coordinates.size(); i++) {
229  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
230  }
231  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
232  texture_coordinates.data(), colors.data(),
233  transforms.size(), BlendMode::kSrc, {}, std::nullopt);
234 
235  // Src blend mode means that colors would be ignored, even if provided.
236  EXPECT_FALSE(geom.ShouldUseBlend());
237  EXPECT_FALSE(geom.ShouldSkip());
238 }

References impeller::kSrc, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [163/549]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometryNoBlendRenamed   
)

Definition at line 182 of file aiks_dl_atlas_unittests.cc.

182  {
183  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
184 
185  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
186  texture_coordinates.data(), nullptr, transforms.size(),
187  BlendMode::kSrcOver, {}, std::nullopt);
188 
189  EXPECT_FALSE(geom.ShouldUseBlend());
190  EXPECT_FALSE(geom.ShouldSkip());
191 
192  ContentContext context(GetContext(), nullptr);
193  auto vertex_buffer =
194  geom.CreateSimpleVertexBuffer(context.GetTransientsDataBuffer());
195 
196  EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
197  EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
198 }

References impeller::DlAtlasGeometry::CreateSimpleVertexBuffer(), impeller::ContentContext::GetTransientsDataBuffer(), impeller::kNone, impeller::kSrcOver, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [164/549]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometrySkip   
)

Definition at line 240 of file aiks_dl_atlas_unittests.cc.

240  {
241  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
242 
243  std::vector<DlColor> colors;
244  colors.reserve(texture_coordinates.size());
245  for (auto i = 0u; i < texture_coordinates.size(); i++) {
246  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
247  }
248  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
249  texture_coordinates.data(), colors.data(),
250  transforms.size(), BlendMode::kClear, {}, std::nullopt);
251  EXPECT_TRUE(geom.ShouldSkip());
252 }

References impeller::kClear, and impeller::DlAtlasGeometry::ShouldSkip().

◆ TEST_P() [165/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawAdvancedBlendPartlyOffscreen   
)

Definition at line 142 of file aiks_dl_blend_unittests.cc.

142  {
143  DisplayListBuilder builder;
144 
145  DlPaint draw_paint;
146  draw_paint.setColor(DlColor::kBlue());
147  builder.DrawPaint(draw_paint);
148  builder.Scale(2, 2);
149  builder.ClipRect(DlRect::MakeLTRB(0, 0, 200, 200));
150 
151  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
152  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
153  std::vector<Scalar> stops = {0.0, 1.0};
154 
155  DlPaint paint;
156  DlMatrix matrix = DlMatrix::MakeScale({0.3, 0.3, 1.0});
157  paint.setColorSource(DlColorSource::MakeLinear(
158  /*start_point=*/{0, 0}, //
159  /*end_point=*/{100, 100}, //
160  /*stop_count=*/colors.size(), //
161  /*colors=*/colors.data(), //
162  /*stops=*/stops.data(), //
163  /*tile_mode=*/DlTileMode::kRepeat, //
164  /*matrix=*/&matrix //
165  ));
166  paint.setBlendMode(DlBlendMode::kLighten);
167 
168  builder.DrawCircle(DlPoint(100, 100), 100, paint);
169  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
170 }

◆ TEST_P() [166/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasAdvancedAndTransform   
)

Definition at line 136 of file aiks_dl_atlas_unittests.cc.

136  {
137  DisplayListBuilder builder;
138  // Draws the image as four squares stiched together.
139  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
140 
141  builder.Scale(0.25, 0.25);
142  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
143  /*colors=*/nullptr, /*count=*/4, DlBlendMode::kModulate,
144  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
145 
146  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
147 }

◆ TEST_P() [167/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasNoColor   
)

Definition at line 59 of file aiks_dl_atlas_unittests.cc.

59  {
60  DisplayListBuilder builder;
61  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
62 
63  builder.Scale(GetContentScale().x, GetContentScale().y);
64  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
65  /*colors=*/nullptr, /*count=*/4, DlBlendMode::kSrcOver,
66  DlImageSampling::kNearestNeighbor, nullptr);
67 
68  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
69 }

References x.

◆ TEST_P() [168/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasNoColorFullSize   
)

Definition at line 119 of file aiks_dl_atlas_unittests.cc.

119  {
120  auto atlas = DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
121  auto size = atlas->impeller_texture()->GetSize();
122  std::vector<DlRect> texture_coordinates = {
123  DlRect::MakeLTRB(0, 0, size.width, size.height)};
124  std::vector<RSTransform> transforms = {MakeTranslation(0, 0)};
125 
126  DisplayListBuilder builder;
127  builder.Scale(GetContentScale().x, GetContentScale().y);
128  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
129  /*colors=*/nullptr, /*count=*/1, DlBlendMode::kSrcOver,
130  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
131 
132  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
133 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [169/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasPlusWideGamut   
)

Definition at line 165 of file aiks_dl_atlas_unittests.cc.

165  {
166  DisplayListBuilder builder;
167  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
168  PixelFormat::kB10G10R10A10XR);
169 
170  // Draws the image as four squares stiched together.
171  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
172  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
173  DlColor::kBlue(), DlColor::kYellow()};
174 
175  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
176  colors.data(), /*count=*/4, DlBlendMode::kPlus,
177  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
178 
179  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
180 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [170/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorAdvanced   
)

Definition at line 71 of file aiks_dl_atlas_unittests.cc.

71  {
72  DisplayListBuilder builder;
73  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
74 
75  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
76  DlColor::kBlue(), DlColor::kYellow()};
77 
78  builder.Scale(GetContentScale().x, GetContentScale().y);
79  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
80  colors.data(), /*count=*/4, DlBlendMode::kModulate,
81  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
82 
83  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
84 }

References x.

◆ TEST_P() [171/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorAdvancedAndTransform   
)

Definition at line 150 of file aiks_dl_atlas_unittests.cc.

150  {
151  DisplayListBuilder builder;
152  // Draws the image as four squares stiched together.
153  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
154  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
155  DlColor::kBlue(), DlColor::kYellow()};
156 
157  builder.Scale(0.25, 0.25);
158  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
159  colors.data(), /*count=*/4, DlBlendMode::kModulate,
160  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
161 
162  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
163 }

◆ TEST_P() [172/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorBurn   
)

Definition at line 319 of file aiks_dl_atlas_unittests.cc.

319  {
320  DisplayListBuilder builder;
321  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
322 
323  std::vector<DlColor> colors = {DlColor::kDarkGrey(), DlColor::kBlack(),
324  DlColor::kLightGrey(), DlColor::kWhite()};
325 
326  builder.Scale(GetContentScale().x, GetContentScale().y);
327  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
328  colors.data(), /*count=*/4, DlBlendMode::kColorBurn,
329  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
330 
331  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
332 }

References x.

◆ TEST_P() [173/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorSimple   
)

Definition at line 86 of file aiks_dl_atlas_unittests.cc.

86  {
87  DisplayListBuilder builder;
88  // Draws the image as four squares stiched together.
89  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
90 
91  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
92  DlColor::kBlue(), DlColor::kYellow()};
93 
94  builder.Scale(GetContentScale().x, GetContentScale().y);
95  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
96  colors.data(), /*count=*/4, DlBlendMode::kSrcATop,
97  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
98 
99  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
100 }

References x.

◆ TEST_P() [174/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithOpacity   
)

Definition at line 102 of file aiks_dl_atlas_unittests.cc.

102  {
103  DisplayListBuilder builder;
104  // Draws the image as four squares stiched together slightly
105  // opaque
106  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
107 
108  DlPaint paint;
109  paint.setAlpha(128);
110  builder.Scale(GetContentScale().x, GetContentScale().y);
111  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
112  /*colors=*/nullptr, 4, DlBlendMode::kSrcOver,
113  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr,
114  &paint);
115 
116  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
117 }

References x.

◆ TEST_P() [175/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawImageRectSrcOutsideBounds   
)

Definition at line 295 of file aiks_dl_basic_unittests.cc.

295  {
296  DisplayListBuilder builder;
297  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
298 
299  // Use a source rect that is partially outside the bounds of the image.
300  auto source_rect = DlRect::MakeXYWH(
301  image->GetSize().width * 0.25f, image->GetSize().height * 0.4f,
302  image->GetSize().width, image->GetSize().height);
303 
304  auto dest_rect = DlRect::MakeXYWH(100, 100, 600, 600);
305 
306  DlPaint paint;
307  paint.setColor(DlColor::kMidGrey());
308  builder.DrawRect(dest_rect, paint);
309 
310  builder.DrawImageRect(image, source_rect, dest_rect,
311  DlImageSampling::kNearestNeighbor);
312  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
313 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [176/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawImageRectWithBlendColorFilter   
)

Definition at line 254 of file aiks_dl_atlas_unittests.cc.

254  {
255  sk_sp<DlImageImpeller> texture =
256  DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
257 
258  DisplayListBuilder builder;
259  DlPaint paint = DlPaint().setColorFilter(DlColorFilter::MakeBlend(
260  DlColor::kRed().withAlphaF(0.4), DlBlendMode::kSrcOver));
261 
262  DlMatrix filter_matrix = DlMatrix();
263  auto filter = flutter::DlMatrixImageFilter(filter_matrix,
264  flutter::DlImageSampling::kLinear);
265  DlPaint paint_with_filter = paint;
266  paint_with_filter.setImageFilter(&filter);
267 
268  // Compare porter-duff blend modes.
269  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
270  // Uses image filter to disable atlas conversion.
271  builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
272  DlRect::MakeLTRB(0, 0, 500, 500), {},
273  &paint_with_filter);
274 
275  // Uses atlas conversion.
276  builder.Translate(600, 0);
277  builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
278  DlRect::MakeLTRB(0, 0, 500, 500), {}, &paint);
279 
280  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
281 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [177/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawImageRectWithMatrixColorFilter   
)

Definition at line 283 of file aiks_dl_atlas_unittests.cc.

283  {
284  sk_sp<DlImageImpeller> texture =
285  DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
286 
287  DisplayListBuilder builder;
288  static const constexpr ColorMatrix kColorInversion = {
289  .array = {
290  -1.0, 0, 0, 1.0, 0, //
291  0, -1.0, 0, 1.0, 0, //
292  0, 0, -1.0, 1.0, 0, //
293  1.0, 1.0, 1.0, 1.0, 0 //
294  }};
295  DlPaint paint = DlPaint().setColorFilter(
296  DlColorFilter::MakeMatrix(kColorInversion.array));
297 
298  DlMatrix filter_matrix = DlMatrix();
299  auto filter = flutter::DlMatrixImageFilter(filter_matrix,
300  flutter::DlImageSampling::kLinear);
301  DlPaint paint_with_filter = paint;
302  paint_with_filter.setImageFilter(&filter);
303 
304  // Compare inverting color matrix filter.
305  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
306  // Uses image filter to disable atlas conversion.
307  builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
308  DlRect::MakeLTRB(0, 0, 500, 500), {},
309  &paint_with_filter);
310 
311  // Uses atlas conversion.
312  builder.Translate(600, 0);
313  builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
314  DlRect::MakeLTRB(0, 0, 500, 500), {}, &paint);
315 
316  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
317 }
static constexpr const ColorMatrix kColorInversion
A color matrix which inverts colors.
Definition: color_filter.h:16
Scalar array[20]
Definition: color.h:118

References impeller::ColorMatrix::array, impeller::kColorInversion, and impeller::DlImageImpeller::Make().

◆ TEST_P() [178/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawLinesRenderCorrectly   
)

Definition at line 553 of file aiks_dl_path_unittests.cc.

553  {
554  DisplayListBuilder builder;
555  builder.Scale(GetContentScale().x, GetContentScale().y);
556 
557  DlPaint paint;
558  paint.setColor(DlColor::kBlue());
559  paint.setStrokeWidth(10);
560 
561  auto draw = [&builder](DlPaint& paint) {
562  for (auto cap :
563  {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
564  paint.setStrokeCap(cap);
565  DlPoint origin = {100, 100};
566  builder.DrawLine(DlPoint(150, 100), DlPoint(250, 100), paint);
567  for (int d = 15; d < 90; d += 15) {
568  Matrix m = Matrix::MakeRotationZ(Degrees(d));
569  Point origin = {100, 100};
570  Point p0 = {50, 0};
571  Point p1 = {150, 0};
572  auto a = origin + m * p0;
573  auto b = origin + m * p1;
574 
575  builder.DrawLine(a, b, paint);
576  }
577  builder.DrawLine(DlPoint(100, 150), DlPoint(100, 250), paint);
578  builder.DrawCircle(origin, 35, paint);
579 
580  builder.DrawLine(DlPoint(250, 250), DlPoint(250, 250), paint);
581 
582  builder.Translate(250, 0);
583  }
584  builder.Translate(-750, 250);
585  };
586 
587  std::vector<DlColor> colors = {
588  DlColor::ARGB(1, 0x1f / 255.0, 0.0, 0x5c / 255.0),
589  DlColor::ARGB(1, 0x5b / 255.0, 0.0, 0x60 / 255.0),
590  DlColor::ARGB(1, 0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0),
591  DlColor::ARGB(1, 0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0),
592  DlColor::ARGB(1, 0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0),
593  DlColor::ARGB(1, 0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0),
594  DlColor::ARGB(1, 0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0)};
595  std::vector<Scalar> stops = {
596  0.0,
597  (1.0 / 6.0) * 1,
598  (1.0 / 6.0) * 2,
599  (1.0 / 6.0) * 3,
600  (1.0 / 6.0) * 4,
601  (1.0 / 6.0) * 5,
602  1.0,
603  };
604 
605  auto texture = DlImageImpeller::Make(
606  CreateTextureForFixture("airplane.jpg",
607  /*enable_mipmapping=*/true));
608 
609  draw(paint);
610 
611  paint.setColorSource(DlColorSource::MakeRadial({100, 100}, 200, stops.size(),
612  colors.data(), stops.data(),
613  DlTileMode::kMirror));
614  draw(paint);
615 
616  DlMatrix matrix = DlMatrix::MakeTranslation({-150, 75});
617  paint.setColorSource(DlColorSource::MakeImage(
618  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
619  DlImageSampling::kMipmapLinear, &matrix));
620  draw(paint);
621 
622  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
623 }

References impeller::saturated::b, impeller::DlImageImpeller::Make(), impeller::Matrix::MakeRotationZ(), and x.

◆ TEST_P() [179/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawOpacityPeephole   
)

Definition at line 18 of file aiks_dl_opacity_unittests.cc.

18  {
19  DisplayListBuilder builder;
20 
21  DlPaint green;
22  green.setColor(DlColor::kGreen().modulateOpacity(0.5));
23 
24  DlPaint alpha;
25  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
26 
27  builder.SaveLayer(std::nullopt, &alpha);
28  builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), green);
29  builder.Restore();
30 
31  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
32 }

◆ TEST_P() [180/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintTransformsBounds   
)

Definition at line 64 of file aiks_dl_runtime_effect_unittests.cc.

64  {
65  struct FragUniforms {
66  Size size;
67  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
68  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
69  uniform_data->resize(sizeof(FragUniforms));
70  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
71 
72  DlPaint paint;
73  paint.setColorSource(
74  MakeRuntimeEffect(this, "gradient.frag.iplr", uniform_data));
75 
76  DisplayListBuilder builder;
77  builder.Save();
78  builder.Scale(GetContentScale().x, GetContentScale().y);
79  builder.DrawPaint(paint);
80  builder.Restore();
81 
82  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
83 }

References impeller::TSize< Scalar >::MakeWH(), and x.

◆ TEST_P() [181/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintWithAdvancedBlendOverFilter   
)

Definition at line 125 of file aiks_dl_blend_unittests.cc.

125  {
126  DlPaint paint;
127  paint.setColor(DlColor::kBlack());
128  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 60));
129 
130  DisplayListBuilder builder;
131  paint.setColor(DlColor::kWhite());
132  builder.DrawPaint(paint);
133  paint.setColor(DlColor::kBlack());
134  builder.DrawCircle(DlPoint(300, 300), 200, paint);
135  paint.setColor(DlColor::kGreen());
136  paint.setBlendMode(DlBlendMode::kScreen);
137  builder.DrawPaint(paint);
138 
139  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
140 }

◆ TEST_P() [182/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectStrokesRenderCorrectly   
)

Definition at line 784 of file aiks_dl_path_unittests.cc.

784  {
785  DisplayListBuilder builder;
786  DlPaint paint;
787  paint.setColor(DlColor::kRed());
788  paint.setDrawStyle(DlDrawStyle::kStroke);
789  paint.setStrokeWidth(10);
790 
791  builder.Translate(100, 100);
792  builder.DrawPath(DlPath::MakeRect(DlRect::MakeSize(DlSize(100, 100))), paint);
793 
794  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
795 }

◆ TEST_P() [183/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectStrokesWithBevelJoinRenderCorrectly   
)

Definition at line 797 of file aiks_dl_path_unittests.cc.

797  {
798  DisplayListBuilder builder;
799  DlPaint paint;
800  paint.setColor(DlColor::kRed());
801  paint.setDrawStyle(DlDrawStyle::kStroke);
802  paint.setStrokeWidth(10);
803  paint.setStrokeJoin(DlStrokeJoin::kBevel);
804 
805  builder.Translate(100, 100);
806  builder.DrawPath(DlPath::MakeRect(DlRect::MakeSize(DlSize(100, 100))), paint);
807 
808  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
809 }

◆ TEST_P() [184/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawScaledTextWithPerspectiveNoSaveLayer   
)

Definition at line 508 of file aiks_dl_text_unittests.cc.

508  {
509  DisplayListBuilder builder;
510 
511  Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
512  0.0, 1.0, 0.0, 0.0, //
513  0.0, 0.0, 1.0, 0.01, //
514  0.0, 0.0, 0.0, 1.0) * //
515  Matrix::MakeRotationY({Degrees{10}});
516 
517  builder.Transform(matrix);
518 
519  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
520  "Roboto-Regular.ttf"));
521  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
522 }

References RenderTextInCanvasSkia(), and impeller::Matrix::Transform().

◆ TEST_P() [185/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawScaledTextWithPerspectiveSaveLayer   
)

Definition at line 524 of file aiks_dl_text_unittests.cc.

524  {
525  DisplayListBuilder builder;
526 
527  Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
528  0.0, 1.0, 0.0, 0.0, //
529  0.0, 0.0, 1.0, 0.01, //
530  0.0, 0.0, 0.0, 1.0) * //
531  Matrix::MakeRotationY({Degrees{10}});
532 
533  DlPaint save_paint;
534  DlRect window_bounds =
535  DlRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
536  // Note: bounds were not needed by the AIKS version, which may indicate a bug.
537  builder.SaveLayer(window_bounds, &save_paint);
538  builder.Transform(matrix);
539 
540  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
541  "Roboto-Regular.ttf"));
542 
543  builder.Restore();
544  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
545 }

References RenderTextInCanvasSkia().

◆ TEST_P() [186/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesImageSourceWithTextureCoordinates   
)

Definition at line 272 of file aiks_dl_vertices_unittests.cc.

272  {
273  auto texture = CreateTextureForFixture("embarcadero.jpg");
274  auto dl_image = DlImageImpeller::Make(texture);
275  std::vector<DlPoint> positions = {
276  DlPoint(100, 300),
277  DlPoint(200, 100),
278  DlPoint(300, 300),
279  };
280  std::vector<DlPoint> texture_coordinates = {
281  DlPoint(0, 0),
282  DlPoint(100, 200),
283  DlPoint(200, 100),
284  };
285 
286  auto vertices = flutter::DlVertices::Make(
287  flutter::DlVertexMode::kTriangles, 3, positions.data(),
288  texture_coordinates.data(), /*colors=*/nullptr);
289 
290  flutter::DisplayListBuilder builder;
291  flutter::DlPaint paint;
292 
293  auto image_source = flutter::DlColorSource::MakeImage(
294  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
295 
296  paint.setColorSource(image_source);
297  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
298 
299  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
300 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [187/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending   
)

Definition at line 302 of file aiks_dl_vertices_unittests.cc.

303  {
304  auto texture = CreateTextureForFixture("embarcadero.jpg");
305  auto dl_image = DlImageImpeller::Make(texture);
306  std::vector<DlPoint> positions = {
307  DlPoint(100, 300),
308  DlPoint(200, 100),
309  DlPoint(300, 300),
310  };
311  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
312  flutter::DlColor::kGreen(),
313  flutter::DlColor::kWhite()};
314  std::vector<DlPoint> texture_coordinates = {
315  DlPoint(0, 0),
316  DlPoint(100, 200),
317  DlPoint(200, 100),
318  };
319 
320  auto vertices = flutter::DlVertices::Make(
321  flutter::DlVertexMode::kTriangles, 3, positions.data(),
322  texture_coordinates.data(), colors.data());
323 
324  flutter::DisplayListBuilder builder;
325  flutter::DlPaint paint;
326 
327  auto image_source = flutter::DlColorSource::MakeImage(
328  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
329 
330  paint.setColorSource(image_source);
331  builder.DrawVertices(vertices, flutter::DlBlendMode::kModulate, paint);
332 
333  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
334 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [188/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithEmptySize   
)

Definition at line 285 of file canvas_unittests.cc.

285  {
286  RenderCallback callback = [&](RenderTarget& render_target) {
287  ContentContext context(GetContext(), nullptr);
288  Canvas canvas(context, render_target, true, false);
289 
290  std::vector<flutter::DlPoint> vertex_coordinates = {
291  flutter::DlPoint(0, 0),
292  flutter::DlPoint(600, 0),
293  flutter::DlPoint(0, 600),
294  };
295  std::vector<flutter::DlPoint> texture_coordinates = {
296  flutter::DlPoint(0, 0),
297  flutter::DlPoint(500, 0),
298  flutter::DlPoint(0, 500),
299  };
300  std::vector<uint16_t> indices = {0, 1, 2};
301  flutter::DlVertices::Builder vertices_builder(
302  flutter::DlVertexMode::kTriangleStrip, vertex_coordinates.size(),
303  flutter::DlVertices::Builder::kHasTextureCoordinates, indices.size());
304  vertices_builder.store_vertices(vertex_coordinates.data());
305  vertices_builder.store_indices(indices.data());
306  vertices_builder.store_texture_coordinates(texture_coordinates.data());
307  auto vertices = vertices_builder.build();
308 
309  // The start and end points of the gradient form an empty rectangle.
310  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
311  flutter::DlColor::kRed()};
312  std::vector<Scalar> stops = {0.0, 1.0};
313  auto gradient = flutter::DlColorSource::MakeLinear(
314  {0, 0}, {0, 600}, 2, colors.data(), stops.data(),
315  flutter::DlTileMode::kClamp);
316 
317  Paint paint;
318  paint.color_source = gradient.get();
319  canvas.DrawVertices(std::make_shared<DlVerticesGeometry>(vertices, context),
320  BlendMode::kSrcOver, paint);
321 
322  canvas.EndReplay();
323  return true;
324  };
325 
326  ASSERT_TRUE(Playground::OpenPlaygroundHere(callback));
327 }

References impeller::Paint::color_source, impeller::Canvas::DrawVertices(), impeller::Canvas::EndReplay(), impeller::kSrcOver, and impeller::Playground::OpenPlaygroundHere().

◆ TEST_P() [189/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithoutIndices   
)

Definition at line 211 of file aiks_dl_vertices_unittests.cc.

211  {
212  std::vector<DlPoint> positions = {
213  DlPoint(100, 300),
214  DlPoint(200, 100),
215  DlPoint(300, 300),
216  };
217 
218  auto vertices = flutter::DlVertices::Make(
219  flutter::DlVertexMode::kTriangles, 3, positions.data(),
220  /*texture_coordinates=*/nullptr, /*colors=*/nullptr);
221 
222  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
223  flutter::DlColor::kRed()};
224  const float stops[2] = {0.0, 1.0};
225 
226  auto linear = flutter::DlColorSource::MakeLinear(
227  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
228  flutter::DlTileMode::kRepeat);
229 
230  flutter::DisplayListBuilder builder;
231  flutter::DlPaint paint;
232 
233  paint.setColorSource(linear);
234  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
235 
236  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
237 }

◆ TEST_P() [190/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithTextureCoordinates   
)

Definition at line 239 of file aiks_dl_vertices_unittests.cc.

239  {
240  std::vector<DlPoint> positions = {
241  DlPoint(100, 300),
242  DlPoint(200, 100),
243  DlPoint(300, 300),
244  };
245  std::vector<DlPoint> texture_coordinates = {
246  DlPoint(300, 100),
247  DlPoint(100, 200),
248  DlPoint(300, 300),
249  };
250 
251  auto vertices = flutter::DlVertices::Make(
252  flutter::DlVertexMode::kTriangles, 3, positions.data(),
253  texture_coordinates.data(), /*colors=*/nullptr);
254 
255  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
256  flutter::DlColor::kRed()};
257  const float stops[2] = {0.0, 1.0};
258 
259  auto linear = flutter::DlColorSource::MakeLinear(
260  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
261  flutter::DlTileMode::kRepeat);
262 
263  flutter::DisplayListBuilder builder;
264  flutter::DlPaint paint;
265 
266  paint.setColorSource(linear);
267  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
268 
269  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
270 }

◆ TEST_P() [191/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesPremultipliesColors   
)

Definition at line 359 of file aiks_dl_vertices_unittests.cc.

359  {
360  std::vector<DlPoint> positions = {
361  DlPoint(100, 300),
362  DlPoint(200, 100),
363  DlPoint(300, 300),
364  DlPoint(200, 500),
365  };
366  auto color = flutter::DlColor::kBlue().withAlpha(0x99);
367  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
368  std::vector<flutter::DlColor> colors = {color, color, color, color};
369 
370  auto vertices = flutter::DlVertices::Make(
371  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
372  /*texture_coordinates=*/nullptr, colors.data(), indices.size(),
373  indices.data());
374 
375  flutter::DisplayListBuilder builder;
376  flutter::DlPaint paint;
377  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
378  paint.setColor(flutter::DlColor::kRed());
379 
380  builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 400), paint);
381  builder.DrawVertices(vertices, flutter::DlBlendMode::kDst, paint);
382 
383  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
384 }

◆ TEST_P() [192/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesSolidColorTrianglesWithIndices   
)

Definition at line 336 of file aiks_dl_vertices_unittests.cc.

336  {
337  std::vector<DlPoint> positions = {
338  DlPoint(100, 300),
339  DlPoint(200, 100),
340  DlPoint(300, 300),
341  DlPoint(200, 500),
342  };
343  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
344 
345  auto vertices = flutter::DlVertices::Make(
346  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
347  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
348  indices.data());
349 
350  flutter::DisplayListBuilder builder;
351  flutter::DlPaint paint;
352 
353  paint.setColor(flutter::DlColor::kRed());
354  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
355 
356  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
357 }

◆ TEST_P() [193/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesSolidColorTrianglesWithoutIndices   
)

Definition at line 185 of file aiks_dl_vertices_unittests.cc.

185  {
186  // Use negative coordinates and then scale the transform by -1, -1 to make
187  // sure coverage is taking the transform into account.
188  std::vector<DlPoint> positions = {
189  DlPoint(-100, -300),
190  DlPoint(-200, -100),
191  DlPoint(-300, -300),
192  };
193  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
194  flutter::DlColor::kGreen(),
195  flutter::DlColor::kWhite()};
196 
197  auto vertices = flutter::DlVertices::Make(
198  flutter::DlVertexMode::kTriangles, 3, positions.data(),
199  /*texture_coordinates=*/nullptr, colors.data());
200 
201  flutter::DisplayListBuilder builder;
202  flutter::DlPaint paint;
203 
204  paint.setColor(flutter::DlColor::kRed().modulateOpacity(0.5));
205  builder.Scale(-1, -1);
206  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
207 
208  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
209 }

◆ TEST_P() [194/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesTextureCoordinatesWithFragmentShader   
)

Definition at line 418 of file aiks_dl_vertices_unittests.cc.

418  {
419  std::vector<DlPoint> positions_lt = {
420  DlPoint(0, 0), //
421  DlPoint(50, 0), //
422  DlPoint(0, 50), //
423  DlPoint(50, 50), //
424  };
425 
426  auto vertices_lt = flutter::DlVertices::Make(
427  flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
428  positions_lt.data(),
429  /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
430  /*index_count=*/0,
431  /*indices=*/nullptr);
432 
433  std::vector<DlPoint> positions_rt = {
434  DlPoint(50, 0), //
435  DlPoint(100, 0), //
436  DlPoint(50, 50), //
437  DlPoint(100, 50), //
438  };
439 
440  auto vertices_rt = flutter::DlVertices::Make(
441  flutter::DlVertexMode::kTriangleStrip, positions_rt.size(),
442  positions_rt.data(),
443  /*texture_coordinates=*/positions_rt.data(), /*colors=*/nullptr,
444  /*index_count=*/0,
445  /*indices=*/nullptr);
446 
447  std::vector<DlPoint> positions_lb = {
448  DlPoint(0, 50), //
449  DlPoint(50, 50), //
450  DlPoint(0, 100), //
451  DlPoint(50, 100), //
452  };
453 
454  auto vertices_lb = flutter::DlVertices::Make(
455  flutter::DlVertexMode::kTriangleStrip, positions_lb.size(),
456  positions_lb.data(),
457  /*texture_coordinates=*/positions_lb.data(), /*colors=*/nullptr,
458  /*index_count=*/0,
459  /*indices=*/nullptr);
460 
461  std::vector<DlPoint> positions_rb = {
462  DlPoint(50, 50), //
463  DlPoint(100, 50), //
464  DlPoint(50, 100), //
465  DlPoint(100, 100), //
466  };
467 
468  auto vertices_rb = flutter::DlVertices::Make(
469  flutter::DlVertexMode::kTriangleStrip, positions_rb.size(),
470  positions_rb.data(),
471  /*texture_coordinates=*/positions_rb.data(), /*colors=*/nullptr,
472  /*index_count=*/0,
473  /*indices=*/nullptr);
474 
475  flutter::DisplayListBuilder builder;
476  flutter::DlPaint paint;
477  flutter::DlPaint rect_paint;
478  rect_paint.setColor(DlColor::kBlue());
479 
480  auto runtime_stages =
481  OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");
482 
483  auto runtime_stage =
484  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
485  ASSERT_TRUE(runtime_stage);
486 
487  auto runtime_effect = DlRuntimeEffectImpeller::Make(runtime_stage);
488  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
489  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
490  runtime_effect, {}, uniform_data);
491 
492  paint.setColorSource(color_source);
493 
494  builder.Scale(GetContentScale().x, GetContentScale().y);
495  builder.Save();
496  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), rect_paint);
497  builder.DrawVertices(vertices_lt, flutter::DlBlendMode::kSrcOver, paint);
498  builder.DrawVertices(vertices_rt, flutter::DlBlendMode::kSrcOver, paint);
499  builder.DrawVertices(vertices_lb, flutter::DlBlendMode::kSrcOver, paint);
500  builder.DrawVertices(vertices_rb, flutter::DlBlendMode::kSrcOver, paint);
501  builder.Restore();
502 
503  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
504 }

References flutter::DlRuntimeEffectImpeller::Make(), impeller::PlaygroundBackendToRuntimeStageBackend(), and x.

◆ TEST_P() [195/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesTextureCoordinatesWithFragmentShaderNonZeroOrigin   
)

Definition at line 508 of file aiks_dl_vertices_unittests.cc.

509  {
510  std::vector<DlPoint> positions_lt = {
511  DlPoint(200, 200), //
512  DlPoint(250, 200), //
513  DlPoint(200, 250), //
514  DlPoint(250, 250), //
515  };
516 
517  auto vertices = flutter::DlVertices::Make(
518  flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
519  positions_lt.data(),
520  /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
521  /*index_count=*/0,
522  /*indices=*/nullptr);
523 
524  flutter::DisplayListBuilder builder;
525  flutter::DlPaint paint;
526  flutter::DlPaint rect_paint;
527  rect_paint.setColor(DlColor::kBlue());
528 
529  auto runtime_stages =
530  OpenAssetAsRuntimeStage("runtime_stage_position.frag.iplr");
531 
532  auto runtime_stage =
533  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
534  ASSERT_TRUE(runtime_stage);
535 
536  auto runtime_effect = DlRuntimeEffectImpeller::Make(runtime_stage);
537  auto rect_data = std::vector<Rect>{Rect::MakeLTRB(200, 200, 250, 250)};
538 
539  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
540  uniform_data->resize(rect_data.size() * sizeof(Rect));
541  memcpy(uniform_data->data(), rect_data.data(), uniform_data->size());
542 
543  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
544  runtime_effect, {}, uniform_data);
545 
546  paint.setColorSource(color_source);
547 
548  builder.Scale(GetContentScale().x, GetContentScale().y);
549  builder.DrawRect(DlRect::MakeLTRB(200, 200, 250, 250), rect_paint);
550  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
551 
552  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
553 }

References flutter::DlRuntimeEffectImpeller::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::PlaygroundBackendToRuntimeStageBackend(), and x.

◆ TEST_P() [196/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesWithEmptyTextureCoordinates   
)

Definition at line 329 of file canvas_unittests.cc.

329  {
330  auto runtime_stages =
331  OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");
332 
333  auto runtime_stage =
334  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
335  ASSERT_TRUE(runtime_stage);
336 
337  auto runtime_effect = flutter::DlRuntimeEffectImpeller::Make(runtime_stage);
338  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
339  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
340  runtime_effect, {}, uniform_data);
341 
342  RenderCallback callback = [&](RenderTarget& render_target) {
343  ContentContext context(GetContext(), nullptr);
344  Canvas canvas(context, render_target, true, false);
345 
346  std::vector<flutter::DlPoint> vertex_coordinates = {
347  flutter::DlPoint(100, 100),
348  flutter::DlPoint(300, 100),
349  flutter::DlPoint(100, 300),
350  };
351  // The bounding box of the texture coordinates is empty.
352  std::vector<flutter::DlPoint> texture_coordinates = {
353  flutter::DlPoint(0, 0),
354  flutter::DlPoint(0, 100),
355  flutter::DlPoint(0, 0),
356  };
357  std::vector<uint16_t> indices = {0, 1, 2};
358  flutter::DlVertices::Builder vertices_builder(
359  flutter::DlVertexMode::kTriangleStrip, vertex_coordinates.size(),
360  flutter::DlVertices::Builder::kHasTextureCoordinates, indices.size());
361  vertices_builder.store_vertices(vertex_coordinates.data());
362  vertices_builder.store_indices(indices.data());
363  vertices_builder.store_texture_coordinates(texture_coordinates.data());
364  auto vertices = vertices_builder.build();
365 
366  Paint paint;
367  paint.color_source = color_source.get();
368  canvas.DrawVertices(std::make_shared<DlVerticesGeometry>(vertices, context),
369  BlendMode::kSrcOver, paint);
370 
371  canvas.EndReplay();
372  return true;
373  };
374 
375  ASSERT_TRUE(Playground::OpenPlaygroundHere(callback));
376 }
static sk_sp< DlRuntimeEffect > Make(std::shared_ptr< impeller::RuntimeStage > runtime_stage)

References impeller::Paint::color_source, impeller::Canvas::DrawVertices(), impeller::Canvas::EndReplay(), impeller::kSrcOver, flutter::DlRuntimeEffectImpeller::Make(), impeller::Playground::OpenPlaygroundHere(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [197/549]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesWithInvalidIndices   
)

Definition at line 386 of file aiks_dl_vertices_unittests.cc.

386  {
387  std::vector<DlPoint> positions = {
388  DlPoint(100, 300),
389  DlPoint(200, 100),
390  DlPoint(300, 300),
391  DlPoint(200, 500),
392  };
393  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3, 99, 100, 101};
394 
395  auto vertices = flutter::DlVertices::Make(
396  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
397  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
398  indices.data());
399 
400  EXPECT_EQ(vertices->GetBounds(), DlRect::MakeLTRB(100, 100, 300, 500));
401 
402  flutter::DisplayListBuilder builder;
403  flutter::DlPaint paint;
404  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
405  paint.setColor(flutter::DlColor::kRed());
406 
407  builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 400), paint);
408  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrc, paint);
409 
410  AiksContext renderer(GetContext(), nullptr);
411  std::shared_ptr<Texture> image =
412  DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
413  EXPECT_TRUE(image);
414 }

References impeller::DisplayListToTexture().

◆ TEST_P() [198/549]

impeller::testing::TEST_P ( AiksTest  ,
EmptySaveLayerIgnoresPaint   
)

Definition at line 1606 of file aiks_dl_basic_unittests.cc.

1606  {
1607  DisplayListBuilder builder;
1608  builder.Scale(GetContentScale().x, GetContentScale().y);
1609 
1610  DlPaint paint;
1611  paint.setColor(DlColor::kRed());
1612  builder.DrawPaint(paint);
1613  builder.ClipRect(DlRect::MakeXYWH(100, 100, 200, 200));
1614  paint.setColor(DlColor::kBlue());
1615  builder.SaveLayer(std::nullopt, &paint);
1616  builder.Restore();
1617 
1618  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1619 }

References x.

◆ TEST_P() [199/549]

impeller::testing::TEST_P ( AiksTest  ,
EmptySaveLayerRendersWithClear   
)

Definition at line 1621 of file aiks_dl_basic_unittests.cc.

1621  {
1622  DisplayListBuilder builder;
1623  builder.Scale(GetContentScale().x, GetContentScale().y);
1624  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
1625  builder.DrawImage(image, DlPoint(10, 10), {});
1626  builder.ClipRect(DlRect::MakeXYWH(100, 100, 200, 200));
1627 
1628  DlPaint paint;
1629  paint.setBlendMode(DlBlendMode::kClear);
1630  builder.SaveLayer(std::nullopt, &paint);
1631  builder.Restore();
1632 
1633  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1634 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [200/549]

impeller::testing::TEST_P ( AiksTest  ,
EmulatedAdvancedBlendRestore   
)

Definition at line 927 of file aiks_dl_blend_unittests.cc.

927  {
928  DisplayListBuilder builder;
929 
930  builder.DrawPaint(DlPaint(DlColor::kWhite()));
931  builder.Save();
932  builder.ClipRect(DlRect::MakeLTRB(100, 100, 400, 300));
933 
934  // Draw should apply the clip, even though it is an advanced blend.
935  builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 300),
936  DlPaint()
937  .setColor(DlColor::kRed())
938  .setBlendMode(DlBlendMode::kDifference));
939  // This color should not show if clip is still functional.
940  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100),
941  DlPaint().setColor(DlColor::kBlue()));
942  builder.Restore();
943 
944  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
945 }

◆ TEST_P() [201/549]

impeller::testing::TEST_P ( AiksTest  ,
FastEllipticalRRectMaskBlursRenderCorrectly   
)

Definition at line 2023 of file aiks_dl_basic_unittests.cc.

2023  {
2024  DisplayListBuilder builder;
2025 
2026  builder.Scale(GetContentScale().x, GetContentScale().y);
2027  DlPaint paint;
2028  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1));
2029 
2030  DlPaint save_paint;
2031  save_paint.setColor(DlColor::kWhite());
2032  builder.DrawPaint(save_paint);
2033 
2034  paint.setColor(DlColor::kBlue());
2035  for (int i = 0; i < 5; i++) {
2036  Scalar y = i * 125;
2037  Scalar y_radius = i * 15;
2038  for (int j = 0; j < 5; j++) {
2039  Scalar x = j * 125;
2040  Scalar x_radius = j * 15;
2041  builder.DrawRoundRect(
2042  DlRoundRect::MakeRectXY(
2043  DlRect::MakeXYWH(x + 50, y + 50, 100.0f, 100.0f), //
2044  x_radius, y_radius),
2045  paint);
2046  }
2047  }
2048 
2049  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
2050 }

References x.

◆ TEST_P() [202/549]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestHorizontal   
)

Definition at line 825 of file aiks_dl_gradient_unittests.cc.

825  {
826  DisplayListBuilder builder;
827  DlPaint paint;
828  builder.Translate(100.0f, 0);
829 
830  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
831  DlColor::kGreen()};
832  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
833 
834  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {300, 0}, stops.size(),
835  colors.data(), stops.data(),
836  DlTileMode::kClamp));
837 
838  paint.setColor(DlColor::kWhite());
839  builder.DrawRect(DlRect::MakeXYWH(0, 0, 300, 300), paint);
840  builder.Translate(400, 0);
841  builder.DrawRoundRect(
842  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 300, 300), 4, 4), paint);
843 
844  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
845 }

◆ TEST_P() [203/549]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestHorizontalReversed   
)

Definition at line 871 of file aiks_dl_gradient_unittests.cc.

871  {
872  DisplayListBuilder builder;
873  DlPaint paint;
874  builder.Translate(100.0f, 0);
875 
876  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
877  DlColor::kGreen()};
878  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
879 
880  paint.setColorSource(DlColorSource::MakeLinear({300, 0}, {0, 0}, stops.size(),
881  colors.data(), stops.data(),
882  DlTileMode::kClamp));
883 
884  paint.setColor(DlColor::kWhite());
885  builder.DrawRect(DlRect::MakeXYWH(0, 0, 300, 300), paint);
886  builder.Translate(400, 0);
887  builder.DrawRoundRect(
888  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 300, 300), 4, 4), paint);
889 
890  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
891 }

◆ TEST_P() [204/549]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestVertical   
)

Definition at line 848 of file aiks_dl_gradient_unittests.cc.

848  {
849  DisplayListBuilder builder;
850  DlPaint paint;
851  builder.Translate(100.0f, 0);
852 
853  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
854  DlColor::kGreen()};
855  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
856 
857  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {0, 300}, stops.size(),
858  colors.data(), stops.data(),
859  DlTileMode::kClamp));
860 
861  paint.setColor(DlColor::kWhite());
862  builder.DrawRect(DlRect::MakeXYWH(0, 0, 300, 300), paint);
863  builder.Translate(400, 0);
864  builder.DrawRoundRect(
865  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 300, 300), 4, 4), paint);
866 
867  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
868 }

◆ TEST_P() [205/549]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestVerticalReversed   
)

Definition at line 894 of file aiks_dl_gradient_unittests.cc.

894  {
895  DisplayListBuilder builder;
896  DlPaint paint;
897  builder.Translate(100.0f, 0);
898 
899  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
900  DlColor::kGreen()};
901  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
902 
903  paint.setColorSource(DlColorSource::MakeLinear({0, 300}, {0, 0}, stops.size(),
904  colors.data(), stops.data(),
905  DlTileMode::kClamp));
906 
907  paint.setColor(DlColor::kWhite());
908  builder.DrawRect(DlRect::MakeXYWH(0, 0, 300, 300), paint);
909  builder.Translate(400, 0);
910  builder.DrawRoundRect(
911  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 300, 300), 4, 4), paint);
912 
913  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
914 }

◆ TEST_P() [206/549]

impeller::testing::TEST_P ( AiksTest  ,
FatStrokeArc   
)

Definition at line 875 of file aiks_dl_path_unittests.cc.

875  {
876  DlScalar stroke_width = 300;
877  DlScalar aspect = 1.0;
878  DlScalar start_angle = 0;
879  DlScalar end_angle = 90;
880  auto callback = [&]() -> sk_sp<DisplayList> {
881  if (AiksTest::ImGuiBegin("Controls", nullptr,
882  ImGuiWindowFlags_AlwaysAutoResize)) {
883  ImGui::SliderFloat("Stroke Width", &stroke_width, 1, 300);
884  ImGui::SliderFloat("Aspect", &aspect, 0.5, 2.0);
885  ImGui::SliderFloat("Start Angle", &start_angle, 0, 360);
886  ImGui::SliderFloat("End Angle", &end_angle, 0, 360);
887  ImGui::End();
888  }
889 
890  DisplayListBuilder builder;
891  DlPaint grey_paint;
892  grey_paint.setColor(DlColor(0xff111111));
893  builder.DrawPaint(grey_paint);
894 
895  DlPaint white_paint;
896  white_paint.setColor(DlColor::kWhite());
897  white_paint.setStrokeWidth(stroke_width);
898  white_paint.setDrawStyle(DlDrawStyle::kStroke);
899  DlPaint red_paint;
900  red_paint.setColor(DlColor::kRed());
901 
902  Rect rect = Rect::MakeXYWH(100, 100, 100, aspect * 100);
903  builder.DrawRect(rect, red_paint);
904  builder.DrawArc(rect, start_angle, end_angle,
905  /*useCenter=*/false, white_paint);
906  DlScalar frontier = rect.GetRight() + stroke_width / 2.0;
907  builder.DrawLine(Point(frontier, 0), Point(frontier, 150), red_paint);
908 
909  return builder.Build();
910  };
911  ASSERT_TRUE(OpenPlaygroundHere(callback));
912 }

References impeller::TRect< T >::GetRight(), impeller::AiksPlayground::ImGuiBegin(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [207/549]

impeller::testing::TEST_P ( AiksTest  ,
FilledArcsRenderCorrectly   
)

Definition at line 857 of file aiks_dl_basic_unittests.cc.

857  {
858  DisplayListBuilder builder;
859  builder.Scale(GetContentScale().x, GetContentScale().y);
860  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
861 
862  DlPaint paint;
863  paint.setColor(DlColor::kBlue());
864 
865  RenderArcFarm(builder, paint,
866  {
867  .use_center = false,
868  .full_circles = false,
869  });
870 
871  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
872 }

References x.

◆ TEST_P() [208/549]

impeller::testing::TEST_P ( AiksTest  ,
FilledArcsRenderCorrectlyWithCenter   
)

Definition at line 874 of file aiks_dl_basic_unittests.cc.

874  {
875  DisplayListBuilder builder;
876  builder.Scale(GetContentScale().x, GetContentScale().y);
877  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
878 
879  DlPaint paint;
880  paint.setColor(DlColor::kBlue());
881 
882  RenderArcFarm(builder, paint,
883  {
884  .use_center = true,
885  .full_circles = false,
886  });
887 
888  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
889 }

References x.

◆ TEST_P() [209/549]

impeller::testing::TEST_P ( AiksTest  ,
FilledCirclesRenderCorrectly   
)

Definition at line 628 of file aiks_dl_basic_unittests.cc.

628  {
629  DisplayListBuilder builder;
630  builder.Scale(GetContentScale().x, GetContentScale().y);
631  DlPaint paint;
632  const int color_count = 3;
633  DlColor colors[color_count] = {
634  DlColor::kBlue(),
635  DlColor::kGreen(),
636  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
637  };
638 
639  paint.setColor(DlColor::kWhite());
640  builder.DrawPaint(paint);
641 
642  int c_index = 0;
643  int radius = 600;
644  while (radius > 0) {
645  paint.setColor(colors[(c_index++) % color_count]);
646  builder.DrawCircle(DlPoint(10, 10), radius, paint);
647  if (radius > 30) {
648  radius -= 10;
649  } else {
650  radius -= 2;
651  }
652  }
653 
654  DlColor gradient_colors[7] = {
655  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
656  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
657  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
658  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
659  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
660  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
661  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
662  };
663  DlScalar stops[7] = {
664  0.0,
665  (1.0 / 6.0) * 1,
666  (1.0 / 6.0) * 2,
667  (1.0 / 6.0) * 3,
668  (1.0 / 6.0) * 4,
669  (1.0 / 6.0) * 5,
670  1.0,
671  };
672  auto texture = CreateTextureForFixture("airplane.jpg",
673  /*enable_mipmapping=*/true);
674  auto image = DlImageImpeller::Make(texture);
675 
676  paint.setColorSource(DlColorSource::MakeRadial(
677  DlPoint(500, 600), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
678  builder.DrawCircle(DlPoint(500, 600), 100, paint);
679 
680  DlMatrix local_matrix = DlMatrix::MakeTranslation({700, 200});
681  paint.setColorSource(DlColorSource::MakeImage(
682  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
683  DlImageSampling::kNearestNeighbor, &local_matrix));
684  builder.DrawCircle(DlPoint(800, 300), 100, paint);
685 
686  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
687 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [210/549]

impeller::testing::TEST_P ( AiksTest  ,
FilledEllipsesRenderCorrectly   
)

Definition at line 755 of file aiks_dl_basic_unittests.cc.

755  {
756  DisplayListBuilder builder;
757  builder.Scale(GetContentScale().x, GetContentScale().y);
758  DlPaint paint;
759  const int color_count = 3;
760  DlColor colors[color_count] = {
761  DlColor::kBlue(),
762  DlColor::kGreen(),
763  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
764  };
765 
766  paint.setColor(DlColor::kWhite());
767  builder.DrawPaint(paint);
768 
769  int c_index = 0;
770  int long_radius = 600;
771  int short_radius = 600;
772  while (long_radius > 0 && short_radius > 0) {
773  paint.setColor(colors[(c_index++) % color_count]);
774  builder.DrawOval(DlRect::MakeXYWH(10 - long_radius, 10 - short_radius,
775  long_radius * 2, short_radius * 2),
776  paint);
777  builder.DrawOval(DlRect::MakeXYWH(1000 - short_radius, 750 - long_radius,
778  short_radius * 2, long_radius * 2),
779  paint);
780  if (short_radius > 30) {
781  short_radius -= 10;
782  long_radius -= 5;
783  } else {
784  short_radius -= 2;
785  long_radius -= 1;
786  }
787  }
788 
789  DlColor gradient_colors[7] = {
790  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
791  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
792  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
793  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
794  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
795  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
796  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
797  };
798  DlScalar stops[7] = {
799  0.0,
800  (1.0 / 6.0) * 1,
801  (1.0 / 6.0) * 2,
802  (1.0 / 6.0) * 3,
803  (1.0 / 6.0) * 4,
804  (1.0 / 6.0) * 5,
805  1.0,
806  };
807  auto texture = CreateTextureForFixture("airplane.jpg",
808  /*enable_mipmapping=*/true);
809  auto image = DlImageImpeller::Make(texture);
810 
811  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
812 
813  paint.setColorSource(DlColorSource::MakeRadial(
814  DlPoint(300, 650), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
815  builder.DrawOval(DlRect::MakeXYWH(200, 625, 200, 50), paint);
816  builder.DrawOval(DlRect::MakeXYWH(275, 550, 50, 200), paint);
817 
818  DlMatrix local_matrix = DlMatrix::MakeTranslation({610, 15});
819  paint.setColorSource(DlColorSource::MakeImage(
820  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
821  DlImageSampling::kNearestNeighbor, &local_matrix));
822  builder.DrawOval(DlRect::MakeXYWH(610, 90, 200, 50), paint);
823  builder.DrawOval(DlRect::MakeXYWH(685, 15, 50, 200), paint);
824 
825  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
826 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [211/549]

impeller::testing::TEST_P ( AiksTest  ,
FilledRoundRectPathsRenderCorrectly   
)

Definition at line 1757 of file aiks_dl_basic_unittests.cc.

1757  {
1758  DisplayListBuilder builder;
1759  builder.Scale(GetContentScale().x, GetContentScale().y);
1760 
1761  DlPaint paint;
1762  const int color_count = 3;
1763  DlColor colors[color_count] = {
1764  DlColor::kBlue(),
1765  DlColor::kGreen(),
1766  DlColor::ARGB(1.0, 220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f),
1767  };
1768 
1769  paint.setColor(DlColor::kWhite());
1770  builder.DrawPaint(paint);
1771 
1772  auto draw_rrect_as_path = [&builder](const DlRect& rect, Scalar x, Scalar y,
1773  const DlPaint& paint) {
1774  builder.DrawPath(DlPath::MakeRoundRectXY(rect, x, y), paint);
1775  };
1776 
1777  int c_index = 0;
1778  for (int i = 0; i < 4; i++) {
1779  for (int j = 0; j < 4; j++) {
1780  paint.setColor(colors[(c_index++) % color_count]);
1781  draw_rrect_as_path(DlRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1782  i * 5 + 10, j * 5 + 10, paint);
1783  }
1784  }
1785  paint.setColor(colors[(c_index++) % color_count]);
1786  draw_rrect_as_path(DlRect::MakeXYWH(10, 420, 380, 80), 40, 40, paint);
1787  paint.setColor(colors[(c_index++) % color_count]);
1788  draw_rrect_as_path(DlRect::MakeXYWH(410, 20, 80, 380), 40, 40, paint);
1789 
1790  std::vector<DlColor> gradient_colors = {
1791  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
1792  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
1793  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
1794  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
1795  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
1796  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
1797  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0)};
1798  std::vector<Scalar> stops = {
1799  0.0,
1800  (1.0 / 6.0) * 1,
1801  (1.0 / 6.0) * 2,
1802  (1.0 / 6.0) * 3,
1803  (1.0 / 6.0) * 4,
1804  (1.0 / 6.0) * 5,
1805  1.0,
1806  };
1807  auto texture = DlImageImpeller::Make(
1808  CreateTextureForFixture("airplane.jpg",
1809  /*enable_mipmapping=*/true));
1810 
1811  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1812  paint.setColorSource(DlColorSource::MakeRadial(
1813  /*center=*/DlPoint(550, 550),
1814  /*radius=*/75,
1815  /*stop_count=*/gradient_colors.size(),
1816  /*colors=*/gradient_colors.data(),
1817  /*stops=*/stops.data(),
1818  /*tile_mode=*/DlTileMode::kMirror));
1819  for (int i = 1; i <= 10; i++) {
1820  int j = 11 - i;
1821  draw_rrect_as_path(DlRect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1822  550 + i * 20, 550 + j * 20),
1823  i * 10, j * 10, paint);
1824  }
1825  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1826  paint.setColorSource(DlColorSource::MakeRadial(
1827  /*center=*/DlPoint(200, 650),
1828  /*radius=*/75,
1829  /*stop_count=*/gradient_colors.size(),
1830  /*colors=*/gradient_colors.data(),
1831  /*stops=*/stops.data(),
1832  /*tile_mode=*/DlTileMode::kMirror));
1833  draw_rrect_as_path(DlRect::MakeLTRB(100, 610, 300, 690), 40, 40, paint);
1834  draw_rrect_as_path(DlRect::MakeLTRB(160, 550, 240, 750), 40, 40, paint);
1835 
1836  auto matrix = DlMatrix::MakeTranslation({520, 20});
1837  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1838  paint.setColorSource(DlColorSource::MakeImage(
1839  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1840  DlImageSampling::kMipmapLinear, &matrix));
1841  for (int i = 1; i <= 10; i++) {
1842  int j = 11 - i;
1843  draw_rrect_as_path(DlRect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1844  720 + i * 20, 220 + j * 20),
1845  i * 10, j * 10, paint);
1846  }
1847  matrix = DlMatrix::MakeTranslation({800, 300});
1848  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1849  paint.setColorSource(DlColorSource::MakeImage(
1850  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1851  DlImageSampling::kMipmapLinear, &matrix));
1852 
1853  draw_rrect_as_path(DlRect::MakeLTRB(800, 410, 1000, 490), 40, 40, paint);
1854  draw_rrect_as_path(DlRect::MakeLTRB(860, 350, 940, 550), 40, 40, paint);
1855 
1856  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1857 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [212/549]

impeller::testing::TEST_P ( AiksTest  ,
FilledRoundRectsRenderCorrectly   
)

Definition at line 1161 of file aiks_dl_basic_unittests.cc.

1161  {
1162  DisplayListBuilder builder;
1163  builder.Scale(GetContentScale().x, GetContentScale().y);
1164  DlPaint paint;
1165  const int color_count = 3;
1166  DlColor colors[color_count] = {
1167  DlColor::kBlue(),
1168  DlColor::kGreen(),
1169  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
1170  };
1171 
1172  paint.setColor(DlColor::kWhite());
1173  builder.DrawPaint(paint);
1174 
1175  int c_index = 0;
1176  for (int i = 0; i < 4; i++) {
1177  for (int j = 0; j < 4; j++) {
1178  paint.setColor(colors[(c_index++) % color_count]);
1179  builder.DrawRoundRect(
1180  DlRoundRect::MakeRectXY(
1181  DlRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80), //
1182  i * 5 + 10, j * 5 + 10),
1183  paint);
1184  }
1185  }
1186  paint.setColor(colors[(c_index++) % color_count]);
1187  builder.DrawRoundRect(
1188  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(10, 420, 380, 80), 40, 40),
1189  paint);
1190  paint.setColor(colors[(c_index++) % color_count]);
1191  builder.DrawRoundRect(
1192  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(410, 20, 80, 380), 40, 40),
1193  paint);
1194 
1195  DlColor gradient_colors[7] = {
1196  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
1197  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
1198  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
1199  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
1200  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
1201  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
1202  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
1203  };
1204  DlScalar stops[7] = {
1205  0.0,
1206  (1.0 / 6.0) * 1,
1207  (1.0 / 6.0) * 2,
1208  (1.0 / 6.0) * 3,
1209  (1.0 / 6.0) * 4,
1210  (1.0 / 6.0) * 5,
1211  1.0,
1212  };
1213  auto texture = CreateTextureForFixture("airplane.jpg",
1214  /*enable_mipmapping=*/true);
1215  auto image = DlImageImpeller::Make(texture);
1216 
1217  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1218  paint.setColorSource(DlColorSource::MakeRadial(
1219  DlPoint(550, 550), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
1220  for (int i = 1; i <= 10; i++) {
1221  int j = 11 - i;
1222  builder.DrawRoundRect(
1223  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1224  550 + i * 20, 550 + j * 20),
1225  i * 10, j * 10),
1226  paint);
1227  }
1228 
1229  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1230  paint.setColorSource(DlColorSource::MakeRadial(
1231  DlPoint(200, 650), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
1232  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1233  builder.DrawRoundRect(
1234  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(100, 610, 300, 690), 40, 40),
1235  paint);
1236  builder.DrawRoundRect(
1237  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(160, 550, 240, 750), 40, 40),
1238  paint);
1239 
1240  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1241  DlMatrix local_matrix = DlMatrix::MakeTranslation({520, 20});
1242  paint.setColorSource(DlColorSource::MakeImage(
1243  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
1244  DlImageSampling::kNearestNeighbor, &local_matrix));
1245  for (int i = 1; i <= 10; i++) {
1246  int j = 11 - i;
1247  builder.DrawRoundRect(
1248  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1249  720 + i * 20, 220 + j * 20),
1250  i * 10, j * 10),
1251  paint);
1252  }
1253 
1254  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1255  local_matrix = DlMatrix::MakeTranslation({800, 300});
1256  paint.setColorSource(DlColorSource::MakeImage(
1257  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
1258  DlImageSampling::kNearestNeighbor, &local_matrix));
1259  builder.DrawRoundRect(
1260  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(800, 410, 1000, 490), 40, 40),
1261  paint);
1262  builder.DrawRoundRect(
1263  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(860, 350, 940, 550), 40, 40),
1264  paint);
1265 
1266  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1267 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [213/549]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundAdvancedBlendAppliesTransformCorrectly   
)

Definition at line 732 of file aiks_dl_blend_unittests.cc.

732  {
733  auto texture = CreateTextureForFixture("airplane.jpg",
734  /*enable_mipmapping=*/true);
735 
736  DisplayListBuilder builder;
737  builder.Rotate(30);
738 
739  DlPaint image_paint;
740  image_paint.setColorFilter(DlColorFilter::MakeBlend(
741  DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
742  DlBlendMode::kColorDodge));
743 
744  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(200, 200),
745  DlImageSampling::kMipmapLinear, &image_paint);
746 
747  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
748 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [214/549]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundBlendSubpassCollapseOptimization   
)

Definition at line 467 of file aiks_dl_blend_unittests.cc.

467  {
468  DisplayListBuilder builder;
469 
470  DlPaint save_paint;
471  save_paint.setColorFilter(
472  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kColorDodge));
473  builder.SaveLayer(std::nullopt, &save_paint);
474 
475  builder.Translate(500, 300);
476  builder.Rotate(120);
477 
478  DlPaint paint;
479  paint.setColor(DlColor::kBlue());
480  builder.DrawRect(DlRect::MakeXYWH(100, 100, 200, 200), paint);
481 
482  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
483 }

◆ TEST_P() [215/549]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundPipelineBlendAppliesTransformCorrectly   
)

Definition at line 714 of file aiks_dl_blend_unittests.cc.

714  {
715  auto texture = CreateTextureForFixture("airplane.jpg",
716  /*enable_mipmapping=*/true);
717 
718  DisplayListBuilder builder;
719  builder.Rotate(30);
720 
721  DlPaint image_paint;
722  image_paint.setColorFilter(DlColorFilter::MakeBlend(
723  DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
724  DlBlendMode::kSrcIn));
725 
726  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(200, 200),
727  DlImageSampling::kMipmapLinear, &image_paint);
728 
729  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
730 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [216/549]

impeller::testing::TEST_P ( AiksTest  ,
FormatSRGB   
)

Definition at line 1670 of file aiks_dl_basic_unittests.cc.

1670  {
1671  PixelFormat pixel_format =
1672  GetContext()->GetCapabilities()->GetDefaultColorFormat();
1673  EXPECT_TRUE(pixel_format == PixelFormat::kR8G8B8A8UNormInt ||
1674  pixel_format == PixelFormat::kB8G8R8A8UNormInt)
1675  << "pixel format: " << PixelFormatToString(pixel_format);
1676 }
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:140

References impeller::kB8G8R8A8UNormInt, impeller::kR8G8B8A8UNormInt, and impeller::PixelFormatToString().

◆ TEST_P() [217/549]

impeller::testing::TEST_P ( AiksTest  ,
FormatWideGamut   
)

Definition at line 1665 of file aiks_dl_basic_unittests.cc.

1665  {
1666  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
1667  PixelFormat::kB10G10R10A10XR);
1668 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [218/549]

impeller::testing::TEST_P ( AiksTest  ,
FramebufferAdvancedBlendCoverage   
)

Definition at line 750 of file aiks_dl_blend_unittests.cc.

750  {
751  auto texture = CreateTextureForFixture("airplane.jpg",
752  /*enable_mipmapping=*/true);
753 
754  // Draw with an advanced blend that can use FramebufferBlendContents and
755  // verify that the scale transform is correctly applied to the image.
756  DisplayListBuilder builder;
757 
758  DlPaint paint;
759  paint.setColor(
760  DlColor::RGBA(169.0f / 255.0f, 169.0f / 255.0f, 169.0f / 255.0f, 1.0f));
761  builder.DrawPaint(paint);
762  builder.Scale(0.4, 0.4);
763 
764  DlPaint image_paint;
765  image_paint.setBlendMode(DlBlendMode::kMultiply);
766 
767  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(20, 20),
768  DlImageSampling::kMipmapLinear, &image_paint);
769 
770  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
771 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [219/549]

impeller::testing::TEST_P ( AiksTest  ,
FramebufferBlendsRespectClips   
)

If correct, this test should draw a green circle. If any red is visible, there is a depth bug.

Definition at line 118 of file aiks_dl_clip_unittests.cc.

118  {
119  DisplayListBuilder builder;
120 
121  // Clear the whole canvas with white.
122  DlPaint paint;
123  paint.setColor(DlColor::kWhite());
124  builder.DrawPaint(paint);
125 
126  builder.ClipPath(DlPath::MakeCircle(DlPoint(150, 150), 50),
127  DlClipOp::kIntersect);
128 
129  // Draw a red rectangle that should not show through the circle clip.
130  paint.setColor(DlColor::kRed());
131  paint.setBlendMode(DlBlendMode::kMultiply);
132  builder.DrawRect(DlRect::MakeXYWH(100, 100, 100, 100), paint);
133 
134  // Draw a green circle that shows through the clip.
135  paint.setColor(DlColor::kGreen());
136  paint.setBlendMode(DlBlendMode::kSrcOver);
137  builder.DrawCircle(DlPoint(150, 150), 50, paint);
138 
139  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
140 }

◆ TEST_P() [220/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAnimatedBackdrop   
)

Definition at line 850 of file aiks_dl_blur_unittests.cc.

850  {
851  // This test is for checking out how stable rendering is when content is
852  // translated underneath a blur. Animating under a blur can cause
853  // *shimmering* to happen as a result of pixel alignment.
854  // See also: https://github.com/flutter/flutter/issues/140193
855  auto boston =
856  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
857  ASSERT_TRUE(boston);
858  int64_t count = 0;
859  Scalar sigma = 20.0;
860  Scalar freq = 0.1;
861  Scalar amp = 50.0;
862  auto callback = [&]() -> sk_sp<DisplayList> {
863  if (AiksTest::ImGuiBegin("Controls", nullptr,
864  ImGuiWindowFlags_AlwaysAutoResize)) {
865  ImGui::SliderFloat("Sigma", &sigma, 0, 200);
866  ImGui::SliderFloat("Frequency", &freq, 0.01, 2.0);
867  ImGui::SliderFloat("Amplitude", &amp, 1, 100);
868  ImGui::End();
869  }
870 
871  DisplayListBuilder builder;
872  builder.Scale(GetContentScale().x, GetContentScale().y);
873  Scalar y = amp * sin(freq * 2.0 * M_PI * count / 60);
874  builder.DrawImage(DlImageImpeller::Make(boston),
875  DlPoint(1024 / 2 - boston->GetSize().width / 2,
876  (768 / 2 - boston->GetSize().height / 2) + y),
877  DlImageSampling::kMipmapLinear);
878  static PlaygroundPoint point_a(Point(100, 100), 20, Color::Red());
879  static PlaygroundPoint point_b(Point(900, 700), 20, Color::Red());
880  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
881 
882  builder.ClipRect(
883  DlRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
884  builder.ClipRect(DlRect::MakeLTRB(100, 100, 900, 700));
885 
886  DlPaint paint;
887  paint.setBlendMode(DlBlendMode::kSrc);
888 
889  auto backdrop_filter =
890  DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
891  builder.SaveLayer(std::nullopt, &paint, backdrop_filter.get());
892  count += 1;
893  return builder.Build();
894  };
895  ASSERT_TRUE(OpenPlaygroundHere(callback));
896 }

References impeller::DrawPlaygroundLine(), impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), impeller::Color::Red(), and x.

◆ TEST_P() [221/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAtPeripheryHorizontal   
)

Definition at line 821 of file aiks_dl_blur_unittests.cc.

821  {
822  DisplayListBuilder builder;
823 
824  builder.Scale(GetContentScale().x, GetContentScale().y);
825  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
826  builder.DrawImageRect(
827  DlImageImpeller::Make(boston),
828  DlRect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
829  DlRect::MakeLTRB(0, 0, GetWindowSize().width, 100),
830  DlImageSampling::kNearestNeighbor);
831 
832  DlPaint paint;
833  paint.setColor(DlColor::kMagenta());
834 
835  DlRoundRect rrect = DlRoundRect::MakeRectXY(
836  DlRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10);
837  builder.DrawRoundRect(rrect, paint);
838  builder.ClipRect(DlRect::MakeLTRB(0, 50, GetWindowSize().width, 150));
839 
840  DlPaint save_paint;
841  save_paint.setBlendMode(DlBlendMode::kSrc);
842 
843  auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
844  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
845 
846  builder.Restore();
847  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
848 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [222/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAtPeripheryVertical   
)

Definition at line 793 of file aiks_dl_blur_unittests.cc.

793  {
794  DisplayListBuilder builder;
795 
796  DlPaint paint;
797  builder.Scale(GetContentScale().x, GetContentScale().y);
798 
799  paint.setColor(DlColor::kLimeGreen());
800  DlRoundRect rrect = DlRoundRect::MakeRectXY(
801  DlRect::MakeLTRB(0, 0, GetWindowSize().width, 100), 10, 10);
802  builder.DrawRoundRect(rrect, paint);
803 
804  paint.setColor(DlColor::kMagenta());
805  rrect = DlRoundRect::MakeRectXY(
806  DlRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10);
807  builder.DrawRoundRect(rrect, paint);
808  builder.ClipRect(DlRect::MakeLTRB(100, 0, 200, GetWindowSize().height));
809 
810  DlPaint save_paint;
811  save_paint.setBlendMode(DlBlendMode::kSrc);
812 
813  auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
814 
815  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
816  builder.Restore();
817 
818  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
819 }

References x.

◆ TEST_P() [223/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurBackdropTinyMipMap   
)

Definition at line 1284 of file aiks_dl_blur_unittests.cc.

1284  {
1285  AiksContext renderer(GetContext(), nullptr);
1286  for (int32_t i = 1; i < 5; ++i) {
1287  DisplayListBuilder builder;
1288 
1289  ISize clip_size = ISize(i, i);
1290  builder.Save();
1291  builder.ClipRect(
1292  DlRect::MakeXYWH(400, 400, clip_size.width, clip_size.height));
1293 
1294  DlPaint paint;
1295  paint.setColor(DlColor::kGreen());
1296  auto blur_filter = DlImageFilter::MakeBlur(0.1, 0.1, DlTileMode::kDecal);
1297  paint.setImageFilter(blur_filter);
1298 
1299  builder.DrawCircle(DlPoint(400, 400), 200, paint);
1300  builder.Restore();
1301 
1302  auto image = DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
1303  EXPECT_TRUE(image) << " length " << i;
1304  }
1305 }

References impeller::DisplayListToTexture(), impeller::TSize< T >::height, and impeller::TSize< T >::width.

◆ TEST_P() [224/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurOneDimension   
)

Definition at line 1096 of file aiks_dl_blur_unittests.cc.

1096  {
1097  DisplayListBuilder builder;
1098 
1099  builder.Scale(GetContentScale().x, GetContentScale().y);
1100  builder.Scale(0.5, 0.5);
1101 
1102  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1103  builder.DrawImage(DlImageImpeller::Make(boston), DlPoint(100, 100), {});
1104 
1105  DlPaint paint;
1106  paint.setBlendMode(DlBlendMode::kSrc);
1107 
1108  auto backdrop_filter = DlImageFilter::MakeBlur(50, 0, DlTileMode::kClamp);
1109  builder.SaveLayer(std::nullopt, &paint, backdrop_filter.get());
1110  builder.Restore();
1111  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1112 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [225/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedAndClipped   
)

Definition at line 1118 of file aiks_dl_blur_unittests.cc.

1118  {
1119  DisplayListBuilder builder;
1120 
1121  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1122  Rect bounds =
1123  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1124 
1125  DlPaint paint;
1126  paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
1127 
1128  Vector2 image_center = Vector2(bounds.GetSize() / 2);
1129  Vector2 clip_size = {150, 75};
1130  Vector2 center = Vector2(1024, 768) / 2;
1131  builder.Scale(GetContentScale().x, GetContentScale().y);
1132 
1133  auto clip_bounds =
1134  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size);
1135  builder.ClipRect(DlRect::MakeLTRB(clip_bounds.GetLeft(), clip_bounds.GetTop(),
1136  clip_bounds.GetRight(),
1137  clip_bounds.GetBottom()));
1138  builder.Translate(center.x, center.y);
1139  builder.Scale(0.6, 0.6);
1140  builder.Rotate(25);
1141 
1142  auto dst_rect = bounds.Shift(-image_center);
1143  builder.DrawImageRect(
1144  DlImageImpeller::Make(boston), /*src=*/
1145  DlRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(), bounds.GetRight(),
1146  bounds.GetBottom()),
1147  /*dst=*/
1148  DlRect::MakeLTRB(dst_rect.GetLeft(), dst_rect.GetTop(),
1149  dst_rect.GetRight(), dst_rect.GetBottom()),
1150  DlImageSampling::kMipmapLinear, &paint);
1151 
1152  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1153 }
constexpr TPoint Rotate(const Radians &angle) const
Definition: point.h:226

References impeller::TRect< T >::Expand(), impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetTop(), impeller::DlImageImpeller::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::TRect< T >::Shift(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [226/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedAndClippedInteractive   
)

Definition at line 1041 of file aiks_dl_blur_unittests.cc.

1041  {
1042  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1043 
1044  auto callback = [&]() -> sk_sp<DisplayList> {
1045  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1046  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
1047  DlTileMode::kMirror, DlTileMode::kDecal};
1048 
1049  static float rotation = 0;
1050  static float scale = 0.6;
1051  static int selected_tile_mode = 3;
1052 
1053  if (AiksTest::ImGuiBegin("Controls", nullptr,
1054  ImGuiWindowFlags_AlwaysAutoResize)) {
1055  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
1056  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
1057  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1058  sizeof(tile_mode_names) / sizeof(char*));
1059  ImGui::End();
1060  }
1061 
1062  DisplayListBuilder builder;
1063  Rect bounds =
1064  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1065  Vector2 image_center = Vector2(bounds.GetSize() / 2);
1066  DlPaint paint;
1067  paint.setImageFilter(
1068  DlImageFilter::MakeBlur(20, 20, tile_modes[selected_tile_mode]));
1069 
1070  static PlaygroundPoint point_a(Point(362, 309), 20, Color::Red());
1071  static PlaygroundPoint point_b(Point(662, 459), 20, Color::Red());
1072  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
1073  Vector2 center = Vector2(1024, 768) / 2;
1074 
1075  builder.Scale(GetContentScale().x, GetContentScale().y);
1076  builder.ClipRect(
1077  DlRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
1078  builder.Translate(center.x, center.y);
1079  builder.Scale(scale, scale);
1080  builder.Rotate(rotation);
1081 
1082  DlRect sk_bounds = DlRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(),
1083  bounds.GetRight(), bounds.GetBottom());
1084  Rect dest = bounds.Shift(-image_center);
1085  DlRect sk_dst = DlRect::MakeLTRB(dest.GetLeft(), dest.GetTop(),
1086  dest.GetRight(), dest.GetBottom());
1087  builder.DrawImageRect(DlImageImpeller::Make(boston), /*src=*/sk_bounds,
1088  /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor,
1089  &paint);
1090  return builder.Build();
1091  };
1092 
1093  ASSERT_TRUE(OpenPlaygroundHere(callback));
1094 }
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
Definition: rect.h:602

References impeller::DrawPlaygroundLine(), impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetTop(), impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::TPoint< T >::Rotate(), impeller::TRect< T >::Shift(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [227/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedNonUniform   
)

Definition at line 1155 of file aiks_dl_blur_unittests.cc.

1155  {
1156  auto callback = [&]() -> sk_sp<DisplayList> {
1157  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1158  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
1159  DlTileMode::kMirror, DlTileMode::kDecal};
1160 
1161  static float rotation = 45;
1162  static float scale = 0.6;
1163  static int selected_tile_mode = 3;
1164 
1165  if (AiksTest::ImGuiBegin("Controls", nullptr,
1166  ImGuiWindowFlags_AlwaysAutoResize)) {
1167  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
1168  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
1169  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1170  sizeof(tile_mode_names) / sizeof(char*));
1171  ImGui::End();
1172  }
1173 
1174  DisplayListBuilder builder;
1175 
1176  DlPaint paint;
1177  paint.setColor(DlColor::kGreen());
1178  paint.setImageFilter(
1179  DlImageFilter::MakeBlur(50, 0, tile_modes[selected_tile_mode]));
1180 
1181  Vector2 center = Vector2(1024, 768) / 2;
1182  builder.Scale(GetContentScale().x, GetContentScale().y);
1183  builder.Translate(center.x, center.y);
1184  builder.Scale(scale, scale);
1185  builder.Rotate(rotation);
1186 
1187  DlRoundRect rrect =
1188  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(-100, -100, 200, 200), 10, 10);
1189  builder.DrawRoundRect(rrect, paint);
1190  return builder.Build();
1191  };
1192 
1193  ASSERT_TRUE(OpenPlaygroundHere(callback));
1194 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::TPoint< T >::Rotate(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [228/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurScaledAndClipped   
)

Definition at line 1008 of file aiks_dl_blur_unittests.cc.

1008  {
1009  DisplayListBuilder builder;
1010  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1011  Rect bounds =
1012  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1013  Vector2 image_center = Vector2(bounds.GetSize() / 2);
1014 
1015  DlPaint paint;
1016  paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
1017 
1018  Vector2 clip_size = {150, 75};
1019  Vector2 center = Vector2(1024, 768) / 2;
1020  builder.Scale(GetContentScale().x, GetContentScale().y);
1021 
1022  auto rect =
1023  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size);
1024  builder.ClipRect(DlRect::MakeLTRB(rect.GetLeft(), rect.GetTop(),
1025  rect.GetRight(), rect.GetBottom()));
1026  builder.Translate(center.x, center.y);
1027  builder.Scale(0.6, 0.6);
1028 
1029  DlRect sk_bounds = DlRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(),
1030  bounds.GetRight(), bounds.GetBottom());
1031  Rect dest = bounds.Shift(-image_center);
1032  DlRect sk_dst = DlRect::MakeLTRB(dest.GetLeft(), dest.GetTop(),
1033  dest.GetRight(), dest.GetBottom());
1034  builder.DrawImageRect(DlImageImpeller::Make(boston), /*src=*/sk_bounds,
1035  /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor,
1036  &paint);
1037 
1038  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1039 }

References impeller::TRect< T >::Expand(), impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetTop(), impeller::DlImageImpeller::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::TRect< T >::Shift(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [229/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurSolidColorTinyMipMap   
)

Definition at line 1259 of file aiks_dl_blur_unittests.cc.

1259  {
1260  AiksContext renderer(GetContext(), nullptr);
1261 
1262  for (int32_t i = 1; i < 5; ++i) {
1263  DisplayListBuilder builder;
1264  Scalar fi = i;
1265  DlPathBuilder path_builder;
1266  path_builder.MoveTo(DlPoint(100, 100));
1267  path_builder.LineTo(DlPoint(100 + fi, 100 + fi));
1268 
1269  DlPaint paint;
1270  paint.setColor(DlColor::kChartreuse());
1271  auto blur_filter = DlImageFilter::MakeBlur(0.1, 0.1, DlTileMode::kClamp);
1272  paint.setImageFilter(blur_filter);
1273 
1274  builder.DrawPath(path_builder.TakePath(), paint);
1275 
1276  auto image = DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
1277  EXPECT_TRUE(image) << " length " << i;
1278  }
1279 }

References impeller::DisplayListToTexture().

◆ TEST_P() [230/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleInner   
)

Definition at line 648 of file aiks_dl_blur_unittests.cc.

648  {
649  DisplayListBuilder builder;
650  builder.Scale(GetContentScale().x, GetContentScale().y);
651 
652  DlPaint paint;
653  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1));
654  builder.DrawPaint(paint);
655 
656  paint.setColor(DlColor::kGreen());
657  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30));
658 
659  DlPathBuilder path_builder;
660  path_builder.MoveTo(DlPoint(200, 200));
661  path_builder.LineTo(DlPoint(300, 400));
662  path_builder.LineTo(DlPoint(100, 400));
663  path_builder.Close();
664 
665  builder.DrawPath(path_builder.TakePath(), paint);
666 
667  // Draw another thing to make sure the clip area is reset.
668  DlPaint red;
669  red.setColor(DlColor::kRed());
670  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
671 
672  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
673 }

References x.

◆ TEST_P() [231/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleInnerGradient   
)

Definition at line 898 of file aiks_dl_blur_unittests.cc.

898  {
899  DisplayListBuilder builder;
900 
901  builder.Scale(GetContentScale().x, GetContentScale().y);
902 
903  DlPaint paint;
904  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
905  builder.DrawPaint(paint);
906 
907  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
908  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
909  std::vector<Scalar> stops = {0.0, 1.0};
910 
911  paint = DlPaint{};
912  paint.setColorSource(DlColorSource::MakeLinear(
913  /*start_point=*/{0, 0},
914  /*end_point=*/{200, 200},
915  /*stop_count=*/colors.size(),
916  /*colors=*/colors.data(),
917  /*stops=*/stops.data(),
918  /*tile_mode=*/DlTileMode::kMirror));
919  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30));
920 
921  DlPathBuilder path_builder;
922  path_builder.MoveTo(DlPoint(200, 200));
923  path_builder.LineTo(DlPoint(300, 400));
924  path_builder.LineTo(DlPoint(100, 400));
925  path_builder.Close();
926  builder.DrawPath(path_builder.TakePath(), paint);
927 
928  // Draw another thing to make sure the clip area is reset.
929  DlPaint red;
930  red.setColor(DlColor::kRed());
931  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
932 
933  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
934 }

References x.

◆ TEST_P() [232/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleOuter   
)

Definition at line 675 of file aiks_dl_blur_unittests.cc.

675  {
676  DisplayListBuilder builder;
677  builder.Scale(GetContentScale().x, GetContentScale().y);
678 
679  DlPaint paint;
680  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
681  builder.DrawPaint(paint);
682 
683  paint.setColor(DlColor::kGreen());
684  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30));
685 
686  DlPathBuilder path_builder;
687  path_builder.MoveTo(DlPoint(200, 200));
688  path_builder.LineTo(DlPoint(300, 400));
689  path_builder.LineTo(DlPoint(100, 400));
690  path_builder.Close();
691 
692  builder.DrawPath(path_builder.TakePath(), paint);
693 
694  // Draw another thing to make sure the clip area is reset.
695  DlPaint red;
696  red.setColor(DlColor::kRed());
697  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
698 
699  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
700 }

References x.

◆ TEST_P() [233/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleOuterGradient   
)

Definition at line 972 of file aiks_dl_blur_unittests.cc.

972  {
973  DisplayListBuilder builder;
974  builder.Scale(GetContentScale().x, GetContentScale().y);
975 
976  DlPaint paint;
977  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
978  builder.DrawPaint(paint);
979 
980  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
981  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
982  std::vector<Scalar> stops = {0.0, 1.0};
983 
984  paint = DlPaint{};
985  paint.setColorSource(DlColorSource::MakeLinear(
986  /*start_point=*/{0, 0},
987  /*end_point=*/{200, 200},
988  /*stop_count=*/colors.size(),
989  /*colors=*/colors.data(),
990  /*stops=*/stops.data(),
991  /*tile_mode=*/DlTileMode::kMirror));
992  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30));
993 
994  DlPathBuilder path_builder;
995  path_builder.MoveTo(DlPoint(200, 200));
996  path_builder.LineTo(DlPoint(300, 400));
997  path_builder.LineTo(DlPoint(100, 400));
998  path_builder.Close();
999  builder.DrawPath(path_builder.TakePath(), paint);
1000 
1001  // Draw another thing to make sure the clip area is reset.
1002  DlPaint red;
1003  red.setColor(DlColor::kRed());
1004  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
1005  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1006 }

References x.

◆ TEST_P() [234/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleSolid   
)

Definition at line 702 of file aiks_dl_blur_unittests.cc.

702  {
703  DisplayListBuilder builder;
704  builder.Scale(GetContentScale().x, GetContentScale().y);
705 
706  DlPaint paint;
707  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
708  builder.DrawPaint(paint);
709 
710  paint.setColor(DlColor::kGreen());
711  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30));
712 
713  DlPathBuilder path_builder;
714  path_builder.MoveTo(DlPoint(200, 200));
715  path_builder.LineTo(DlPoint(300, 400));
716  path_builder.LineTo(DlPoint(100, 400));
717  path_builder.Close();
718 
719  builder.DrawPath(path_builder.TakePath(), paint);
720 
721  // Draw another thing to make sure the clip area is reset.
722  DlPaint red;
723  red.setColor(DlColor::kRed());
724  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
725 
726  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
727 }

References x.

◆ TEST_P() [235/549]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleSolidGradient   
)

Definition at line 936 of file aiks_dl_blur_unittests.cc.

936  {
937  DisplayListBuilder builder;
938  builder.Scale(GetContentScale().x, GetContentScale().y);
939 
940  DlPaint paint;
941  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
942  builder.DrawPaint(paint);
943 
944  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
945  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
946  std::vector<Scalar> stops = {0.0, 1.0};
947 
948  paint = DlPaint{};
949  paint.setColorSource(DlColorSource::MakeLinear(
950  /*start_point=*/{0, 0},
951  /*end_point=*/{200, 200},
952  /*stop_count=*/colors.size(),
953  /*colors=*/colors.data(),
954  /*stops=*/stops.data(),
955  /*tile_mode=*/DlTileMode::kMirror));
956  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30));
957 
958  DlPathBuilder path_builder;
959  path_builder.MoveTo(DlPoint(200, 200));
960  path_builder.LineTo(DlPoint(300, 400));
961  path_builder.LineTo(DlPoint(100, 400));
962  path_builder.Close();
963  builder.DrawPath(path_builder.TakePath(), paint);
964 
965  // Draw another thing to make sure the clip area is reset.
966  DlPaint red;
967  red.setColor(DlColor::kRed());
968  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
969  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
970 }

References x.

◆ TEST_P() [236/549]

impeller::testing::TEST_P ( AiksTest  ,
GradientOvalStrokeMaskBlur   
)

Definition at line 103 of file aiks_dl_blur_unittests.cc.

103  {
104  ASSERT_TRUE(OpenPlaygroundHere(DoGradientOvalStrokeMaskBlur(
105  GetContentScale(), /*sigma=*/10, DlBlurStyle::kNormal)));
106 }
sk_sp< flutter::DisplayList > DoGradientOvalStrokeMaskBlur(Vector2 content_Scale, Scalar sigma, DlBlurStyle style)

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [237/549]

impeller::testing::TEST_P ( AiksTest  ,
GradientOvalStrokeMaskBlurInner   
)

Definition at line 118 of file aiks_dl_blur_unittests.cc.

118  {
119  ASSERT_TRUE(OpenPlaygroundHere(DoGradientOvalStrokeMaskBlur(
120  GetContentScale(), /*sigma=*/10, DlBlurStyle::kInner)));
121 }

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [238/549]

impeller::testing::TEST_P ( AiksTest  ,
GradientOvalStrokeMaskBlurOuter   
)

Definition at line 113 of file aiks_dl_blur_unittests.cc.

113  {
114  ASSERT_TRUE(OpenPlaygroundHere(DoGradientOvalStrokeMaskBlur(
115  GetContentScale(), /*sigma=*/10, DlBlurStyle::kOuter)));
116 }

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [239/549]

impeller::testing::TEST_P ( AiksTest  ,
GradientOvalStrokeMaskBlurSigmaZero   
)

Definition at line 108 of file aiks_dl_blur_unittests.cc.

108  {
109  ASSERT_TRUE(OpenPlaygroundHere(DoGradientOvalStrokeMaskBlur(
110  GetContentScale(), /*sigma=*/0, DlBlurStyle::kNormal)));
111 }

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [240/549]

impeller::testing::TEST_P ( AiksTest  ,
GradientOvalStrokeMaskBlurSolid   
)

Definition at line 123 of file aiks_dl_blur_unittests.cc.

123  {
124  ASSERT_TRUE(OpenPlaygroundHere(DoGradientOvalStrokeMaskBlur(
125  GetContentScale(), /*sigma=*/10, DlBlurStyle::kSolid)));
126 }

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [241/549]

impeller::testing::TEST_P ( AiksTest  ,
GradientStrokesRenderCorrectly   
)

Definition at line 734 of file aiks_dl_gradient_unittests.cc.

734  {
735  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
736  auto callback = [&]() -> sk_sp<DisplayList> {
737  static float scale = 3;
738  static bool add_circle_clip = true;
739  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
740  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
741  DlTileMode::kMirror, DlTileMode::kDecal};
742  static int selected_tile_mode = 0;
743  static float alpha = 1;
744 
745  if (AiksTest::ImGuiBegin("Controls", nullptr,
746  ImGuiWindowFlags_AlwaysAutoResize)) {
747  ImGui::SliderFloat("Scale", &scale, 0, 6);
748  ImGui::Checkbox("Circle clip", &add_circle_clip);
749  ImGui::SliderFloat("Alpha", &alpha, 0, 1);
750  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
751  sizeof(tile_mode_names) / sizeof(char*));
752  ImGui::End();
753  }
754 
755  DisplayListBuilder builder;
756  builder.Scale(GetContentScale().x, GetContentScale().y);
757  DlPaint paint;
758  paint.setColor(DlColor::kWhite());
759  builder.DrawPaint(paint);
760 
761  paint.setDrawStyle(DlDrawStyle::kStroke);
762  paint.setColor(DlColor::kWhite().withAlpha(alpha * 255));
763  paint.setStrokeWidth(10);
764  auto tile_mode = tile_modes[selected_tile_mode];
765 
766  std::vector<DlColor> colors = {
767  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
768  DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
769  std::vector<Scalar> stops = {0.0, 1.0};
770 
771  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {50, 50},
772  stops.size(), colors.data(),
773  stops.data(), tile_mode));
774 
775  DlPathBuilder path_builder;
776  path_builder.MoveTo(DlPoint(20, 20));
777  path_builder.QuadraticCurveTo(DlPoint(60, 20), DlPoint(60, 60));
778  path_builder.Close();
779  path_builder.MoveTo(DlPoint(60, 20));
780  path_builder.QuadraticCurveTo(DlPoint(60, 60), DlPoint(20, 60));
781  DlPath path = path_builder.TakePath();
782 
783  builder.Scale(scale, scale);
784 
785  if (add_circle_clip) {
786  static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
787  Color::Red());
788  static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
789  Color::Red());
790  auto [handle_a, handle_b] =
791  DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
792 
793  Matrix ip_matrix = builder.GetMatrix();
794  if (!ip_matrix.IsInvertible()) {
795  return nullptr;
796  }
797  ip_matrix = ip_matrix.Invert();
798  Point point_a = ip_matrix * handle_a * GetContentScale();
799  Point point_b = ip_matrix * handle_b * GetContentScale();
800 
801  Point middle = (point_a + point_b) / 2;
802  auto radius = point_a.GetDistance(middle);
803  builder.ClipPath(DlPath::MakeCircle(middle, radius));
804  }
805 
806  for (auto join :
807  {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
808  paint.setStrokeJoin(join);
809  for (auto cap :
810  {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
811  paint.setStrokeCap(cap);
812  builder.DrawPath(path, paint);
813  builder.Translate(80, 0);
814  }
815  builder.Translate(-240, 60);
816  }
817 
818  return builder.Build();
819  };
820 
821  ASSERT_TRUE(OpenPlaygroundHere(callback));
822 }
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:200

References impeller::DrawPlaygroundLine(), impeller::TPoint< T >::GetDistance(), impeller::Matrix::Invert(), impeller::Matrix::IsInvertible(), impeller::Color::ToARGB(), and x.

◆ TEST_P() [242/549]

impeller::testing::TEST_P ( AiksTest  ,
HairlineDrawLine   
)

Definition at line 308 of file aiks_dl_path_unittests.cc.

308  {
309  Scalar scale = 1.f;
310  Scalar rotation = 0.f;
311  Scalar offset = 0.f;
312  auto callback = [&]() -> sk_sp<DisplayList> {
313  if (AiksTest::ImGuiBegin("Controls", nullptr,
314  ImGuiWindowFlags_AlwaysAutoResize)) {
315  ImGui::SliderFloat("Scale", &scale, 0, 6);
316  ImGui::SliderFloat("Rotate", &rotation, 0, 90);
317  ImGui::SliderFloat("Offset", &offset, 0, 2);
318  ImGui::End();
319  }
320 
321  DisplayListBuilder builder;
322  builder.Scale(GetContentScale().x, GetContentScale().y);
323  builder.DrawPaint(DlPaint(DlColor(0xff111111)));
324 
325  DlPaint paint;
326  paint.setStrokeWidth(0.f);
327  paint.setColor(DlColor::kWhite());
328 
329  builder.Translate(512, 384);
330  builder.Scale(scale, scale);
331  builder.Rotate(rotation);
332  builder.Translate(-512, -384 + offset);
333 
334  for (int i = 0; i < 5; ++i) {
335  Scalar yoffset = i * 25.25f + 300.f;
336 
337  builder.DrawLine(DlPoint(100, yoffset), DlPoint(924, yoffset), paint);
338  }
339 
340  return builder.Build();
341  };
342 
343  ASSERT_TRUE(OpenPlaygroundHere(callback));
344 }

References impeller::AiksPlayground::ImGuiBegin(), and x.

◆ TEST_P() [243/549]

impeller::testing::TEST_P ( AiksTest  ,
HairlinePath   
)

Definition at line 264 of file aiks_dl_path_unittests.cc.

264  {
265  Scalar scale = 1.f;
266  Scalar rotation = 0.f;
267  Scalar offset = 0.f;
268  auto callback = [&]() -> sk_sp<DisplayList> {
269  if (AiksTest::ImGuiBegin("Controls", nullptr,
270  ImGuiWindowFlags_AlwaysAutoResize)) {
271  ImGui::SliderFloat("Scale", &scale, 0, 6);
272  ImGui::SliderFloat("Rotate", &rotation, 0, 90);
273  ImGui::SliderFloat("Offset", &offset, 0, 2);
274  ImGui::End();
275  }
276 
277  DisplayListBuilder builder;
278  builder.Scale(GetContentScale().x, GetContentScale().y);
279  builder.DrawPaint(DlPaint(DlColor(0xff111111)));
280 
281  DlPaint paint;
282  paint.setStrokeWidth(0.f);
283  paint.setColor(DlColor::kWhite());
284  paint.setStrokeCap(DlStrokeCap::kRound);
285  paint.setStrokeJoin(DlStrokeJoin::kRound);
286  paint.setDrawStyle(DlDrawStyle::kStroke);
287 
288  builder.Translate(512, 384);
289  builder.Scale(scale, scale);
290  builder.Rotate(rotation);
291  builder.Translate(-512, -384 + offset);
292 
293  for (int i = 0; i < 5; ++i) {
294  Scalar yoffset = i * 25.25f + 300.f;
295  DlPathBuilder path_builder;
296 
297  path_builder.MoveTo(DlPoint(100, yoffset));
298  path_builder.LineTo(DlPoint(924, yoffset));
299  builder.DrawPath(path_builder.TakePath(), paint);
300  }
301 
302  return builder.Build();
303  };
304 
305  ASSERT_TRUE(OpenPlaygroundHere(callback));
306 }

References impeller::AiksPlayground::ImGuiBegin(), and x.

◆ TEST_P() [244/549]

impeller::testing::TEST_P ( AiksTest  ,
HexagonExperimentAntialiasLines   
)

Definition at line 680 of file aiks_dl_path_unittests.cc.

680  {
681  float scale = 5.0f;
682  float line_width = 10.f;
683  float rotation = 0.f;
684 
685  auto callback = [&]() -> sk_sp<DisplayList> {
686  if (AiksTest::ImGuiBegin("Controls", nullptr,
687  ImGuiWindowFlags_AlwaysAutoResize)) {
688  // Use ImGui::SliderFloat for consistency
689  ImGui::SliderFloat("Scale", &scale, 0.001f, 5.0f);
690  ImGui::SliderFloat("Width", &line_width, 1.0f, 20.0f);
691  ImGui::SliderFloat("Rotation", &rotation, 0.0f, 180.0f);
692 
693  ImGui::End();
694  }
695  DisplayListBuilder builder;
696  builder.Scale(static_cast<float>(GetContentScale().x),
697  static_cast<float>(GetContentScale().y));
698 
699  builder.DrawPaint(DlPaint(DlColor(0xff111111))); // Background
700 
701  {
702  DlPaint hex_paint;
703  hex_paint.setColor(
704  DlColor::kGreen()); // Changed color to Red for visibility
705  hex_paint.setStrokeWidth(line_width); // Use the interactive width
706 
707  float cx = 512.0f; // Center X
708  float cy = 384.0f; // Center Y
709  float r = 80.0f; // Radius (distance from center to vertex)
710 
711  float r_sin60 = r * std::sqrt(3.0f) / 2.0f;
712  float r_cos60 = r / 2.0f;
713 
714  DlPoint v0 = DlPoint(cx + r, cy); // Right vertex
715  DlPoint v1 = DlPoint(cx + r_cos60, cy - r_sin60); // Top-right vertex
716  DlPoint v2 = DlPoint(
717  cx - r_cos60,
718  cy - r_sin60); // Top-left vertex (v1-v2 is top horizontal side)
719  DlPoint v3 = DlPoint(cx - r, cy); // Left vertex
720  DlPoint v4 = DlPoint(cx - r_cos60, cy + r_sin60); // Bottom-left vertex
721  DlPoint v5 =
722  DlPoint(cx + r_cos60, cy + r_sin60); // Bottom-right vertex (v4-v5 is
723  // bottom horizontal side)
724 
725  builder.Translate(cx, cy);
726  builder.Scale(scale, scale);
727  builder.Rotate(rotation);
728  builder.Translate(-cx, -cy);
729 
730  builder.DrawLine(v0, v1, hex_paint);
731  builder.DrawLine(v1, v2, hex_paint); // Top side
732  builder.DrawLine(v2, v3, hex_paint);
733  builder.DrawLine(v3, v4, hex_paint);
734  builder.DrawLine(v4, v5, hex_paint); // Bottom side
735  builder.DrawLine(v5, v0, hex_paint); // Close the hexagon
736  }
737 
738  return builder.Build();
739  };
740  ASSERT_TRUE(OpenPlaygroundHere(callback));
741 }

References impeller::AiksPlayground::ImGuiBegin(), and x.

◆ TEST_P() [245/549]

impeller::testing::TEST_P ( AiksTest  ,
ImageColorSourceEffectTransform   
)

Definition at line 1434 of file aiks_dl_basic_unittests.cc.

1434  {
1435  // Compare with https://fiddle.skia.org/c/6cdc5aefb291fda3833b806ca347a885
1436 
1437  DisplayListBuilder builder;
1438  auto texture = DlImageImpeller::Make(CreateTextureForFixture("monkey.png"));
1439 
1440  DlPaint paint;
1441  paint.setColor(DlColor::kWhite());
1442  builder.DrawPaint(paint);
1443 
1444  // Translation
1445  {
1446  DlMatrix matrix = DlMatrix::MakeTranslation({50, 50});
1447  DlPaint paint;
1448  paint.setColorSource(DlColorSource::MakeImage(
1449  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1450  DlImageSampling::kNearestNeighbor, &matrix));
1451 
1452  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), paint);
1453  }
1454 
1455  // Rotation/skew
1456  {
1457  builder.Save();
1458  builder.Rotate(45);
1459  DlPaint paint;
1460 
1461  Matrix matrix(1, -1, 0, 0, //
1462  1, 1, 0, 0, //
1463  0, 0, 1, 0, //
1464  0, 0, 0, 1);
1465  paint.setColorSource(DlColorSource::MakeImage(
1466  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1467  DlImageSampling::kNearestNeighbor, &matrix));
1468  builder.DrawRect(DlRect::MakeLTRB(100, 0, 200, 100), paint);
1469  builder.Restore();
1470  }
1471 
1472  // Scale
1473  {
1474  builder.Save();
1475  builder.Translate(100, 0);
1476  builder.Scale(100, 100);
1477  DlPaint paint;
1478 
1479  DlMatrix matrix = DlMatrix::MakeScale({0.005, 0.005, 1});
1480  paint.setColorSource(DlColorSource::MakeImage(
1481  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1482  DlImageSampling::kNearestNeighbor, &matrix));
1483 
1484  builder.DrawRect(DlRect::MakeLTRB(0, 0, 1, 1), paint);
1485  builder.Restore();
1486  }
1487 
1488  // Perspective
1489  {
1490  builder.Save();
1491  builder.Translate(150, 150);
1492  DlPaint paint;
1493 
1494  DlMatrix matrix =
1495  DlMatrix::MakePerspective(Radians{0.5}, ISize{200, 200}, 0.05, 1);
1496  paint.setColorSource(DlColorSource::MakeImage(
1497  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1498  DlImageSampling::kNearestNeighbor, &matrix));
1499 
1500  builder.DrawRect(DlRect::MakeLTRB(0, 0, 200, 200), paint);
1501  builder.Restore();
1502  }
1503 
1504  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1505 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [246/549]

impeller::testing::TEST_P ( AiksTest  ,
ImageFilteredSaveLayerWithUnboundedContents   
)

Definition at line 661 of file aiks_dl_unittests.cc.

661  {
662  DisplayListBuilder builder;
663  builder.Scale(GetContentScale().x, GetContentScale().y);
664 
665  auto test = [&builder](const std::shared_ptr<DlImageFilter>& filter) {
666  auto DrawLine = [&builder](const DlPoint& p0, const DlPoint& p1,
667  const DlPaint& p) {
668  DlPaint paint = p;
669  paint.setDrawStyle(DlDrawStyle::kStroke);
670  builder.DrawPath(DlPath::MakeLine(p0, p1), paint);
671  };
672  // Registration marks for the edge of the SaveLayer
673  DlPaint paint;
674  paint.setColor(DlColor::kWhite());
675  DrawLine(DlPoint(75, 100), DlPoint(225, 100), paint);
676  DrawLine(DlPoint(75, 200), DlPoint(225, 200), paint);
677  DrawLine(DlPoint(100, 75), DlPoint(100, 225), paint);
678  DrawLine(DlPoint(200, 75), DlPoint(200, 225), paint);
679 
680  DlPaint save_paint;
681  save_paint.setImageFilter(filter);
682  DlRect bounds = DlRect::MakeLTRB(100, 100, 200, 200);
683  builder.SaveLayer(bounds, &save_paint);
684 
685  {
686  // DrawPaint to verify correct behavior when the contents are unbounded.
687  DlPaint paint;
688  paint.setColor(DlColor::kYellow());
689  builder.DrawPaint(paint);
690 
691  // Contrasting rectangle to see interior blurring
692  paint.setColor(DlColor::kBlue());
693  builder.DrawRect(DlRect::MakeLTRB(125, 125, 175, 175), paint);
694  }
695  builder.Restore();
696  };
697 
698  test(DlImageFilter::MakeBlur(10.0, 10.0, DlTileMode::kDecal));
699 
700  builder.Translate(200.0, 0.0);
701 
702  test(DlImageFilter::MakeDilate(10.0, 10.0));
703 
704  builder.Translate(200.0, 0.0);
705 
706  test(DlImageFilter::MakeErode(10.0, 10.0));
707 
708  builder.Translate(-400.0, 200.0);
709 
710  DlMatrix matrix = DlMatrix::MakeRotationZ(DlDegrees(10));
711 
712  auto rotate_filter =
713  DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear);
714  test(rotate_filter);
715 
716  builder.Translate(200.0, 0.0);
717 
718  const float m[20] = {
719  0, 1, 0, 0, 0, //
720  0, 0, 1, 0, 0, //
721  1, 0, 0, 0, 0, //
722  0, 0, 0, 1, 0 //
723  };
724  auto rgb_swap_filter =
725  DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(m));
726  test(rgb_swap_filter);
727 
728  builder.Translate(200.0, 0.0);
729 
730  test(DlImageFilter::MakeCompose(rotate_filter, rgb_swap_filter));
731 
732  builder.Translate(-400.0, 200.0);
733 
734  test(rotate_filter->makeWithLocalMatrix(
735  DlMatrix::MakeTranslation({25.0, 25.0})));
736 
737  builder.Translate(200.0, 0.0);
738 
739  test(rgb_swap_filter->makeWithLocalMatrix(
740  DlMatrix::MakeTranslation({25.0, 25.0})));
741 
742  builder.Translate(200.0, 0.0);
743 
744  test(DlImageFilter::MakeCompose(rotate_filter, rgb_swap_filter)
745  ->makeWithLocalMatrix(DlMatrix::MakeTranslation({25.0, 25.0})));
746 
747  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
748 }

References x.

◆ TEST_P() [247/549]

impeller::testing::TEST_P ( AiksTest  ,
ImageFilteredUnboundedSaveLayerWithUnboundedContents   
)

Definition at line 225 of file aiks_dl_unittests.cc.

225  {
226  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
227  builder.Scale(GetContentScale().x, GetContentScale().y);
228 
229  DlPaint save_paint;
230  save_paint.setImageFilter(
231  DlImageFilter::MakeBlur(10.0, 10.0, DlTileMode::kDecal));
232  builder.SaveLayer(std::nullopt, &save_paint);
233 
234  {
235  // DrawPaint to verify correct behavior when the contents are unbounded.
236  DlPaint draw_paint;
237  draw_paint.setColor(DlColor::kYellow());
238  builder.DrawPaint(draw_paint);
239 
240  // Contrasting rectangle to see interior blurring
241  DlPaint draw_rect;
242  draw_rect.setColor(DlColor::kBlue());
243  builder.DrawRect(DlRect::MakeLTRB(125, 125, 175, 175), draw_rect);
244  }
245  builder.Restore();
246 
247  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
248 }

References x.

◆ TEST_P() [248/549]

impeller::testing::TEST_P ( AiksTest  ,
LinearToSrgbFilterSubpassCollapseOptimization   
)

Definition at line 105 of file aiks_dl_unittests.cc.

105  {
106  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
107 
108  DlPaint paint;
109  paint.setColorFilter(DlColorFilter::MakeLinearToSrgbGamma());
110  builder.SaveLayer(std::nullopt, &paint);
111 
112  builder.Translate(500, 300);
113  builder.Rotate(120); // 120 deg.
114 
115  DlPaint draw_paint;
116  draw_paint.setColor(DlColor::kBlue());
117  builder.DrawRect(DlRect::MakeXYWH(100, 100, 200, 200), draw_paint);
118 
119  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
120 }

◆ TEST_P() [249/549]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurDoesntStretchContents   
)

Definition at line 758 of file aiks_dl_blur_unittests.cc.

758  {
759  Scalar sigma = 70;
760  auto callback = [&]() -> sk_sp<DisplayList> {
761  if (AiksTest::ImGuiBegin("Controls", nullptr,
762  ImGuiWindowFlags_AlwaysAutoResize)) {
763  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
764  ImGui::End();
765  }
766 
767  DisplayListBuilder builder;
768  builder.Scale(GetContentScale().x, GetContentScale().y);
769 
770  DlPaint paint;
771  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
772  builder.DrawPaint(paint);
773 
774  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
775 
776  builder.Transform(Matrix::MakeTranslation({100, 100}) *
777  Matrix::MakeScale({0.5, 0.5, 1.0f}));
778 
779  paint.setColorSource(DlColorSource::MakeImage(
780  DlImageImpeller::Make(boston), DlTileMode::kRepeat, DlTileMode::kRepeat,
781  DlImageSampling::kMipmapLinear));
782  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
783 
784  builder.DrawRect(DlRect::MakeXYWH(0, 0, boston->GetSize().width,
785  boston->GetSize().height),
786  paint);
787 
788  return builder.Build();
789  };
790  ASSERT_TRUE(OpenPlaygroundHere(callback));
791 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and x.

◆ TEST_P() [250/549]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurOnZeroDimensionIsSkippedWideGamut   
)

Definition at line 474 of file aiks_dl_blur_unittests.cc.

474  {
475  // Making sure this test is run on a wide gamut enabled backend
476  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
477  PixelFormat::kB10G10R10A10XR);
478 
479  DisplayListBuilder builder;
480  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
481 
482  DlPaint paint;
483  paint.setColor(DlColor::kBlue());
484  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 10));
485 
486  // Zero height above
487  builder.DrawRect(DlRect::MakeLTRB(100, 250, 500, 250), paint);
488  // Regular rect
489  builder.DrawRect(DlRect::MakeLTRB(100, 300, 500, 600), paint);
490  // Zero width to the right
491  builder.DrawRect(DlRect::MakeLTRB(550, 300, 550, 600), paint);
492 
493  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
494 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [251/549]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurTexture   
)

Definition at line 729 of file aiks_dl_blur_unittests.cc.

729  {
730  Scalar sigma = 30;
731  auto callback = [&]() -> sk_sp<DisplayList> {
732  if (AiksTest::ImGuiBegin("Controls", nullptr,
733  ImGuiWindowFlags_AlwaysAutoResize)) {
734  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
735  ImGui::End();
736  }
737 
738  DisplayListBuilder builder;
739  builder.Scale(GetContentScale().x, GetContentScale().y);
740 
741  DlPaint paint;
742  paint.setColor(DlColor::kGreen());
743  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
744 
745  builder.DrawImage(
746  DlImageImpeller::Make(CreateTextureForFixture("boston.jpg")),
747  DlPoint(200, 200), DlImageSampling::kNearestNeighbor, &paint);
748 
749  DlPaint red;
750  red.setColor(DlColor::kRed());
751  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
752 
753  return builder.Build();
754  };
755  ASSERT_TRUE(OpenPlaygroundHere(callback));
756 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [252/549]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurWithZeroSigmaIsSkipped   
)

Definition at line 461 of file aiks_dl_blur_unittests.cc.

461  {
462  DisplayListBuilder builder;
463 
464  DlPaint paint;
465  paint.setColor(DlColor::kBlue());
466  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 0));
467 
468  builder.DrawCircle(DlPoint(300, 300), 200, paint);
469  builder.DrawRect(DlRect::MakeLTRB(100, 300, 500, 600), paint);
470 
471  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
472 }

◆ TEST_P() [253/549]

impeller::testing::TEST_P ( AiksTest  ,
MassiveScaleConvertToPath   
)

Definition at line 196 of file aiks_dl_text_unittests.cc.

196  {
197  Scalar scale = 16.0;
198  auto callback = [&]() -> sk_sp<DisplayList> {
199  if (AiksTest::ImGuiBegin("Controls", nullptr,
200  ImGuiWindowFlags_AlwaysAutoResize)) {
201  ImGui::SliderFloat("Scale", &scale, 4, 20);
202  ImGui::End();
203  }
204 
205  DisplayListBuilder builder;
206  DlPaint paint;
207  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
208  builder.DrawPaint(paint);
209 
210  builder.Scale(scale, scale);
212  GetContext(), builder, "HELLO", "Roboto-Regular.ttf",
213  TextRenderOptions{.font_size = 16,
214  .color = (16 * scale >= 250) ? DlColor::kYellow()
215  : DlColor::kOrange(),
216  .position = DlPoint(0, 20)});
217  return builder.Build();
218  };
219 
220  ASSERT_TRUE(OpenPlaygroundHere(callback));
221 }

References impeller::testing::TextRenderOptions::font_size, and RenderTextInCanvasSkia().

◆ TEST_P() [254/549]

impeller::testing::TEST_P ( AiksTest  ,
MassiveScalingMatrixImageFilter   
)

Definition at line 2078 of file aiks_dl_basic_unittests.cc.

2078  {
2079  if (GetBackend() == PlaygroundBackend::kVulkan) {
2080  GTEST_SKIP() << "Swiftshader is running out of memory on this example.";
2081  }
2082  DisplayListBuilder builder(DlRect::MakeSize(DlSize(1000, 1000)));
2083 
2084  auto filter = DlImageFilter::MakeMatrix(
2085  DlMatrix::MakeScale({0.001, 0.001, 1}), DlImageSampling::kLinear);
2086 
2087  DlPaint paint;
2088  paint.setImageFilter(filter);
2089  builder.SaveLayer(std::nullopt, &paint);
2090  {
2091  DlPaint paint;
2092  paint.setColor(DlColor::kRed());
2093  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100000, 100000), paint);
2094  }
2095  builder.Restore();
2096 
2097  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
2098 }

References impeller::kVulkan.

◆ TEST_P() [255/549]

impeller::testing::TEST_P ( AiksTest  ,
MatrixBackdropFilter   
)

Definition at line 750 of file aiks_dl_unittests.cc.

750  {
751  DisplayListBuilder builder;
752 
753  DlPaint paint;
754  paint.setColor(DlColor::kBlack());
755  builder.DrawPaint(paint);
756  builder.SaveLayer(std::nullopt, nullptr);
757  {
758  DlPaint paint;
759  paint.setColor(DlColor::kGreen().withAlpha(0.5 * 255));
760  paint.setBlendMode(DlBlendMode::kPlus);
761 
762  DlPaint rect_paint;
763  rect_paint.setColor(DlColor::kRed());
764  rect_paint.setStrokeWidth(4);
765  rect_paint.setDrawStyle(DlDrawStyle::kStroke);
766  builder.DrawRect(DlRect::MakeLTRB(0, 0, 300, 300), rect_paint);
767  builder.DrawCircle(DlPoint(200, 200), 100, paint);
768  // Should render a second circle, centered on the bottom-right-most edge of
769  // the circle.
770  DlMatrix matrix = DlMatrix::MakeTranslation({(100 + 100 * k1OverSqrt2),
771  (100 + 100 * k1OverSqrt2)}) *
772  DlMatrix::MakeScale({0.5, 0.5, 1}) *
773  DlMatrix::MakeTranslation({-100, -100});
774  auto backdrop_filter =
775  DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear);
776  builder.SaveLayer(std::nullopt, nullptr, backdrop_filter.get());
777  builder.Restore();
778  }
779  builder.Restore();
780 
781  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
782 }

References impeller::k1OverSqrt2.

◆ TEST_P() [256/549]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen   
)

Definition at line 1557 of file aiks_dl_basic_unittests.cc.

1558  {
1559  DisplayListBuilder builder;
1560  builder.Scale(GetContentScale().x, GetContentScale().y);
1561  builder.Translate(100, 100);
1562  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
1563  // +300 translation applied by a SaveLayer image filter.
1564 
1565  DlPaint paint;
1566  paint.setImageFilter(DlImageFilter::MakeMatrix(
1567  DlMatrix::MakeTranslation({300, 0}) * DlMatrix::MakeScale({2, 2, 1}),
1568  DlImageSampling::kNearestNeighbor));
1569  builder.SaveLayer(std::nullopt, &paint);
1570 
1571  DlPaint circle_paint;
1572  circle_paint.setColor(DlColor::kGreen());
1573  builder.DrawCircle(DlPoint(-150, 0), 50, circle_paint);
1574  builder.Restore();
1575 
1576  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1577 }

References x.

◆ TEST_P() [257/549]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen   
)

Definition at line 1536 of file aiks_dl_basic_unittests.cc.

1536  {
1537  DisplayListBuilder builder;
1538  builder.Scale(GetContentScale().x, GetContentScale().y);
1539  builder.Translate(100, 100);
1540  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
1541  // +300 translation applied by a SaveLayer image filter.
1542  DlPaint paint;
1543  DlMatrix translate = DlMatrix::MakeTranslation({300, 0});
1544  paint.setImageFilter(
1545  DlImageFilter::MakeMatrix(translate, DlImageSampling::kLinear));
1546  builder.SaveLayer(std::nullopt, &paint);
1547 
1548  DlPaint circle_paint;
1549  circle_paint.setColor(DlColor::kGreen());
1550  builder.DrawCircle(DlPoint(-300, 0), 100, circle_paint);
1551  builder.Restore();
1552 
1553  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1554 }

References x.

◆ TEST_P() [258/549]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterMagnify   
)

Definition at line 629 of file aiks_dl_unittests.cc.

629  {
630  Scalar scale = 2.0;
631  auto callback = [&]() -> sk_sp<DisplayList> {
632  if (AiksTest::ImGuiBegin("Controls", nullptr,
633  ImGuiWindowFlags_AlwaysAutoResize)) {
634  ImGui::SliderFloat("Scale", &scale, 1, 2);
635  ImGui::End();
636  }
637  DisplayListBuilder builder;
638  builder.Scale(GetContentScale().x, GetContentScale().y);
639  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
640 
641  builder.Translate(600, -200);
642 
643  DlMatrix matrix = DlMatrix::MakeScale({scale, scale, 1});
644  DlPaint paint;
645  paint.setImageFilter(
646  DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear));
647  builder.SaveLayer(std::nullopt, &paint);
648 
649  DlPaint rect_paint;
650  rect_paint.setAlpha(0.5 * 255);
651  builder.DrawImage(image, DlPoint(0, 0), DlImageSampling::kLinear,
652  &rect_paint);
653  builder.Restore();
654 
655  return builder.Build();
656  };
657 
658  ASSERT_TRUE(OpenPlaygroundHere(callback));
659 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [259/549]

impeller::testing::TEST_P ( AiksTest  ,
MatrixSaveLayerFilter   
)

Definition at line 784 of file aiks_dl_unittests.cc.

784  {
785  DisplayListBuilder builder;
786 
787  DlPaint paint;
788  paint.setColor(DlColor::kBlack());
789  builder.DrawPaint(paint);
790  builder.SaveLayer(std::nullopt, nullptr);
791  {
792  paint.setColor(DlColor::kGreen().withAlpha(255 * 0.5));
793  paint.setBlendMode(DlBlendMode::kPlus);
794  builder.DrawCircle(DlPoint(200, 200), 100, paint);
795  // Should render a second circle, centered on the bottom-right-most edge of
796  // the circle.
797 
798  DlMatrix matrix = DlMatrix::MakeTranslation({(200 + 100 * k1OverSqrt2),
799  (200 + 100 * k1OverSqrt2)}) *
800  DlMatrix::MakeScale({0.5, 0.5, 1}) *
801  DlMatrix::MakeTranslation({-200, -200});
802  DlPaint save_paint;
803  save_paint.setImageFilter(
804  DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear));
805 
806  builder.SaveLayer(std::nullopt, &save_paint);
807 
808  DlPaint circle_paint;
809  circle_paint.setColor(DlColor::kGreen().withAlpha(255 * 0.5));
810  circle_paint.setBlendMode(DlBlendMode::kPlus);
811  builder.DrawCircle(DlPoint(200, 200), 100, circle_paint);
812  builder.Restore();
813  }
814  builder.Restore();
815 
816  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
817 }

References impeller::k1OverSqrt2.

◆ TEST_P() [260/549]

impeller::testing::TEST_P ( AiksTest  ,
MipmapGenerationWorksCorrectly   
)

Definition at line 481 of file aiks_dl_unittests.cc.

481  {
482  TextureDescriptor texture_descriptor;
483  texture_descriptor.size = ISize{1024, 1024};
484  texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
485  texture_descriptor.storage_mode = StorageMode::kHostVisible;
486  texture_descriptor.mip_count = texture_descriptor.size.MipCount();
487 
488  std::vector<uint8_t> bytes(4194304);
489  bool alternate = false;
490  for (auto i = 0u; i < 4194304; i += 4) {
491  if (alternate) {
492  bytes[i] = 255;
493  bytes[i + 1] = 0;
494  bytes[i + 2] = 0;
495  bytes[i + 3] = 255;
496  } else {
497  bytes[i] = 0;
498  bytes[i + 1] = 255;
499  bytes[i + 2] = 0;
500  bytes[i + 3] = 255;
501  }
502  alternate = !alternate;
503  }
504 
505  ASSERT_EQ(texture_descriptor.GetByteSizeOfBaseMipLevel(), bytes.size());
506  auto mapping = std::make_shared<fml::NonOwnedMapping>(
507  bytes.data(), // data
508  texture_descriptor.GetByteSizeOfBaseMipLevel() // size
509  );
510  auto texture =
511  GetContext()->GetResourceAllocator()->CreateTexture(texture_descriptor);
512 
513  auto device_buffer =
514  GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
515  auto command_buffer = GetContext()->CreateCommandBuffer();
516  auto blit_pass = command_buffer->CreateBlitPass();
517 
518  blit_pass->AddCopy(DeviceBuffer::AsBufferView(std::move(device_buffer)),
519  texture);
520  blit_pass->GenerateMipmap(texture);
521  EXPECT_TRUE(blit_pass->EncodeCommands());
522  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({command_buffer}).ok());
523 
524  auto image = DlImageImpeller::Make(texture);
525 
526  DisplayListBuilder builder;
527  builder.DrawImageRect(
528  image,
529  DlRect::MakeWH(texture->GetSize().width, texture->GetSize().height),
530  DlRect::MakeLTRB(0, 0, 100, 100), DlImageSampling::kMipmapLinear);
531 
532  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
533 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel(), impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::DlImageImpeller::Make(), impeller::TextureDescriptor::mip_count, impeller::TSize< T >::MipCount(), impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [261/549]

impeller::testing::TEST_P ( AiksTest  ,
MultipleTextWithShadowCache   
)

Definition at line 804 of file aiks_dl_text_unittests.cc.

804  {
805  DisplayListBuilder builder;
806  builder.Scale(GetContentScale().x, GetContentScale().y);
807  DlPaint paint;
808  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
809  builder.DrawPaint(paint);
810 
811  AiksContext aiks_context(GetContext(),
812  std::make_shared<TypographerContextSkia>());
813  // Cache empty
814  EXPECT_EQ(aiks_context.GetContentContext()
815  .GetTextShadowCache()
816  .GetCacheSizeForTesting(),
817  0u);
818 
819  for (auto i = 0; i < 5; i++) {
820  ASSERT_TRUE(RenderTextInCanvasSkia(
821  GetContext(), builder, "Hello World", kFontFixture,
822  TextRenderOptions{
823  .color = DlColor::kBlue(),
824  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
825  }
826 
827  DisplayListToTexture(builder.Build(), {400, 400}, aiks_context);
828 
829  // Text should be cached. Each text gets its own entry as we don't analyze the
830  // strings.
831  EXPECT_EQ(aiks_context.GetContentContext()
832  .GetTextShadowCache()
833  .GetCacheSizeForTesting(),
834  5u);
835 }

References impeller::testing::TextRenderOptions::color, impeller::DisplayListToTexture(), impeller::TextShadowCache::GetCacheSizeForTesting(), impeller::AiksContext::GetContentContext(), impeller::ContentContext::GetTextShadowCache(), kFontFixture, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [262/549]

impeller::testing::TEST_P ( AiksTest  ,
NoDimplesInRRectPath   
)

Definition at line 2100 of file aiks_dl_basic_unittests.cc.

2100  {
2101  Scalar width = 200.f;
2102  Scalar height = 60.f;
2103  Scalar corner = 1.f;
2104  auto callback = [&]() -> sk_sp<DisplayList> {
2105  if (AiksTest::ImGuiBegin("Controls", nullptr,
2106  ImGuiWindowFlags_AlwaysAutoResize)) {
2107  ImGui::SliderFloat("width", &width, 0, 200);
2108  ImGui::SliderFloat("height", &height, 0, 200);
2109  ImGui::SliderFloat("corner", &corner, 0, 1);
2110  ImGui::End();
2111  }
2112 
2113  DisplayListBuilder builder;
2114  builder.Scale(GetContentScale().x, GetContentScale().y);
2115 
2116  DlPaint background_paint;
2117  background_paint.setColor(DlColor(1, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
2118  builder.DrawPaint(background_paint);
2119 
2120  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue()};
2121  std::vector<Scalar> stops = {0.0, 1.0};
2122 
2123  DlPaint paint;
2124  auto gradient = DlColorSource::MakeLinear(DlPoint(0, 0), DlPoint(200, 200),
2125  2, colors.data(), stops.data(),
2126  DlTileMode::kClamp);
2127  paint.setColorSource(gradient);
2128  paint.setColor(DlColor::kWhite());
2129  paint.setDrawStyle(DlDrawStyle::kStroke);
2130  paint.setStrokeWidth(20);
2131 
2132  builder.Save();
2133  builder.Translate(100, 100);
2134 
2135  Scalar corner_x = ((1 - corner) * 50) + 50;
2136  Scalar corner_y = corner * 50 + 50;
2137  DlRoundRect rrect = DlRoundRect::MakeRectXY(
2138  DlRect::MakeXYWH(0, 0, width, height), corner_x, corner_y);
2139  builder.DrawRoundRect(rrect, paint);
2140  builder.Restore();
2141  return builder.Build();
2142  };
2143  ASSERT_TRUE(OpenPlaygroundHere(callback));
2144 }

References impeller::AiksPlayground::ImGuiBegin(), and x.

◆ TEST_P() [263/549]

impeller::testing::TEST_P ( AiksTest  ,
NonSquareFilledArcsRenderCorrectly   
)

Definition at line 891 of file aiks_dl_basic_unittests.cc.

891  {
892  DisplayListBuilder builder;
893  builder.Scale(GetContentScale().x, GetContentScale().y);
894  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
895 
896  DlPaint paint;
897  paint.setColor(DlColor::kBlue());
898 
899  RenderArcFarm(builder, paint,
900  {
901  .use_center = false,
902  .full_circles = false,
903  .vertical_scale = 0.8f,
904  });
905 
906  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
907 }

References x.

◆ TEST_P() [264/549]

impeller::testing::TEST_P ( AiksTest  ,
NonSquareFilledArcsRenderCorrectlyWithCenter   
)

Definition at line 909 of file aiks_dl_basic_unittests.cc.

909  {
910  DisplayListBuilder builder;
911  builder.Scale(GetContentScale().x, GetContentScale().y);
912  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
913 
914  DlPaint paint;
915  paint.setColor(DlColor::kBlue());
916 
917  RenderArcFarm(builder, paint,
918  {
919  .use_center = true,
920  .full_circles = false,
921  .vertical_scale = 0.8f,
922  });
923 
924  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
925 }

References x.

◆ TEST_P() [265/549]

impeller::testing::TEST_P ( AiksTest  ,
PaintBlendModeIsRespected   
)

Definition at line 172 of file aiks_dl_blend_unittests.cc.

172  {
173  DlPaint paint;
174  DisplayListBuilder builder;
175  // Default is kSourceOver.
176 
177  paint.setColor(DlColor::RGBA(1, 0, 0, 0.5));
178  builder.DrawCircle(DlPoint(150, 200), 100, paint);
179 
180  paint.setColor(DlColor::RGBA(0, 1, 0, 0.5));
181  builder.DrawCircle(DlPoint(250, 200), 100, paint);
182 
183  paint.setBlendMode(DlBlendMode::kPlus);
184 
185  paint.setColor(DlColor::kRed());
186  builder.DrawCircle(DlPoint(450, 250), 100, paint);
187 
188  paint.setColor(DlColor::kGreen());
189  builder.DrawCircle(DlPoint(550, 250), 100, paint);
190 
191  paint.setColor(DlColor::kBlue());
192  builder.DrawCircle(DlPoint(500, 150), 100, paint);
193 
194  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
195 }

◆ TEST_P() [266/549]

impeller::testing::TEST_P ( AiksTest  ,
PipelineBlendSingleParameter   
)

Definition at line 2052 of file aiks_dl_basic_unittests.cc.

2052  {
2053  DisplayListBuilder builder;
2054 
2055  // Should render a green square in the middle of a blue circle.
2056  DlPaint paint;
2057  builder.SaveLayer(std::nullopt, &paint);
2058  {
2059  builder.Translate(100, 100);
2060  paint.setColor(DlColor::kBlue());
2061  builder.DrawCircle(DlPoint(200, 200), 200, paint);
2062  builder.ClipRect(DlRect::MakeXYWH(100, 100, 200, 200));
2063 
2064  paint.setColor(DlColor::kGreen());
2065  paint.setBlendMode(DlBlendMode::kSrcOver);
2066  paint.setImageFilter(DlImageFilter::MakeColorFilter(
2067  DlColorFilter::MakeBlend(DlColor::kWhite(), DlBlendMode::kDst)));
2068  builder.DrawCircle(DlPoint(200, 200), 200, paint);
2069  builder.Restore();
2070  }
2071 
2072  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
2073 }

◆ TEST_P() [267/549]

impeller::testing::TEST_P ( AiksTest  ,
ReleasesTextureOnTeardown   
)

Definition at line 594 of file aiks_dl_unittests.cc.

594  {
595  auto context = MakeContext();
596  std::weak_ptr<Texture> weak_texture;
597 
598  {
599  auto texture = CreateTextureForFixture("table_mountain_nx.png");
600  weak_texture = texture;
601 
602  DisplayListBuilder builder;
603  builder.Scale(GetContentScale().x, GetContentScale().y);
604  builder.Translate(100.0f, 100.0f);
605 
606  DlPaint paint;
607  paint.setColorSource(DlColorSource::MakeImage(
608  DlImageImpeller::Make(texture), DlTileMode::kClamp, DlTileMode::kClamp,
609  DlImageSampling::kLinear, nullptr));
610 
611  builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
612 
613  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
614  }
615 
616  // See https://github.com/flutter/flutter/issues/134751.
617  //
618  // If the fence waiter was working this may not be released by the end of the
619  // scope above. Adding a manual shutdown so that future changes to the fence
620  // waiter will not flake this test.
621  context->Shutdown();
622 
623  // The texture should be released by now.
624  ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
625  "by the backend, it should be "
626  "released.";
627 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [268/549]

impeller::testing::TEST_P ( AiksTest  ,
RotateColorFilteredPath   
)

Definition at line 27 of file aiks_dl_path_unittests.cc.

27  {
28  DisplayListBuilder builder;
29  builder.Transform(DlMatrix::MakeTranslation(DlPoint(300, 300)) *
30  DlMatrix::MakeRotationZ(DlDegrees(90)));
31 
32  DlPathBuilder arrow_stem;
33  DlPathBuilder arrow_head;
34 
35  arrow_stem.MoveTo(DlPoint(120, 190)).LineTo(DlPoint(120, 50));
36  arrow_head.MoveTo(DlPoint(50, 120))
37  .LineTo(DlPoint(120, 190))
38  .LineTo(DlPoint(190, 120));
39 
40  auto filter =
41  DlColorFilter::MakeBlend(DlColor::kAliceBlue(), DlBlendMode::kSrcIn);
42 
43  DlPaint paint;
44  paint.setStrokeWidth(15.0);
45  paint.setStrokeCap(DlStrokeCap::kRound);
46  paint.setStrokeJoin(DlStrokeJoin::kRound);
47  paint.setDrawStyle(DlDrawStyle::kStroke);
48  paint.setColorFilter(filter);
49  paint.setColor(DlColor::kBlack());
50 
51  builder.DrawPath(arrow_stem.TakePath(), paint);
52  builder.DrawPath(arrow_head.TakePath(), paint);
53 
54  auto dl = builder.Build();
55  ASSERT_TRUE(OpenPlaygroundHere(dl));
56 }

◆ TEST_P() [269/549]

impeller::testing::TEST_P ( AiksTest  ,
RoundSuperellipseShadowComparison   
)

Definition at line 390 of file canvas_unittests.cc.

390  {
391  // Config
392  Size default_size(600, 400);
393  Point left_center(400, 700);
394  Point right_center(1300, 700);
395  Color color = Color::Red();
396 
397  // Convert `color` to a `color_source`. This forces
398  // `canvas.DrawRoundSuperellipse` to use the regular shadow algorithm
399  // (blurring) instead of the fast shadow algorithm.
400  std::shared_ptr<flutter::DlColorSource> color_source;
401  {
402  flutter::DlColor dl_color = flutter::DlColor(color.ToARGB());
403  std::vector<flutter::DlColor> colors = {dl_color, dl_color};
404  std::vector<Scalar> stops = {0.0, 1.0};
405  color_source = flutter::DlColorSource::MakeLinear(
406  {0, 0}, {1000, 1000}, 2, colors.data(), stops.data(),
407  flutter::DlTileMode::kClamp);
408  }
409 
410  auto RectMakeCenterHalfSize = [](Point center, Point half_size) {
411  Size size(half_size.x * 2, half_size.y * 2);
412  return Rect::MakeOriginSize(center - half_size, size);
413  };
414 
415  RenderCallback callback = [&](RenderTarget& render_target) {
416  ContentContext context(GetContext(), nullptr);
417  Canvas canvas(context, render_target, true, false);
418  // Somehow there's a scaling factor between PlaygroundPoint and Canvas.
419  Matrix ctm = Matrix::MakeScale(Vector2(1, 1) * 0.5);
420  Matrix i_ctm = ctm.Invert();
421 
422  static Scalar sigma = 0.05;
423  static Scalar radius = 200;
424 
425  // Define the ImGui
426  ImGui::Begin("Shadow", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
427  {
428  ImGui::SliderFloat("Sigma", &sigma, 0, 100);
429  ImGui::SliderFloat("Radius", &radius, 0, 1000);
430  }
431  ImGui::End();
432 
433  static PlaygroundPoint right_reference_var(
434  ctm * (right_center + default_size / 2), 30, Color::White());
435  Point right_reference = i_ctm * DrawPlaygroundPoint(right_reference_var);
436  Point half_size = (right_reference - right_center).Abs();
437  Rect left_bounds = RectMakeCenterHalfSize(left_center, half_size);
438  Rect right_bounds = RectMakeCenterHalfSize(right_center, half_size);
439 
440  Paint paint{
441  .color = color,
442  .mask_blur_descriptor =
443  Paint::MaskBlurDescriptor{
444  .sigma = Sigma(sigma),
445  },
446  };
447 
448  // Left: Draw with canvas
449  canvas.DrawRoundSuperellipse(
450  RoundSuperellipse::MakeRectRadius(left_bounds, radius), paint);
451 
452  // Right: Direct draw
453  paint.color_source = color_source.get();
454  canvas.DrawRoundSuperellipse(
455  RoundSuperellipse::MakeRectRadius(right_bounds, radius), paint);
456 
457  canvas.EndReplay();
458  return true;
459  };
460 
461  ASSERT_TRUE(Playground::OpenPlaygroundHere(callback));
462 }

References impeller::Paint::color, impeller::DrawPlaygroundPoint(), impeller::Canvas::DrawRoundSuperellipse(), impeller::Canvas::EndReplay(), impeller::Matrix::Invert(), impeller::TRect< Scalar >::MakeOriginSize(), impeller::RoundSuperellipse::MakeRectRadius(), impeller::Matrix::MakeScale(), impeller::Playground::OpenPlaygroundHere(), impeller::Color::Red(), impeller::Paint::MaskBlurDescriptor::sigma, impeller::Color::ToARGB(), and impeller::Color::White().

◆ TEST_P() [270/549]

impeller::testing::TEST_P ( AiksTest  ,
RuntimeEffectWithInvalidSamplerDoesNotCrash   
)

Definition at line 112 of file aiks_dl_runtime_effect_unittests.cc.

112  {
113  ScopedValidationDisable disable_validation;
114 
115  // Create a sampler that is not usable as an input to the runtime effect.
116  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
117  flutter::DlColor::kRed()};
118  const float stops[2] = {0.0, 1.0};
119  auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
120  2, colors.data(), stops,
121  flutter::DlTileMode::kClamp);
122  std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
123  linear,
124  };
125 
126  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
127  uniform_data->resize(sizeof(Vector2));
128 
129  DlPaint paint;
130  paint.setColorSource(
131  MakeRuntimeEffect(this, "runtime_stage_filter_example.frag.iplr",
132  uniform_data, sampler_inputs));
133 
134  DisplayListBuilder builder;
135  builder.DrawPaint(paint);
136 
137  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
138 }

◆ TEST_P() [271/549]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerDrawsBehindSubsequentEntities   
)

Definition at line 1907 of file aiks_dl_basic_unittests.cc.

1907  {
1908  // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
1909  DisplayListBuilder builder;
1910  DlPaint paint;
1911 
1912  paint.setColor(DlColor::kBlack());
1913  DlRect rect = DlRect::MakeXYWH(25, 25, 25, 25);
1914  builder.DrawRect(rect, paint);
1915 
1916  builder.Translate(10, 10);
1917 
1918  DlPaint save_paint;
1919  builder.SaveLayer(std::nullopt, &save_paint);
1920 
1921  paint.setColor(DlColor::kGreen());
1922  builder.DrawRect(rect, paint);
1923 
1924  builder.Restore();
1925 
1926  builder.Translate(10, 10);
1927  paint.setColor(DlColor::kRed());
1928  builder.DrawRect(rect, paint);
1929 
1930  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1931 }

◆ TEST_P() [272/549]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerFiltersScaleWithTransform   
)

Definition at line 1999 of file aiks_dl_basic_unittests.cc.

1999  {
2000  DisplayListBuilder builder;
2001 
2002  builder.Scale(GetContentScale().x, GetContentScale().y);
2003  builder.Translate(100, 100);
2004 
2005  auto texture = DlImageImpeller::Make(CreateTextureForFixture("boston.jpg"));
2006  auto draw_image_layer = [&builder, &texture](const DlPaint& paint) {
2007  builder.SaveLayer(std::nullopt, &paint);
2008  builder.DrawImage(texture, DlPoint(), DlImageSampling::kLinear);
2009  builder.Restore();
2010  };
2011 
2012  DlPaint effect_paint;
2013  effect_paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 6));
2014  draw_image_layer(effect_paint);
2015 
2016  builder.Translate(300, 300);
2017  builder.Scale(3, 3);
2018  draw_image_layer(effect_paint);
2019 
2020  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
2021 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [273/549]

impeller::testing::TEST_P ( AiksTest  ,
ScaledK   
)

Definition at line 174 of file aiks_dl_text_unittests.cc.

174  {
175  DisplayListBuilder builder;
176  DlPaint paint;
177  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
178  builder.DrawPaint(paint);
179  for (int i = 0; i < 6; ++i) {
180  builder.Save();
181  builder.Translate(300 * i, 0);
182  Scalar scale = 0.445 - (i / 1000.f);
183  builder.Scale(scale, scale);
185  GetContext(), builder, "k", "Roboto-Regular.ttf",
186  TextRenderOptions{.font_size = 600, .position = DlPoint(10, 500)});
188  GetContext(), builder, "k", "Roboto-Regular.ttf",
189  TextRenderOptions{.font_size = 300, .position = DlPoint(10, 800)});
190  builder.Restore();
191  }
192  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
193 }

References impeller::testing::TextRenderOptions::font_size, and RenderTextInCanvasSkia().

◆ TEST_P() [274/549]

impeller::testing::TEST_P ( AiksTest  ,
ScaleExperimentAntialiasLines   
)

Definition at line 628 of file aiks_dl_path_unittests.cc.

628  {
629  Scalar scale = 5.0;
630  Scalar line_width = 10.f;
631  auto callback = [&]() -> sk_sp<DisplayList> {
632  if (AiksTest::ImGuiBegin("Controls", nullptr,
633  ImGuiWindowFlags_AlwaysAutoResize)) {
634  ImGui::SliderFloat("Scale", &scale, 0.001, 5);
635  ImGui::SliderFloat("Width", &line_width, 1, 20);
636 
637  ImGui::End();
638  }
639  DisplayListBuilder builder;
640  builder.Scale(GetContentScale().x, GetContentScale().y);
641 
642  builder.DrawPaint(DlPaint(DlColor(0xff111111)));
643 
644  {
645  DlPaint paint;
646  paint.setColor(DlColor::kGreenYellow());
647  paint.setStrokeWidth(line_width);
648 
649  builder.DrawLine(DlPoint(100, 100), DlPoint(350, 100), paint);
650  builder.DrawLine(DlPoint(100, 100), DlPoint(350, 150), paint);
651 
652  builder.Save();
653  builder.Translate(100, 300);
654  builder.Scale(scale, scale);
655  builder.Translate(-100, -300);
656  builder.DrawLine(DlPoint(100, 300), DlPoint(350, 300), paint);
657  builder.DrawLine(DlPoint(100, 300), DlPoint(350, 450), paint);
658  builder.Restore();
659  }
660 
661  {
662  DlPaint paint;
663  paint.setColor(DlColor::kGreenYellow());
664  paint.setStrokeWidth(2.0);
665 
666  builder.Save();
667  builder.Translate(100, 500);
668  builder.Scale(0.2, 0.2);
669  builder.Translate(-100, -500);
670  builder.DrawLine(DlPoint(100, 500), DlPoint(350, 500), paint);
671  builder.DrawLine(DlPoint(100, 500), DlPoint(350, 650), paint);
672  builder.Restore();
673  }
674 
675  return builder.Build();
676  };
677  ASSERT_TRUE(OpenPlaygroundHere(callback));
678 }

References impeller::AiksPlayground::ImGuiBegin(), and x.

◆ TEST_P() [275/549]

impeller::testing::TEST_P ( AiksTest  ,
SetContentsWithRegion   
)

Definition at line 560 of file aiks_dl_unittests.cc.

560  {
561  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
562 
563  // Replace part of the texture with a red rectangle.
564  std::vector<uint8_t> bytes(100 * 100 * 4);
565  for (auto i = 0u; i < bytes.size(); i += 4) {
566  bytes[i] = 255;
567  bytes[i + 1] = 0;
568  bytes[i + 2] = 0;
569  bytes[i + 3] = 255;
570  }
571  auto mapping =
572  std::make_shared<fml::NonOwnedMapping>(bytes.data(), bytes.size());
573  auto device_buffer =
574  GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
575  auto cmd_buffer = GetContext()->CreateCommandBuffer();
576  auto blit_pass = cmd_buffer->CreateBlitPass();
577  blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer), bridge,
578  IRect::MakeLTRB(50, 50, 150, 150));
579 
580  auto did_submit =
581  blit_pass->EncodeCommands() &&
582  GetContext()->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok();
583  ASSERT_TRUE(did_submit);
584 
585  auto image = DlImageImpeller::Make(bridge);
586 
587  DisplayListBuilder builder;
588  builder.DrawImage(image, DlPoint(0, 0), {});
589 
590  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
591 }

References impeller::DeviceBuffer::AsBufferView(), impeller::DlImageImpeller::Make(), and impeller::TRect< T >::MakeLTRB().

◆ TEST_P() [276/549]

impeller::testing::TEST_P ( AiksTest  ,
SiblingSaveLayerBoundsAreRespected   
)

Definition at line 1933 of file aiks_dl_basic_unittests.cc.

1933  {
1934  DisplayListBuilder builder;
1935  DlPaint paint;
1936  DlRect rect = DlRect::MakeXYWH(0, 0, 1000, 1000);
1937 
1938  // Black, green, and red squares offset by [10, 10].
1939  {
1940  DlPaint save_paint;
1941  DlRect bounds = DlRect::MakeXYWH(25, 25, 25, 25);
1942  builder.SaveLayer(bounds, &save_paint);
1943  paint.setColor(DlColor::kBlack());
1944  builder.DrawRect(rect, paint);
1945  builder.Restore();
1946  }
1947 
1948  {
1949  DlPaint save_paint;
1950  DlRect bounds = DlRect::MakeXYWH(35, 35, 25, 25);
1951  builder.SaveLayer(bounds, &save_paint);
1952  paint.setColor(DlColor::kGreen());
1953  builder.DrawRect(rect, paint);
1954  builder.Restore();
1955  }
1956 
1957  {
1958  DlPaint save_paint;
1959  DlRect bounds = DlRect::MakeXYWH(45, 45, 25, 25);
1960  builder.SaveLayer(bounds, &save_paint);
1961  paint.setColor(DlColor::kRed());
1962  builder.DrawRect(rect, paint);
1963  builder.Restore();
1964  }
1965 
1966  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1967 }

◆ TEST_P() [277/549]

impeller::testing::TEST_P ( AiksTest  ,
SimpleExperimentAntialiasLines   
)

Definition at line 743 of file aiks_dl_path_unittests.cc.

743  {
744  DisplayListBuilder builder;
745  builder.Scale(GetContentScale().x, GetContentScale().y);
746 
747  builder.DrawPaint(DlPaint(DlColor(0xff111111)));
748 
749  DlPaint paint;
750  paint.setColor(DlColor::kGreenYellow());
751  paint.setStrokeWidth(10);
752 
753  auto draw = [&builder](DlPaint& paint) {
754  for (auto cap :
755  {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
756  paint.setStrokeCap(cap);
757  DlPoint origin = {100, 100};
758  builder.DrawLine(DlPoint(150, 100), DlPoint(250, 100), paint);
759  for (int d = 15; d < 90; d += 15) {
760  Matrix m = Matrix::MakeRotationZ(Degrees(d));
761  Point origin = {100, 100};
762  Point p0 = {50, 0};
763  Point p1 = {150, 0};
764  auto a = origin + m * p0;
765  auto b = origin + m * p1;
766 
767  builder.DrawLine(a, b, paint);
768  }
769  builder.DrawLine(DlPoint(100, 150), DlPoint(100, 250), paint);
770  builder.DrawCircle(origin, 35, paint);
771 
772  builder.DrawLine(DlPoint(250, 250), DlPoint(250, 250), paint);
773 
774  builder.Translate(250, 0);
775  }
776  builder.Translate(-750, 250);
777  };
778 
779  draw(paint);
780 
781  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
782 }

References impeller::saturated::b, impeller::Matrix::MakeRotationZ(), and x.

◆ TEST_P() [278/549]

impeller::testing::TEST_P ( AiksTest  ,
SingleIconShadowTest   
)

Definition at line 837 of file aiks_dl_text_unittests.cc.

837  {
838  DisplayListBuilder builder;
839  builder.Scale(GetContentScale().x, GetContentScale().y);
840  DlPaint paint;
841  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
842  builder.DrawPaint(paint);
843 
844  AiksContext aiks_context(GetContext(),
845  std::make_shared<TypographerContextSkia>());
846  // Cache empty
847  EXPECT_EQ(aiks_context.GetContentContext()
848  .GetTextShadowCache()
849  .GetCacheSizeForTesting(),
850  0u);
851 
852  // Create font instance outside loop so all draws use identical font instance.
853  auto c_font_fixture = std::string(kFontFixture);
854  auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
855  ASSERT_TRUE(mapping);
856  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
857  SkFont sk_font(font_mgr->makeFromData(mapping), 50);
858 
859  for (auto i = 0; i < 10; i++) {
860  ASSERT_TRUE(RenderTextInCanvasSkia(
861  GetContext(), builder, "A", kFontFixture,
862  TextRenderOptions{
863  .color = DlColor::kBlue(),
864  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)},
865  sk_font));
866  }
867 
868  DisplayListToTexture(builder.Build(), {400, 400}, aiks_context);
869 
870  // Text should be cached. All 10 glyphs use the same cache entry.
871  EXPECT_EQ(aiks_context.GetContentContext()
872  .GetTextShadowCache()
873  .GetCacheSizeForTesting(),
874  1u);
875 }

References impeller::testing::TextRenderOptions::color, impeller::DisplayListToTexture(), impeller::TextShadowCache::GetCacheSizeForTesting(), impeller::AiksContext::GetContentContext(), impeller::ContentContext::GetTextShadowCache(), kFontFixture, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [279/549]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorCircleMaskBlurTinySigma   
)

Definition at line 128 of file aiks_dl_blur_unittests.cc.

128  {
129  DisplayListBuilder builder;
130  builder.Scale(GetContentScale().x, GetContentScale().y);
131 
132  std::vector<float> sigmas = {0.0, 0.01, 1.0};
133  std::vector<DlColor> colors = {DlColor::kGreen(), DlColor::kYellow(),
134  DlColor::kRed()};
135  for (uint32_t i = 0; i < sigmas.size(); ++i) {
136  DlPaint paint;
137  paint.setColor(colors[i]);
138  paint.setMaskFilter(
139  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigmas[i]));
140 
141  builder.Save();
142  builder.Translate(100 + (i * 100), 100);
143  DlRoundRect rrect = DlRoundRect::MakeRectXY(
144  DlRect::MakeXYWH(0, 0, 100.0f, 100.0f), 100, 100);
145  builder.DrawRoundRect(rrect, paint);
146  builder.Restore();
147  }
148 
149  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
150 }

References x.

◆ TEST_P() [280/549]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorCirclesOvalsRRectsMaskBlurCorrectly   
)

Definition at line 1269 of file aiks_dl_basic_unittests.cc.

1269  {
1270  DisplayListBuilder builder;
1271  builder.Scale(GetContentScale().x, GetContentScale().y);
1272  DlPaint paint;
1273  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1.0f));
1274 
1275  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
1276 
1277  paint.setColor(
1278  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f));
1279  Scalar y = 100.0f;
1280  for (int i = 0; i < 5; i++) {
1281  Scalar x = (i + 1) * 100;
1282  Scalar radius = x / 10.0f;
1283  builder.DrawRect(DlRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1284  radius, 60.0f - radius),
1285  paint);
1286  }
1287 
1288  paint.setColor(DlColor::kBlue());
1289  y += 100.0f;
1290  for (int i = 0; i < 5; i++) {
1291  Scalar x = (i + 1) * 100;
1292  Scalar radius = x / 10.0f;
1293  builder.DrawCircle(DlPoint(x + 25, y + 25), radius, paint);
1294  }
1295 
1296  paint.setColor(DlColor::kGreen());
1297  y += 100.0f;
1298  for (int i = 0; i < 5; i++) {
1299  Scalar x = (i + 1) * 100;
1300  Scalar radius = x / 10.0f;
1301  builder.DrawOval(DlRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1302  radius, 60.0f - radius),
1303  paint);
1304  }
1305 
1306  paint.setColor(
1307  DlColor::RGBA(128.0f / 255.0f, 0.0f / 255.0f, 128.0f / 255.0f, 1.0f));
1308  y += 100.0f;
1309  for (int i = 0; i < 5; i++) {
1310  Scalar x = (i + 1) * 100;
1311  Scalar radius = x / 20.0f;
1312  builder.DrawRoundRect(
1313  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(x, y, 60.0f, 60.0f), //
1314  radius, radius),
1315  paint);
1316  }
1317 
1318  paint.setColor(
1319  DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f));
1320  y += 100.0f;
1321  for (int i = 0; i < 5; i++) {
1322  Scalar x = (i + 1) * 100;
1323  Scalar radius = x / 20.0f;
1324  builder.DrawRoundRect(
1325  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(x, y, 60.0f, 60.0f), //
1326  radius, 5.0f),
1327  paint);
1328  }
1329 
1330  auto dl = builder.Build();
1331  ASSERT_TRUE(OpenPlaygroundHere(dl));
1332 }

References x.

◆ TEST_P() [281/549]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorOvalsMaskBlurTinySigma   
)

Definition at line 38 of file aiks_dl_blur_unittests.cc.

38  {
39  DisplayListBuilder builder;
40  builder.Scale(GetContentScale().x, GetContentScale().y);
41 
42  std::vector<float> sigmas = {0.0, 0.01, 1.0};
43  std::vector<DlColor> colors = {DlColor::kGreen(), DlColor::kYellow(),
44  DlColor::kRed()};
45  for (uint32_t i = 0; i < sigmas.size(); ++i) {
46  DlPaint paint;
47  paint.setColor(colors[i]);
48  paint.setMaskFilter(
49  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigmas[i]));
50 
51  builder.Save();
52  builder.Translate(100 + (i * 100), 100);
53  DlRoundRect rrect =
54  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 60.0f, 160.0f), 50, 100);
55  builder.DrawRoundRect(rrect, paint);
56  builder.Restore();
57  }
58 
59  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
60 }

References x.

◆ TEST_P() [282/549]

impeller::testing::TEST_P ( AiksTest  ,
SolidStrokesRenderCorrectly   
)

Definition at line 473 of file aiks_dl_path_unittests.cc.

473  {
474  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
475  auto callback = [&]() -> sk_sp<DisplayList> {
476  static Color color = Color::Black().WithAlpha(0.5);
477  static float scale = 3;
478  static bool add_circle_clip = true;
479 
480  if (AiksTest::ImGuiBegin("Controls", nullptr,
481  ImGuiWindowFlags_AlwaysAutoResize)) {
482  ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
483  ImGui::SliderFloat("Scale", &scale, 0, 6);
484  ImGui::Checkbox("Circle clip", &add_circle_clip);
485  ImGui::End();
486  }
487 
488  DisplayListBuilder builder;
489  builder.Scale(GetContentScale().x, GetContentScale().y);
490  DlPaint paint;
491 
492  paint.setColor(DlColor::kWhite());
493  builder.DrawPaint(paint);
494 
495  paint.setColor(
496  DlColor::ARGB(color.alpha, color.red, color.green, color.blue));
497  paint.setDrawStyle(DlDrawStyle::kStroke);
498  paint.setStrokeWidth(10);
499 
500  DlPathBuilder path_builder;
501  path_builder.MoveTo(DlPoint(20, 20));
502  path_builder.QuadraticCurveTo(DlPoint(60, 20), DlPoint(60, 60));
503  path_builder.Close();
504  path_builder.MoveTo(DlPoint(60, 20));
505  path_builder.QuadraticCurveTo(DlPoint(60, 60), DlPoint(20, 60));
506  DlPath path = path_builder.TakePath();
507 
508  builder.Scale(scale, scale);
509 
510  if (add_circle_clip) {
511  static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
512  Color::Red());
513  static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
514  Color::Red());
515  auto [handle_a, handle_b] =
516  DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
517 
518  Matrix screen_to_canvas = builder.GetMatrix();
519  if (!screen_to_canvas.IsInvertible()) {
520  return nullptr;
521  }
522  screen_to_canvas = screen_to_canvas.Invert();
523 
524  Point point_a = screen_to_canvas * handle_a;
525  Point point_b = screen_to_canvas * handle_b;
526 
527  Point middle = point_a + point_b;
528  middle *= GetContentScale().x / 2;
529 
530  auto radius = point_a.GetDistance(middle);
531 
532  builder.ClipPath(DlPath::MakeCircle(middle, radius));
533  }
534 
535  for (auto join :
536  {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
537  paint.setStrokeJoin(join);
538  for (auto cap :
539  {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
540  paint.setStrokeCap(cap);
541  builder.DrawPath(path, paint);
542  builder.Translate(80, 0);
543  }
544  builder.Translate(-240, 60);
545  }
546 
547  return builder.Build();
548  };
549 
550  ASSERT_TRUE(OpenPlaygroundHere(callback));
551 }

References impeller::Color::alpha, impeller::Color::Black(), impeller::Color::blue, impeller::DrawPlaygroundLine(), impeller::TPoint< T >::GetDistance(), impeller::Color::green, impeller::AiksPlayground::ImGuiBegin(), impeller::Matrix::Invert(), impeller::Matrix::IsInvertible(), impeller::Color::red, impeller::Color::Red(), impeller::Color::WithAlpha(), x, and impeller::TPoint< T >::x.

◆ TEST_P() [283/549]

impeller::testing::TEST_P ( AiksTest  ,
SrgbToLinearFilterSubpassCollapseOptimization   
)

Definition at line 122 of file aiks_dl_unittests.cc.

122  {
123  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
124 
125  DlPaint paint;
126  paint.setColorFilter(DlColorFilter::MakeLinearToSrgbGamma());
127  builder.SaveLayer(std::nullopt, &paint);
128 
129  builder.Translate(500, 300);
130  builder.Rotate(120); // 120 deg
131 
132  DlPaint draw_paint;
133  draw_paint.setColor(DlColor::kBlue());
134  builder.DrawRect(DlRect::MakeXYWH(100, 100, 200, 200), draw_paint);
135 
136  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
137 }

◆ TEST_P() [284/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokeCapsAndJoins   
)

Definition at line 987 of file aiks_dl_path_unittests.cc.

987  {
988  DisplayListBuilder builder;
989  builder.Scale(GetContentScale().x, GetContentScale().y);
990 
991  builder.Translate(100, 0);
992 
993  builder.Save();
994  for (auto cap : std::vector<DlStrokeCap>{
995  DlStrokeCap::kButt, DlStrokeCap::kRound, DlStrokeCap::kSquare}) {
996  DlPathBuilder path_builder;
997  path_builder.MoveTo({20, 50});
998  path_builder.LineTo({50, 50});
999  path_builder.MoveTo({120, 50});
1000  path_builder.LineTo({120, 80});
1001  path_builder.MoveTo({180, 50});
1002  path_builder.LineTo({180, 50});
1003  DlPath path = path_builder.TakePath();
1004 
1005  DlPaint paint;
1006  paint.setColor(DlColor::kRed());
1007  paint.setDrawStyle(DlDrawStyle::kStroke);
1008  paint.setStrokeWidth(20.0f);
1009  paint.setStrokeCap(cap);
1010  paint.setStrokeJoin(DlStrokeJoin::kBevel);
1011 
1012  builder.DrawPath(path, paint);
1013 
1014  paint.setColor(DlColor::kYellow());
1015  paint.setStrokeWidth(1.0f);
1016  paint.setStrokeCap(DlStrokeCap::kButt);
1017 
1018  builder.DrawPath(path, paint);
1019 
1020  builder.Translate(250, 0);
1021  }
1022  builder.Restore();
1023 
1024  builder.Translate(0, 100);
1025 
1026  builder.Save();
1027  for (auto join : std::vector<DlStrokeJoin>{
1028  DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
1029  DlPathBuilder path_builder;
1030  path_builder.MoveTo({20, 50}); // 0 degree right turn
1031  path_builder.LineTo({50, 50});
1032  path_builder.LineTo({80, 50});
1033  path_builder.MoveTo({20, 150}); // 90 degree right turn
1034  path_builder.LineTo({50, 150});
1035  path_builder.LineTo({50, 180});
1036  path_builder.MoveTo({20, 250}); // 45 degree right turn
1037  path_builder.LineTo({50, 250});
1038  path_builder.LineTo({70, 270});
1039  path_builder.MoveTo({20, 350}); // 135 degree right turn
1040  path_builder.LineTo({50, 350});
1041  path_builder.LineTo({30, 370});
1042  path_builder.MoveTo({20, 450}); // 180 degree right turn
1043  path_builder.LineTo({50, 450});
1044  path_builder.LineTo({20, 450});
1045  path_builder.MoveTo({120, 80}); // 0 degree left turn
1046  path_builder.LineTo({150, 80});
1047  path_builder.LineTo({180, 80});
1048  path_builder.MoveTo({120, 180}); // 90 degree left turn
1049  path_builder.LineTo({150, 180});
1050  path_builder.LineTo({150, 150});
1051  path_builder.MoveTo({120, 280}); // 45 degree left turn
1052  path_builder.LineTo({150, 280});
1053  path_builder.LineTo({170, 260});
1054  path_builder.MoveTo({120, 380}); // 135 degree left turn
1055  path_builder.LineTo({150, 380});
1056  path_builder.LineTo({130, 360});
1057  path_builder.MoveTo({120, 480}); // 180 degree left turn
1058  path_builder.LineTo({150, 480});
1059  path_builder.LineTo({120, 480});
1060  DlPath path = path_builder.TakePath();
1061 
1062  DlPaint paint;
1063 
1064  paint.setColor(DlColor::kRed());
1065  paint.setDrawStyle(DlDrawStyle::kStroke);
1066  paint.setStrokeWidth(20.0f);
1067  paint.setStrokeCap(DlStrokeCap::kSquare);
1068  paint.setStrokeJoin(join);
1069  builder.DrawPath(path, paint);
1070 
1071  paint.setColor(DlColor::kYellow());
1072  paint.setStrokeWidth(1.0f);
1073  paint.setStrokeCap(DlStrokeCap::kButt);
1074  builder.DrawPath(path, paint);
1075 
1076  builder.Translate(250, 0);
1077  }
1078  builder.Restore();
1079 
1080  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1081 }

References x.

◆ TEST_P() [285/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsCoverFullArcWithButtEnds   
)

Definition at line 1120 of file aiks_dl_basic_unittests.cc.

1120  {
1121  // This test compares the rendering of a full circle arc against a partial
1122  // arc by drawing a one over the other in high contrast. If the partial
1123  // arc misses any pixels that were drawn by the full arc, there will be
1124  // some "pixel dirt" around the missing "erased" parts of the arcs. This
1125  // case arises while rendering a CircularProgressIndicator with a background
1126  // color where we want the rendering of the background full arc to hit the
1127  // same pixels around the edges as the partial arc that covers it.
1128  //
1129  // In this case we draw a full blue circle and then draw a partial arc
1130  // over it in the background color (white).
1131 
1132  DisplayListBuilder builder;
1133  builder.Scale(GetContentScale().x, GetContentScale().y);
1134  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
1135 
1136  DlPaint paint;
1137  paint.setDrawStyle(DlDrawStyle::kStroke);
1138  paint.setStrokeWidth(6.0f);
1139  paint.setStrokeCap(DlStrokeCap::kButt);
1140  paint.setColor(DlColor::kBlue());
1141 
1142  // First draw full circles in blue to establish the pixels to be erased
1143  RenderArcFarm(builder, paint,
1144  {
1145  .use_center = false,
1146  .full_circles = true,
1147  });
1148 
1149  paint.setColor(DlColor::kWhite());
1150 
1151  // Then draw partial arcs in white over the circles to "erase" them
1152  RenderArcFarm(builder, paint,
1153  {
1154  .use_center = false,
1155  .full_circles = false,
1156  });
1157 
1158  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1159 }

References x.

◆ TEST_P() [286/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithBevelJoinsAndCenter   
)

Definition at line 987 of file aiks_dl_basic_unittests.cc.

987  {
988  DisplayListBuilder builder;
989  builder.Scale(GetContentScale().x, GetContentScale().y);
990  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
991 
992  DlPaint paint;
993  paint.setDrawStyle(DlDrawStyle::kStroke);
994  paint.setStrokeWidth(6.0f);
995  paint.setStrokeJoin(DlStrokeJoin::kBevel);
996  paint.setColor(DlColor::kBlue());
997 
998  RenderArcFarm(builder, paint,
999  {
1000  .use_center = true,
1001  .full_circles = false,
1002  .sweeps_over_360 = true,
1003  });
1004 
1005  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1006 }

References x.

◆ TEST_P() [287/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithButtEnds   
)

Definition at line 927 of file aiks_dl_basic_unittests.cc.

927  {
928  DisplayListBuilder builder;
929  builder.Scale(GetContentScale().x, GetContentScale().y);
930  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
931 
932  DlPaint paint;
933  paint.setDrawStyle(DlDrawStyle::kStroke);
934  paint.setStrokeWidth(6.0f);
935  paint.setStrokeCap(DlStrokeCap::kButt);
936  paint.setColor(DlColor::kBlue());
937 
938  RenderArcFarm(builder, paint,
939  {
940  .use_center = false,
941  .full_circles = false,
942  });
943 
944  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
945 }

References x.

◆ TEST_P() [288/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithMiterJoinsAndCenter   
)

Definition at line 1008 of file aiks_dl_basic_unittests.cc.

1008  {
1009  DisplayListBuilder builder;
1010  builder.Scale(GetContentScale().x, GetContentScale().y);
1011  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
1012 
1013  DlPaint paint;
1014  paint.setDrawStyle(DlDrawStyle::kStroke);
1015  paint.setStrokeWidth(6.0f);
1016  paint.setStrokeJoin(DlStrokeJoin::kMiter);
1017  // Default miter of 4.0 does a miter on all of the centers, but
1018  // using 3.0 will show some bevels on the widest interior angles...
1019  paint.setStrokeMiter(3.0f);
1020  paint.setColor(DlColor::kBlue());
1021 
1022  RenderArcFarm(builder, paint,
1023  {
1024  .use_center = true,
1025  .full_circles = false,
1026  .sweeps_over_360 = true,
1027  });
1028 
1029  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1030 }

References x.

◆ TEST_P() [289/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithRoundEnds   
)

Definition at line 967 of file aiks_dl_basic_unittests.cc.

967  {
968  DisplayListBuilder builder;
969  builder.Scale(GetContentScale().x, GetContentScale().y);
970  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
971 
972  DlPaint paint;
973  paint.setDrawStyle(DlDrawStyle::kStroke);
974  paint.setStrokeWidth(6.0f);
975  paint.setStrokeCap(DlStrokeCap::kRound);
976  paint.setColor(DlColor::kBlue());
977 
978  RenderArcFarm(builder, paint,
979  {
980  .use_center = false,
981  .full_circles = false,
982  });
983 
984  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
985 }

References x.

◆ TEST_P() [290/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithRoundJoinsAndCenter   
)

Definition at line 1032 of file aiks_dl_basic_unittests.cc.

1032  {
1033  DisplayListBuilder builder;
1034  builder.Scale(GetContentScale().x, GetContentScale().y);
1035  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
1036 
1037  DlPaint paint;
1038  paint.setDrawStyle(DlDrawStyle::kStroke);
1039  paint.setStrokeWidth(6.0f);
1040  paint.setStrokeJoin(DlStrokeJoin::kRound);
1041  paint.setColor(DlColor::kBlue());
1042 
1043  RenderArcFarm(builder, paint,
1044  {
1045  .use_center = true,
1046  .full_circles = false,
1047  .sweeps_over_360 = true,
1048  });
1049 
1050  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1051 }

References x.

◆ TEST_P() [291/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithSquareAndButtAndRoundEnds   
)

Definition at line 1082 of file aiks_dl_basic_unittests.cc.

1082  {
1083  DisplayListBuilder builder;
1084  builder.Scale(GetContentScale().x, GetContentScale().y);
1085  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
1086 
1087  DlPaint paint;
1088  paint.setDrawStyle(DlDrawStyle::kStroke);
1089  paint.setStrokeWidth(8.0f);
1090  paint.setStrokeCap(DlStrokeCap::kSquare);
1091  paint.setColor(DlColor::kRed());
1092 
1093  RenderArcFarm(builder, paint,
1094  {
1095  .use_center = false,
1096  .full_circles = false,
1097  });
1098 
1099  paint.setStrokeCap(DlStrokeCap::kRound);
1100  paint.setColor(DlColor::kGreen());
1101 
1102  RenderArcFarm(builder, paint,
1103  {
1104  .use_center = false,
1105  .full_circles = false,
1106  });
1107 
1108  paint.setStrokeCap(DlStrokeCap::kButt);
1109  paint.setColor(DlColor::kBlue());
1110 
1111  RenderArcFarm(builder, paint,
1112  {
1113  .use_center = false,
1114  .full_circles = false,
1115  });
1116 
1117  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1118 }

References x.

◆ TEST_P() [292/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithSquareAndButtEnds   
)

Definition at line 1053 of file aiks_dl_basic_unittests.cc.

1053  {
1054  DisplayListBuilder builder;
1055  builder.Scale(GetContentScale().x, GetContentScale().y);
1056  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
1057 
1058  DlPaint paint;
1059  paint.setDrawStyle(DlDrawStyle::kStroke);
1060  paint.setStrokeWidth(8.0f);
1061  paint.setStrokeCap(DlStrokeCap::kSquare);
1062  paint.setColor(DlColor::kRed());
1063 
1064  RenderArcFarm(builder, paint,
1065  {
1066  .use_center = false,
1067  .full_circles = false,
1068  });
1069 
1070  paint.setStrokeCap(DlStrokeCap::kButt);
1071  paint.setColor(DlColor::kBlue());
1072 
1073  RenderArcFarm(builder, paint,
1074  {
1075  .use_center = false,
1076  .full_circles = false,
1077  });
1078 
1079  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1080 }

References x.

◆ TEST_P() [293/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithSquareEnds   
)

Definition at line 947 of file aiks_dl_basic_unittests.cc.

947  {
948  DisplayListBuilder builder;
949  builder.Scale(GetContentScale().x, GetContentScale().y);
950  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
951 
952  DlPaint paint;
953  paint.setDrawStyle(DlDrawStyle::kStroke);
954  paint.setStrokeWidth(6.0f);
955  paint.setStrokeCap(DlStrokeCap::kSquare);
956  paint.setColor(DlColor::kBlue());
957 
958  RenderArcFarm(builder, paint,
959  {
960  .use_center = false,
961  .full_circles = false,
962  });
963 
964  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
965 }

References x.

◆ TEST_P() [294/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedCirclesRenderCorrectly   
)

Definition at line 689 of file aiks_dl_basic_unittests.cc.

689  {
690  DisplayListBuilder builder;
691  builder.Scale(GetContentScale().x, GetContentScale().y);
692  DlPaint paint;
693  const int color_count = 3;
694  DlColor colors[color_count] = {
695  DlColor::kBlue(),
696  DlColor::kGreen(),
697  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
698  };
699 
700  paint.setColor(DlColor::kWhite());
701  builder.DrawPaint(paint);
702 
703  int c_index = 0;
704 
705  auto draw = [&paint, &colors, &c_index](DlCanvas& canvas, DlPoint center,
706  Scalar r, Scalar dr, int n) {
707  for (int i = 0; i < n; i++) {
708  paint.setColor(colors[(c_index++) % color_count]);
709  canvas.DrawCircle(center, r, paint);
710  r += dr;
711  }
712  };
713 
714  paint.setDrawStyle(DlDrawStyle::kStroke);
715  paint.setStrokeWidth(1);
716  draw(builder, DlPoint(10, 10), 2, 2, 14); // r = [2, 28], covers [1,29]
717  paint.setStrokeWidth(5);
718  draw(builder, DlPoint(10, 10), 35, 10, 56); // r = [35, 585], covers [30,590]
719 
720  DlColor gradient_colors[7] = {
721  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
722  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
723  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
724  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
725  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
726  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
727  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
728  };
729  DlScalar stops[7] = {
730  0.0,
731  (1.0 / 6.0) * 1,
732  (1.0 / 6.0) * 2,
733  (1.0 / 6.0) * 3,
734  (1.0 / 6.0) * 4,
735  (1.0 / 6.0) * 5,
736  1.0,
737  };
738  auto texture = CreateTextureForFixture("airplane.jpg",
739  /*enable_mipmapping=*/true);
740  auto image = DlImageImpeller::Make(texture);
741 
742  paint.setColorSource(DlColorSource::MakeRadial(
743  DlPoint(500, 600), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
744  draw(builder, DlPoint(500, 600), 5, 10, 10);
745 
746  DlMatrix local_matrix = DlMatrix::MakeTranslation({700, 200});
747  paint.setColorSource(DlColorSource::MakeImage(
748  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
749  DlImageSampling::kNearestNeighbor, &local_matrix));
750  draw(builder, DlPoint(800, 300), 5, 10, 10);
751 
752  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
753 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [295/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedPathWithMoveToThenCloseDrawnCorrectly   
)

Definition at line 536 of file aiks_dl_unittests.cc.

536  {
537  DlPathBuilder path_builder;
538  path_builder.MoveTo(DlPoint(0, 400))
539  .LineTo(DlPoint(0, 0))
540  .LineTo(DlPoint(400, 0))
541  // MoveTo implicitly adds a contour, ensure that close doesn't
542  // add another nearly-empty contour.
543  .MoveTo(DlPoint(0, 400))
544  .Close();
545  DlPath path = path_builder.TakePath();
546 
547  DisplayListBuilder builder;
548  builder.Translate(50, 50);
549 
550  DlPaint paint;
551  paint.setColor(DlColor::kBlue());
552  paint.setStrokeCap(DlStrokeCap::kRound);
553  paint.setStrokeWidth(10);
554  paint.setDrawStyle(DlDrawStyle::kStroke);
555  builder.DrawPath(path, paint);
556 
557  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
558 }

◆ TEST_P() [296/549]

impeller::testing::TEST_P ( AiksTest  ,
StrokedRectsRenderCorrectly   
)

Definition at line 493 of file aiks_dl_basic_unittests.cc.

493  {
494  DisplayListBuilder builder;
495  builder.Scale(GetContentScale().x, GetContentScale().y);
496 
497  DlPaint paint;
498  paint.setColor(DlColor::kPurple());
499  paint.setDrawStyle(DlDrawStyle::kStroke);
500  paint.setStrokeWidth(20.0f);
501 
502  DlPaint thin_paint = paint;
503  thin_paint.setColor(DlColor::kYellow());
504  thin_paint.setStrokeWidth(0.0f);
505 
506  DlRect rect = DlRect::MakeLTRB(10, 10, 90, 90);
507  DlRect thin_tall_rect = DlRect::MakeLTRB(120, 10, 120, 90);
508  DlRect thin_wide_rect = DlRect::MakeLTRB(10, 120, 90, 120);
509  DlRect empty_rect = DlRect::MakeLTRB(120, 120, 120, 120);
510 
511  // We draw the following sets of rectangles:
512  //
513  // A E X
514  // X
515  // B F X
516  // X
517  // C D G H X
518  //
519  // Purple A,B,C,D are all drawn with stroke width 20 (non-overflowing).
520  // Each of those sets has 4 rectangles of dimension 80x80, 80x0, 0x80,
521  // and 0,0 to demonstrate the basic behavior and also the behavior of
522  // empty dimensions.
523  //
524  // Blue E,F,G,H are the same 80x80 rectangles, but with an overflowing
525  // stroke width of 120 to show the behavior with degenerately large
526  // stroke widths.
527  //
528  // A,E are drawn with Bevel joins.
529  // B,F are drawn with Round joins.
530  // C,G are drawn with Miter joins and a large enough miter limit.
531  // D,H are drawn with Miter joins and a too small miter limit (== Bevel).
532  //
533  // All orange X rectangles are drawn with round joins and increasing stroke
534  // widths to demonstrate fidelity of the rounding code at various arc sizes.
535  // These X rectangles also help test that the variable sizing estimates in
536  // the round join code are accurate.
537 
538  // rects (A)
539  paint.setStrokeJoin(DlStrokeJoin::kBevel);
540  builder.DrawRect(rect.Shift({100, 100}), paint);
541  builder.DrawRect(rect.Shift({100, 100}), thin_paint);
542  builder.DrawRect(thin_tall_rect.Shift({100, 100}), paint);
543  builder.DrawRect(thin_tall_rect.Shift({100, 100}), thin_paint);
544  builder.DrawRect(thin_wide_rect.Shift({100, 100}), paint);
545  builder.DrawRect(thin_wide_rect.Shift({100, 100}), thin_paint);
546  builder.DrawRect(empty_rect.Shift({100, 100}), paint);
547  builder.DrawRect(empty_rect.Shift({100, 100}), thin_paint);
548 
549  // rects (B)
550  paint.setStrokeJoin(DlStrokeJoin::kRound);
551  builder.DrawRect(rect.Shift({100, 300}), paint);
552  builder.DrawRect(rect.Shift({100, 300}), thin_paint);
553  builder.DrawRect(thin_tall_rect.Shift({100, 300}), paint);
554  builder.DrawRect(thin_tall_rect.Shift({100, 300}), thin_paint);
555  builder.DrawRect(thin_wide_rect.Shift({100, 300}), paint);
556  builder.DrawRect(thin_wide_rect.Shift({100, 300}), thin_paint);
557  builder.DrawRect(empty_rect.Shift({100, 300}), paint);
558  builder.DrawRect(empty_rect.Shift({100, 300}), thin_paint);
559 
560  // rects (C)
561  paint.setStrokeJoin(DlStrokeJoin::kMiter);
562  paint.setStrokeMiter(kSqrt2 + flutter::kEhCloseEnough);
563  builder.DrawRect(rect.Shift({100, 500}), paint);
564  builder.DrawRect(rect.Shift({100, 500}), thin_paint);
565  builder.DrawRect(thin_tall_rect.Shift({100, 500}), paint);
566  builder.DrawRect(thin_tall_rect.Shift({100, 500}), thin_paint);
567  builder.DrawRect(thin_wide_rect.Shift({100, 500}), paint);
568  builder.DrawRect(thin_wide_rect.Shift({100, 500}), thin_paint);
569  builder.DrawRect(empty_rect.Shift({100, 500}), paint);
570  builder.DrawRect(empty_rect.Shift({100, 500}), thin_paint);
571 
572  // rects (D)
573  paint.setStrokeJoin(DlStrokeJoin::kMiter);
574  paint.setStrokeMiter(kSqrt2 - flutter::kEhCloseEnough);
575  builder.DrawRect(rect.Shift({300, 500}), paint);
576  builder.DrawRect(rect.Shift({300, 500}), thin_paint);
577  builder.DrawRect(thin_tall_rect.Shift({300, 500}), paint);
578  builder.DrawRect(thin_tall_rect.Shift({300, 500}), thin_paint);
579  builder.DrawRect(thin_wide_rect.Shift({300, 500}), paint);
580  builder.DrawRect(thin_wide_rect.Shift({300, 500}), thin_paint);
581  builder.DrawRect(empty_rect.Shift({300, 500}), paint);
582  builder.DrawRect(empty_rect.Shift({300, 500}), thin_paint);
583 
584  paint.setStrokeWidth(120.0f);
585  paint.setColor(DlColor::kBlue());
586  rect = rect.Expand(-20);
587 
588  // rect (E)
589  paint.setStrokeJoin(DlStrokeJoin::kBevel);
590  builder.DrawRect(rect.Shift({500, 100}), paint);
591  builder.DrawRect(rect.Shift({500, 100}), thin_paint);
592 
593  // rect (F)
594  paint.setStrokeJoin(DlStrokeJoin::kRound);
595  builder.DrawRect(rect.Shift({500, 300}), paint);
596  builder.DrawRect(rect.Shift({500, 300}), thin_paint);
597 
598  // rect (G)
599  paint.setStrokeJoin(DlStrokeJoin::kMiter);
600  paint.setStrokeMiter(kSqrt2 + flutter::kEhCloseEnough);
601  builder.DrawRect(rect.Shift({500, 500}), paint);
602  builder.DrawRect(rect.Shift({500, 500}), thin_paint);
603 
604  // rect (H)
605  paint.setStrokeJoin(DlStrokeJoin::kMiter);
606  paint.setStrokeMiter(kSqrt2 - flutter::kEhCloseEnough);
607  builder.DrawRect(rect.Shift({700, 500}), paint);
608  builder.DrawRect(rect.Shift({700, 500}), thin_paint);
609 
610  DlPaint round_mock_paint;
611  round_mock_paint.setColor(DlColor::kGreen());
612  round_mock_paint.setDrawStyle(DlDrawStyle::kFill);
613 
614  // array of rects (X)
615  Scalar x = 900;
616  Scalar y = 50;
617  for (int i = 0; i < 15; i++) {
618  paint.setStrokeWidth(i);
619  paint.setColor(DlColor::kOrange());
620  paint.setStrokeJoin(DlStrokeJoin::kRound);
621  builder.DrawRect(DlRect::MakeXYWH(x, y, 30, 30), paint);
622  y += 32 + i;
623  }
624 
625  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
626 }

References impeller::kEhCloseEnough, impeller::kSqrt2, and x.

◆ TEST_P() [297/549]

impeller::testing::TEST_P ( AiksTest  ,
SubpassWithClearColorOptimization   
)

Definition at line 1507 of file aiks_dl_basic_unittests.cc.

1507  {
1508  DisplayListBuilder builder;
1509 
1510  // Use a non-srcOver blend mode to ensure that we don't detect this as an
1511  // opacity peephole optimization.
1512  DlPaint paint;
1513  paint.setColor(DlColor::kBlue().modulateOpacity(0.5));
1514  paint.setBlendMode(DlBlendMode::kSrc);
1515 
1516  DlRect bounds = DlRect::MakeLTRB(0, 0, 200, 200);
1517  builder.SaveLayer(bounds, &paint);
1518 
1519  paint.setColor(DlColor::kTransparent());
1520  paint.setBlendMode(DlBlendMode::kSrc);
1521  builder.DrawPaint(paint);
1522  builder.Restore();
1523 
1524  paint.setColor(DlColor::kBlue());
1525  paint.setBlendMode(DlBlendMode::kDstOver);
1526  builder.SaveLayer(std::nullopt, &paint);
1527  builder.Restore();
1528 
1529  // This playground should appear blank on CI since we are only drawing
1530  // transparent black. If the clear color optimization is broken, the texture
1531  // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
1532  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1533 }

◆ TEST_P() [298/549]

impeller::testing::TEST_P ( AiksTest  ,
SupportsBlitToOnscreen   
)

Definition at line 378 of file canvas_unittests.cc.

378  {
379  ContentContext context(GetContext(), nullptr);
380  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
381  /*requires_readback=*/true);
382 
383  if (GetBackend() != PlaygroundBackend::kMetal) {
384  EXPECT_FALSE(canvas->SupportsBlitToOnscreen());
385  } else {
386  EXPECT_TRUE(canvas->SupportsBlitToOnscreen());
387  }
388 }

References CreateTestCanvas(), impeller::kMetal, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [299/549]

impeller::testing::TEST_P ( AiksTest  ,
TextContentsMismatchedTransformTest   
)

Definition at line 708 of file aiks_dl_text_unittests.cc.

708  {
709  AiksContext aiks_context(GetContext(),
710  std::make_shared<TypographerContextSkia>());
711 
712  // Verifies that TextContents only use the scale/transform that is
713  // computed during preroll.
714  constexpr const char* font_fixture = "Roboto-Regular.ttf";
715 
716  // Construct the text blob.
717  auto c_font_fixture = std::string(font_fixture);
718  auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
719  ASSERT_TRUE(mapping);
720 
721  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
722  SkFont sk_font(font_mgr->makeFromData(mapping), 16);
723 
724  auto blob = SkTextBlob::MakeFromString("Hello World", sk_font);
725  ASSERT_TRUE(blob);
726 
727  auto text_frame = MakeTextFrameFromTextBlobSkia(blob);
728 
729  // Simulate recording the text frame during preroll.
730  Matrix preroll_matrix =
731  Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
732  Point preroll_point = Point{23, 45};
733  {
734  auto scale = TextFrame::RoundScaledFontSize(
735  (preroll_matrix * Matrix::MakeTranslation(preroll_point))
736  .GetMaxBasisLengthXY());
737 
738  aiks_context.GetContentContext().GetLazyGlyphAtlas()->AddTextFrame(
739  text_frame, //
740  scale, //
741  preroll_point, //
742  preroll_matrix,
743  std::nullopt //
744  );
745  }
746 
747  // Now simulate rendering with a slightly different scale factor.
748  RenderTarget render_target =
749  aiks_context.GetContentContext()
750  .GetRenderTargetCache()
751  ->CreateOffscreenMSAA(*aiks_context.GetContext(), {100, 100}, 1);
752 
753  TextContents text_contents;
754  text_contents.SetTextFrame(text_frame);
755  text_contents.SetOffset(preroll_point);
756  text_contents.SetScale(1.6);
757  text_contents.SetColor(Color::Aqua());
758 
759  Matrix not_preroll_matrix =
760  Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
761 
762  Entity entity;
763  entity.SetTransform(not_preroll_matrix);
764 
765  std::shared_ptr<CommandBuffer> command_buffer =
766  aiks_context.GetContext()->CreateCommandBuffer();
767  std::shared_ptr<RenderPass> render_pass =
768  command_buffer->CreateRenderPass(render_target);
769 
770  EXPECT_TRUE(text_contents.Render(aiks_context.GetContentContext(), entity,
771  *render_pass));
772 }

References impeller::AiksContext::GetContentContext(), impeller::AiksContext::GetContext(), impeller::ContentContext::GetLazyGlyphAtlas(), impeller::ContentContext::GetRenderTargetCache(), impeller::MakeTextFrameFromTextBlobSkia(), impeller::TextContents::Render(), impeller::TextContents::SetColor(), impeller::TextContents::SetOffset(), impeller::TextContents::SetScale(), impeller::TextContents::SetTextFrame(), and impeller::Entity::SetTransform().

◆ TEST_P() [300/549]

impeller::testing::TEST_P ( AiksTest  ,
TextForegroundShaderWithTransform   
)

Definition at line 593 of file aiks_dl_text_unittests.cc.

593  {
594  auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
595  ASSERT_NE(mapping, nullptr);
596 
597  Scalar font_size = 100;
598  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
599  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
600 
601  DlPaint text_paint;
602  text_paint.setColor(DlColor::kBlue());
603 
604  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
605  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
606  std::vector<Scalar> stops = {
607  0.0,
608  1.0,
609  };
610  text_paint.setColorSource(DlColorSource::MakeLinear(
611  /*start_point=*/DlPoint(0, 0), //
612  /*end_point=*/DlPoint(100, 100), //
613  /*stop_count=*/2, //
614  /*colors=*/colors.data(), //
615  /*stops=*/stops.data(), //
616  /*tile_mode=*/DlTileMode::kRepeat //
617  ));
618 
619  DisplayListBuilder builder;
620  builder.Translate(100, 100);
621  builder.Rotate(45);
622 
623  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
624  ASSERT_NE(blob, nullptr);
625  auto frame = MakeTextFrameFromTextBlobSkia(blob);
626  builder.DrawText(DlTextImpeller::Make(frame), 0, 0, text_paint);
627 
628  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
629 }

References font_size, flutter::DlTextImpeller::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [301/549]

impeller::testing::TEST_P ( AiksTest  ,
TextFrameSubpixelAlignment   
)

Definition at line 317 of file aiks_dl_text_unittests.cc.

317  {
318  // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
319  std::array<Scalar, 20> phase_offsets = {
320  7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
321  0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
322  0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
323  0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
324  auto callback = [&]() -> sk_sp<DisplayList> {
325  static float font_size = 20;
326  static float phase_variation = 0.2;
327  static float speed = 0.5;
328  static float magnitude = 100;
329  if (AiksTest::ImGuiBegin("Controls", nullptr,
330  ImGuiWindowFlags_AlwaysAutoResize)) {
331  ImGui::SliderFloat("Font size", &font_size, 5, 50);
332  ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
333  ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
334  ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
335  ImGui::End();
336  }
337 
338  DisplayListBuilder builder;
339  builder.Scale(GetContentScale().x, GetContentScale().y);
340 
341  for (size_t i = 0; i < phase_offsets.size(); i++) {
342  DlPoint position = DlPoint(
343  200 +
344  magnitude * std::sin((-phase_offsets[i] * k2Pi * phase_variation +
345  GetSecondsElapsed() * speed)), //
346  200 + i * font_size * 1.1 //
347  );
349  GetContext(), builder,
350  "the quick brown fox jumped over "
351  "the lazy dog!.?",
352  "Roboto-Regular.ttf",
353  {.font_size = font_size, .position = position})) {
354  return nullptr;
355  }
356  }
357  return builder.Build();
358  };
359 
360  ASSERT_TRUE(OpenPlaygroundHere(callback));
361 }

References font_size, impeller::k2Pi, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [302/549]

impeller::testing::TEST_P ( AiksTest  ,
TextRotated   
)

Definition at line 489 of file aiks_dl_text_unittests.cc.

489  {
490  DisplayListBuilder builder;
491 
492  builder.Scale(GetContentScale().x, GetContentScale().y);
493  DlPaint paint;
494  paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
495  builder.DrawPaint(paint);
496 
497  builder.Transform(Matrix(0.25, -0.3, 0, -0.002, //
498  0, 0.5, 0, 0, //
499  0, 0, 0.3, 0, //
500  100, 100, 0, 1.3));
501  ASSERT_TRUE(RenderTextInCanvasSkia(
502  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
503  "Roboto-Regular.ttf"));
504 
505  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
506 }

References RenderTextInCanvasSkia(), and x.

◆ TEST_P() [303/549]

impeller::testing::TEST_P ( AiksTest  ,
TextRotated180Degrees   
)

Definition at line 280 of file aiks_dl_text_unittests.cc.

280  {
281  float fpivot[2] = {200 + 30, 200 - 20};
282  float rotation = 180;
283  float foffset[2] = {200, 200};
284 
285  auto callback = [&]() -> sk_sp<DisplayList> {
286  if (AiksTest::ImGuiBegin("Controls", nullptr,
287  ImGuiWindowFlags_AlwaysAutoResize)) {
288  ImGui::SliderFloat("pivotx", &fpivot[0], 0, 300);
289  ImGui::SliderFloat("pivoty", &fpivot[1], 0, 300);
290  ImGui::SliderFloat("rotation", &rotation, 0, 360);
291  ImGui::SliderFloat("foffsetx", &foffset[0], 0, 300);
292  ImGui::SliderFloat("foffsety", &foffset[1], 0, 300);
293  ImGui::End();
294  }
295  DisplayListBuilder builder;
296  builder.Scale(GetContentScale().x, GetContentScale().y);
297  builder.DrawPaint(DlPaint().setColor(DlColor(0xffffeeff)));
298 
299  builder.Save();
300  DlPoint pivot = Point(fpivot[0], fpivot[1]);
301  builder.Translate(pivot.x, pivot.y);
302  builder.Rotate(rotation);
303  builder.Translate(-pivot.x, -pivot.y);
304 
305  RenderTextInCanvasSkia(GetContext(), builder, "test", "Roboto-Regular.ttf",
306  TextRenderOptions{
307  .color = DlColor::kBlack(),
308  .position = DlPoint(foffset[0], foffset[1]),
309  });
310 
311  builder.Restore();
312  return builder.Build();
313  };
314  ASSERT_TRUE(OpenPlaygroundHere(callback));
315 }

References impeller::testing::TextRenderOptions::color, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [304/549]

impeller::testing::TEST_P ( AiksTest  ,
TextWithShadowCache   
)

Definition at line 774 of file aiks_dl_text_unittests.cc.

774  {
775  DisplayListBuilder builder;
776  builder.Scale(GetContentScale().x, GetContentScale().y);
777  DlPaint paint;
778  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
779  builder.DrawPaint(paint);
780 
781  AiksContext aiks_context(GetContext(),
782  std::make_shared<TypographerContextSkia>());
783  // Cache empty
784  EXPECT_EQ(aiks_context.GetContentContext()
785  .GetTextShadowCache()
786  .GetCacheSizeForTesting(),
787  0u);
788 
789  ASSERT_TRUE(RenderTextInCanvasSkia(
790  GetContext(), builder, "Hello World", kFontFixture,
791  TextRenderOptions{
792  .color = DlColor::kBlue(),
793  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
794 
795  DisplayListToTexture(builder.Build(), {400, 400}, aiks_context);
796 
797  // Text should be cached.
798  EXPECT_EQ(aiks_context.GetContentContext()
799  .GetTextShadowCache()
800  .GetCacheSizeForTesting(),
801  1u);
802 }

References impeller::testing::TextRenderOptions::color, impeller::DisplayListToTexture(), impeller::TextShadowCache::GetCacheSizeForTesting(), impeller::AiksContext::GetContentContext(), impeller::ContentContext::GetTextShadowCache(), kFontFixture, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [305/549]

impeller::testing::TEST_P ( AiksTest  ,
ToImageFromImage   
)

Definition at line 1042 of file aiks_dl_unittests.cc.

1042  {
1043  DisplayListBuilder builder;
1044  DlPath path = DlPath::MakeArc(DlRect::MakeLTRB(0, 0, 100, 100), DlDegrees(0),
1045  DlDegrees(90),
1046  /*use_center=*/true);
1047 
1048  builder.DrawPath(path, DlPaint().setColor(DlColor::kRed()));
1049 
1050  AiksContext renderer(GetContext(), nullptr);
1051  auto texture =
1052  DisplayListToTexture(builder.Build(), ISize(100, 100), renderer);
1053 
1054  // First, Readback the texture data into a host buffer.
1056  desc.size = texture->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
1057  desc.readback = true;
1058  desc.storage_mode = StorageMode::kHostVisible;
1059 
1060  auto device_buffer = GetContext()->GetResourceAllocator()->CreateBuffer(desc);
1061  {
1062  auto cmd_buffer = GetContext()->CreateCommandBuffer();
1063  auto blit_pass = cmd_buffer->CreateBlitPass();
1064 
1065  blit_pass->AddCopy(texture, device_buffer);
1066  blit_pass->EncodeCommands();
1067 
1068  auto latch = std::make_shared<fml::CountDownLatch>(1u);
1069  GetContext()->GetCommandQueue()->Submit(
1070  {cmd_buffer},
1071  [latch](CommandBuffer::Status status) { latch->CountDown(); });
1072  latch->Wait();
1073  }
1074 
1075  impeller::TextureDescriptor tex_desc = texture->GetTextureDescriptor();
1076  auto reupload_texture =
1077  GetContext()->GetResourceAllocator()->CreateTexture(tex_desc);
1078 
1079  // Next, Re-upload the data into a new texture.
1080  {
1081  auto cmd_buffer = GetContext()->CreateCommandBuffer();
1082  auto blit_pass = cmd_buffer->CreateBlitPass();
1083  blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer),
1084  reupload_texture);
1085  blit_pass->ConvertTextureToShaderRead(texture);
1086  blit_pass->EncodeCommands();
1087 
1088  auto latch = std::make_shared<fml::CountDownLatch>(1u);
1089  GetContext()->GetCommandQueue()->Submit(
1090  {cmd_buffer},
1091  [latch](CommandBuffer::Status status) { latch->CountDown(); });
1092  latch->Wait();
1093  }
1094 
1095  // Draw the results side by side. These should look the same.
1096  DisplayListBuilder canvas;
1097  DlPaint paint = DlPaint();
1098  canvas.DrawRect(
1099  DlRect::MakeLTRB(0, 0, 100, 100),
1100  DlPaint().setColor(DlColor::kBlue()).setDrawStyle(DlDrawStyle::kStroke));
1101  canvas.DrawImage(DlImageImpeller::Make(texture), DlPoint(0, 0),
1102  DlImageSampling::kNearestNeighbor, &paint);
1103 
1104  canvas.DrawRect(
1105  DlRect::MakeLTRB(0, 100, 100, 200),
1106  DlPaint().setColor(DlColor::kRed()).setDrawStyle(DlDrawStyle::kStroke));
1107  canvas.DrawImage(DlImageImpeller::Make(reupload_texture), DlPoint(0, 100),
1108  DlImageSampling::kNearestNeighbor, &paint);
1109  OpenPlaygroundHere(canvas.Build());
1110 }

References impeller::DeviceBuffer::AsBufferView(), impeller::DisplayListToTexture(), impeller::kHostVisible, impeller::DlImageImpeller::Make(), impeller::DeviceBufferDescriptor::readback, impeller::DeviceBufferDescriptor::size, and impeller::DeviceBufferDescriptor::storage_mode.

◆ TEST_P() [306/549]

impeller::testing::TEST_P ( AiksTest  ,
TransformMultipliesCorrectly   
)

Definition at line 71 of file canvas_unittests.cc.

71  {
72  ContentContext context(GetContext(), nullptr);
73  auto canvas = CreateTestCanvas(context);
74 
75  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(), Matrix());
76 
77  // clang-format off
78  canvas->Translate(Vector3(100, 200));
80  canvas->GetCurrentTransform(),
81  Matrix( 1, 0, 0, 0,
82  0, 1, 0, 0,
83  0, 0, 1, 0,
84  100, 200, 0, 1));
85 
86  canvas->Rotate(Radians(kPiOver2));
88  canvas->GetCurrentTransform(),
89  Matrix( 0, 1, 0, 0,
90  -1, 0, 0, 0,
91  0, 0, 1, 0,
92  100, 200, 0, 1));
93 
94  canvas->Scale(Vector3(2, 3));
96  canvas->GetCurrentTransform(),
97  Matrix( 0, 2, 0, 0,
98  -3, 0, 0, 0,
99  0, 0, 0, 0,
100  100, 200, 0, 1));
101 
102  canvas->Translate(Vector3(100, 200));
104  canvas->GetCurrentTransform(),
105  Matrix( 0, 2, 0, 0,
106  -3, 0, 0, 0,
107  0, 0, 0, 0,
108  -500, 400, 0, 1));
109  // clang-format on
110 }

References ASSERT_MATRIX_NEAR, CreateTestCanvas(), and impeller::kPiOver2.

◆ TEST_P() [307/549]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerDrawsCorrectly   
)

Definition at line 139 of file aiks_dl_unittests.cc.

139  {
140  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
141 
142  DlPaint paint;
143  paint.setColor(DlColor::kBlue());
144  builder.DrawRect(DlRect::MakeXYWH(100, 100, 300, 300), paint);
145 
146  DlPaint save_paint;
147  save_paint.setColor(DlColor::kBlack().withAlpha(128));
148  builder.SaveLayer(std::nullopt, &save_paint);
149  builder.DrawRect(DlRect::MakeXYWH(100, 500, 300, 300), paint);
150  builder.Restore();
151 
152  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
153 }

◆ TEST_P() [308/549]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerImageDrawsCorrectly   
)

Definition at line 250 of file aiks_dl_unittests.cc.

250  {
251  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
252 
253  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
254  builder.DrawImage(image, DlPoint(100, 100), DlImageSampling::kMipmapLinear);
255 
256  DlPaint paint;
257  paint.setColor(DlColor::kBlack().withAlpha(128));
258  builder.SaveLayer(std::nullopt, &paint);
259  builder.DrawImage(image, DlPoint(100, 500), DlImageSampling::kMipmapLinear);
260  builder.Restore();
261 
262  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
263 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [309/549]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly   
)

Definition at line 335 of file aiks_dl_unittests.cc.

335  {
336  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
337 
338  DlPaint paint;
339  paint.setColor(DlColor::kRed());
340  builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
341 
342  DlPaint save_paint;
343  save_paint.setAlpha(128);
344  save_paint.setBlendMode(DlBlendMode::kLighten);
345  builder.SaveLayer(std::nullopt, &save_paint);
346 
347  DlPaint draw_paint;
348  draw_paint.setColor(DlColor::kGreen());
349  builder.DrawCircle(DlPoint(200, 200), 100, draw_paint);
350  builder.Restore();
351 
352  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
353 }

◆ TEST_P() [310/549]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly   
)

Definition at line 155 of file aiks_dl_unittests.cc.

155  {
156  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
157 
158  DlPaint paint;
159  paint.setColor(DlColor::kBlue());
160  builder.DrawRect(DlRect::MakeXYWH(100, 100, 300, 300), paint);
161 
162  DlPaint save_paint;
163  paint.setColor(DlColor::kBlack().withAlpha(128));
164  paint.setColorFilter(
165  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver));
166  builder.Save();
167  builder.ClipRect(DlRect::MakeXYWH(100, 500, 300, 300));
168  builder.SaveLayer(std::nullopt, &paint);
169 
170  DlPaint draw_paint;
171  draw_paint.setColor(DlColor::kBlue());
172  builder.DrawRect(DlRect::MakeXYWH(100, 500, 300, 300), draw_paint);
173  builder.Restore();
174  builder.Restore();
175 
176  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
177 }

◆ TEST_P() [311/549]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly   
)

Definition at line 179 of file aiks_dl_unittests.cc.

179  {
180  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
181 
182  DlPaint paint;
183  paint.setColor(DlColor::kBlue());
184  builder.DrawRect(DlRect::MakeXYWH(100, 100, 300, 300), paint);
185 
186  DlPaint save_paint;
187  save_paint.setColor(DlColor::kBlack().withAlpha(128));
188  save_paint.setImageFilter(DlImageFilter::MakeColorFilter(
189  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver)));
190 
191  builder.SaveLayer(std::nullopt, &save_paint);
192 
193  DlPaint draw_paint;
194  draw_paint.setColor(DlColor::kBlue());
195  builder.DrawRect(DlRect::MakeXYWH(100, 500, 300, 300), draw_paint);
196  builder.Restore();
197 
198  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
199 }

◆ TEST_P() [312/549]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly   
)

Definition at line 201 of file aiks_dl_unittests.cc.

201  {
202  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
203 
204  DlPaint paint;
205  paint.setColor(DlColor::kBlue());
206  builder.DrawRect(DlRect::MakeXYWH(100, 100, 300, 300), paint);
207 
208  DlPaint save_paint;
209  save_paint.setColor(DlColor::kBlack().withAlpha(128));
210  save_paint.setColorFilter(
211  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver));
212  builder.Save();
213  builder.ClipRect(DlRect::MakeXYWH(100, 500, 300, 300));
214  builder.SaveLayer(std::nullopt, &save_paint);
215 
216  DlPaint draw_paint;
217  draw_paint.setColor(DlColor::kBlue());
218  builder.DrawRect(DlRect::MakeXYWH(100, 500, 300, 300), draw_paint);
219  builder.Restore();
220  builder.Restore();
221 
222  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
223 }

◆ TEST_P() [313/549]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly   
)

Definition at line 309 of file aiks_dl_unittests.cc.

310  {
311  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
312 
313  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
314  builder.DrawImage(image, DlPoint(100, 100), {});
315 
316  const float matrix[20] = {
317  1, 0, 0, 0, 0, //
318  0, 1, 0, 0, 0, //
319  0, 0.2, 1, 0, 0, //
320  0, 0, 0, 0.5, 0 //
321  };
322  DlPaint paint;
323  paint.setColor(DlColor::kBlack().withAlpha(128));
324  paint.setImageFilter(
325  DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(matrix)));
326  paint.setColorFilter(
327  DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kModulate));
328  builder.SaveLayer(std::nullopt, &paint);
329  builder.DrawImage(image, DlPoint(100, 500), {});
330  builder.Restore();
331 
332  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
333 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [314/549]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly   
)

Definition at line 265 of file aiks_dl_unittests.cc.

265  {
266  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
267 
268  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
269  builder.DrawImage(image, DlPoint(100, 100), {});
270 
271  const float matrix[20] = {
272  1, 0, 0, 0, 0, //
273  0, 1, 0, 0, 0, //
274  0, 0, 1, 0, 0, //
275  0, 0, 0, 2, 0 //
276  };
277  DlPaint paint;
278  paint.setColor(DlColor::kBlack().withAlpha(128));
279  paint.setColorFilter(DlColorFilter::MakeMatrix(matrix));
280  builder.SaveLayer(std::nullopt, &paint);
281  builder.DrawImage(image, DlPoint(100, 500), {});
282  builder.Restore();
283 
284  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
285 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [315/549]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly   
)

Definition at line 287 of file aiks_dl_unittests.cc.

287  {
288  DisplayListBuilder builder(DlRect::MakeSize(GetWindowSize()));
289 
290  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
291  builder.DrawImage(image, DlPoint(100, 100), {});
292 
293  const float matrix[20] = {
294  1, 0, 0, 0, 0, //
295  0, 1, 0, 0, 0, //
296  0, 0, 1, 0, 0, //
297  0, 0, 0, 2, 0 //
298  };
299  DlPaint paint;
300  paint.setColor(DlColor::kBlack().withAlpha(128));
301  paint.setColorFilter(DlColorFilter::MakeMatrix(matrix));
302  builder.SaveLayer(std::nullopt, &paint);
303  builder.DrawImage(image, DlPoint(100, 500), {});
304  builder.Restore();
305 
306  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
307 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [316/549]

impeller::testing::TEST_P ( AiksTest  ,
TransparentShadowProducesCorrectColor   
)

Definition at line 858 of file aiks_dl_unittests.cc.

858  {
859  DisplayListBuilder builder;
860  builder.Save();
861  builder.Scale(1.618, 1.618);
862  DlPath path = DlPath::MakeRect(DlRect::MakeXYWH(0, 0, 200, 100));
863 
864  builder.DrawShadow(path, flutter::DlColor::kTransparent(), 15, false, 1);
865  builder.Restore();
866 
867  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
868 }

◆ TEST_P() [317/549]

impeller::testing::TEST_P ( AiksTest  ,
TwoContourPathWithSinglePointContour   
)

Definition at line 967 of file aiks_dl_path_unittests.cc.

967  {
968  DisplayListBuilder builder;
969 
970  DlPaint paint;
971  paint.setColor(DlColor::kRed());
972  paint.setDrawStyle(DlDrawStyle::kStroke);
973  paint.setStrokeWidth(15.0);
974  paint.setStrokeCap(DlStrokeCap::kRound);
975 
976  DlPathBuilder path_builder;
977  path_builder.MoveTo(DlPoint(100, 100));
978  path_builder.LineTo(DlPoint(150, 150));
979  path_builder.MoveTo(DlPoint(200, 200));
980  path_builder.LineTo(DlPoint(200, 200));
981 
982  builder.DrawPath(path_builder.TakePath(), paint);
983 
984  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
985 }

◆ TEST_P() [318/549]

impeller::testing::TEST_P ( AiksTest  ,
VarietyOfTextScalesShowingRasterAndPath   
)

Definition at line 877 of file aiks_dl_text_unittests.cc.

877  {
878  DisplayListBuilder builder;
879  DlPaint paint;
880  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
881  builder.DrawPaint(paint);
882  builder.Scale(GetContentScale().x, GetContentScale().y);
883 
884  std::vector<Scalar> scales = {4, 8, 16, 24, 32};
885  std::vector<Scalar> spacing = {8, 8, 8, 8, 8};
886  Scalar space = 16;
887  Scalar x = 0;
888  for (auto i = 0u; i < scales.size(); i++) {
889  builder.Save();
890  builder.Scale(scales[i], scales[i]);
892  GetContext(), builder, "lo", "Roboto-Regular.ttf",
893  TextRenderOptions{.font_size = 16, .position = DlPoint(x, space)});
894  space += spacing[i];
895  if (i == 3) {
896  x = 10;
897  space = 16;
898  }
899  builder.Restore();
900  }
901  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
902 }

References impeller::testing::TextRenderOptions::font_size, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [319/549]

impeller::testing::TEST_P ( AiksTest  ,
VerifyNonOptimizedGradient   
)

Definition at line 916 of file aiks_dl_gradient_unittests.cc.

916  {
917  DisplayListBuilder builder;
918  DlPaint paint;
919  builder.Translate(100.0f, 0);
920 
921  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
922  DlColor::kGreen()};
923  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
924 
925  // Inset the start and end point to verify that we do not apply
926  // the fast gradient condition.
927  paint.setColorSource(
928  DlColorSource::MakeLinear({0, 150}, {0, 100}, stops.size(), colors.data(),
929  stops.data(), DlTileMode::kRepeat));
930 
931  paint.setColor(DlColor::kWhite());
932  builder.DrawRect(DlRect::MakeXYWH(0, 0, 300, 300), paint);
933  builder.Translate(400, 0);
934  builder.DrawRoundRect(
935  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 300, 300), 4, 4), paint);
936 
937  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
938 }

◆ TEST_P() [320/549]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryColorUVPositionData   
)

Definition at line 98 of file aiks_dl_vertices_unittests.cc.

98  {
99  DisplayListBuilder builder;
100  DlPaint paint;
101  auto image =
102  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
103  auto size = image->impeller_texture()->GetSize();
104 
105  paint.setColorSource(
106  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp));
107 
108  std::vector<DlPoint> positions = {
109  DlPoint(0, 0), DlPoint(size.width, 0),
110  DlPoint(0, size.height), DlPoint(size.width, 0),
111  DlPoint(0, 0), DlPoint(size.width, size.height),
112  };
113  std::vector<DlColor> colors = {
114  DlColor::kRed().withAlpha(128), DlColor::kBlue().withAlpha(128),
115  DlColor::kGreen().withAlpha(128), DlColor::kRed().withAlpha(128),
116  DlColor::kBlue().withAlpha(128), DlColor::kGreen().withAlpha(128),
117  };
118 
119  auto vertices =
120  MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
121 
122  builder.DrawVertices(vertices, DlBlendMode::kDstOver, paint);
123  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
124 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [321/549]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryColorUVPositionDataAdvancedBlend   
)

Definition at line 126 of file aiks_dl_vertices_unittests.cc.

126  {
127  DisplayListBuilder builder;
128  DlPaint paint;
129  auto image =
130  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
131  auto size = image->impeller_texture()->GetSize();
132 
133  paint.setColorSource(
134  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp));
135 
136  std::vector<DlPoint> positions = {
137  DlPoint(0, 0), DlPoint(size.width, 0),
138  DlPoint(0, size.height), DlPoint(size.width, 0),
139  DlPoint(0, 0), DlPoint(size.width, size.height),
140  };
141  std::vector<DlColor> colors = {
142  DlColor::kRed().modulateOpacity(0.5),
143  DlColor::kBlue().modulateOpacity(0.5),
144  DlColor::kGreen().modulateOpacity(0.5),
145  DlColor::kRed().modulateOpacity(0.5),
146  DlColor::kBlue().modulateOpacity(0.5),
147  DlColor::kGreen().modulateOpacity(0.5),
148  };
149 
150  auto vertices =
151  MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
152 
153  builder.DrawVertices(vertices, DlBlendMode::kColorBurn, paint);
154  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
155 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [322/549]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionData   
)

Definition at line 50 of file aiks_dl_vertices_unittests.cc.

50  {
51  DisplayListBuilder builder;
52  DlPaint paint;
53  auto image =
54  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
55  auto size = image->impeller_texture()->GetSize();
56 
57  paint.setColorSource(
58  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp));
59 
60  std::vector<DlPoint> vertex_coordinates = {
61  DlPoint(0, 0),
62  DlPoint(size.width, 0),
63  DlPoint(0, size.height),
64  };
65  auto vertices = MakeVertices(DlVertexMode::kTriangleStrip, vertex_coordinates,
66  {0, 1, 2}, {}, {});
67 
68  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
69  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
70 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [323/549]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionDataWithTranslate   
)

Definition at line 73 of file aiks_dl_vertices_unittests.cc.

73  {
74  DisplayListBuilder builder;
75  DlPaint paint;
76  auto image =
77  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
78  auto size = image->impeller_texture()->GetSize();
79 
80  DlMatrix matrix = DlMatrix::MakeTranslation({100, 100});
81  paint.setColorSource(
82  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp,
83  DlImageSampling::kLinear, &matrix));
84 
85  std::vector<DlPoint> positions = {
86  DlPoint(0, 0),
87  DlPoint(size.width, 0),
88  DlPoint(0, size.height),
89  };
90  auto vertices =
91  MakeVertices(DlVertexMode::kTriangleStrip, positions, {0, 1, 2}, {}, {});
92 
93  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
94  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
95 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [324/549]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryWithMaskFilter   
)

Definition at line 556 of file aiks_dl_vertices_unittests.cc.

556  {
557  DisplayListBuilder builder;
558  DlPaint paint;
559  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 10));
560 
561  std::vector<DlPoint> vertex_coordinates = {
562  DlPoint(0, 0),
563  DlPoint(400, 0),
564  DlPoint(0, 400),
565  };
566  auto vertices = MakeVertices(DlVertexMode::kTriangleStrip, vertex_coordinates,
567  {0, 1, 2}, {}, {});
568 
569  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
570  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
571 }

◆ TEST_P() [325/549]

impeller::testing::TEST_P ( AllocatorMTLTest  ,
DebugTraceMemoryStatistics   
)

Definition at line 28 of file allocator_mtl_unittests.mm.

28  {
29  auto& context_mtl = ContextMTL::Cast(*GetContext());
30  const auto& allocator = context_mtl.GetResourceAllocator();
31 
32  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
33  0u);
34 
35  // Memoryless texture does not increase allocated size.
36  {
37  TextureDescriptor desc;
38  desc.format = PixelFormat::kR8G8B8A8UNormInt;
39  desc.storage_mode = StorageMode::kDeviceTransient;
40  desc.size = {1024, 1024};
41  auto texture_1 = allocator->CreateTexture(desc);
42 
43  // Private storage texture increases allocated size.
44  desc.storage_mode = StorageMode::kDevicePrivate;
45  auto texture_2 = allocator->CreateTexture(desc);
46 
47 #ifdef IMPELLER_DEBUG
48  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
49  4u);
50 #else
51  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
52  0u);
53 #endif // IMPELLER_DEBUG
54 
55  // Host storage texture increases allocated size.
56  desc.storage_mode = StorageMode::kHostVisible;
57  auto texture_3 = allocator->CreateTexture(desc);
58 
59 #ifdef IMPELLER_DEBUG
60  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
61  8u);
62 #else
63  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
64  0u);
65 #endif // IMPELLER_DEBUG
66  }
67 
68  // After all textures are out of scope, memory has been decremented.
69  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
70  0u);
71 }

References impeller::BackendCast< ContextMTL, Context >::Cast(), impeller::TextureDescriptor::format, impeller::AllocationSize< Period >::GetSize(), impeller::kDevicePrivate, impeller::kDeviceTransient, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [326/549]

impeller::testing::TEST_P ( AllocatorMTLTest  ,
ManagedMemory   
)

Definition at line 73 of file allocator_mtl_unittests.mm.

73  {
74  auto& context_mtl = ContextMTL::Cast(*GetContext());
75  auto allocator = std::make_unique<AllocatorMTL>(context_mtl.GetMTLDevice(),
76  "test-allocator");
77  allocator->DebugSetSupportsUMA(false);
78 
79  DeviceBufferDescriptor desc;
80  desc.size = 100;
81  desc.storage_mode = StorageMode::kHostVisible;
82 
83  auto buffer = allocator->CreateBuffer(desc);
84  ASSERT_TRUE(buffer);
85 
86  EXPECT_NE(buffer->OnGetContents(), nullptr);
87 }

References impeller::BackendCast< ContextMTL, Context >::Cast(), impeller::kHostVisible, impeller::DeviceBufferDescriptor::size, and impeller::DeviceBufferDescriptor::storage_mode.

◆ TEST_P() [327/549]

impeller::testing::TEST_P ( BlendFilterContentsTest  ,
AdvancedBlendColorAlignsColorTo4   
)

Definition at line 45 of file blend_filter_contents_unittests.cc.

45  {
46  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
47  BlendFilterContents filter_contents;
48  filter_contents.SetInputs({FilterInput::Make(texture)});
49  filter_contents.SetForegroundColor(Color(1.0, 0.0, 0.0, 1.0));
50  filter_contents.SetBlendMode(BlendMode::kColorDodge);
51 
52  std::shared_ptr<ContentContext> renderer = GetContentContext();
53  // Add random byte to get the HostBuffer in a bad alignment.
54  uint8_t byte = 0xff;
55  BufferView buffer_view = renderer->GetTransientsDataBuffer().Emplace(
56  &byte, /*length=*/1, /*align=*/1);
57  EXPECT_EQ(buffer_view.GetRange().offset, 4u);
58  EXPECT_EQ(buffer_view.GetRange().length, 1u);
59  Entity entity;
60 
61  std::optional<Entity> result = filter_contents.GetEntity(
62  *renderer, entity, /*coverage_hint=*/std::nullopt);
63 
64  EXPECT_TRUE(result.has_value());
65 }

References buffer_view, impeller::FilterContents::GetEntity(), impeller::kColorDodge, impeller::FilterInput::Make(), impeller::BlendFilterContents::SetBlendMode(), impeller::BlendFilterContents::SetForegroundColor(), and impeller::FilterContents::SetInputs().

◆ TEST_P() [328/549]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentPixelFormatsFails   
)

Definition at line 30 of file blit_pass_unittests.cc.

30  {
31  ScopedValidationDisable scope; // avoid noise in output.
32  auto context = GetContext();
33  auto cmd_buffer = context->CreateCommandBuffer();
34  auto blit_pass = cmd_buffer->CreateBlitPass();
35 
36  TextureDescriptor src_desc;
37  src_desc.format = PixelFormat::kA8UNormInt;
38  src_desc.size = {100, 100};
39  src_desc.storage_mode = StorageMode::kHostVisible;
40  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
41 
42  TextureDescriptor dst_format;
43  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
44  dst_format.size = {100, 100};
45  dst_format.storage_mode = StorageMode::kHostVisible;
46  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
47 
48  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
49 }

References impeller::TextureDescriptor::format, impeller::kA8UNormInt, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [329/549]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentSampleCountsFails   
)

Definition at line 51 of file blit_pass_unittests.cc.

51  {
52  ScopedValidationDisable scope; // avoid noise in output.
53  auto context = GetContext();
54  auto cmd_buffer = context->CreateCommandBuffer();
55  auto blit_pass = cmd_buffer->CreateBlitPass();
56 
57  TextureDescriptor src_desc;
58  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
59  src_desc.sample_count = SampleCount::kCount4;
60  src_desc.size = {100, 100};
61  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
62 
63  TextureDescriptor dst_format;
64  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
65  dst_format.size = {100, 100};
66  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
67 
68  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
69 }

References impeller::TextureDescriptor::format, impeller::kCount4, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::sample_count, and impeller::TextureDescriptor::size.

◆ TEST_P() [330/549]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitPassesForMatchingFormats   
)

Definition at line 71 of file blit_pass_unittests.cc.

71  {
72  ScopedValidationDisable scope; // avoid noise in output.
73  auto context = GetContext();
74  auto cmd_buffer = context->CreateCommandBuffer();
75  auto blit_pass = cmd_buffer->CreateBlitPass();
76 
77  TextureDescriptor src_desc;
78  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
79  src_desc.size = {100, 100};
80  src_desc.storage_mode = StorageMode::kHostVisible;
81  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
82 
83  TextureDescriptor dst_format;
84  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
85  dst_format.size = {100, 100};
86  dst_format.storage_mode = StorageMode::kHostVisible;
87  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
88 
89  EXPECT_TRUE(blit_pass->AddCopy(src, dst));
90 }

References impeller::TextureDescriptor::format, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [331/549]

impeller::testing::TEST_P ( BlitPassTest  ,
CanBlitSmallRegionToUninitializedTexture   
)

Definition at line 123 of file blit_pass_unittests.cc.

123  {
124  auto context = GetContext();
125  auto cmd_buffer = context->CreateCommandBuffer();
126  auto blit_pass = cmd_buffer->CreateBlitPass();
127 
128  TextureDescriptor dst_format;
129  dst_format.storage_mode = StorageMode::kDevicePrivate;
130  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
131  dst_format.size = {1000, 1000};
132  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
133 
134  DeviceBufferDescriptor src_format;
135  src_format.size = 4;
136  src_format.storage_mode = StorageMode::kHostVisible;
137  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
138 
139  ASSERT_TRUE(dst);
140 
141  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
142  IRect::MakeLTRB(0, 0, 1, 1), "",
143  /*mip_level=*/0, /*slice=*/0));
144  EXPECT_TRUE(blit_pass->EncodeCommands());
145  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
146 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TRect< T >::MakeLTRB(), impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [332/549]

impeller::testing::TEST_P ( BlitPassTest  ,
CanBlitToHigherTextureMipLevels   
)

Definition at line 176 of file blit_pass_unittests.cc.

176  {
177  auto context = GetContext();
178  auto cmd_buffer = context->CreateCommandBuffer();
179  auto blit_pass = cmd_buffer->CreateBlitPass();
180 
181  TextureDescriptor dst_format;
182  dst_format.storage_mode = StorageMode::kDevicePrivate;
183  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
184  dst_format.size = {1000, 1000};
185  dst_format.mip_count = 4;
186  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
187 
188  DeviceBufferDescriptor src_format;
189  src_format.size = 4;
190  src_format.storage_mode = StorageMode::kHostVisible;
191  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
192 
193  ASSERT_TRUE(dst);
194 
195  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
196  IRect::MakeLTRB(0, 0, 1, 1), "",
197  /*mip_level=*/1, /*slice=*/0));
198  EXPECT_TRUE(blit_pass->EncodeCommands());
199  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
200 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TRect< T >::MakeLTRB(), impeller::TextureDescriptor::mip_count, impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [333/549]

impeller::testing::TEST_P ( BlitPassTest  ,
CanResizeTextures   
)

Definition at line 202 of file blit_pass_unittests.cc.

202  {
203  auto context = GetContext();
204  auto cmd_buffer = context->CreateCommandBuffer();
205  auto blit_pass = cmd_buffer->CreateBlitPass();
206 
207  TextureDescriptor dst_format;
208  dst_format.storage_mode = StorageMode::kDevicePrivate;
209  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
210  dst_format.size = {10, 10};
211  dst_format.usage = TextureUsage::kShaderRead | TextureUsage::kShaderWrite;
212  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
213 
214  TextureDescriptor src_format;
215  src_format.storage_mode = StorageMode::kDevicePrivate;
216  src_format.format = PixelFormat::kR8G8B8A8UNormInt;
217  src_format.size = {100, 100};
218  auto src = context->GetResourceAllocator()->CreateTexture(src_format);
219 
220  std::vector<uint8_t> bytes(src_format.GetByteSizeOfBaseMipLevel());
221  for (auto i = 0u; i < src_format.GetByteSizeOfBaseMipLevel(); i += 4) {
222  // RGBA
223  bytes[i + 0] = 255;
224  bytes[i + 1] = 0;
225  bytes[i + 2] = 0;
226  bytes[i + 3] = 255;
227  }
228  auto mapping = fml::DataMapping(bytes);
229  auto staging = context->GetResourceAllocator()->CreateBufferWithCopy(mapping);
230 
231  ASSERT_TRUE(dst);
232  ASSERT_TRUE(src);
233  ASSERT_TRUE(staging);
234 
235  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(staging), src));
236  EXPECT_TRUE(blit_pass->ResizeTexture(src, dst));
237  EXPECT_TRUE(blit_pass->EncodeCommands());
238  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
239 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel(), impeller::kDevicePrivate, impeller::kR8G8B8A8UNormInt, impeller::kShaderRead, impeller::kShaderWrite, impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::usage.

◆ TEST_P() [334/549]

impeller::testing::TEST_P ( BlitPassTest  ,
CanResizeTexturesPlayground   
)

Definition at line 241 of file blit_pass_unittests.cc.

241  {
242  auto context = GetContext();
243  auto cmd_buffer = context->CreateCommandBuffer();
244  auto blit_pass = cmd_buffer->CreateBlitPass();
245 
246  std::shared_ptr<Texture> src = CreateTextureForFixture("kalimba.jpg");
247 
248  TextureDescriptor dst_format;
249  dst_format.storage_mode = StorageMode::kDevicePrivate;
250  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
251  dst_format.size = {src->GetSize().width / 2, src->GetSize().height};
252  dst_format.usage = TextureUsage::kShaderRead | TextureUsage::kShaderWrite;
253  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
254 
255  ASSERT_TRUE(dst);
256  ASSERT_TRUE(src);
257 
258  EXPECT_TRUE(blit_pass->ResizeTexture(src, dst));
259  EXPECT_TRUE(blit_pass->EncodeCommands());
260  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
261 
262  DisplayListBuilder builder;
263  builder.Scale(GetContentScale().x, GetContentScale().y);
264  DlPaint paint;
265  paint.setColor(DlColor::kRed());
266  auto image = DlImageImpeller::Make(dst);
267  builder.DrawImage(image, flutter::DlPoint(100.0, 100.0),
268  DlImageSampling::kNearestNeighbor, &paint);
269  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
270 }

References impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kR8G8B8A8UNormInt, impeller::kShaderRead, impeller::kShaderWrite, impeller::DlImageImpeller::Make(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::TextureDescriptor::usage, impeller::TSize< T >::width, and x.

◆ TEST_P() [335/549]

impeller::testing::TEST_P ( BlitPassTest  ,
ChecksInvalidMipLevelParameter   
)

Definition at line 148 of file blit_pass_unittests.cc.

148  {
149  ScopedValidationDisable scope;
150  auto context = GetContext();
151  auto cmd_buffer = context->CreateCommandBuffer();
152  auto blit_pass = cmd_buffer->CreateBlitPass();
153 
154  TextureDescriptor dst_format;
155  dst_format.storage_mode = StorageMode::kDevicePrivate;
156  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
157  dst_format.size = {1000, 1000};
158  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
159 
160  DeviceBufferDescriptor src_format;
161  src_format.size = 4;
162  src_format.storage_mode = StorageMode::kHostVisible;
163  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
164 
165  ASSERT_TRUE(dst);
166 
167  EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
168  IRect::MakeLTRB(0, 0, 1, 1), "",
169  /*mip_level=*/1, /*slice=*/0));
170 
171  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
172  IRect::MakeLTRB(0, 0, 1, 1), "",
173  /*mip_level=*/0, /*slice=*/0));
174 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TRect< T >::MakeLTRB(), impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [336/549]

impeller::testing::TEST_P ( BlitPassTest  ,
ChecksInvalidSliceParameters   
)

Definition at line 92 of file blit_pass_unittests.cc.

92  {
93  ScopedValidationDisable scope; // avoid noise in output.
94  auto context = GetContext();
95  auto cmd_buffer = context->CreateCommandBuffer();
96  auto blit_pass = cmd_buffer->CreateBlitPass();
97 
98  TextureDescriptor dst_format;
99  dst_format.storage_mode = StorageMode::kDevicePrivate;
100  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
101  dst_format.size = {100, 100};
102  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
103 
104  DeviceBufferDescriptor src_format;
105  src_format.size = 40000;
106  src_format.storage_mode = StorageMode::kHostVisible;
107  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
108 
109  ASSERT_TRUE(dst);
110  ASSERT_TRUE(src);
111 
112  EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
113  std::nullopt, "", /*mip_level=*/0,
114  /*slice=*/25));
115  EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
116  std::nullopt, "", /*mip_level=*/0,
117  /*slice=*/6));
118  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
119  std::nullopt, "", /*mip_level=*/0,
120  /*slice=*/0));
121 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [337/549]

impeller::testing::TEST_P ( ComputeTest  ,
1DThreadgroupSizingIsCorrect   
)

Definition at line 177 of file compute_unittests.cc.

177  {
178  using CS = ThreadgroupSizingTestComputeShader;
179  auto context = GetContext();
180  ASSERT_TRUE(context);
181  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
182 
183  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
184  auto pipeline_desc =
185  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
186  ASSERT_TRUE(pipeline_desc.has_value());
187  auto compute_pipeline =
188  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
189  ASSERT_TRUE(compute_pipeline);
190 
191  auto cmd_buffer = context->CreateCommandBuffer();
192  auto pass = cmd_buffer->CreateComputePass();
193  ASSERT_TRUE(pass && pass->IsValid());
194 
195  static constexpr size_t kCount = 2048;
196 
197  pass->SetPipeline(compute_pipeline);
198 
199  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
200  context, "Output Buffer");
201 
202  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
203 
204  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
205  ASSERT_TRUE(pass->EncodeCommands());
206 
207  fml::AutoResetWaitableEvent latch;
208  ASSERT_TRUE(
209  context->GetCommandQueue()
210  ->Submit({cmd_buffer},
211  [&latch, output_buffer](CommandBuffer::Status status) {
212  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
213 
214  auto view = DeviceBuffer::AsBufferView(output_buffer);
215  EXPECT_EQ(view.GetRange().length,
216  sizeof(CS::OutputData<kCount>));
217 
218  CS::OutputData<kCount>* output =
219  reinterpret_cast<CS::OutputData<kCount>*>(
220  output_buffer->OnGetContents());
221  EXPECT_TRUE(output);
222  EXPECT_EQ(output->data[kCount - 1], kCount - 1);
223  latch.Signal();
224  })
225  .ok());
226 
227  latch.Wait();
228 }

◆ TEST_P() [338/549]

impeller::testing::TEST_P ( ComputeTest  ,
CanCompute1DimensionalData   
)

Definition at line 377 of file compute_unittests.cc.

377  {
378  using CS = SampleComputeShader;
379  auto context = GetContext();
380  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
381  context->GetIdleWaiter());
382  ASSERT_TRUE(context);
383  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
384 
385  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
386  auto pipeline_desc =
387  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
388  ASSERT_TRUE(pipeline_desc.has_value());
389  auto compute_pipeline =
390  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
391  ASSERT_TRUE(compute_pipeline);
392 
393  auto cmd_buffer = context->CreateCommandBuffer();
394  auto pass = cmd_buffer->CreateComputePass();
395  ASSERT_TRUE(pass && pass->IsValid());
396 
397  static constexpr size_t kCount = 5;
398 
399  pass->SetPipeline(compute_pipeline);
400 
401  CS::Info info{.count = kCount};
402  CS::Input0<kCount> input_0;
403  CS::Input1<kCount> input_1;
404  for (size_t i = 0; i < kCount; i++) {
405  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
406  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
407  }
408 
409  input_0.fixed_array[1] = IPoint32(2, 2);
410  input_1.fixed_array[0] = UintPoint32(3, 3);
411  input_0.some_int = 5;
412  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
413 
414  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
415  context, "Output Buffer");
416 
417  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
418  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
419  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
420  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
421 
422  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
423  ASSERT_TRUE(pass->EncodeCommands());
424 
425  fml::AutoResetWaitableEvent latch;
426  ASSERT_TRUE(
427  context->GetCommandQueue()
428  ->Submit(
429  {cmd_buffer},
430  [&latch, output_buffer, &input_0,
431  &input_1](CommandBuffer::Status status) {
432  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
433 
434  auto view = DeviceBuffer::AsBufferView(output_buffer);
435  EXPECT_EQ(view.GetRange().length, sizeof(CS::Output<kCount>));
436 
437  CS::Output<kCount>* output =
438  reinterpret_cast<CS::Output<kCount>*>(
439  output_buffer->OnGetContents());
440  EXPECT_TRUE(output);
441  for (size_t i = 0; i < kCount; i++) {
442  Vector4 vector = output->elements[i];
443  Vector4 computed = input_0.elements[i] * input_1.elements[i];
444  EXPECT_EQ(vector,
445  Vector4(computed.x + 2 + input_1.some_struct.i,
446  computed.y + 3 + input_1.some_struct.vf.x,
447  computed.z + 5 + input_1.some_struct.vf.y,
448  computed.w));
449  }
450  latch.Signal();
451  })
452  .ok());
453 
454  latch.Wait();
455 }
TPoint< int32_t > IPoint32
Definition: point.h:329
TPoint< uint32_t > UintPoint32
Definition: point.h:330

References impeller::interop::Create().

◆ TEST_P() [339/549]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSum   
)

Definition at line 110 of file compute_unittests.cc.

110  {
111  using CS = PrefixSumTestComputeShader;
112  auto context = GetContext();
113  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
114  context->GetIdleWaiter());
115  ASSERT_TRUE(context);
116  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
117 
118  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
119  auto pipeline_desc =
120  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
121  ASSERT_TRUE(pipeline_desc.has_value());
122  auto compute_pipeline =
123  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
124  ASSERT_TRUE(compute_pipeline);
125 
126  auto cmd_buffer = context->CreateCommandBuffer();
127  auto pass = cmd_buffer->CreateComputePass();
128  ASSERT_TRUE(pass && pass->IsValid());
129 
130  static constexpr size_t kCount = 5;
131 
132  pass->SetPipeline(compute_pipeline);
133 
134  CS::InputData<kCount> input_data;
135  input_data.count = kCount;
136  for (size_t i = 0; i < kCount; i++) {
137  input_data.data[i] = 1 + i;
138  }
139 
140  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
141  context, "Output Buffer");
142 
143  CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
144  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
145 
146  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
147  ASSERT_TRUE(pass->EncodeCommands());
148 
149  fml::AutoResetWaitableEvent latch;
150  ASSERT_TRUE(
151  context->GetCommandQueue()
152  ->Submit({cmd_buffer},
153  [&latch, output_buffer](CommandBuffer::Status status) {
154  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
155 
156  auto view = DeviceBuffer::AsBufferView(output_buffer);
157  EXPECT_EQ(view.GetRange().length,
158  sizeof(CS::OutputData<kCount>));
159 
160  CS::OutputData<kCount>* output =
161  reinterpret_cast<CS::OutputData<kCount>*>(
162  output_buffer->OnGetContents());
163  EXPECT_TRUE(output);
164 
165  constexpr uint32_t expected[kCount] = {1, 3, 6, 10, 15};
166  for (size_t i = 0; i < kCount; i++) {
167  auto computed_sum = output->data[i];
168  EXPECT_EQ(computed_sum, expected[i]);
169  }
170  latch.Signal();
171  })
172  .ok());
173 
174  latch.Wait();
175 }

References impeller::DeviceBuffer::AsBufferView(), and impeller::HostBuffer::Create().

◆ TEST_P() [340/549]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSumLargeInteractive   
)

Definition at line 230 of file compute_unittests.cc.

230  {
231  using CS = PrefixSumTestComputeShader;
232 
233  auto context = GetContext();
234  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
235  context->GetIdleWaiter());
236 
237  ASSERT_TRUE(context);
238  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
239 
240  auto callback = [&](RenderPass& render_pass) -> bool {
241  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
242  auto pipeline_desc =
243  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
244  auto compute_pipeline =
245  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
246 
247  auto cmd_buffer = context->CreateCommandBuffer();
248  auto pass = cmd_buffer->CreateComputePass();
249 
250  static constexpr size_t kCount = 1023;
251 
252  pass->SetPipeline(compute_pipeline);
253 
254  CS::InputData<kCount> input_data;
255  input_data.count = kCount;
256  for (size_t i = 0; i < kCount; i++) {
257  input_data.data[i] = 1 + i;
258  }
259 
260  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
261  context, "Output Buffer");
262 
263  CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
264  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
265 
266  pass->Compute(ISize(kCount, 1));
267  pass->EncodeCommands();
268  host_buffer->Reset();
269  return context->GetCommandQueue()->Submit({cmd_buffer}).ok();
270  };
271  ASSERT_TRUE(OpenPlaygroundHere(callback));
272 }

References impeller::interop::Create().

◆ TEST_P() [341/549]

impeller::testing::TEST_P ( ComputeTest  ,
CanCreateComputePass   
)

Definition at line 30 of file compute_unittests.cc.

30  {
31  using CS = SampleComputeShader;
32  auto context = GetContext();
33  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
34  context->GetIdleWaiter());
35  ASSERT_TRUE(context);
36  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
37 
38  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
39  auto pipeline_desc =
40  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
41  ASSERT_TRUE(pipeline_desc.has_value());
42  auto compute_pipeline =
43  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
44  ASSERT_TRUE(compute_pipeline);
45 
46  auto cmd_buffer = context->CreateCommandBuffer();
47  auto pass = cmd_buffer->CreateComputePass();
48  ASSERT_TRUE(pass && pass->IsValid());
49 
50  static constexpr size_t kCount = 5;
51 
52  pass->SetPipeline(compute_pipeline);
53 
54  CS::Info info{.count = kCount};
55  CS::Input0<kCount> input_0;
56  CS::Input1<kCount> input_1;
57  for (size_t i = 0; i < kCount; i++) {
58  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
59  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
60  }
61 
62  input_0.fixed_array[1] = IPoint32(2, 2);
63  input_1.fixed_array[0] = UintPoint32(3, 3);
64  input_0.some_int = 5;
65  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
66 
67  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
68  context, "Output Buffer");
69 
70  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
71  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
72  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
73  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
74 
75  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
76  ASSERT_TRUE(pass->EncodeCommands());
77 
78  fml::AutoResetWaitableEvent latch;
79  ASSERT_TRUE(
80  context->GetCommandQueue()
81  ->Submit(
82  {cmd_buffer},
83  [&latch, output_buffer, &input_0,
84  &input_1](CommandBuffer::Status status) {
85  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
86 
87  auto view = DeviceBuffer::AsBufferView(output_buffer);
88  EXPECT_EQ(view.GetRange().length, sizeof(CS::Output<kCount>));
89 
90  CS::Output<kCount>* output =
91  reinterpret_cast<CS::Output<kCount>*>(
92  output_buffer->OnGetContents());
93  EXPECT_TRUE(output);
94  for (size_t i = 0; i < kCount; i++) {
95  Vector4 vector = output->elements[i];
96  Vector4 computed = input_0.elements[i] * input_1.elements[i];
97  EXPECT_EQ(vector,
98  Vector4(computed.x + 2 + input_1.some_struct.i,
99  computed.y + 3 + input_1.some_struct.vf.x,
100  computed.z + 5 + input_1.some_struct.vf.y,
101  computed.w));
102  }
103  latch.Signal();
104  })
105  .ok());
106 
107  latch.Wait();
108 }

References impeller::DeviceBuffer::AsBufferView(), and impeller::HostBuffer::Create().

◆ TEST_P() [342/549]

impeller::testing::TEST_P ( ComputeTest  ,
CapabilitiesReportSupport   
)

Definition at line 24 of file compute_unittests.cc.

24  {
25  auto context = GetContext();
26  ASSERT_TRUE(context);
27  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
28 }

◆ TEST_P() [343/549]

impeller::testing::TEST_P ( ComputeTest  ,
MultiStageInputAndOutput   
)

Definition at line 274 of file compute_unittests.cc.

274  {
275  using CS1 = Stage1ComputeShader;
276  using Stage1PipelineBuilder = ComputePipelineBuilder<CS1>;
277  using CS2 = Stage2ComputeShader;
278  using Stage2PipelineBuilder = ComputePipelineBuilder<CS2>;
279 
280  auto context = GetContext();
281  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
282  context->GetIdleWaiter());
283  ASSERT_TRUE(context);
284  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
285 
286  auto pipeline_desc_1 =
287  Stage1PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
288  ASSERT_TRUE(pipeline_desc_1.has_value());
289  auto compute_pipeline_1 =
290  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_1).Get();
291  ASSERT_TRUE(compute_pipeline_1);
292 
293  auto pipeline_desc_2 =
294  Stage2PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
295  ASSERT_TRUE(pipeline_desc_2.has_value());
296  auto compute_pipeline_2 =
297  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_2).Get();
298  ASSERT_TRUE(compute_pipeline_2);
299 
300  auto cmd_buffer = context->CreateCommandBuffer();
301  auto pass = cmd_buffer->CreateComputePass();
302  ASSERT_TRUE(pass && pass->IsValid());
303 
304  static constexpr size_t kCount1 = 5;
305  static constexpr size_t kCount2 = kCount1 * 2;
306 
307  CS1::Input<kCount1> input_1;
308  input_1.count = kCount1;
309  for (size_t i = 0; i < kCount1; i++) {
310  input_1.elements[i] = i;
311  }
312 
313  CS2::Input<kCount2> input_2;
314  input_2.count = kCount2;
315  for (size_t i = 0; i < kCount2; i++) {
316  input_2.elements[i] = i;
317  }
318 
319  auto output_buffer_1 = CreateHostVisibleDeviceBuffer<CS1::Output<kCount2>>(
320  context, "Output Buffer Stage 1");
321  auto output_buffer_2 = CreateHostVisibleDeviceBuffer<CS2::Output<kCount2>>(
322  context, "Output Buffer Stage 2");
323 
324  {
325  pass->SetPipeline(compute_pipeline_1);
326 
327  CS1::BindInput(*pass, host_buffer->EmplaceStorageBuffer(input_1));
328  CS1::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
329 
330  ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
331  pass->AddBufferMemoryBarrier();
332  }
333 
334  {
335  pass->SetPipeline(compute_pipeline_2);
336 
337  CS1::BindInput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
338  CS2::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_2));
339  ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
340  }
341 
342  ASSERT_TRUE(pass->EncodeCommands());
343 
344  fml::AutoResetWaitableEvent latch;
345  ASSERT_TRUE(
346  context->GetCommandQueue()
347  ->Submit({cmd_buffer},
348  [&latch, &output_buffer_1,
349  &output_buffer_2](CommandBuffer::Status status) {
350  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
351 
352  CS1::Output<kCount2>* output_1 =
353  reinterpret_cast<CS1::Output<kCount2>*>(
354  output_buffer_1->OnGetContents());
355  EXPECT_TRUE(output_1);
356  EXPECT_EQ(output_1->count, 10u);
357  EXPECT_THAT(
358  output_1->elements,
359  ::testing::ElementsAre(0, 0, 2, 3, 4, 6, 6, 9, 8, 12));
360 
361  CS2::Output<kCount2>* output_2 =
362  reinterpret_cast<CS2::Output<kCount2>*>(
363  output_buffer_2->OnGetContents());
364  EXPECT_TRUE(output_2);
365  EXPECT_EQ(output_2->count, 10u);
366  EXPECT_THAT(output_2->elements,
367  ::testing::ElementsAre(0, 0, 4, 6, 8, 12, 12,
368  18, 16, 24));
369 
370  latch.Signal();
371  })
372  .ok());
373 
374  latch.Wait();
375 }

References impeller::interop::Create(), and impeller::kCount1.

◆ TEST_P() [344/549]

impeller::testing::TEST_P ( ComputeTest  ,
ReturnsEarlyWhenAnyGridDimensionIsZero   
)

Definition at line 457 of file compute_unittests.cc.

457  {
458  using CS = SampleComputeShader;
459  auto context = GetContext();
460  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
461  context->GetIdleWaiter());
462  ASSERT_TRUE(context);
463  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
464 
465  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
466  auto pipeline_desc =
467  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
468  ASSERT_TRUE(pipeline_desc.has_value());
469  auto compute_pipeline =
470  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
471  ASSERT_TRUE(compute_pipeline);
472 
473  auto cmd_buffer = context->CreateCommandBuffer();
474  auto pass = cmd_buffer->CreateComputePass();
475  ASSERT_TRUE(pass && pass->IsValid());
476 
477  static constexpr size_t kCount = 5;
478 
479  pass->SetPipeline(compute_pipeline);
480 
481  CS::Info info{.count = kCount};
482  CS::Input0<kCount> input_0;
483  CS::Input1<kCount> input_1;
484  for (size_t i = 0; i < kCount; i++) {
485  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
486  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
487  }
488 
489  input_0.fixed_array[1] = IPoint32(2, 2);
490  input_1.fixed_array[0] = UintPoint32(3, 3);
491  input_0.some_int = 5;
492  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
493 
494  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
495  context, "Output Buffer");
496 
497  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
498  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
499  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
500  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
501 
502  // Intentionally making the grid size zero in one dimension. No GPU will
503  // tolerate this.
504  EXPECT_FALSE(pass->Compute(ISize(0, 1)).ok());
505  pass->EncodeCommands();
506 }

References impeller::interop::Create().

◆ TEST_P() [345/549]

impeller::testing::TEST_P ( ContextMTLTest  ,
FlushTask   
)

Definition at line 28 of file context_mtl_unittests.mm.

28  {
29  auto& context_mtl = ContextMTL::Cast(*GetContext());
30 
31  int executed = 0;
32  int failed = 0;
33  context_mtl.StoreTaskForGPU([&]() { executed++; }, [&]() { failed++; });
34 
35  context_mtl.FlushTasksAwaitingGPU();
36 
37  EXPECT_EQ(executed, 1);
38  EXPECT_EQ(failed, 0);
39 }

References impeller::BackendCast< ContextMTL, Context >::Cast().

◆ TEST_P() [346/549]

impeller::testing::TEST_P ( ContextMTLTest  ,
FlushTaskWithGPULoss   
)

Definition at line 41 of file context_mtl_unittests.mm.

41  {
42  auto& context_mtl = ContextMTL::Cast(*GetContext());
43 
44  int executed = 0;
45  int failed = 0;
46  context_mtl.StoreTaskForGPU([&]() { executed++; }, [&]() { failed++; });
47 
48  // If tasks are flushed while the GPU is disabled, then
49  // they should not be executed.
50  SetGPUDisabled(/*disabled=*/true);
51  context_mtl.FlushTasksAwaitingGPU();
52 
53  EXPECT_EQ(executed, 0);
54  EXPECT_EQ(failed, 0);
55 
56  // Toggling availibility should flush tasks.
57  SetGPUDisabled(/*disabled=*/false);
58 
59  EXPECT_EQ(executed, 1);
60  EXPECT_EQ(failed, 0);
61 }

References impeller::BackendCast< ContextMTL, Context >::Cast().

◆ TEST_P() [347/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanBlendDstOverAndDstCorrectly   
)

Definition at line 1180 of file dl_unittests.cc.

1180  {
1181  flutter::DisplayListBuilder builder;
1182 
1183  {
1184  builder.SaveLayer(std::nullopt, nullptr);
1185  builder.Translate(100, 100);
1186  flutter::DlPaint paint;
1187  paint.setColor(flutter::DlColor::kRed());
1188  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1189  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1190  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1191  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1192  builder.Restore();
1193  }
1194  {
1195  builder.SaveLayer(std::nullopt, nullptr);
1196  builder.Translate(300, 100);
1197  flutter::DlPaint paint;
1198  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1199  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1200  paint.setColor(flutter::DlColor::kRed());
1201  paint.setBlendMode(flutter::DlBlendMode::kDstOver);
1202  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1203  builder.Restore();
1204  }
1205  {
1206  builder.SaveLayer(std::nullopt, nullptr);
1207  builder.Translate(100, 300);
1208  flutter::DlPaint paint;
1209  paint.setColor(flutter::DlColor::kRed());
1210  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1211  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1212  paint.setBlendMode(flutter::DlBlendMode::kSrc);
1213  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1214  builder.Restore();
1215  }
1216  {
1217  builder.SaveLayer(std::nullopt, nullptr);
1218  builder.Translate(300, 300);
1219  flutter::DlPaint paint;
1220  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1221  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1222  paint.setColor(flutter::DlColor::kRed());
1223  paint.setBlendMode(flutter::DlBlendMode::kDst);
1224  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1225  builder.Restore();
1226  }
1227 
1228  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1229 }

◆ TEST_P() [348/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanClampTheResultingColorOfColorMatrixFilter   
)

Definition at line 626 of file dl_unittests.cc.

626  {
627  auto texture = CreateTextureForFixture("boston.jpg");
628  const float inner_color_matrix[20] = {
629  1, 0, 0, 0, 0, //
630  0, 1, 0, 0, 0, //
631  0, 0, 1, 0, 0, //
632  0, 0, 0, 2, 0, //
633  };
634  const float outer_color_matrix[20] = {
635  1, 0, 0, 0, 0, //
636  0, 1, 0, 0, 0, //
637  0, 0, 1, 0, 0, //
638  0, 0, 0, 0.5, 0, //
639  };
640  auto inner_color_filter =
641  flutter::DlColorFilter::MakeMatrix(inner_color_matrix);
642  auto outer_color_filter =
643  flutter::DlColorFilter::MakeMatrix(outer_color_matrix);
644  auto inner = flutter::DlImageFilter::MakeColorFilter(inner_color_filter);
645  auto outer = flutter::DlImageFilter::MakeColorFilter(outer_color_filter);
646  auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
647 
648  flutter::DisplayListBuilder builder;
649  flutter::DlPaint paint;
650  paint.setImageFilter(compose.get());
651  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
652  flutter::DlImageSampling::kNearestNeighbor, &paint);
653  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
654 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [349/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawAnOpenPath   
)

Definition at line 417 of file dl_unittests.cc.

417  {
418  flutter::DisplayListBuilder builder;
419  flutter::DlPaint paint;
420 
421  paint.setColor(flutter::DlColor::kRed());
422  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
423  paint.setStrokeWidth(10);
424 
425  builder.Translate(300, 300);
426 
427  // Move to (50, 50) and draw lines from:
428  // 1. (50, height)
429  // 2. (width, height)
430  // 3. (width, 50)
431  flutter::DlPathBuilder path_builder;
432  path_builder.MoveTo(DlPoint(50, 50));
433  path_builder.LineTo(DlPoint(50, 100));
434  path_builder.LineTo(DlPoint(100, 100));
435  path_builder.LineTo(DlPoint(100, 50));
436  builder.DrawPath(path_builder.TakePath(), paint);
437 
438  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
439 }

◆ TEST_P() [350/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawArc   
)

Definition at line 155 of file dl_unittests.cc.

155  {
156  auto callback = [&]() {
157  static float start_angle = 45;
158  static float sweep_angle = 270;
159  static float stroke_width = 10;
160  static bool use_center = true;
161 
162  static int selected_cap = 0;
163  const char* cap_names[] = {"Butt", "Round", "Square"};
164  flutter::DlStrokeCap cap;
165 
166  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
167  ImGui::SliderFloat("Start angle", &start_angle, -360, 360);
168  ImGui::SliderFloat("Sweep angle", &sweep_angle, -360, 360);
169  ImGui::SliderFloat("Stroke width", &stroke_width, 0, 300);
170  ImGui::Combo("Cap", &selected_cap, cap_names,
171  sizeof(cap_names) / sizeof(char*));
172  ImGui::Checkbox("Use center", &use_center);
173  ImGui::End();
174 
175  switch (selected_cap) {
176  case 0:
177  cap = flutter::DlStrokeCap::kButt;
178  break;
179  case 1:
180  cap = flutter::DlStrokeCap::kRound;
181  break;
182  case 2:
183  cap = flutter::DlStrokeCap::kSquare;
184  break;
185  default:
186  cap = flutter::DlStrokeCap::kButt;
187  break;
188  }
189 
190  static PlaygroundPoint point_a(Point(200, 200), 20, Color::White());
191  static PlaygroundPoint point_b(Point(400, 400), 20, Color::White());
192  auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
193 
194  flutter::DisplayListBuilder builder;
195  flutter::DlPaint paint;
196 
197  Vector2 scale = GetContentScale();
198  builder.Scale(scale.x, scale.y);
199  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
200  paint.setStrokeCap(cap);
201  paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
202  paint.setStrokeMiter(10);
203  auto rect = DlRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
204  paint.setColor(flutter::DlColor::kGreen());
205  paint.setStrokeWidth(2);
206  builder.DrawRect(rect, paint);
207  paint.setColor(flutter::DlColor::kRed());
208  paint.setStrokeWidth(stroke_width);
209  builder.DrawArc(rect, start_angle, sweep_angle, use_center, paint);
210 
211  return builder.Build();
212  };
213  ASSERT_TRUE(OpenPlaygroundHere(callback));
214 }
bool use_center

References impeller::DrawPlaygroundLine(), use_center, impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [351/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawBackdropFilter   
)

Definition at line 656 of file dl_unittests.cc.

656  {
657  auto texture = CreateTextureForFixture("embarcadero.jpg");
658 
659  auto callback = [&]() {
660  static float sigma[] = {10, 10};
661  static float ctm_scale = 1;
662  static bool use_bounds = true;
663  static bool draw_circle = true;
664  static bool add_clip = true;
665 
666  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
667  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
668  ImGui::SliderFloat("Scale", &ctm_scale, 0, 10);
669  ImGui::NewLine();
670  ImGui::TextWrapped(
671  "If everything is working correctly, none of the options below should "
672  "impact the filter's appearance.");
673  ImGui::Checkbox("Use SaveLayer bounds", &use_bounds);
674  ImGui::Checkbox("Draw child element", &draw_circle);
675  ImGui::Checkbox("Add pre-clip", &add_clip);
676  ImGui::End();
677 
678  flutter::DisplayListBuilder builder;
679 
680  Vector2 scale = ctm_scale * GetContentScale();
681  builder.Scale(scale.x, scale.y);
682 
683  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
684  flutter::DlTileMode::kClamp);
685 
686  std::optional<DlRect> bounds;
687  if (use_bounds) {
688  static PlaygroundPoint point_a(Point(350, 150), 20, Color::White());
689  static PlaygroundPoint point_b(Point(800, 600), 20, Color::White());
690  auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
691  bounds = DlRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
692  }
693 
694  // Insert a clip to test that the backdrop filter handles stencil depths > 0
695  // correctly.
696  if (add_clip) {
697  builder.ClipRect(DlRect::MakeLTRB(0, 0, 99999, 99999),
698  flutter::DlClipOp::kIntersect, true);
699  }
700 
701  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(200, 200),
702  flutter::DlImageSampling::kNearestNeighbor, nullptr);
703  builder.SaveLayer(bounds, nullptr, &filter);
704 
705  if (draw_circle) {
706  static PlaygroundPoint center_point(Point(500, 400), 20, Color::Red());
707  auto circle_center = DrawPlaygroundPoint(center_point);
708 
709  flutter::DlPaint paint;
710  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
711  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
712  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
713  paint.setStrokeWidth(10);
714  paint.setColor(flutter::DlColor::kRed().withAlpha(100));
715  builder.DrawCircle(DlPoint(circle_center.x, circle_center.y), 100, paint);
716  }
717 
718  return builder.Build();
719  };
720 
721  ASSERT_TRUE(OpenPlaygroundHere(callback));
722 }

References impeller::DrawPlaygroundLine(), impeller::DrawPlaygroundPoint(), impeller::DlImageImpeller::Make(), impeller::Color::Red(), impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [352/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCapsAndJoins   
)

Definition at line 106 of file dl_unittests.cc.

106  {
107  flutter::DisplayListBuilder builder;
108  flutter::DlPaint paint;
109 
110  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
111  paint.setStrokeWidth(30);
112  paint.setColor(flutter::DlColor::kRed());
113 
114  flutter::DlPathBuilder path_builder;
115  path_builder.MoveTo(DlPoint(-50, 0));
116  path_builder.LineTo(DlPoint(0, -50));
117  path_builder.LineTo(DlPoint(50, 0));
118  flutter::DlPath path = path_builder.TakePath();
119 
120  builder.Translate(100, 100);
121  {
122  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
123  paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
124  paint.setStrokeMiter(4);
125  builder.DrawPath(path, paint);
126  }
127 
128  {
129  builder.Save();
130  builder.Translate(0, 100);
131  // The joint in the path is 45 degrees. A miter length of 1 convert to a
132  // bevel in this case.
133  paint.setStrokeMiter(1);
134  builder.DrawPath(path, paint);
135  builder.Restore();
136  }
137 
138  builder.Translate(150, 0);
139  {
140  paint.setStrokeCap(flutter::DlStrokeCap::kSquare);
141  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
142  builder.DrawPath(path, paint);
143  }
144 
145  builder.Translate(150, 0);
146  {
147  paint.setStrokeCap(flutter::DlStrokeCap::kRound);
148  paint.setStrokeJoin(flutter::DlStrokeJoin::kRound);
149  builder.DrawPath(path, paint);
150  }
151 
152  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
153 }

◆ TEST_P() [353/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCorrectlyWithColorFilterAndImageFilter   
)

Definition at line 1231 of file dl_unittests.cc.

1231  {
1232  flutter::DisplayListBuilder builder;
1233  const float green_color_matrix[20] = {
1234  0, 0, 0, 0, 0, //
1235  0, 0, 0, 0, 1, //
1236  0, 0, 0, 0, 0, //
1237  0, 0, 0, 1, 0, //
1238  };
1239  const float blue_color_matrix[20] = {
1240  0, 0, 0, 0, 0, //
1241  0, 0, 0, 0, 0, //
1242  0, 0, 0, 0, 1, //
1243  0, 0, 0, 1, 0, //
1244  };
1245  auto green_color_filter =
1246  flutter::DlColorFilter::MakeMatrix(green_color_matrix);
1247  auto blue_color_filter =
1248  flutter::DlColorFilter::MakeMatrix(blue_color_matrix);
1249  auto blue_image_filter =
1250  flutter::DlImageFilter::MakeColorFilter(blue_color_filter);
1251 
1252  flutter::DlPaint paint;
1253  paint.setColor(flutter::DlColor::kRed());
1254  paint.setColorFilter(green_color_filter);
1255  paint.setImageFilter(blue_image_filter);
1256  builder.DrawRect(DlRect::MakeLTRB(100, 100, 500, 500), paint);
1257  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1258 }

◆ TEST_P() [354/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawImage   
)

Definition at line 98 of file dl_unittests.cc.

98  {
99  auto texture = CreateTextureForFixture("embarcadero.jpg");
100  flutter::DisplayListBuilder builder;
101  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
102  flutter::DlImageSampling::kNearestNeighbor, nullptr);
103  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
104 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [355/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImage   
)

Definition at line 724 of file dl_unittests.cc.

724  {
725  // Image is drawn with corners to scale and center pieces stretched to fit.
726  auto texture = CreateTextureForFixture("embarcadero.jpg");
727  flutter::DisplayListBuilder builder;
728  auto size = texture->GetSize();
729  builder.DrawImageNine(
730  DlImageImpeller::Make(texture),
731  DlIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
732  size.height * 3 / 4),
733  DlRect::MakeLTRB(0, 0, size.width * 2, size.height * 2),
734  flutter::DlFilterMode::kNearest, nullptr);
735  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
736 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [356/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterBiggerThanDest   
)

Definition at line 770 of file dl_unittests.cc.

770  {
771  // Edge case, the width and height of the corners does not leave any
772  // room for the center slices. Only the corners are displayed.
773  auto texture = CreateTextureForFixture("embarcadero.jpg");
774  flutter::DisplayListBuilder builder;
775  auto size = texture->GetSize();
776  builder.DrawImageNine(
777  DlImageImpeller::Make(texture),
778  DlIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
779  size.height * 3 / 4),
780  DlRect::MakeLTRB(0, 0, size.width / 2, size.height / 2),
781  flutter::DlFilterMode::kNearest, nullptr);
782  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
783 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [357/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterHeightBiggerThanDest   
)

Definition at line 754 of file dl_unittests.cc.

754  {
755  // Edge case, the height of the corners does not leave any room for the
756  // center slice. The center (across the horizontal axis) is folded out of the
757  // resulting image.
758  auto texture = CreateTextureForFixture("embarcadero.jpg");
759  flutter::DisplayListBuilder builder;
760  auto size = texture->GetSize();
761  builder.DrawImageNine(
762  DlImageImpeller::Make(texture),
763  DlIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
764  size.height * 3 / 4),
765  DlRect::MakeLTRB(0, 0, size.width, size.height / 2),
766  flutter::DlFilterMode::kNearest, nullptr);
767  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
768 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [358/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterWidthBiggerThanDest   
)

Definition at line 738 of file dl_unittests.cc.

738  {
739  // Edge case, the width of the corners does not leave any room for the
740  // center slice. The center (across the vertical axis) is folded out of the
741  // resulting image.
742  auto texture = CreateTextureForFixture("embarcadero.jpg");
743  flutter::DisplayListBuilder builder;
744  auto size = texture->GetSize();
745  builder.DrawImageNine(
746  DlImageImpeller::Make(texture),
747  DlIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
748  size.height * 3 / 4),
749  DlRect::MakeLTRB(0, 0, size.width / 2, size.height),
750  flutter::DlFilterMode::kNearest, nullptr);
751  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
752 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [359/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCornersScaledDown   
)

Definition at line 785 of file dl_unittests.cc.

785  {
786  // Edge case, there is not enough room for the corners to be drawn
787  // without scaling them down.
788  auto texture = CreateTextureForFixture("embarcadero.jpg");
789  flutter::DisplayListBuilder builder;
790  auto size = texture->GetSize();
791  builder.DrawImageNine(
792  DlImageImpeller::Make(texture),
793  DlIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
794  size.height * 3 / 4),
795  DlRect::MakeLTRB(0, 0, size.width / 4, size.height / 4),
796  flutter::DlFilterMode::kNearest, nullptr);
797  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
798 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [360/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPaintWithColorSource   
)

Definition at line 1128 of file dl_unittests.cc.

1128  {
1129  const flutter::DlColor colors[2] = {
1130  flutter::DlColor(0xFFF44336),
1131  flutter::DlColor(0xFF2196F3),
1132  };
1133  const float stops[2] = {0.0, 1.0};
1134  flutter::DlPaint paint;
1135  flutter::DisplayListBuilder builder;
1136  auto clip_bounds = DlRect::MakeWH(300.0, 300.0);
1137  builder.Save();
1138  builder.Translate(100, 100);
1139  builder.ClipRect(clip_bounds, flutter::DlClipOp::kIntersect, false);
1140  auto linear =
1141  flutter::DlColorSource::MakeLinear({0.0, 0.0}, {100.0, 100.0}, 2, colors,
1142  stops, flutter::DlTileMode::kRepeat);
1143  paint.setColorSource(linear);
1144  builder.DrawPaint(paint);
1145  builder.Restore();
1146 
1147  builder.Save();
1148  builder.Translate(500, 100);
1149  builder.ClipRect(clip_bounds, flutter::DlClipOp::kIntersect, false);
1150  auto radial = flutter::DlColorSource::MakeRadial(
1151  {100.0, 100.0}, 100.0, 2, colors, stops, flutter::DlTileMode::kRepeat);
1152  paint.setColorSource(radial);
1153  builder.DrawPaint(paint);
1154  builder.Restore();
1155 
1156  builder.Save();
1157  builder.Translate(100, 500);
1158  builder.ClipRect(clip_bounds, flutter::DlClipOp::kIntersect, false);
1159  auto sweep =
1160  flutter::DlColorSource::MakeSweep({100.0, 100.0}, 180.0, 270.0, 2, colors,
1161  stops, flutter::DlTileMode::kRepeat);
1162  paint.setColorSource(sweep);
1163  builder.DrawPaint(paint);
1164  builder.Restore();
1165 
1166  builder.Save();
1167  builder.Translate(500, 500);
1168  builder.ClipRect(clip_bounds, flutter::DlClipOp::kIntersect, false);
1169  auto texture = CreateTextureForFixture("table_mountain_nx.png");
1170  auto image = flutter::DlColorSource::MakeImage(DlImageImpeller::Make(texture),
1171  flutter::DlTileMode::kRepeat,
1172  flutter::DlTileMode::kRepeat);
1173  paint.setColorSource(image);
1174  builder.DrawPaint(paint);
1175  builder.Restore();
1176 
1177  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1178 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [361/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPoints   
)

Definition at line 812 of file dl_unittests.cc.

812  {
813  flutter::DisplayListBuilder builder;
814  DlPoint points[7] = {
815  {0, 0}, //
816  {100, 100}, //
817  {100, 0}, //
818  {0, 100}, //
819  {0, 0}, //
820  {48, 48}, //
821  {52, 52}, //
822  };
823  std::vector<flutter::DlStrokeCap> caps = {
824  flutter::DlStrokeCap::kButt,
825  flutter::DlStrokeCap::kRound,
826  flutter::DlStrokeCap::kSquare,
827  };
828  flutter::DlPaint paint =
829  flutter::DlPaint() //
830  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
831  .setStrokeWidth(20);
832  builder.Translate(50, 50);
833  for (auto cap : caps) {
834  paint.setStrokeCap(cap);
835  builder.Save();
836  builder.DrawPoints(flutter::DlPointMode::kPoints, 7, points, paint);
837  builder.Translate(150, 0);
838  builder.DrawPoints(flutter::DlPointMode::kLines, 5, points, paint);
839  builder.Translate(150, 0);
840  builder.DrawPoints(flutter::DlPointMode::kPolygon, 5, points, paint);
841  builder.Restore();
842  builder.Translate(0, 150);
843  }
844  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
845 }

References points.

◆ TEST_P() [362/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRect   
)

Definition at line 47 of file dl_unittests.cc.

47  {
48  flutter::DisplayListBuilder builder;
49  builder.DrawRect(DlRect::MakeXYWH(10, 10, 100, 100),
50  flutter::DlPaint(flutter::DlColor::kBlue()));
51  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
52 }

◆ TEST_P() [363/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRectWithLinearToSrgbColorFilter   
)

Definition at line 1114 of file dl_unittests.cc.

1114  {
1115  flutter::DlPaint paint;
1116  paint.setColor(flutter::DlColor(0xFF2196F3).withAlpha(128));
1117  flutter::DisplayListBuilder builder;
1118  paint.setColorFilter(flutter::DlColorFilter::MakeLinearToSrgbGamma());
1119  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), paint);
1120  builder.Translate(0, 200);
1121 
1122  paint.setColorFilter(flutter::DlColorFilter::MakeSrgbToLinearGamma());
1123  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), paint);
1124 
1125  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1126 }

◆ TEST_P() [364/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawShadow   
)

Definition at line 870 of file dl_unittests.cc.

870  {
871  flutter::DisplayListBuilder builder;
872  flutter::DlPaint paint;
873 
874  auto content_scale = GetContentScale() * 0.8;
875  builder.Scale(content_scale.x, content_scale.y);
876 
877  constexpr size_t star_spikes = 5;
878  constexpr DlScalar half_spike_rotation = kPi / star_spikes;
879  constexpr DlScalar radius = 40;
880  constexpr DlScalar spike_size = 10;
881  constexpr DlScalar outer_radius = radius + spike_size;
882  constexpr DlScalar inner_radius = radius - spike_size;
883  std::array<DlPoint, star_spikes * 2> star;
884  for (size_t i = 0; i < star_spikes; i++) {
885  const DlScalar rotation = half_spike_rotation * i * 2;
886  star[i * 2] = DlPoint(50 + std::sin(rotation) * outer_radius,
887  50 - std::cos(rotation) * outer_radius);
888  star[i * 2 + 1] =
889  DlPoint(50 + std::sin(rotation + half_spike_rotation) * inner_radius,
890  50 - std::cos(rotation + half_spike_rotation) * inner_radius);
891  }
892 
893  std::array<DlPath, 4> paths = {
894  DlPath::MakeRect(DlRect::MakeXYWH(0, 0, 200, 100)),
895  DlPath::MakeRoundRectXY(DlRect::MakeXYWH(20, 0, 200, 100), 30, 30),
896  DlPath::MakeCircle(DlPoint(100, 50), 50),
897  DlPath::MakePoly(star.data(), star.size(), true),
898  };
899  paint.setColor(flutter::DlColor::kWhite());
900  builder.DrawPaint(paint);
901  paint.setColor(flutter::DlColor::kCyan());
902  builder.Translate(100, 50);
903  for (size_t x = 0; x < paths.size(); x++) {
904  builder.Save();
905  for (size_t y = 0; y < 6; y++) {
906  builder.DrawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
907  1);
908  builder.DrawPath(paths[x], paint);
909  builder.Translate(0, 150);
910  }
911  builder.Restore();
912  builder.Translate(250, 0);
913  }
914 
915  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
916 }

References impeller::kPi, and x.

◆ TEST_P() [365/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawStrokedText   
)

Definition at line 477 of file dl_unittests.cc.

477  {
478  flutter::DisplayListBuilder builder;
479  flutter::DlPaint paint;
480 
481  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
482  paint.setColor(flutter::DlColor::kRed());
483  builder.DrawText(flutter::DlTextSkia::Make(SkTextBlob::MakeFromString(
484  "stoked about stroked text", CreateTestFont())),
485  250, 250, paint);
486 
487  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
488 }

◆ TEST_P() [366/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlob   
)

Definition at line 54 of file dl_unittests.cc.

54  {
55  flutter::DisplayListBuilder builder;
56  builder.DrawText(flutter::DlTextSkia::Make(
57  SkTextBlob::MakeFromString("Hello", CreateTestFont())),
58  100, 100, flutter::DlPaint(flutter::DlColor::kBlue()));
59  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
60 }

◆ TEST_P() [367/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlobWithGradient   
)

Definition at line 62 of file dl_unittests.cc.

62  {
63  flutter::DisplayListBuilder builder;
64 
65  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
66  flutter::DlColor::kRed()};
67  const float stops[2] = {0.0, 1.0};
68 
69  auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
70  2, colors.data(), stops,
71  flutter::DlTileMode::kClamp);
72  flutter::DlPaint paint;
73  paint.setColorSource(linear);
74 
75  builder.DrawText(flutter::DlTextSkia::Make(SkTextBlob::MakeFromString(
76  "Hello World", CreateTestFont())),
77  100, 100, paint);
78  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
79 }

◆ TEST_P() [368/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextWithSaveLayer   
)

Definition at line 81 of file dl_unittests.cc.

81  {
82  flutter::DisplayListBuilder builder;
83  builder.DrawText(flutter::DlTextSkia::Make(
84  SkTextBlob::MakeFromString("Hello", CreateTestFont())),
85  100, 100, flutter::DlPaint(flutter::DlColor::kRed()));
86 
87  flutter::DlPaint save_paint;
88  float alpha = 0.5;
89  save_paint.setAlpha(static_cast<uint8_t>(255 * alpha));
90  builder.SaveLayer(std::nullopt, &save_paint);
91  builder.DrawText(flutter::DlTextSkia::Make(SkTextBlob::MakeFromString(
92  "Hello with half alpha", CreateTestFontOfSize(100))),
93  100, 300, flutter::DlPaint(flutter::DlColor::kRed()));
94  builder.Restore();
95  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
96 }

◆ TEST_P() [369/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithBlendColorFilter   
)

Definition at line 530 of file dl_unittests.cc.

530  {
531  auto texture = CreateTextureForFixture("embarcadero.jpg");
532  flutter::DisplayListBuilder builder;
533  flutter::DlPaint paint;
534 
535  // Pipeline blended image.
536  {
537  auto filter = flutter::DlColorFilter::MakeBlend(
538  flutter::DlColor::kYellow(), flutter::DlBlendMode::kModulate);
539  paint.setColorFilter(filter);
540  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
541  flutter::DlImageSampling::kNearestNeighbor, &paint);
542  }
543 
544  // Advanced blended image.
545  {
546  auto filter = flutter::DlColorFilter::MakeBlend(
547  flutter::DlColor::kRed(), flutter::DlBlendMode::kScreen);
548  paint.setColorFilter(filter);
549  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(250, 250),
550  flutter::DlImageSampling::kNearestNeighbor, &paint);
551  }
552 
553  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
554 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [370/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithColorFilterImageFilter   
)

Definition at line 556 of file dl_unittests.cc.

556  {
557  const float invert_color_matrix[20] = {
558  -1, 0, 0, 0, 1, //
559  0, -1, 0, 0, 1, //
560  0, 0, -1, 0, 1, //
561  0, 0, 0, 1, 0, //
562  };
563  auto texture = CreateTextureForFixture("boston.jpg");
564  flutter::DisplayListBuilder builder;
565  flutter::DlPaint paint;
566 
567  auto color_filter = flutter::DlColorFilter::MakeMatrix(invert_color_matrix);
568  auto image_filter = flutter::DlImageFilter::MakeColorFilter(color_filter);
569 
570  paint.setImageFilter(image_filter);
571  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
572  flutter::DlImageSampling::kNearestNeighbor, &paint);
573 
574  builder.Translate(0, 700);
575  paint.setColorFilter(color_filter);
576  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
577  flutter::DlImageSampling::kNearestNeighbor, &paint);
578  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
579 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [371/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithComposeImageFilter   
)

Definition at line 606 of file dl_unittests.cc.

606  {
607  auto texture = CreateTextureForFixture("boston.jpg");
608  flutter::DisplayListBuilder builder;
609  flutter::DlPaint paint;
610 
611  auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
612  auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
613  auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
614  auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
615 
616  paint.setImageFilter(open.get());
617  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
618  flutter::DlImageSampling::kNearestNeighbor, &paint);
619  builder.Translate(0, 700);
620  paint.setImageFilter(close.get());
621  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
622  flutter::DlImageSampling::kNearestNeighbor, &paint);
623  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
624 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [372/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithImageBlurFilter   
)

Definition at line 581 of file dl_unittests.cc.

581  {
582  auto texture = CreateTextureForFixture("embarcadero.jpg");
583 
584  auto callback = [&]() {
585  static float sigma[] = {10, 10};
586 
587  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
588  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
589  ImGui::End();
590 
591  flutter::DisplayListBuilder builder;
592  flutter::DlPaint paint;
593 
594  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
595  flutter::DlTileMode::kClamp);
596  paint.setImageFilter(&filter);
597  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(200, 200),
598  flutter::DlImageSampling::kNearestNeighbor, &paint);
599 
600  return builder.Build();
601  };
602 
603  ASSERT_TRUE(OpenPlaygroundHere(callback));
604 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [373/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMaskBlur   
)

Definition at line 441 of file dl_unittests.cc.

441  {
442  auto texture = CreateTextureForFixture("embarcadero.jpg");
443  flutter::DisplayListBuilder builder;
444  flutter::DlPaint paint;
445 
446  // Mask blurred image.
447  {
448  auto filter =
449  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
450  paint.setMaskFilter(&filter);
451  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
452  flutter::DlImageSampling::kNearestNeighbor, &paint);
453  }
454 
455  // Mask blurred filled path.
456  {
457  paint.setColor(flutter::DlColor::kYellow());
458  auto filter =
459  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kOuter, 10.0f);
460  paint.setMaskFilter(&filter);
461  builder.DrawArc(DlRect::MakeXYWH(410, 110, 100, 100), 45, 270, true, paint);
462  }
463 
464  // Mask blurred text.
465  {
466  auto filter =
467  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kSolid, 10.0f);
468  paint.setMaskFilter(&filter);
469  builder.DrawText(flutter::DlTextSkia::Make(SkTextBlob::MakeFromString(
470  "Testing", CreateTestFont())),
471  220, 170, paint);
472  }
473 
474  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
475 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [374/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilter   
)

Definition at line 952 of file dl_unittests.cc.

952  {
953  auto boston = CreateTextureForFixture("boston.jpg");
954 
955  auto callback = [&]() {
956  static int selected_matrix_type = 0;
957  const char* matrix_type_names[] = {"Matrix", "Local Matrix"};
958 
959  static float ctm_translation[2] = {200, 200};
960  static float ctm_scale[2] = {0.65, 0.65};
961  static float ctm_skew[2] = {0, 0};
962 
963  static bool enable = true;
964  static float translation[2] = {100, 100};
965  static float scale[2] = {0.8, 0.8};
966  static float skew[2] = {0.2, 0.2};
967 
968  static bool enable_savelayer = true;
969 
970  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
971  {
972  ImGui::Combo("Filter type", &selected_matrix_type, matrix_type_names,
973  sizeof(matrix_type_names) / sizeof(char*));
974 
975  ImGui::TextWrapped("Current Transform");
976  ImGui::SliderFloat2("CTM Translation", ctm_translation, 0, 1000);
977  ImGui::SliderFloat2("CTM Scale", ctm_scale, 0, 3);
978  ImGui::SliderFloat2("CTM Skew", ctm_skew, -3, 3);
979 
980  ImGui::TextWrapped(
981  "MatrixFilter and LocalMatrixFilter modify the CTM in the same way. "
982  "The only difference is that MatrixFilter doesn't affect the effect "
983  "transform, whereas LocalMatrixFilter does.");
984  // Note: See this behavior in:
985  // https://fiddle.skia.org/c/6cbb551ab36d06f163db8693972be954
986  ImGui::Checkbox("Enable", &enable);
987  ImGui::SliderFloat2("Filter Translation", translation, 0, 1000);
988  ImGui::SliderFloat2("Filter Scale", scale, 0, 3);
989  ImGui::SliderFloat2("Filter Skew", skew, -3, 3);
990 
991  ImGui::TextWrapped(
992  "Rendering the filtered image within a layer can expose bounds "
993  "issues. If the rendered image gets cut off when this setting is "
994  "enabled, there's a coverage bug in the filter.");
995  ImGui::Checkbox("Render in layer", &enable_savelayer);
996  }
997  ImGui::End();
998 
999  flutter::DisplayListBuilder builder;
1000  flutter::DlPaint paint;
1001 
1002  if (enable_savelayer) {
1003  builder.SaveLayer(std::nullopt, nullptr);
1004  }
1005  {
1006  auto content_scale = GetContentScale();
1007  builder.Scale(content_scale.x, content_scale.y);
1008 
1009  // Set the current transform
1010  auto ctm_matrix = Matrix::MakeRow(
1011  ctm_scale[0], ctm_skew[0], 0.0f, ctm_translation[0], //
1012  ctm_skew[1], ctm_scale[1], 0.0f, ctm_translation[1], //
1013  0, 0, 1, 0, //
1014  0, 0, 0, 1);
1015  builder.Transform(ctm_matrix);
1016 
1017  // Set the matrix filter
1018  auto filter_matrix =
1019  Matrix::MakeRow(scale[0], skew[0], 0.0f, translation[0], //
1020  skew[1], scale[1], 0.0f, translation[1], //
1021  0.0f, 0.0f, 1.0f, 0.0f, //
1022  0.0f, 0.0f, 0.0f, 1.0f);
1023 
1024  if (enable) {
1025  switch (selected_matrix_type) {
1026  case 0: {
1027  auto filter = flutter::DlMatrixImageFilter(
1028  filter_matrix, flutter::DlImageSampling::kLinear);
1029  paint.setImageFilter(&filter);
1030  break;
1031  }
1032  case 1: {
1033  auto internal_filter =
1034  flutter::DlBlurImageFilter(10, 10, flutter::DlTileMode::kDecal)
1035  .shared();
1036  auto filter = flutter::DlLocalMatrixImageFilter(filter_matrix,
1037  internal_filter);
1038  paint.setImageFilter(&filter);
1039  break;
1040  }
1041  }
1042  }
1043 
1044  builder.DrawImage(DlImageImpeller::Make(boston), DlPoint(),
1045  flutter::DlImageSampling::kLinear, &paint);
1046  }
1047  if (enable_savelayer) {
1048  builder.Restore();
1049  }
1050 
1051  return builder.Build();
1052  };
1053 
1054  ASSERT_TRUE(OpenPlaygroundHere(callback));
1055 }

References impeller::DlImageImpeller::Make(), and impeller::Matrix::MakeRow().

◆ TEST_P() [375/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilterWhenSavingLayer   
)

Definition at line 1057 of file dl_unittests.cc.

1057  {
1058  auto callback = [&]() {
1059  static float translation[2] = {0, 0};
1060  static bool enable_save_layer = true;
1061 
1062  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1063  ImGui::SliderFloat2("Translation", translation, -130, 130);
1064  ImGui::Checkbox("Enable save layer", &enable_save_layer);
1065  ImGui::End();
1066 
1067  flutter::DisplayListBuilder builder;
1068  builder.Save();
1069  builder.Scale(2.0, 2.0);
1070  flutter::DlPaint paint;
1071  paint.setColor(flutter::DlColor::kYellow());
1072  builder.DrawRect(DlRect::MakeWH(300, 300), paint);
1073  paint.setStrokeWidth(1.0);
1074  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1075  paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80));
1076  builder.DrawLine(DlPoint(150, 0), DlPoint(150, 300), paint);
1077  builder.DrawLine(DlPoint(0, 150), DlPoint(300, 150), paint);
1078 
1079  flutter::DlPaint save_paint;
1080  DlRect bounds = DlRect::MakeXYWH(100, 100, 100, 100);
1081  Matrix translate_matrix =
1082  Matrix::MakeTranslation({translation[0], translation[1]});
1083  if (enable_save_layer) {
1084  auto filter = flutter::DlMatrixImageFilter(
1085  translate_matrix, flutter::DlImageSampling::kNearestNeighbor);
1086  save_paint.setImageFilter(filter.shared());
1087  builder.SaveLayer(bounds, &save_paint);
1088  } else {
1089  builder.Save();
1090  builder.Transform(translate_matrix);
1091  }
1092 
1093  Matrix filter_matrix;
1094  filter_matrix.Translate({150, 150});
1095  filter_matrix.Scale({0.2f, 0.2f});
1096  filter_matrix.Translate({-150, -150});
1097  auto filter = flutter::DlMatrixImageFilter(
1098  filter_matrix, flutter::DlImageSampling::kNearestNeighbor);
1099 
1100  save_paint.setImageFilter(filter.shared());
1101 
1102  builder.SaveLayer(bounds, &save_paint);
1103  flutter::DlPaint paint2;
1104  paint2.setColor(flutter::DlColor::kBlue());
1105  builder.DrawRect(bounds, paint2);
1106  builder.Restore();
1107  builder.Restore();
1108  return builder.Build();
1109  };
1110 
1111  ASSERT_TRUE(OpenPlaygroundHere(callback));
1112 }

References impeller::Matrix::MakeTranslation(), impeller::Matrix::Scale(), and impeller::Matrix::Translate().

◆ TEST_P() [376/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithOddPathWinding   
)

Definition at line 397 of file dl_unittests.cc.

397  {
398  flutter::DisplayListBuilder builder;
399  flutter::DlPaint paint;
400 
401  paint.setColor(flutter::DlColor::kRed());
402  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
403 
404  builder.Translate(300, 300);
405  flutter::DlPathBuilder path_builder;
406  path_builder.AddCircle(DlPoint(0, 0), 100);
407  path_builder.AddCircle(DlPoint(0, 0), 50);
408  path_builder.SetFillType(flutter::DlPathFillType::kOdd);
409  builder.DrawPath(path_builder.TakePath(), paint);
410 
411  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
412 }

◆ TEST_P() [377/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroLengthLine   
)

Definition at line 847 of file dl_unittests.cc.

847  {
848  flutter::DisplayListBuilder builder;
849  std::vector<flutter::DlStrokeCap> caps = {
850  flutter::DlStrokeCap::kButt,
851  flutter::DlStrokeCap::kRound,
852  flutter::DlStrokeCap::kSquare,
853  };
854  flutter::DlPaint paint =
855  flutter::DlPaint() //
856  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
857  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
858  .setStrokeCap(flutter::DlStrokeCap::kButt) //
859  .setStrokeWidth(20);
860  DlPath path = DlPath::MakeLine({150, 50}, {150, 50});
861  for (auto cap : caps) {
862  paint.setStrokeCap(cap);
863  builder.DrawLine(DlPoint(50, 50), DlPoint(50, 50), paint);
864  builder.DrawPath(path, paint);
865  builder.Translate(0, 150);
866  }
867  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
868 }

◆ TEST_P() [378/549]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroWidthLine   
)

Definition at line 918 of file dl_unittests.cc.

918  {
919  flutter::DisplayListBuilder builder;
920  std::vector<flutter::DlStrokeCap> caps = {
921  flutter::DlStrokeCap::kButt,
922  flutter::DlStrokeCap::kRound,
923  flutter::DlStrokeCap::kSquare,
924  };
925  flutter::DlPaint paint = //
926  flutter::DlPaint() //
927  .setColor(flutter::DlColor::kWhite()) //
928  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
929  .setStrokeWidth(0);
930  flutter::DlPaint outline_paint = //
931  flutter::DlPaint() //
932  .setColor(flutter::DlColor::kYellow()) //
933  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
934  .setStrokeCap(flutter::DlStrokeCap::kSquare) //
935  .setStrokeWidth(1);
936  DlPath path = DlPath::MakeLine({150, 50}, {160, 50});
937  for (auto cap : caps) {
938  paint.setStrokeCap(cap);
939  builder.DrawLine(DlPoint(50, 50), DlPoint(60, 50), paint);
940  builder.DrawRect(DlRect::MakeLTRB(45, 45, 65, 55), outline_paint);
941  builder.DrawLine(DlPoint{100, 50}, DlPoint{100, 50}, paint);
942  if (cap != flutter::DlStrokeCap::kButt) {
943  builder.DrawRect(DlRect::MakeLTRB(95, 45, 105, 55), outline_paint);
944  }
945  builder.DrawPath(path, paint);
946  builder.DrawRect(path.GetBounds().Expand(5, 5), outline_paint);
947  builder.Translate(0, 150);
948  }
949  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
950 }

◆ TEST_P() [379/549]

impeller::testing::TEST_P ( DisplayListTest  ,
ClipDrawRRectWithNonCircularRadii   
)

Definition at line 1347 of file dl_unittests.cc.

1347  {
1348  flutter::DisplayListBuilder builder;
1349 
1350  flutter::DlPaint fill_paint = //
1351  flutter::DlPaint() //
1352  .setColor(flutter::DlColor::kBlue()) //
1353  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1354  .setStrokeWidth(10);
1355  flutter::DlPaint stroke_paint = //
1356  flutter::DlPaint() //
1357  .setColor(flutter::DlColor::kGreen()) //
1358  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1359  .setStrokeWidth(10);
1360 
1361  builder.DrawRoundRect(
1362  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1363  fill_paint);
1364  builder.DrawRoundRect(
1365  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1366  stroke_paint);
1367 
1368  builder.DrawRoundRect(
1369  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1370  fill_paint);
1371  builder.DrawRoundRect(
1372  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1373  stroke_paint);
1374 
1375  flutter::DlPaint reference_paint = //
1376  flutter::DlPaint() //
1377  .setColor(flutter::DlColor::kMidGrey()) //
1378  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1379  .setStrokeWidth(10);
1380 
1381  builder.DrawRoundRect(
1382  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(500, 500, 300, 300), 40, 40),
1383  reference_paint);
1384  builder.DrawRoundRect(
1385  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(100, 100, 300, 300), 120, 120),
1386  reference_paint);
1387 
1388  flutter::DlPaint clip_fill_paint = //
1389  flutter::DlPaint() //
1390  .setColor(flutter::DlColor::kCyan()) //
1391  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1392  .setStrokeWidth(10);
1393 
1394  builder.Save();
1395  builder.ClipRoundRect(
1396  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(900, 100, 300, 300), 120, 40));
1397  builder.DrawPaint(clip_fill_paint);
1398  builder.Restore();
1399 
1400  builder.Save();
1401  builder.ClipRoundRect(
1402  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(100, 900, 300, 300), 40, 120));
1403  builder.DrawPaint(clip_fill_paint);
1404  builder.Restore();
1405 
1406  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1407 }

◆ TEST_P() [380/549]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawMaskBlursThatMightUseSaveLayers   
)

Definition at line 1523 of file dl_unittests.cc.

1523  {
1524  flutter::DisplayListBuilder builder;
1525  builder.DrawColor(flutter::DlColor::kWhite(), flutter::DlBlendMode::kSrc);
1526  Vector2 scale = GetContentScale();
1527  builder.Scale(scale.x, scale.y);
1528 
1529  builder.Save();
1530  // We need a small transform op to avoid a deferred save
1531  builder.Translate(1.0f, 1.0f);
1532  auto solid_filter =
1533  flutter::DlBlurMaskFilter::Make(flutter::DlBlurStyle::kSolid, 5.0f);
1534  flutter::DlPaint solid_alpha_paint =
1535  flutter::DlPaint() //
1536  .setMaskFilter(solid_filter) //
1537  .setColor(flutter::DlColor::kBlue()) //
1538  .setAlpha(0x7f);
1539  for (int x = 1; x <= 4; x++) {
1540  for (int y = 1; y <= 4; y++) {
1541  builder.DrawRect(DlRect::MakeXYWH(x * 100, y * 100, 80, 80),
1542  solid_alpha_paint);
1543  }
1544  }
1545  builder.Restore();
1546 
1547  builder.Save();
1548  builder.Translate(500.0f, 0.0f);
1549  auto normal_filter =
1550  flutter::DlBlurMaskFilter::Make(flutter::DlBlurStyle::kNormal, 5.0f);
1551  auto rotate_if = flutter::DlMatrixImageFilter::Make(
1552  Matrix::MakeRotationZ(Degrees(10)), flutter::DlImageSampling::kLinear);
1553  flutter::DlPaint normal_if_paint =
1554  flutter::DlPaint() //
1555  .setMaskFilter(solid_filter) //
1556  .setImageFilter(rotate_if) //
1557  .setColor(flutter::DlColor::kGreen()) //
1558  .setAlpha(0x7f);
1559  for (int x = 1; x <= 4; x++) {
1560  for (int y = 1; y <= 4; y++) {
1561  builder.DrawRect(DlRect::MakeXYWH(x * 100, y * 100, 80, 80),
1562  normal_if_paint);
1563  }
1564  }
1565  builder.Restore();
1566 
1567  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1568 }

References impeller::Matrix::MakeRotationZ(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [381/549]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawPaintIgnoresMaskFilter   
)

Definition at line 1500 of file dl_unittests.cc.

1500  {
1501  flutter::DisplayListBuilder builder;
1502  builder.DrawPaint(flutter::DlPaint().setColor(flutter::DlColor::kWhite()));
1503 
1504  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
1505  builder.DrawCircle(DlPoint(300, 300), 200,
1506  flutter::DlPaint().setMaskFilter(&filter));
1507 
1508  std::vector<flutter::DlColor> colors = {flutter::DlColor::kGreen(),
1509  flutter::DlColor::kGreen()};
1510  const float stops[2] = {0.0, 1.0};
1511  auto linear = flutter::DlColorSource::MakeLinear(
1512  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1513  flutter::DlTileMode::kRepeat);
1514  flutter::DlPaint blend_paint =
1515  flutter::DlPaint() //
1516  .setColorSource(linear) //
1517  .setBlendMode(flutter::DlBlendMode::kScreen);
1518  builder.DrawPaint(blend_paint);
1519 
1520  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1521 }

◆ TEST_P() [382/549]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawShapes   
)

Definition at line 1308 of file dl_unittests.cc.

1308  {
1309  flutter::DisplayListBuilder builder;
1310  std::vector<flutter::DlStrokeJoin> joins = {
1311  flutter::DlStrokeJoin::kBevel,
1312  flutter::DlStrokeJoin::kRound,
1313  flutter::DlStrokeJoin::kMiter,
1314  };
1315  flutter::DlPaint paint = //
1316  flutter::DlPaint() //
1317  .setColor(flutter::DlColor::kWhite()) //
1318  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1319  .setStrokeWidth(10);
1320  flutter::DlPaint stroke_paint = //
1321  flutter::DlPaint() //
1322  .setColor(flutter::DlColor::kWhite()) //
1323  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1324  .setStrokeWidth(10);
1325  DlPath path = DlPath::MakeLine({150, 50}, {160, 50});
1326 
1327  builder.Translate(300, 50);
1328  builder.Scale(0.8, 0.8);
1329  for (auto join : joins) {
1330  paint.setStrokeJoin(join);
1331  stroke_paint.setStrokeJoin(join);
1332  builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), paint);
1333  builder.DrawRect(DlRect::MakeXYWH(0, 150, 100, 100), stroke_paint);
1334  builder.DrawRoundRect(
1335  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(150, 0, 100, 100), 30, 30),
1336  paint);
1337  builder.DrawRoundRect(
1338  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(150, 150, 100, 100), 30, 30),
1339  stroke_paint);
1340  builder.DrawCircle(DlPoint(350, 50), 50, paint);
1341  builder.DrawCircle(DlPoint(350, 200), 50, stroke_paint);
1342  builder.Translate(0, 300);
1343  }
1344  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1345 }

◆ TEST_P() [383/549]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesBlendModes   
)

Definition at line 1409 of file dl_unittests.cc.

1409  {
1410  std::vector<const char*> blend_mode_names;
1411  std::vector<flutter::DlBlendMode> blend_mode_values;
1412  {
1413  const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = {
1414  // Pipeline blends (Porter-Duff alpha compositing)
1415  {"Clear", flutter::DlBlendMode::kClear},
1416  {"Source", flutter::DlBlendMode::kSrc},
1417  {"Destination", flutter::DlBlendMode::kDst},
1418  {"SourceOver", flutter::DlBlendMode::kSrcOver},
1419  {"DestinationOver", flutter::DlBlendMode::kDstOver},
1420  {"SourceIn", flutter::DlBlendMode::kSrcIn},
1421  {"DestinationIn", flutter::DlBlendMode::kDstIn},
1422  {"SourceOut", flutter::DlBlendMode::kSrcOut},
1423  {"DestinationOut", flutter::DlBlendMode::kDstOut},
1424  {"SourceATop", flutter::DlBlendMode::kSrcATop},
1425  {"DestinationATop", flutter::DlBlendMode::kDstATop},
1426  {"Xor", flutter::DlBlendMode::kXor},
1427  {"Plus", flutter::DlBlendMode::kPlus},
1428  {"Modulate", flutter::DlBlendMode::kModulate},
1429  // Advanced blends (color component blends)
1430  {"Screen", flutter::DlBlendMode::kScreen},
1431  {"Overlay", flutter::DlBlendMode::kOverlay},
1432  {"Darken", flutter::DlBlendMode::kDarken},
1433  {"Lighten", flutter::DlBlendMode::kLighten},
1434  {"ColorDodge", flutter::DlBlendMode::kColorDodge},
1435  {"ColorBurn", flutter::DlBlendMode::kColorBurn},
1436  {"HardLight", flutter::DlBlendMode::kHardLight},
1437  {"SoftLight", flutter::DlBlendMode::kSoftLight},
1438  {"Difference", flutter::DlBlendMode::kDifference},
1439  {"Exclusion", flutter::DlBlendMode::kExclusion},
1440  {"Multiply", flutter::DlBlendMode::kMultiply},
1441  {"Hue", flutter::DlBlendMode::kHue},
1442  {"Saturation", flutter::DlBlendMode::kSaturation},
1443  {"Color", flutter::DlBlendMode::kColor},
1444  {"Luminosity", flutter::DlBlendMode::kLuminosity},
1445  };
1446  assert(blends.size() ==
1447  static_cast<size_t>(flutter::DlBlendMode::kLastMode) + 1);
1448  for (const auto& [name, mode] : blends) {
1449  blend_mode_names.push_back(name);
1450  blend_mode_values.push_back(mode);
1451  }
1452  }
1453 
1454  auto callback = [&]() {
1455  static int current_blend_index = 3;
1456  static float dst_alpha = 1;
1457  static float src_alpha = 1;
1458  static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1459  static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1460  static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1461  static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1462 
1463  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1464  {
1465  ImGui::ListBox("Blending mode", &current_blend_index,
1466  blend_mode_names.data(), blend_mode_names.size());
1467  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1468  ImGui::ColorEdit4("Color A", color0);
1469  ImGui::ColorEdit4("Color B", color1);
1470  ImGui::ColorEdit4("Color C", color2);
1471  ImGui::ColorEdit4("Source Color", src_color);
1472  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1473  }
1474  ImGui::End();
1475 
1476  std::vector<DlPoint> positions = {DlPoint(100, 300), //
1477  DlPoint(200, 100), //
1478  DlPoint(300, 300)};
1479  std::vector<flutter::DlColor> colors = {
1480  toColor(color0).modulateOpacity(dst_alpha),
1481  toColor(color1).modulateOpacity(dst_alpha),
1482  toColor(color2).modulateOpacity(dst_alpha)};
1483 
1484  auto vertices = flutter::DlVertices::Make(
1485  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1486  /*texture_coordinates=*/nullptr, colors.data());
1487 
1488  flutter::DisplayListBuilder builder;
1489  flutter::DlPaint paint;
1490 
1491  paint.setColor(toColor(src_color).modulateOpacity(src_alpha));
1492  builder.DrawVertices(vertices, blend_mode_values[current_blend_index],
1493  paint);
1494  return builder.Build();
1495  };
1496 
1497  ASSERT_TRUE(OpenPlaygroundHere(callback));
1498 }
flutter::DlColor toColor(const float *components)
Definition: dl_unittests.cc:39

References toColor().

◆ TEST_P() [384/549]

impeller::testing::TEST_P ( DisplayListTest  ,
IgnoreMaskFilterWhenSavingLayer   
)

Definition at line 517 of file dl_unittests.cc.

517  {
518  auto texture = CreateTextureForFixture("embarcadero.jpg");
519  flutter::DisplayListBuilder builder;
520  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
521  flutter::DlPaint paint;
522  paint.setMaskFilter(&filter);
523  builder.SaveLayer(std::nullopt, &paint);
524  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
525  flutter::DlImageSampling::kNearestNeighbor);
526  builder.Restore();
527  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
528 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [385/549]

impeller::testing::TEST_P ( DisplayListTest  ,
MaskBlursApplyCorrectlyToColorSources   
)

Definition at line 1260 of file dl_unittests.cc.

1260  {
1261  auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
1262  flutter::DlBlurStyle::kNormal, 10);
1263 
1264  flutter::DisplayListBuilder builder;
1265 
1266  std::array<flutter::DlColor, 2> colors = {flutter::DlColor::kBlue(),
1267  flutter::DlColor::kGreen()};
1268  std::array<float, 2> stops = {0, 1};
1269  auto texture = CreateTextureForFixture("airplane.jpg");
1270  auto matrix = flutter::DlMatrix::MakeTranslation({-300, -110});
1271  std::array<std::shared_ptr<flutter::DlColorSource>, 2> color_sources = {
1272  flutter::DlColorSource::MakeImage(
1273  DlImageImpeller::Make(texture), flutter::DlTileMode::kRepeat,
1274  flutter::DlTileMode::kRepeat, flutter::DlImageSampling::kLinear,
1275  &matrix),
1276  flutter::DlColorSource::MakeLinear(
1277  flutter::DlPoint(0, 0), flutter::DlPoint(100, 50), 2, colors.data(),
1278  stops.data(), flutter::DlTileMode::kClamp),
1279  };
1280 
1281  builder.Save();
1282  builder.Translate(0, 100);
1283  for (const auto& color_source : color_sources) {
1284  flutter::DlPaint paint;
1285  paint.setColorSource(color_source);
1286  paint.setMaskFilter(blur_filter);
1287 
1288  builder.Save();
1289  builder.Translate(100, 0);
1290  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
1291  builder.DrawRoundRect(
1292  DlRoundRect::MakeRectXY(DlRect::MakeWH(100, 50), 30, 30), paint);
1293 
1294  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1295  paint.setStrokeWidth(10);
1296  builder.Translate(200, 0);
1297  builder.DrawRoundRect(
1298  DlRoundRect::MakeRectXY(DlRect::MakeWH(100, 50), 30, 30), paint);
1299 
1300  builder.Restore();
1301  builder.Translate(0, 100);
1302  }
1303  builder.Restore();
1304 
1305  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1306 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [386/549]

impeller::testing::TEST_P ( DisplayListTest  ,
NinePatchImagePrecision   
)

Definition at line 800 of file dl_unittests.cc.

800  {
801  // Draw a nine patch image with colored corners and verify that the corner
802  // color does not leak outside the intended region.
803  auto texture = CreateTextureForFixture("nine_patch_corners.png");
804  flutter::DisplayListBuilder builder;
805  builder.DrawImageNine(DlImageImpeller::Make(texture),
806  DlIRect::MakeXYWH(10, 10, 1, 1),
807  DlRect::MakeXYWH(0, 0, 200, 100),
808  flutter::DlFilterMode::kNearest, nullptr);
809  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
810 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [387/549]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedPathsDrawCorrectly   
)

Definition at line 216 of file dl_unittests.cc.

216  {
217  auto callback = [&]() {
218  flutter::DisplayListBuilder builder;
219  flutter::DlPaint paint;
220 
221  paint.setColor(flutter::DlColor::kRed());
222  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
223 
224  static float stroke_width = 10.0f;
225  static int selected_stroke_type = 0;
226  static int selected_join_type = 0;
227  const char* stroke_types[] = {"Butte", "Round", "Square"};
228  const char* join_type[] = {"kMiter", "Round", "kBevel"};
229 
230  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
231  ImGui::Combo("Cap", &selected_stroke_type, stroke_types,
232  sizeof(stroke_types) / sizeof(char*));
233  ImGui::Combo("Join", &selected_join_type, join_type,
234  sizeof(join_type) / sizeof(char*));
235  ImGui::SliderFloat("Stroke Width", &stroke_width, 10.0f, 50.0f);
236  ImGui::End();
237 
238  flutter::DlStrokeCap cap;
239  flutter::DlStrokeJoin join;
240  switch (selected_stroke_type) {
241  case 0:
242  cap = flutter::DlStrokeCap::kButt;
243  break;
244  case 1:
245  cap = flutter::DlStrokeCap::kRound;
246  break;
247  case 2:
248  cap = flutter::DlStrokeCap::kSquare;
249  break;
250  default:
251  cap = flutter::DlStrokeCap::kButt;
252  break;
253  }
254  switch (selected_join_type) {
255  case 0:
256  join = flutter::DlStrokeJoin::kMiter;
257  break;
258  case 1:
259  join = flutter::DlStrokeJoin::kRound;
260  break;
261  case 2:
262  join = flutter::DlStrokeJoin::kBevel;
263  break;
264  default:
265  join = flutter::DlStrokeJoin::kMiter;
266  break;
267  }
268  paint.setStrokeCap(cap);
269  paint.setStrokeJoin(join);
270  paint.setStrokeWidth(stroke_width);
271 
272  // Make rendering better to watch.
273  builder.Scale(1.5f, 1.5f);
274 
275  // Rectangle
276  builder.Translate(100, 100);
277  builder.DrawRect(DlRect::MakeWH(100, 100), paint);
278 
279  // Rounded rectangle
280  builder.Translate(150, 0);
281  builder.DrawRoundRect(
282  DlRoundRect::MakeRectXY(DlRect::MakeWH(100, 50), 10, 10), paint);
283 
284  // Double rounded rectangle
285  builder.Translate(150, 0);
286  builder.DrawDiffRoundRect(
287  DlRoundRect::MakeRectXY(DlRect::MakeWH(100, 50), 10, 10),
288  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(10, 10, 80, 30), 10, 10),
289  paint);
290 
291  // Contour with duplicate join points
292  {
293  builder.Translate(150, 0);
294  flutter::DlPathBuilder path_builder;
295  path_builder.MoveTo(DlPoint(0, 0));
296  path_builder.LineTo(DlPoint(0, 0));
297  path_builder.LineTo(DlPoint(100, 0));
298  path_builder.LineTo(DlPoint(100, 0));
299  path_builder.LineTo(DlPoint(100, 100));
300  builder.DrawPath(path_builder.TakePath(), paint);
301  }
302 
303  // Contour with duplicate start and end points
304 
305  // Line.
306  builder.Translate(200, 0);
307  {
308  builder.Save();
309 
310  flutter::DlPathBuilder line_path_builder;
311  line_path_builder.MoveTo(DlPoint(0, 0));
312  line_path_builder.MoveTo(DlPoint(0, 0));
313  line_path_builder.LineTo(DlPoint(0, 0));
314  line_path_builder.LineTo(DlPoint(0, 0));
315  line_path_builder.LineTo(DlPoint(50, 50));
316  line_path_builder.LineTo(DlPoint(50, 50));
317  line_path_builder.LineTo(DlPoint(100, 0));
318  line_path_builder.LineTo(DlPoint(100, 0));
319  DlPath line_path = line_path_builder.TakePath();
320  builder.DrawPath(line_path, paint);
321 
322  builder.Translate(0, 100);
323  builder.DrawPath(line_path, paint);
324 
325  builder.Translate(0, 100);
326  flutter::DlPathBuilder line_path_builder2;
327  line_path_builder2.MoveTo(DlPoint(0, 0));
328  line_path_builder2.LineTo(DlPoint(0, 0));
329  line_path_builder2.LineTo(DlPoint(0, 0));
330  builder.DrawPath(line_path_builder2.TakePath(), paint);
331 
332  builder.Restore();
333  }
334 
335  // Cubic.
336  builder.Translate(150, 0);
337  {
338  builder.Save();
339 
340  flutter::DlPathBuilder cubic_path;
341  cubic_path.MoveTo(DlPoint(0, 0));
342  cubic_path.CubicCurveTo(DlPoint(0, 0), //
343  DlPoint(140.0, 100.0), //
344  DlPoint(140, 20));
345  builder.DrawPath(cubic_path.TakePath(), paint);
346 
347  builder.Translate(0, 100);
348  flutter::DlPathBuilder cubic_path2;
349  cubic_path2.MoveTo(DlPoint(0, 0));
350  cubic_path2.CubicCurveTo(DlPoint(0, 0), //
351  DlPoint(0, 0), //
352  DlPoint(150, 150));
353  builder.DrawPath(cubic_path2.TakePath(), paint);
354 
355  builder.Translate(0, 100);
356  flutter::DlPathBuilder cubic_path3;
357  cubic_path3.MoveTo(DlPoint(0, 0));
358  cubic_path3.CubicCurveTo(DlPoint(0, 0), //
359  DlPoint(0, 0), //
360  DlPoint(0, 0));
361  builder.DrawPath(cubic_path3.TakePath(), paint);
362 
363  builder.Restore();
364  }
365 
366  // Quad.
367  builder.Translate(200, 0);
368  {
369  builder.Save();
370 
371  flutter::DlPathBuilder quad_path;
372  quad_path.MoveTo(DlPoint(0, 0));
373  quad_path.MoveTo(DlPoint(0, 0));
374  quad_path.QuadraticCurveTo(DlPoint(100, 40), DlPoint(50, 80));
375  builder.DrawPath(quad_path.TakePath(), paint);
376 
377  builder.Translate(0, 150);
378  flutter::DlPathBuilder quad_path2;
379  quad_path2.MoveTo(DlPoint(0, 0));
380  quad_path2.MoveTo(DlPoint(0, 0));
381  quad_path2.QuadraticCurveTo(DlPoint(0, 0), DlPoint(100, 100));
382  builder.DrawPath(quad_path2.TakePath(), paint);
383 
384  builder.Translate(0, 100);
385  flutter::DlPathBuilder quad_path3;
386  quad_path3.MoveTo(DlPoint(0, 0));
387  quad_path3.QuadraticCurveTo(DlPoint(0, 0), DlPoint(0, 0));
388  builder.DrawPath(quad_path3.TakePath(), paint);
389 
390  builder.Restore();
391  }
392  return builder.Build();
393  };
394  ASSERT_TRUE(OpenPlaygroundHere(callback));
395 }

◆ TEST_P() [388/549]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedTextNotOffsetFromNormalText   
)

Definition at line 491 of file dl_unittests.cc.

491  {
492  flutter::DisplayListBuilder builder;
493  flutter::DlPaint paint;
494  auto const& text_blob = SkTextBlob::MakeFromString("00000", CreateTestFont());
495  auto text = flutter::DlTextSkia::Make(text_blob);
496 
497  // https://api.flutter.dev/flutter/material/Colors/blue-constant.html.
498  auto const& mat_blue = flutter::DlColor(0xFF2196f3);
499 
500  // Draw a blue filled rectangle so the text is easier to see.
501  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
502  paint.setColor(mat_blue);
503  builder.DrawRect(DlRect::MakeXYWH(0, 0, 500, 500), paint);
504 
505  // Draw stacked text, with stroked text on top.
506  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
507  paint.setColor(flutter::DlColor::kWhite());
508  builder.DrawText(text, 250, 250, paint);
509 
510  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
511  paint.setColor(flutter::DlColor::kBlack());
512  builder.DrawText(text, 250, 250, paint);
513 
514  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
515 }

◆ TEST_P() [389/549]

impeller::testing::TEST_P ( DriverInfoVKTest  ,
CanDumpToLog   
)

Definition at line 30 of file driver_info_vk_unittests.cc.

30  {
31  ASSERT_TRUE(GetContext());
32  const auto& driver_info =
33  SurfaceContextVK::Cast(*GetContext()).GetParent()->GetDriverInfo();
34  ASSERT_NE(driver_info, nullptr);
35  fml::testing::LogCapture log;
36  driver_info->DumpToLog();
37  EXPECT_TRUE(log.str().find("Driver Information") != std::string::npos);
38 }

References impeller::BackendCast< SurfaceContextVK, Context >::Cast(), and impeller::SurfaceContextVK::GetParent().

◆ TEST_P() [390/549]

impeller::testing::TEST_P ( DriverInfoVKTest  ,
CanQueryDriverInfo   
)

Definition at line 17 of file driver_info_vk_unittests.cc.

17  {
18  ASSERT_TRUE(GetContext());
19  const auto& driver_info =
20  SurfaceContextVK::Cast(*GetContext()).GetParent()->GetDriverInfo();
21  ASSERT_NE(driver_info, nullptr);
22  // 1.1 is the base Impeller version. The driver can't be lower than that.
23  ASSERT_TRUE(driver_info->GetAPIVersion().IsAtLeast(Version{1, 1, 0}));
24  ASSERT_NE(driver_info->GetVendor(), VendorVK::kUnknown);
25  ASSERT_NE(driver_info->GetDeviceType(), DeviceTypeVK::kUnknown);
26  ASSERT_NE(driver_info->GetDriverName(), "");
27  EXPECT_FALSE(driver_info->IsKnownBadDriver());
28 }

References impeller::BackendCast< SurfaceContextVK, Context >::Cast(), impeller::SurfaceContextVK::GetParent(), and impeller::kUnknown.

◆ TEST_P() [391/549]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAAImplicitResolve   
)

Definition at line 47 of file entity_pass_target_unittests.cc.

47  {
48  auto content_context = GetContentContext();
49  auto buffer = content_context->GetContext()->CreateCommandBuffer();
50  auto context = content_context->GetContext();
51  auto& allocator = *context->GetResourceAllocator();
52 
53  // Emulate implicit MSAA resolve by making color resolve and msaa texture the
54  // same.
55  RenderTarget render_target;
56  {
57  PixelFormat pixel_format =
58  context->GetCapabilities()->GetDefaultColorFormat();
59 
60  // Create MSAA color texture.
61 
62  TextureDescriptor color0_tex_desc;
63  color0_tex_desc.storage_mode = StorageMode::kDevicePrivate;
64  color0_tex_desc.type = TextureType::kTexture2DMultisample;
65  color0_tex_desc.sample_count = SampleCount::kCount4;
66  color0_tex_desc.format = pixel_format;
67  color0_tex_desc.size = ISize{100, 100};
68  color0_tex_desc.usage = TextureUsage::kRenderTarget;
69 
70  auto color0_msaa_tex = allocator.CreateTexture(color0_tex_desc);
71 
72  // Color attachment.
73 
74  ColorAttachment color0;
75  color0.load_action = LoadAction::kDontCare;
76  color0.store_action = StoreAction::kStoreAndMultisampleResolve;
77  color0.texture = color0_msaa_tex;
78  color0.resolve_texture = color0_msaa_tex;
79 
80  render_target.SetColorAttachment(color0, 0u);
81  render_target.SetStencilAttachment(std::nullopt);
82  }
83 
84  auto entity_pass_target = EntityPassTarget(render_target, false, true);
85 
86  auto color0 = entity_pass_target.GetRenderTarget().GetColorAttachment(0);
87  auto msaa_tex = color0.texture;
88  auto resolve_tex = color0.resolve_texture;
89 
90  ASSERT_EQ(msaa_tex, resolve_tex);
91 
92  FML_DCHECK(content_context);
93  entity_pass_target.Flip(*content_context);
94 
95  color0 = entity_pass_target.GetRenderTarget().GetColorAttachment(0);
96 
97  ASSERT_NE(msaa_tex, color0.texture);
98  ASSERT_NE(resolve_tex, color0.resolve_texture);
99  ASSERT_EQ(color0.texture, color0.resolve_texture);
100 }

References impeller::TextureDescriptor::format, impeller::kCount4, impeller::kDevicePrivate, impeller::kDontCare, impeller::kRenderTarget, impeller::kStoreAndMultisampleResolve, impeller::kTexture2DMultisample, impeller::Attachment::load_action, impeller::Attachment::resolve_texture, impeller::TextureDescriptor::sample_count, impeller::RenderTarget::SetColorAttachment(), impeller::RenderTarget::SetStencilAttachment(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, impeller::Attachment::texture, impeller::TextureDescriptor::type, and impeller::TextureDescriptor::usage.

◆ TEST_P() [392/549]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAATexture   
)

Definition at line 19 of file entity_pass_target_unittests.cc.

19  {
20  if (GetContentContext()
21  ->GetDeviceCapabilities()
22  .SupportsImplicitResolvingMSAA()) {
23  GTEST_SKIP() << "Implicit MSAA is used on this device.";
24  }
25  auto content_context = GetContentContext();
26  auto buffer = content_context->GetContext()->CreateCommandBuffer();
27  auto render_target =
28  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
29  *content_context->GetContext(), {100, 100},
30  /*mip_count=*/1);
31 
32  auto entity_pass_target = EntityPassTarget(render_target, false, false);
33 
34  auto color0 = entity_pass_target.GetRenderTarget().GetColorAttachment(0);
35  auto msaa_tex = color0.texture;
36  auto resolve_tex = color0.resolve_texture;
37 
38  FML_DCHECK(content_context);
39  entity_pass_target.Flip(*content_context);
40 
41  color0 = entity_pass_target.GetRenderTarget().GetColorAttachment(0);
42 
43  ASSERT_EQ(msaa_tex, color0.texture);
44  ASSERT_NE(resolve_tex, color0.resolve_texture);
45 }

◆ TEST_P() [393/549]

impeller::testing::TEST_P ( EntityTest  ,
BezierCircleScaled   
)

Definition at line 879 of file entity_unittests.cc.

879  {
880  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
881  static float scale = 20;
882 
883  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
884  ImGui::SliderFloat("Scale", &scale, 1, 100);
885  ImGui::End();
886 
887  Entity entity;
888  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
889  auto path = flutter::DlPathBuilder{}
890  .MoveTo({97.325, 34.818})
891  .CubicCurveTo({98.50862885295136, 34.81812293973836},
892  {99.46822048142015, 33.85863261475589},
893  {99.46822048142015, 32.67499810206613})
894  .CubicCurveTo({99.46822048142015, 31.491363589376355},
895  {98.50862885295136, 30.53187326439389},
896  {97.32499434685802, 30.531998226542708})
897  .CubicCurveTo({96.14153655073771, 30.532123170035373},
898  {95.18222070648729, 31.491540299350355},
899  {95.18222070648729, 32.67499810206613})
900  .CubicCurveTo({95.18222070648729, 33.85845590478189},
901  {96.14153655073771, 34.81787303409686},
902  {97.32499434685802, 34.81799797758954})
903  .Close()
904  .TakePath();
905  entity.SetTransform(
906  Matrix::MakeScale({scale, scale, 1.0}).Translate({-90, -20, 0}));
907 
908  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
909 
910  auto contents = std::make_shared<SolidColorContents>();
911  contents->SetColor(Color::Red());
912  contents->SetGeometry(geom.get());
913 
914  entity.SetContents(contents);
915  return entity.Render(context, pass);
916  };
917  ASSERT_TRUE(OpenPlaygroundHere(callback));
918 }

References impeller::Close(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [394/549]

impeller::testing::TEST_P ( EntityTest  ,
BlendingModeOptions   
)

Definition at line 747 of file entity_unittests.cc.

747  {
748  std::vector<const char*> blend_mode_names;
749  std::vector<BlendMode> blend_mode_values;
750  {
751  // Force an exhausiveness check with a switch. When adding blend modes,
752  // update this switch with a new name/value to make it selectable in the
753  // test GUI.
754 
755  const BlendMode b{};
756  static_assert(b == BlendMode::kClear); // Ensure the first item in
757  // the switch is the first
758  // item in the enum.
759  static_assert(Entity::kLastPipelineBlendMode == BlendMode::kModulate);
760  switch (b) {
761  case BlendMode::kClear:
762  blend_mode_names.push_back("Clear");
763  blend_mode_values.push_back(BlendMode::kClear);
764  case BlendMode::kSrc:
765  blend_mode_names.push_back("Source");
766  blend_mode_values.push_back(BlendMode::kSrc);
767  case BlendMode::kDst:
768  blend_mode_names.push_back("Destination");
769  blend_mode_values.push_back(BlendMode::kDst);
770  case BlendMode::kSrcOver:
771  blend_mode_names.push_back("SourceOver");
772  blend_mode_values.push_back(BlendMode::kSrcOver);
773  case BlendMode::kDstOver:
774  blend_mode_names.push_back("DestinationOver");
775  blend_mode_values.push_back(BlendMode::kDstOver);
776  case BlendMode::kSrcIn:
777  blend_mode_names.push_back("SourceIn");
778  blend_mode_values.push_back(BlendMode::kSrcIn);
779  case BlendMode::kDstIn:
780  blend_mode_names.push_back("DestinationIn");
781  blend_mode_values.push_back(BlendMode::kDstIn);
782  case BlendMode::kSrcOut:
783  blend_mode_names.push_back("SourceOut");
784  blend_mode_values.push_back(BlendMode::kSrcOut);
785  case BlendMode::kDstOut:
786  blend_mode_names.push_back("DestinationOut");
787  blend_mode_values.push_back(BlendMode::kDstOut);
788  case BlendMode::kSrcATop:
789  blend_mode_names.push_back("SourceATop");
790  blend_mode_values.push_back(BlendMode::kSrcATop);
791  case BlendMode::kDstATop:
792  blend_mode_names.push_back("DestinationATop");
793  blend_mode_values.push_back(BlendMode::kDstATop);
794  case BlendMode::kXor:
795  blend_mode_names.push_back("Xor");
796  blend_mode_values.push_back(BlendMode::kXor);
797  case BlendMode::kPlus:
798  blend_mode_names.push_back("Plus");
799  blend_mode_values.push_back(BlendMode::kPlus);
800  case BlendMode::kModulate:
801  blend_mode_names.push_back("Modulate");
802  blend_mode_values.push_back(BlendMode::kModulate);
803  };
804  }
805 
806  auto callback = [&](ContentContext& context, RenderPass& pass) {
807  auto world_matrix = Matrix::MakeScale(GetContentScale());
808  auto draw_rect = [&context, &pass, &world_matrix](
809  Rect rect, Color color, BlendMode blend_mode) -> bool {
810  using VS = SolidFillPipeline::VertexShader;
811  using FS = SolidFillPipeline::FragmentShader;
812 
813  VertexBufferBuilder<VS::PerVertexData> vtx_builder;
814  {
815  auto r = rect.GetLTRB();
816  vtx_builder.AddVertices({
817  {Point(r[0], r[1])},
818  {Point(r[2], r[1])},
819  {Point(r[2], r[3])},
820  {Point(r[0], r[1])},
821  {Point(r[2], r[3])},
822  {Point(r[0], r[3])},
823  });
824  }
825 
826  pass.SetCommandLabel("Blended Rectangle");
827  auto options = OptionsFromPass(pass);
828  options.blend_mode = blend_mode;
829  options.primitive_type = PrimitiveType::kTriangle;
830  pass.SetPipeline(context.GetSolidFillPipeline(options));
831  pass.SetVertexBuffer(
832  vtx_builder.CreateVertexBuffer(context.GetTransientsDataBuffer(),
833  context.GetTransientsIndexesBuffer()));
834 
835  VS::FrameInfo frame_info;
836  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
837  VS::BindFrameInfo(
838  pass, context.GetTransientsDataBuffer().EmplaceUniform(frame_info));
839  FS::FragInfo frag_info;
840  frag_info.color = color.Premultiply();
841  FS::BindFragInfo(
842  pass, context.GetTransientsDataBuffer().EmplaceUniform(frag_info));
843  return pass.Draw().ok();
844  };
845 
846  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
847  static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
848  ImGui::ColorEdit4("Color 1", reinterpret_cast<float*>(&color1));
849  ImGui::ColorEdit4("Color 2", reinterpret_cast<float*>(&color2));
850  static int current_blend_index = 3;
851  ImGui::ListBox("Blending mode", &current_blend_index,
852  blend_mode_names.data(), blend_mode_names.size());
853  ImGui::End();
854 
855  BlendMode selected_mode = blend_mode_values[current_blend_index];
856 
857  Point a, b, c, d;
858  static PlaygroundPoint point_a(Point(400, 100), 20, Color::White());
859  static PlaygroundPoint point_b(Point(200, 300), 20, Color::White());
860  std::tie(a, b) = DrawPlaygroundLine(point_a, point_b);
861  static PlaygroundPoint point_c(Point(470, 190), 20, Color::White());
862  static PlaygroundPoint point_d(Point(270, 390), 20, Color::White());
863  std::tie(c, d) = DrawPlaygroundLine(point_c, point_d);
864 
865  bool result = true;
866  result = result &&
867  draw_rect(Rect::MakeXYWH(0, 0, pass.GetRenderTargetSize().width,
868  pass.GetRenderTargetSize().height),
869  Color(), BlendMode::kClear);
870  result = result && draw_rect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), color1,
871  BlendMode::kSrcOver);
872  result = result && draw_rect(Rect::MakeLTRB(c.x, c.y, d.x, d.y), color2,
873  selected_mode);
874  return result;
875  };
876  ASSERT_TRUE(OpenPlaygroundHere(callback));
877 }
LinePipeline::FragmentShader FS
LinePipeline::VertexShader VS
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:19

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::saturated::b, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::DrawPlaygroundLine(), impeller::HostBuffer::EmplaceUniform(), impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContext::GetTransientsDataBuffer(), impeller::ContentContext::GetTransientsIndexesBuffer(), impeller::kClear, impeller::kDst, impeller::kDstATop, impeller::kDstIn, impeller::kDstOut, impeller::kDstOver, impeller::Entity::kLastPipelineBlendMode, impeller::kModulate, impeller::kPlus, impeller::kSrc, impeller::kSrcATop, impeller::kSrcIn, impeller::kSrcOut, impeller::kSrcOver, impeller::kTriangle, impeller::kXor, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::OptionsFromPass(), impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [395/549]

impeller::testing::TEST_P ( EntityTest  ,
BorderMaskBlurCoverageIsCorrect   
)

Definition at line 1320 of file entity_unittests.cc.

1320  {
1321  auto fill = std::make_shared<SolidColorContents>();
1322  auto geom = Geometry::MakeFillPath(
1323  flutter::DlPath::MakeRect(Rect::MakeXYWH(0, 0, 300, 400)));
1324  fill->SetGeometry(geom.get());
1325  fill->SetColor(Color::CornflowerBlue());
1326  auto border_mask_blur = FilterContents::MakeBorderMaskBlur(
1327  FilterInput::Make(fill), Radius{3}, Radius{4});
1328 
1329  {
1330  Entity e;
1331  e.SetTransform(Matrix());
1332  auto actual = border_mask_blur->GetCoverage(e);
1333  auto expected = Rect::MakeXYWH(-3, -4, 306, 408);
1334  ASSERT_TRUE(actual.has_value());
1335  ASSERT_RECT_NEAR(actual.value(), expected);
1336  }
1337 
1338  {
1339  Entity e;
1340  e.SetTransform(Matrix::MakeRotationZ(Radians{kPi / 4}));
1341  auto actual = border_mask_blur->GetCoverage(e);
1342  auto expected = Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1343  ASSERT_TRUE(actual.has_value());
1344  ASSERT_RECT_NEAR(actual.value(), expected);
1345  }
1346 }
#define ASSERT_RECT_NEAR(a, b)

References ASSERT_RECT_NEAR, impeller::Color::CornflowerBlue(), impeller::kPi, impeller::FilterInput::Make(), impeller::FilterContents::MakeBorderMaskBlur(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeRotationZ(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Entity::SetTransform().

◆ TEST_P() [396/549]

impeller::testing::TEST_P ( EntityTest  ,
CanComputeGeometryForEmptyPathsWithoutCrashing   
)

Definition at line 2317 of file entity_unittests.cc.

2317  {
2318  flutter::DlPath path = flutter::DlPath::MakeRect(Rect::MakeLTRB(0, 0, 0, 0));
2319 
2320  EXPECT_TRUE(path.GetBounds().IsEmpty());
2321 
2322  auto geom = Geometry::MakeFillPath(path);
2323 
2324  Entity entity;
2325  RenderTarget target =
2326  GetContentContext()->GetRenderTargetCache()->CreateOffscreen(
2327  *GetContext(), {1, 1}, 1u);
2328  testing::MockRenderPass render_pass(GetContext(), target);
2329  auto position_result =
2330  geom->GetPositionBuffer(*GetContentContext(), entity, render_pass);
2331 
2332  EXPECT_EQ(position_result.vertex_buffer.vertex_count, 0u);
2333 
2334  EXPECT_EQ(geom->GetResultMode(), GeometryResult::Mode::kNormal);
2335 }

References impeller::GeometryResult::kNormal, impeller::Geometry::MakeFillPath(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [397/549]

impeller::testing::TEST_P ( EntityTest  ,
CanCreateEntity   
)

Definition at line 72 of file entity_unittests.cc.

72  {
73  Entity entity;
74  ASSERT_TRUE(entity.GetTransform().IsIdentity());
75 }

References impeller::Entity::GetTransform(), and impeller::Matrix::IsIdentity().

◆ TEST_P() [398/549]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawCorrectlyWithRotatedTransform   
)

Definition at line 399 of file entity_unittests.cc.

399  {
400  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
401  const char* input_axis[] = {"X", "Y", "Z"};
402  static int rotation_axis_index = 0;
403  static float rotation = 0;
404  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
405  ImGui::SliderFloat("Rotation", &rotation, -kPi, kPi);
406  ImGui::Combo("Rotation Axis", &rotation_axis_index, input_axis,
407  sizeof(input_axis) / sizeof(char*));
408  Matrix rotation_matrix;
409  switch (rotation_axis_index) {
410  case 0:
411  rotation_matrix = Matrix::MakeRotationX(Radians(rotation));
412  break;
413  case 1:
414  rotation_matrix = Matrix::MakeRotationY(Radians(rotation));
415  break;
416  case 2:
417  rotation_matrix = Matrix::MakeRotationZ(Radians(rotation));
418  break;
419  default:
420  rotation_matrix = Matrix{};
421  break;
422  }
423 
424  if (ImGui::Button("Reset")) {
425  rotation = 0;
426  }
427  ImGui::End();
428  Matrix current_transform =
429  Matrix::MakeScale(GetContentScale())
430  .MakeTranslation(
431  Vector3(Point(pass.GetRenderTargetSize().width / 2.0,
432  pass.GetRenderTargetSize().height / 2.0)));
433  Matrix result_transform = current_transform * rotation_matrix;
434  flutter::DlPath path =
435  flutter::DlPath::MakeRect(Rect::MakeXYWH(-300, -400, 600, 800));
436 
437  Entity entity;
438  entity.SetTransform(result_transform);
439 
440  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
441 
442  auto contents = std::make_shared<SolidColorContents>();
443  contents->SetColor(Color::Red());
444  contents->SetGeometry(geom.get());
445 
446  entity.SetContents(contents);
447  return entity.Render(context, pass);
448  };
449  ASSERT_TRUE(OpenPlaygroundHere(callback));
450 }

References impeller::kPi, impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [399/549]

impeller::testing::TEST_P ( EntityTest  ,
CanRenderEmptyPathsWithoutCrashing   
)

Definition at line 2337 of file entity_unittests.cc.

2337  {
2338  flutter::DlPath path = flutter::DlPath::MakeRect(Rect::MakeLTRB(0, 0, 0, 0));
2339 
2340  EXPECT_TRUE(path.GetBounds().IsEmpty());
2341 
2342  auto contents = std::make_shared<SolidColorContents>();
2343  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
2344  contents->SetGeometry(geom.get());
2345  contents->SetColor(Color::Red());
2346 
2347  Entity entity;
2348  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2349  entity.SetContents(contents);
2350 
2351  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2352 }

References impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [400/549]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterContentsWithLargeGeometry   
)

Definition at line 2161 of file entity_unittests.cc.

2161  {
2162  Entity entity;
2163  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2164  auto src_contents = std::make_shared<SolidColorContents>();
2165  auto src_geom = Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000));
2166  src_contents->SetGeometry(src_geom.get());
2167  src_contents->SetColor(Color::Red());
2168 
2169  auto dst_contents = std::make_shared<SolidColorContents>();
2170  auto dst_geom = Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000));
2171  dst_contents->SetGeometry(dst_geom.get());
2172  dst_contents->SetColor(Color::Blue());
2173 
2174  auto contents = ColorFilterContents::MakeBlend(
2175  BlendMode::kSrcOver, {FilterInput::Make(dst_contents, false),
2176  FilterInput::Make(src_contents, false)});
2177  entity.SetContents(std::move(contents));
2178  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2179 }

References impeller::Color::Blue(), impeller::kSrcOver, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [401/549]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorAdvancedBlend   
)

Definition at line 1924 of file entity_unittests.cc.

1924  {
1925  auto image = CreateTextureForFixture("boston.jpg");
1926  auto filter = ColorFilterContents::MakeBlend(
1927  BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());
1928 
1929  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1930  Entity entity;
1931  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1932  Matrix::MakeTranslation({500, 300}) *
1933  Matrix::MakeScale(Vector2{0.5, 0.5}));
1934  entity.SetContents(filter);
1935  return entity.Render(context, pass);
1936  };
1937  ASSERT_TRUE(OpenPlaygroundHere(callback));
1938 }

References impeller::kColorBurn, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [402/549]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorClearBlend   
)

Definition at line 1940 of file entity_unittests.cc.

1940  {
1941  auto image = CreateTextureForFixture("boston.jpg");
1942  auto filter = ColorFilterContents::MakeBlend(
1943  BlendMode::kClear, FilterInput::Make({image}), Color::Red());
1944 
1945  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1946  Entity entity;
1947  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1948  Matrix::MakeTranslation({500, 300}) *
1949  Matrix::MakeScale(Vector2{0.5, 0.5}));
1950  entity.SetContents(filter);
1951  return entity.Render(context, pass);
1952  };
1953  ASSERT_TRUE(OpenPlaygroundHere(callback));
1954 }

References impeller::kClear, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [403/549]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorDstBlend   
)

Definition at line 1972 of file entity_unittests.cc.

1972  {
1973  auto image = CreateTextureForFixture("boston.jpg");
1974  auto filter = ColorFilterContents::MakeBlend(
1975  BlendMode::kDst, FilterInput::Make({image}), Color::Red());
1976 
1977  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1978  Entity entity;
1979  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1980  Matrix::MakeTranslation({500, 300}) *
1981  Matrix::MakeScale(Vector2{0.5, 0.5}));
1982  entity.SetContents(filter);
1983  return entity.Render(context, pass);
1984  };
1985  ASSERT_TRUE(OpenPlaygroundHere(callback));
1986 }

References impeller::kDst, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [404/549]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcBlend   
)

Definition at line 1956 of file entity_unittests.cc.

1956  {
1957  auto image = CreateTextureForFixture("boston.jpg");
1958  auto filter = ColorFilterContents::MakeBlend(
1959  BlendMode::kSrc, FilterInput::Make({image}), Color::Red());
1960 
1961  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1962  Entity entity;
1963  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1964  Matrix::MakeTranslation({500, 300}) *
1965  Matrix::MakeScale(Vector2{0.5, 0.5}));
1966  entity.SetContents(filter);
1967  return entity.Render(context, pass);
1968  };
1969  ASSERT_TRUE(OpenPlaygroundHere(callback));
1970 }

References impeller::kSrc, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [405/549]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcInBlend   
)

Definition at line 1988 of file entity_unittests.cc.

1988  {
1989  auto image = CreateTextureForFixture("boston.jpg");
1990  auto filter = ColorFilterContents::MakeBlend(
1991  BlendMode::kSrcIn, FilterInput::Make({image}), Color::Red());
1992 
1993  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1994  Entity entity;
1995  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1996  Matrix::MakeTranslation({500, 300}) *
1997  Matrix::MakeScale(Vector2{0.5, 0.5}));
1998  entity.SetContents(filter);
1999  return entity.Render(context, pass);
2000  };
2001  ASSERT_TRUE(OpenPlaygroundHere(callback));
2002 }

References impeller::kSrcIn, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [406/549]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterCoverageIsCorrect   
)

Definition at line 1447 of file entity_unittests.cc.

1447  {
1448  // Set up a simple color background.
1449  auto fill = std::make_shared<SolidColorContents>();
1450  auto geom = Geometry::MakeFillPath(
1451  flutter::DlPath::MakeRect(Rect::MakeXYWH(0, 0, 300, 400)));
1452  fill->SetGeometry(geom.get());
1453  fill->SetColor(Color::Coral());
1454 
1455  // Set the color matrix filter.
1456  ColorMatrix matrix = {
1457  1, 1, 1, 1, 1, //
1458  1, 1, 1, 1, 1, //
1459  1, 1, 1, 1, 1, //
1460  1, 1, 1, 1, 1, //
1461  };
1462 
1463  auto filter =
1464  ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);
1465 
1466  Entity e;
1467  e.SetTransform(Matrix());
1468 
1469  // Confirm that the actual filter coverage matches the expected coverage.
1470  auto actual = filter->GetCoverage(e);
1471  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1472 
1473  ASSERT_TRUE(actual.has_value());
1474  ASSERT_RECT_NEAR(actual.value(), expected);
1475 }

References ASSERT_RECT_NEAR, impeller::Color::Coral(), impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeColorMatrix(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Entity::SetTransform().

◆ TEST_P() [407/549]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterEditable   
)

Definition at line 1477 of file entity_unittests.cc.

1477  {
1478  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
1479  ASSERT_TRUE(bay_bridge);
1480 
1481  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1482  // UI state.
1483  static ColorMatrix color_matrix = {
1484  1, 0, 0, 0, 0, //
1485  0, 3, 0, 0, 0, //
1486  0, 0, 1, 0, 0, //
1487  0, 0, 0, 1, 0, //
1488  };
1489  static float offset[2] = {500, 400};
1490  static float rotation = 0;
1491  static float scale[2] = {0.65, 0.65};
1492  static float skew[2] = {0, 0};
1493 
1494  // Define the ImGui
1495  ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1496  {
1497  std::string label = "##1";
1498  for (int i = 0; i < 20; i += 5) {
1499  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1500  &(color_matrix.array[i]), 5, nullptr, nullptr,
1501  "%.2f", 0);
1502  label[2]++;
1503  }
1504 
1505  ImGui::SliderFloat2("Translation", &offset[0], 0,
1506  pass.GetRenderTargetSize().width);
1507  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1508  ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
1509  ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
1510  }
1511  ImGui::End();
1512 
1513  // Set the color matrix filter.
1514  auto filter = ColorFilterContents::MakeColorMatrix(
1515  FilterInput::Make(bay_bridge), color_matrix);
1516 
1517  // Define the entity with the color matrix filter.
1518  Entity entity;
1519  entity.SetTransform(
1520  Matrix::MakeScale(GetContentScale()) *
1521  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1522  Matrix::MakeRotationZ(Radians(rotation)) *
1523  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1524  Matrix::MakeSkew(skew[0], skew[1]) *
1525  Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
1526  entity.SetContents(filter);
1527  entity.Render(context, pass);
1528 
1529  return true;
1530  };
1531 
1532  ASSERT_TRUE(OpenPlaygroundHere(callback));
1533 }

References impeller::ColorMatrix::array, impeller::kPi, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeColorMatrix(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [408/549]

impeller::testing::TEST_P ( EntityTest  ,
ConicalGradientContentsIsOpaque   
)

Definition at line 2049 of file entity_unittests.cc.

2049  {
2050  Matrix matrix;
2051  ConicalGradientContents contents;
2052  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2053  contents.SetGeometry(geom.get());
2054 
2055  contents.SetColors({Color::CornflowerBlue()});
2056  EXPECT_FALSE(contents.IsOpaque(matrix));
2057  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2058  EXPECT_FALSE(contents.IsOpaque(matrix));
2059 
2060  // Create stroked path that required alpha coverage.
2061  geom = Geometry::MakeStrokePath(
2062  flutter::DlPathBuilder{}.MoveTo({0, 0}).LineTo({100, 100}).TakePath(),
2063  {.width = 0.05f});
2064  contents.SetGeometry(geom.get());
2065  contents.SetColors({Color::CornflowerBlue()});
2066 
2067  EXPECT_FALSE(contents.IsOpaque(matrix));
2068 }

References impeller::Color::CornflowerBlue(), impeller::Contents::IsOpaque(), impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Geometry::MakeStrokePath(), impeller::ConicalGradientContents::SetColors(), impeller::ColorSourceContents::SetGeometry(), and impeller::Color::WithAlpha().

◆ TEST_P() [409/549]

impeller::testing::TEST_P ( EntityTest  ,
ContentContextOptionsHasReasonableHashFunctions   
)

Definition at line 2228 of file entity_unittests.cc.

2228  {
2229  ContentContextOptions opts;
2230  auto hash_a = opts.ToKey();
2231 
2232  opts.blend_mode = BlendMode::kColorBurn;
2233  auto hash_b = opts.ToKey();
2234 
2235  opts.has_depth_stencil_attachments = false;
2236  auto hash_c = opts.ToKey();
2237 
2238  opts.primitive_type = PrimitiveType::kPoint;
2239  auto hash_d = opts.ToKey();
2240 
2241  EXPECT_NE(hash_a, hash_b);
2242  EXPECT_NE(hash_b, hash_c);
2243  EXPECT_NE(hash_c, hash_d);
2244 }

References impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::has_depth_stencil_attachments, impeller::kColorBurn, impeller::kPoint, impeller::ContentContextOptions::primitive_type, and impeller::ContentContextOptions::ToKey().

◆ TEST_P() [410/549]

impeller::testing::TEST_P ( EntityTest  ,
ContentsGetBoundsForEmptyPathReturnsNullopt   
)

Definition at line 1243 of file entity_unittests.cc.

1243  {
1244  Entity entity;
1245  entity.SetContents(std::make_shared<SolidColorContents>());
1246  ASSERT_FALSE(entity.GetCoverage().has_value());
1247 }

References impeller::Entity::GetCoverage(), and impeller::Entity::SetContents().

◆ TEST_P() [411/549]

impeller::testing::TEST_P ( EntityTest  ,
CoverageForStrokePathWithNegativeValuesInTransform   
)

Definition at line 2004 of file entity_unittests.cc.

2004  {
2005  auto arrow_head = flutter::DlPathBuilder{}
2006  .MoveTo({50, 120})
2007  .LineTo({120, 190})
2008  .LineTo({190, 120})
2009  .TakePath();
2010  auto geometry = Geometry::MakeStrokePath(arrow_head, //
2011  {
2012  .width = 15.0f,
2013  .cap = Cap::kRound,
2014  .join = Join::kRound,
2015  .miter_limit = 4.0f,
2016  });
2017 
2018  auto transform = Matrix::MakeTranslation({300, 300}) *
2019  Matrix::MakeRotationZ(Radians(kPiOver2));
2020  // Note that e[0][0] used to be tested here, but it was -epsilon solely
2021  // due to floating point inaccuracy in the transcendental trig functions.
2022  // e[1][0] is the intended negative value that we care about (-1.0) as it
2023  // comes from the rotation of pi/2.
2024  EXPECT_LT(transform.e[1][0], 0.0f);
2025  auto coverage = geometry->GetCoverage(transform);
2026  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
2027 }

References ASSERT_RECT_NEAR, impeller::kPiOver2, impeller::kRound, impeller::LineTo(), impeller::Matrix::MakeRotationZ(), impeller::Geometry::MakeStrokePath(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), and transform.

◆ TEST_P() [412/549]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveAndOverlapTest   
)

Definition at line 452 of file entity_unittests.cc.

452  {
453  // Compare with https://fiddle.skia.org/c/7a05a3e186c65a8dfb732f68020aae06
454  flutter::DlPath path =
455  flutter::DlPathBuilder{}
456  .MoveTo({359.934, 96.6335})
457  .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
458  {354.673, 96.8895})
459  .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
460  {354.367, 96.9075})
461  .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
462  {349.259, 97.2355})
463  .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
464  {348.625, 97.2834})
465  .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
466  {343.789, 97.6722})
467  .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
468  {342.703, 97.7734})
469  .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
470  {338.246, 98.207})
471  .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
472  {336.612, 98.3894})
473  .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
474  {332.623, 98.8476})
475  .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
476  {332.237, 98.8982})
477  .LineTo({332.237, 102.601})
478  .LineTo({321.778, 102.601})
479  .LineTo({321.778, 100.382})
480  .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
481  {321.161, 100.476})
482  .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
483  {315.332, 101.479})
484  .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
485  {315.301, 101.484})
486  .LineTo({310.017, 105.94})
487  .LineTo({309.779, 105.427})
488  .LineTo({314.403, 101.651})
489  .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
490  {314.368, 101.658})
491  .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
492  {308.846, 102.748})
493  .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
494  .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
495  {303.425, 103.936})
496  .LineTo({299.105, 107.578})
497  .LineTo({298.867, 107.065})
498  .LineTo({302.394, 104.185})
499  .LineTo({302.412, 104.171})
500  .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
501  {299.344, 104.921})
502  .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
503  .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
504  {291.462, 106.979})
505  .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
506  {290.471, 107.257})
507  .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
508  {287.449, 108.139})
509  .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
510  {284.536, 109.035})
511  .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
512  {281.952, 109.859})
513  .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
514  {279.633, 110.638})
515  .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
516  {276.803, 111.607})
517  .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
518  {276.672, 111.653})
519  .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
520  {271.721, 113.463})
521  .LineTo({271.717, 113.449})
522  .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
523  {270.963, 113.628})
524  .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
525  {270.748, 113.682})
526  .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
527  {269.839, 113.926})
528  .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
529  {269.681, 113.972})
530  .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
531  {268.756, 114.239})
532  .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
533  {268.367, 114.354})
534  .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
535  {267.752, 114.54})
536  .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
537  {253.564, 119.252})
538  .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
539  {253.538, 119.261})
540  .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
541  {248.189, 121.131})
542  .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
543  .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
544  {245.975, 121.912})
545  .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
546  {244.698, 122.364})
547  .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
548  {242.794, 123.04})
549  .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
550  {240.961, 123.693})
551  .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
552  {240.052, 124.018})
553  .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
554  .LineTo({237.164, 125.003})
555  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
556  {235.81, 125.538})
557  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
558  {234.592, 125.977})
559  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
560  {234.59, 125.977})
561  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
562  {192.381, 141.429})
563  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
564  .LineTo({360, 160})
565  .LineTo({360, 119.256})
566  .LineTo({360, 106.332})
567  .LineTo({360, 96.6307})
568  .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
569  {359.934, 96.6335})
570  .Close()
571  .MoveTo({337.336, 124.143})
572  .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
573  {338.903, 121.511})
574  .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
575  {337.336, 124.143})
576  .Close()
577  .MoveTo({340.082, 121.849})
578  .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
579  {340.046, 122.075})
580  .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
581  {340.023, 122.177})
582  .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
583  {339.952, 122.437})
584  .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
585  {339.918, 122.544})
586  .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
587  {339.75, 122.938})
588  .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
589  {339.74, 122.955})
590  .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
591  {339.501, 123.328})
592  .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
593  {339.41, 123.438})
594  .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
595  {339.145, 123.714})
596  .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
597  {339.025, 123.821})
598  .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
599  {338.539, 124.143})
600  .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
601  {338.58, 123.626})
602  .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
603  .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
604  {338.704, 123.151})
605  .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
606  {338.714, 123.117})
607  .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
608  {338.905, 122.712})
609  .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
610  {338.922, 122.682})
611  .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
612  {339.155, 122.34})
613  .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
614  {339.172, 122.319})
615  .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
616  {339.425, 122.037})
617  .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
618  {339.435, 122.027})
619  .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
620  {340.106, 121.511})
621  .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
622  {340.082, 121.849})
623  .Close()
624  .MoveTo({340.678, 113.245})
625  .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
626  {340.135, 113.775})
627  .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
628  {339.115, 114.151})
629  .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
630  {336.448, 114.516})
631  .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
632  {334.384, 114.513})
633  .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
634  {333.605, 114.424})
635  .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
636  {331.41, 113.883})
637  .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
638  {330.672, 112.813})
639  .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
640  {334.526, 113.833})
641  .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
642  .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
643  {332.76, 110.402})
644  .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
645  {335.228, 113.395})
646  .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
647  {335.661, 109.592})
648  .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
649  {336.07, 113.389})
650  .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
651  {338.563, 110.402})
652  .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
653  {336.753, 113.784})
654  .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
655  {336.796, 113.833})
656  .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
657  {340.65, 112.813})
658  .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
659  {340.678, 113.245})
660  .Close()
661  .MoveTo({346.357, 106.771})
662  .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
663  {347.924, 104.139})
664  .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
665  {346.357, 106.771})
666  .Close()
667  .MoveTo({347.56, 106.771})
668  .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
669  {349.127, 104.139})
670  .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
671  {347.56, 106.771})
672  .Close()
673  .TakePath();
674  Entity entity;
675  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
676 
677  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
678 
679  auto contents = std::make_shared<SolidColorContents>();
680  contents->SetColor(Color::Red());
681  contents->SetGeometry(geom.get());
682 
683  entity.SetContents(contents);
684  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
685 }

References impeller::Close(), impeller::LineTo(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [413/549]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveTest   
)

Definition at line 370 of file entity_unittests.cc.

370  {
371  // Compare with https://fiddle.skia.org/c/b3625f26122c9de7afe7794fcf25ead3
372  flutter::DlPath path =
373  flutter::DlPathBuilder{}
374  .MoveTo({237.164, 125.003})
375  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
376  {235.81, 125.538})
377  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
378  {234.592, 125.977})
379  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
380  {234.59, 125.977})
381  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
382  {192.381, 141.429})
383  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
384  .Close()
385  .TakePath();
386  Entity entity;
387  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
388 
389  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
390 
391  auto contents = std::make_shared<SolidColorContents>();
392  contents->SetColor(Color::Red());
393  contents->SetGeometry(geom.get());
394 
395  entity.SetContents(contents);
396  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
397 }

References impeller::Close(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [414/549]

impeller::testing::TEST_P ( EntityTest  ,
DecalSpecializationAppliedToMorphologyFilter   
)

Definition at line 2212 of file entity_unittests.cc.

2212  {
2213  auto content_context = GetContentContext();
2214  auto default_color_burn = content_context->GetMorphologyFilterPipeline({
2215  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2216  });
2217 
2218  auto decal_supported = static_cast<Scalar>(
2219  GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2220  std::vector<Scalar> expected_constants = {decal_supported};
2221  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2222  expected_constants);
2223 }

References impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [415/549]

impeller::testing::TEST_P ( EntityTest  ,
DrawRoundSuperEllipse   
)

Definition at line 2387 of file entity_unittests.cc.

2387  {
2388  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2389  // UI state.
2390  static int style_index = 0;
2391  static float center[2] = {830, 830};
2392  static float size[2] = {600, 600};
2393  static bool horizontal_symmetry = true;
2394  static bool vertical_symmetry = true;
2395  static bool corner_symmetry = true;
2396 
2397  const char* style_options[] = {"Fill", "Stroke"};
2398 
2399  // Initially radius_tl[0] will be mirrored to all 8 values since all 3
2400  // symmetries are enabled.
2401  static std::array<float, 2> radius_tl = {200};
2402  static std::array<float, 2> radius_tr;
2403  static std::array<float, 2> radius_bl;
2404  static std::array<float, 2> radius_br;
2405 
2406  auto AddRadiusControl = [](std::array<float, 2>& radii, const char* tb_name,
2407  const char* lr_name) {
2408  std::string name = "Radius";
2409  if (!horizontal_symmetry || !vertical_symmetry) {
2410  name += ":";
2411  }
2412  if (!vertical_symmetry) {
2413  name = name + " " + tb_name;
2414  }
2415  if (!horizontal_symmetry) {
2416  name = name + " " + lr_name;
2417  }
2418  if (corner_symmetry) {
2419  ImGui::SliderFloat(name.c_str(), radii.data(), 0, 1000);
2420  } else {
2421  ImGui::SliderFloat2(name.c_str(), radii.data(), 0, 1000);
2422  }
2423  };
2424 
2425  if (corner_symmetry) {
2426  radius_tl[1] = radius_tl[0];
2427  radius_tr[1] = radius_tr[0];
2428  radius_bl[1] = radius_bl[0];
2429  radius_br[1] = radius_br[0];
2430  }
2431 
2432  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
2433  {
2434  ImGui::Combo("Style", &style_index, style_options,
2435  sizeof(style_options) / sizeof(char*));
2436  ImGui::SliderFloat2("Center", center, 0, 1000);
2437  ImGui::SliderFloat2("Size", size, 0, 1000);
2438  ImGui::Checkbox("Symmetry: Horizontal", &horizontal_symmetry);
2439  ImGui::Checkbox("Symmetry: Vertical", &vertical_symmetry);
2440  ImGui::Checkbox("Symmetry: Corners", &corner_symmetry);
2441  AddRadiusControl(radius_tl, "Top", "Left");
2442  if (!horizontal_symmetry) {
2443  AddRadiusControl(radius_tr, "Top", "Right");
2444  } else {
2445  radius_tr = radius_tl;
2446  }
2447  if (!vertical_symmetry) {
2448  AddRadiusControl(radius_bl, "Bottom", "Left");
2449  } else {
2450  radius_bl = radius_tl;
2451  }
2452  if (!horizontal_symmetry && !vertical_symmetry) {
2453  AddRadiusControl(radius_br, "Bottom", "Right");
2454  } else {
2455  if (horizontal_symmetry) {
2456  radius_br = radius_bl;
2457  } else {
2458  radius_br = radius_tr;
2459  }
2460  }
2461  }
2462 
2463  ImGui::End();
2464 
2465  RoundingRadii radii{
2466  .top_left = {radius_tl[0], radius_tl[1]},
2467  .top_right = {radius_tr[0], radius_tr[1]},
2468  .bottom_left = {radius_bl[0], radius_bl[1]},
2469  .bottom_right = {radius_br[0], radius_br[1]},
2470  };
2471 
2472  auto rse = RoundSuperellipse::MakeRectRadii(
2473  RectMakeCenterSize({center[0], center[1]}, {size[0], size[1]}), radii);
2474 
2475  flutter::DlPath path;
2476  std::unique_ptr<Geometry> geom;
2477  if (style_index == 0) {
2478  geom = std::make_unique<RoundSuperellipseGeometry>(
2479  RectMakeCenterSize({center[0], center[1]}, {size[0], size[1]}),
2480  radii);
2481  } else {
2482  path = flutter::DlPath::MakeRoundSuperellipse(rse);
2483  geom = Geometry::MakeStrokePath(path, {.width = 2.0f});
2484  }
2485 
2486  auto contents = std::make_shared<SolidColorContents>();
2487  contents->SetColor(Color::Red());
2488  contents->SetGeometry(geom.get());
2489 
2490  Entity entity;
2491  entity.SetContents(contents);
2492 
2493  return entity.Render(context, pass);
2494  };
2495 
2496  ASSERT_TRUE(OpenPlaygroundHere(callback));
2497 }
Rect RectMakeCenterSize(Point center, Size size)

References impeller::RoundSuperellipse::MakeRectRadii(), impeller::Geometry::MakeStrokePath(), RectMakeCenterSize(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::RoundingRadii::top_left.

◆ TEST_P() [416/549]

impeller::testing::TEST_P ( EntityTest  ,
DrawSuperEllipse   
)

Definition at line 2354 of file entity_unittests.cc.

2354  {
2355  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2356  // UI state.
2357  static float alpha = 10;
2358  static float beta = 10;
2359  static float radius = 40;
2360  static int degree = 4;
2361  static Color color = Color::Red();
2362 
2363  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
2364  ImGui::SliderFloat("Alpha", &alpha, 0, 100);
2365  ImGui::SliderFloat("Beta", &beta, 0, 100);
2366  ImGui::SliderInt("Degreee", &degree, 1, 20);
2367  ImGui::SliderFloat("Radius", &radius, 0, 400);
2368  ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
2369  ImGui::End();
2370 
2371  auto contents = std::make_shared<SolidColorContents>();
2372  std::unique_ptr<SuperellipseGeometry> geom =
2373  std::make_unique<SuperellipseGeometry>(Point{400, 400}, radius, degree,
2374  alpha, beta);
2375  contents->SetColor(color);
2376  contents->SetGeometry(geom.get());
2377 
2378  Entity entity;
2379  entity.SetContents(contents);
2380 
2381  return entity.Render(context, pass);
2382  };
2383 
2384  ASSERT_TRUE(OpenPlaygroundHere(callback));
2385 }

References impeller::Color::Red(), impeller::Entity::Render(), and impeller::Entity::SetContents().

◆ TEST_P() [417/549]

impeller::testing::TEST_P ( EntityTest  ,
FailOnValidationError   
)

Definition at line 2303 of file entity_unittests.cc.

2303  {
2304  if (GetParam() != PlaygroundBackend::kVulkan) {
2305  GTEST_SKIP() << "Validation is only fatal on Vulkan backend.";
2306  }
2307  EXPECT_DEATH(
2308  // The easiest way to trigger a validation error is to try to compile
2309  // a shader with an unsupported pixel format.
2310  GetContentContext()->GetBlendColorBurnPipeline({
2311  .color_attachment_pixel_format = PixelFormat::kUnknown,
2312  .has_depth_stencil_attachments = false,
2313  }),
2314  "");
2315 }

References impeller::kUnknown, and impeller::kVulkan.

◆ TEST_P() [418/549]

impeller::testing::TEST_P ( EntityTest  ,
FillPathGeometryGetPositionBufferReturnsExpectedMode   
)

Definition at line 2272 of file entity_unittests.cc.

2272  {
2273  RenderTarget target;
2274  testing::MockRenderPass mock_pass(GetContext(), target);
2275 
2276  auto get_result = [this, &mock_pass](const flutter::DlPath& path) {
2277  auto geometry = Geometry::MakeFillPath(
2278  path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
2279  return geometry->GetPositionBuffer(*GetContentContext(), {}, mock_pass);
2280  };
2281 
2282  // Convex path
2283  {
2284  GeometryResult result =
2285  get_result(flutter::DlPath::MakeRect(Rect::MakeLTRB(0, 0, 100, 100)));
2286  EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
2287  }
2288 
2289  // Concave path
2290  {
2291  flutter::DlPath path = flutter::DlPathBuilder{}
2292  .MoveTo({0, 0})
2293  .LineTo({100, 0})
2294  .LineTo({100, 100})
2295  .LineTo({51, 50})
2296  .Close()
2297  .TakePath();
2298  GeometryResult result = get_result(path);
2299  EXPECT_EQ(result.mode, GeometryResult::Mode::kNonZero);
2300  }
2301 }

References impeller::Close(), impeller::GeometryResult::kNonZero, impeller::GeometryResult::kNormal, impeller::LineTo(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::GeometryResult::mode.

◆ TEST_P() [419/549]

impeller::testing::TEST_P ( EntityTest  ,
FilterCoverageRespectsCropRect   
)

Definition at line 77 of file entity_unittests.cc.

77  {
78  auto image = CreateTextureForFixture("boston.jpg");
79  auto filter = ColorFilterContents::MakeBlend(BlendMode::kSoftLight,
80  FilterInput::Make({image}));
81 
82  // Without the crop rect (default behavior).
83  {
84  auto actual = filter->GetCoverage({});
85  auto expected = Rect::MakeSize(image->GetSize());
86 
87  ASSERT_TRUE(actual.has_value());
88  ASSERT_RECT_NEAR(actual.value(), expected);
89  }
90 
91  // With the crop rect.
92  {
93  auto expected = Rect::MakeLTRB(50, 50, 100, 100);
94  filter->SetCoverageHint(expected);
95  auto actual = filter->GetCoverage({});
96 
97  ASSERT_TRUE(actual.has_value());
98  ASSERT_RECT_NEAR(actual.value(), expected);
99  }
100 }

References ASSERT_RECT_NEAR, impeller::kSoftLight, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [420/549]

impeller::testing::TEST_P ( EntityTest  ,
Filters   
)

Definition at line 920 of file entity_unittests.cc.

920  {
921  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
922  auto boston = CreateTextureForFixture("boston.jpg");
923  auto kalimba = CreateTextureForFixture("kalimba.jpg");
924  ASSERT_TRUE(bridge && boston && kalimba);
925 
926  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
927  auto fi_bridge = FilterInput::Make(bridge);
928  auto fi_boston = FilterInput::Make(boston);
929  auto fi_kalimba = FilterInput::Make(kalimba);
930 
931  std::shared_ptr<FilterContents> blend0 = ColorFilterContents::MakeBlend(
932  BlendMode::kModulate, {fi_kalimba, fi_boston});
933 
934  auto blend1 = ColorFilterContents::MakeBlend(
935  BlendMode::kScreen,
936  {FilterInput::Make(blend0), fi_bridge, fi_bridge, fi_bridge});
937 
938  Entity entity;
939  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
940  Matrix::MakeTranslation({500, 300}) *
941  Matrix::MakeScale(Vector2{0.5, 0.5}));
942  entity.SetContents(blend1);
943  return entity.Render(context, pass);
944  };
945  ASSERT_TRUE(OpenPlaygroundHere(callback));
946 }

References impeller::kModulate, impeller::kScreen, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [421/549]

impeller::testing::TEST_P ( EntityTest  ,
GaussianBlurFilter   
)

Definition at line 948 of file entity_unittests.cc.

948  {
949  auto boston =
950  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
951  ASSERT_TRUE(boston);
952 
953  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
954  const char* input_type_names[] = {"Texture", "Solid Color"};
955  const char* blur_type_names[] = {"Image blur", "Mask blur"};
956  const char* pass_variation_names[] = {"New"};
957  const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
958  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
959  const FilterContents::BlurStyle blur_styles[] = {
960  FilterContents::BlurStyle::kNormal, FilterContents::BlurStyle::kSolid,
961  FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};
962  const Entity::TileMode tile_modes[] = {
963  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
964  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
965 
966  // UI state.
967  static int selected_input_type = 0;
968  static Color input_color = Color::Black();
969  static int selected_blur_type = 0;
970  static int selected_pass_variation = 0;
971  static bool combined_sigma = false;
972  static float blur_amount_coarse[2] = {0, 0};
973  static float blur_amount_fine[2] = {10, 10};
974  static int selected_blur_style = 0;
975  static int selected_tile_mode = 3;
976  static Color cover_color(1, 0, 0, 0.2);
977  static Color bounds_color(0, 1, 0, 0.1);
978  static float offset[2] = {500, 400};
979  static float rotation = 0;
980  static float scale[2] = {0.65, 0.65};
981  static float skew[2] = {0, 0};
982  static float path_rect[4] = {0, 0,
983  static_cast<float>(boston->GetSize().width),
984  static_cast<float>(boston->GetSize().height)};
985 
986  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
987  {
988  ImGui::Combo("Input type", &selected_input_type, input_type_names,
989  sizeof(input_type_names) / sizeof(char*));
990  if (selected_input_type == 0) {
991  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
992  } else {
993  ImGui::ColorEdit4("Input color",
994  reinterpret_cast<float*>(&input_color));
995  }
996  ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
997  sizeof(blur_type_names) / sizeof(char*));
998  if (selected_blur_type == 0) {
999  ImGui::Combo("Pass variation", &selected_pass_variation,
1000  pass_variation_names,
1001  sizeof(pass_variation_names) / sizeof(char*));
1002  }
1003  ImGui::Checkbox("Combined sigma", &combined_sigma);
1004  if (combined_sigma) {
1005  ImGui::SliderFloat("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1006  ImGui::SliderFloat("Sigma (fine)", blur_amount_fine, 0, 10);
1007  blur_amount_coarse[1] = blur_amount_coarse[0];
1008  blur_amount_fine[1] = blur_amount_fine[0];
1009  } else {
1010  ImGui::SliderFloat2("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1011  ImGui::SliderFloat2("Sigma (fine)", blur_amount_fine, 0, 10);
1012  }
1013  ImGui::Combo("Blur style", &selected_blur_style, blur_style_names,
1014  sizeof(blur_style_names) / sizeof(char*));
1015  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1016  sizeof(tile_mode_names) / sizeof(char*));
1017  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1018  ImGui::ColorEdit4("Bounds color ",
1019  reinterpret_cast<float*>(&bounds_color));
1020  ImGui::SliderFloat2("Translation", offset, 0,
1021  pass.GetRenderTargetSize().width);
1022  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1023  ImGui::SliderFloat2("Scale", scale, 0, 3);
1024  ImGui::SliderFloat2("Skew", skew, -3, 3);
1025  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1026  }
1027  ImGui::End();
1028 
1029  auto blur_sigma_x = Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
1030  auto blur_sigma_y = Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
1031 
1032  std::shared_ptr<Contents> input;
1033  Size input_size;
1034 
1035  auto input_rect =
1036  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1037 
1038  std::unique_ptr<Geometry> solid_color_input;
1039  if (selected_input_type == 0) {
1040  auto texture = std::make_shared<TextureContents>();
1041  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1042  texture->SetDestinationRect(input_rect);
1043  texture->SetTexture(boston);
1044  texture->SetOpacity(input_color.alpha);
1045 
1046  input = texture;
1047  input_size = input_rect.GetSize();
1048  } else {
1049  auto fill = std::make_shared<SolidColorContents>();
1050  fill->SetColor(input_color);
1051  solid_color_input =
1052  Geometry::MakeFillPath(flutter::DlPath::MakeRect(input_rect));
1053 
1054  fill->SetGeometry(solid_color_input.get());
1055 
1056  input = fill;
1057  input_size = input_rect.GetSize();
1058  }
1059 
1060  std::shared_ptr<FilterContents> blur;
1061  switch (selected_pass_variation) {
1062  case 0:
1063  blur = std::make_shared<GaussianBlurFilterContents>(
1064  blur_sigma_x.sigma, blur_sigma_y.sigma,
1065  tile_modes[selected_tile_mode], blur_styles[selected_blur_style],
1066  /*geometry=*/nullptr);
1067  blur->SetInputs({FilterInput::Make(input)});
1068  break;
1069  case 1:
1070  blur = FilterContents::MakeGaussianBlur(
1071  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1072  tile_modes[selected_tile_mode], blur_styles[selected_blur_style]);
1073  break;
1074  };
1075  FML_CHECK(blur);
1076 
1077  auto mask_blur = FilterContents::MakeBorderMaskBlur(
1078  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1079  blur_styles[selected_blur_style]);
1080 
1081  auto ctm = Matrix::MakeScale(GetContentScale()) *
1082  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1083  Matrix::MakeRotationZ(Radians(rotation)) *
1084  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1085  Matrix::MakeSkew(skew[0], skew[1]) *
1086  Matrix::MakeTranslation(-Point(input_size) / 2);
1087 
1088  auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1089 
1090  Entity entity;
1091  entity.SetContents(target_contents);
1092  entity.SetTransform(ctm);
1093 
1094  entity.Render(context, pass);
1095 
1096  // Renders a red "cover" rectangle that shows the original position of the
1097  // unfiltered input.
1098  Entity cover_entity;
1099  std::unique_ptr<Geometry> geom =
1100  Geometry::MakeFillPath(flutter::DlPath::MakeRect(input_rect));
1101  auto contents = std::make_shared<SolidColorContents>();
1102  contents->SetColor(cover_color);
1103  contents->SetGeometry(geom.get());
1104  cover_entity.SetContents(std::move(contents));
1105  cover_entity.SetTransform(ctm);
1106  cover_entity.Render(context, pass);
1107 
1108  // Renders a green bounding rect of the target filter.
1109  Entity bounds_entity;
1110  std::optional<Rect> target_contents_coverage =
1111  target_contents->GetCoverage(entity);
1112  if (target_contents_coverage.has_value()) {
1113  std::unique_ptr<Geometry> geom =
1114  Geometry::MakeFillPath(flutter::DlPath::MakeRect(
1115  target_contents->GetCoverage(entity).value()));
1116  auto contents = std::make_shared<SolidColorContents>();
1117  contents->SetColor(bounds_color);
1118  contents->SetGeometry(geom.get());
1119 
1120  bounds_entity.SetContents(contents);
1121  bounds_entity.SetTransform(Matrix());
1122  bounds_entity.Render(context, pass);
1123  }
1124 
1125  return true;
1126  };
1127  ASSERT_TRUE(OpenPlaygroundHere(callback));
1128 }

References impeller::Color::alpha, impeller::Color::Black(), impeller::Entity::GetCoverage(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::FilterContents::kInner, impeller::Entity::kMirror, impeller::FilterContents::kNormal, impeller::FilterContents::kOuter, impeller::kPi, impeller::Entity::kRepeat, impeller::FilterContents::kSolid, impeller::FilterInput::Make(), impeller::FilterContents::MakeBorderMaskBlur(), impeller::Geometry::MakeFillPath(), impeller::FilterContents::MakeGaussianBlur(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [422/549]

impeller::testing::TEST_P ( EntityTest  ,
GeometryBoundsAreTransformed   
)

Definition at line 102 of file entity_unittests.cc.

102  {
103  auto geometry = Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100));
104  auto transform = Matrix::MakeScale({2.0, 2.0, 2.0});
105 
106  ASSERT_RECT_NEAR(geometry->GetCoverage(transform).value(),
107  Rect::MakeXYWH(200, 200, 200, 200));
108 }

References ASSERT_RECT_NEAR, impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), and transform.

◆ TEST_P() [423/549]

impeller::testing::TEST_P ( EntityTest  ,
GiantStrokePathAllocation   
)

Definition at line 2529 of file entity_unittests.cc.

2529  {
2530  flutter::DlPathBuilder builder;
2531  for (int i = 0; i < 10000; i++) {
2532  builder.LineTo(Point(i, i));
2533  }
2534  flutter::DlPath path = builder.TakePath();
2535  auto geom = Geometry::MakeStrokePath(path, {.width = 10.0f});
2536 
2537  ContentContext content_context(GetContext(), /*typographer_context=*/nullptr);
2538  Entity entity;
2539 
2540  auto cmd_buffer = content_context.GetContext()->CreateCommandBuffer();
2541 
2542  RenderTargetAllocator allocator(
2543  content_context.GetContext()->GetResourceAllocator());
2544 
2545  auto render_target = allocator.CreateOffscreen(
2546  *content_context.GetContext(), /*size=*/{10, 10}, /*mip_count=*/1);
2547  auto pass = cmd_buffer->CreateRenderPass(render_target);
2548 
2549  GeometryResult result =
2550  geom->GetPositionBuffer(content_context, entity, *pass);
2551 
2552  // Validate the buffer data overflowed the small buffer
2553  EXPECT_GT(result.vertex_buffer.vertex_count, kPointArenaSize);
2554 
2555  // Validate that there are no uninitialized points near the gap.
2556  Point* written_data = reinterpret_cast<Point*>(
2557  (result.vertex_buffer.vertex_buffer.GetBuffer()->OnGetContents() +
2558  result.vertex_buffer.vertex_buffer.GetRange().offset));
2559 
2560  std::vector<Point> expected = {
2561  Point(2043.46, 2050.54), //
2562  Point(2050.54, 2043.46), //
2563  Point(2044.46, 2051.54), //
2564  Point(2051.54, 2044.46), //
2565  Point(2045.46, 2052.54) //
2566  };
2567 
2568  Point point = written_data[kPointArenaSize - 2];
2569  EXPECT_NEAR(point.x, expected[0].x, 0.1);
2570  EXPECT_NEAR(point.y, expected[0].y, 0.1);
2571 
2572  point = written_data[kPointArenaSize - 1];
2573  EXPECT_NEAR(point.x, expected[1].x, 0.1);
2574  EXPECT_NEAR(point.y, expected[1].y, 0.1);
2575 
2576  point = written_data[kPointArenaSize];
2577  EXPECT_NEAR(point.x, expected[2].x, 0.1);
2578  EXPECT_NEAR(point.y, expected[2].y, 0.1);
2579 
2580  point = written_data[kPointArenaSize + 1];
2581  EXPECT_NEAR(point.x, expected[3].x, 0.1);
2582  EXPECT_NEAR(point.y, expected[3].y, 0.1);
2583 
2584  point = written_data[kPointArenaSize + 2];
2585  EXPECT_NEAR(point.x, expected[4].x, 0.1);
2586  EXPECT_NEAR(point.y, expected[4].y, 0.1);
2587 }
static constexpr size_t kPointArenaSize
The size of the point arena buffer stored on the tessellator.
Definition: tessellator.h:25

References impeller::RenderTargetAllocator::CreateOffscreen(), impeller::BufferView::GetBuffer(), impeller::BufferView::GetRange(), impeller::kPointArenaSize, impeller::Geometry::MakeStrokePath(), impeller::Range::offset, impeller::DeviceBuffer::OnGetContents(), impeller::VertexBuffer::vertex_buffer, impeller::GeometryResult::vertex_buffer, impeller::VertexBuffer::vertex_count, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [424/549]

impeller::testing::TEST_P ( EntityTest  ,
LinearGradientContentsIsOpaque   
)

Definition at line 2070 of file entity_unittests.cc.

2070  {
2071  Matrix matrix;
2072  LinearGradientContents contents;
2073  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2074  contents.SetGeometry(geom.get());
2075 
2076  contents.SetColors({Color::CornflowerBlue()});
2077  EXPECT_TRUE(contents.IsOpaque(matrix));
2078  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2079  EXPECT_FALSE(contents.IsOpaque(matrix));
2080  contents.SetColors({Color::CornflowerBlue()});
2081  contents.SetTileMode(Entity::TileMode::kDecal);
2082  EXPECT_FALSE(contents.IsOpaque(matrix));
2083 
2084  // Create stroked path that required alpha coverage.
2085  geom = Geometry::MakeStrokePath(
2086  flutter::DlPathBuilder{}.MoveTo({0, 0}).LineTo({100, 100}).TakePath(),
2087  {.width = 0.05f});
2088  contents.SetGeometry(geom.get());
2089  contents.SetColors({Color::CornflowerBlue()});
2090 
2091  EXPECT_FALSE(contents.IsOpaque(matrix));
2092 }

References impeller::Color::CornflowerBlue(), impeller::LinearGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Geometry::MakeStrokePath(), impeller::LinearGradientContents::SetColors(), impeller::ColorSourceContents::SetGeometry(), impeller::LinearGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [425/549]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilter   
)

Definition at line 1557 of file entity_unittests.cc.

1557  {
1558  auto image = CreateTextureForFixture("kalimba.jpg");
1559  ASSERT_TRUE(image);
1560 
1561  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1562  auto filtered =
1563  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));
1564 
1565  // Define the entity that will serve as the control image as a Gaussian blur
1566  // filter with no filter at all.
1567  Entity entity_left;
1568  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1569  Matrix::MakeTranslation({100, 300}) *
1570  Matrix::MakeScale(Vector2{0.5, 0.5}));
1571  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1572  Sigma{0}, Sigma{0});
1573  entity_left.SetContents(unfiltered);
1574 
1575  // Define the entity that will be filtered from linear to sRGB.
1576  Entity entity_right;
1577  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1578  Matrix::MakeTranslation({500, 300}) *
1579  Matrix::MakeScale(Vector2{0.5, 0.5}));
1580  entity_right.SetContents(filtered);
1581  return entity_left.Render(context, pass) &&
1582  entity_right.Render(context, pass);
1583  };
1584 
1585  ASSERT_TRUE(OpenPlaygroundHere(callback));
1586 }

References impeller::FilterInput::Make(), impeller::FilterContents::MakeGaussianBlur(), impeller::ColorFilterContents::MakeLinearToSrgbFilter(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [426/549]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilterCoverageIsCorrect   
)

Definition at line 1535 of file entity_unittests.cc.

1535  {
1536  // Set up a simple color background.
1537  auto geom = Geometry::MakeFillPath(
1538  flutter::DlPath::MakeRect(Rect::MakeXYWH(0, 0, 300, 400)));
1539  auto fill = std::make_shared<SolidColorContents>();
1540  fill->SetGeometry(geom.get());
1541  fill->SetColor(Color::MintCream());
1542 
1543  auto filter =
1544  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));
1545 
1546  Entity e;
1547  e.SetTransform(Matrix());
1548 
1549  // Confirm that the actual filter coverage matches the expected coverage.
1550  auto actual = filter->GetCoverage(e);
1551  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1552 
1553  ASSERT_TRUE(actual.has_value());
1554  ASSERT_RECT_NEAR(actual.value(), expected);
1555 }

References ASSERT_RECT_NEAR, impeller::FilterInput::Make(), impeller::Geometry::MakeFillPath(), impeller::ColorFilterContents::MakeLinearToSrgbFilter(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::MintCream(), and impeller::Entity::SetTransform().

◆ TEST_P() [427/549]

impeller::testing::TEST_P ( EntityTest  ,
MorphologyFilter   
)

Definition at line 1130 of file entity_unittests.cc.

1130  {
1131  auto boston = CreateTextureForFixture("boston.jpg");
1132  ASSERT_TRUE(boston);
1133 
1134  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1135  const char* morphology_type_names[] = {"Dilate", "Erode"};
1136  const FilterContents::MorphType morphology_types[] = {
1137  FilterContents::MorphType::kDilate, FilterContents::MorphType::kErode};
1138  static Color input_color = Color::Black();
1139  // UI state.
1140  static int selected_morphology_type = 0;
1141  static float radius[2] = {20, 20};
1142  static Color cover_color(1, 0, 0, 0.2);
1143  static Color bounds_color(0, 1, 0, 0.1);
1144  static float offset[2] = {500, 400};
1145  static float rotation = 0;
1146  static float scale[2] = {0.65, 0.65};
1147  static float skew[2] = {0, 0};
1148  static float path_rect[4] = {0, 0,
1149  static_cast<float>(boston->GetSize().width),
1150  static_cast<float>(boston->GetSize().height)};
1151  static float effect_transform_scale = 1;
1152 
1153  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1154  {
1155  ImGui::Combo("Morphology type", &selected_morphology_type,
1156  morphology_type_names,
1157  sizeof(morphology_type_names) / sizeof(char*));
1158  ImGui::SliderFloat2("Radius", radius, 0, 200);
1159  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1160  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1161  ImGui::ColorEdit4("Bounds color ",
1162  reinterpret_cast<float*>(&bounds_color));
1163  ImGui::SliderFloat2("Translation", offset, 0,
1164  pass.GetRenderTargetSize().width);
1165  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1166  ImGui::SliderFloat2("Scale", scale, 0, 3);
1167  ImGui::SliderFloat2("Skew", skew, -3, 3);
1168  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1169  ImGui::SliderFloat("Effect transform scale", &effect_transform_scale, 0,
1170  3);
1171  }
1172  ImGui::End();
1173 
1174  std::shared_ptr<Contents> input;
1175  Size input_size;
1176 
1177  auto input_rect =
1178  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1179  auto texture = std::make_shared<TextureContents>();
1180  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1181  texture->SetDestinationRect(input_rect);
1182  texture->SetTexture(boston);
1183  texture->SetOpacity(input_color.alpha);
1184 
1185  input = texture;
1186  input_size = input_rect.GetSize();
1187 
1188  auto contents = FilterContents::MakeMorphology(
1189  FilterInput::Make(input), Radius{radius[0]}, Radius{radius[1]},
1190  morphology_types[selected_morphology_type]);
1191  contents->SetEffectTransform(Matrix::MakeScale(
1192  Vector2{effect_transform_scale, effect_transform_scale}));
1193 
1194  auto ctm = Matrix::MakeScale(GetContentScale()) *
1195  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1196  Matrix::MakeRotationZ(Radians(rotation)) *
1197  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1198  Matrix::MakeSkew(skew[0], skew[1]) *
1199  Matrix::MakeTranslation(-Point(input_size) / 2);
1200 
1201  Entity entity;
1202  entity.SetContents(contents);
1203  entity.SetTransform(ctm);
1204 
1205  entity.Render(context, pass);
1206 
1207  // Renders a red "cover" rectangle that shows the original position of the
1208  // unfiltered input.
1209  Entity cover_entity;
1210  std::unique_ptr<Geometry> geom =
1211  Geometry::MakeFillPath(flutter::DlPath::MakeRect(input_rect));
1212  auto cover_contents = std::make_shared<SolidColorContents>();
1213  cover_contents->SetColor(cover_color);
1214  cover_contents->SetGeometry(geom.get());
1215  cover_entity.SetContents(cover_contents);
1216  cover_entity.SetTransform(ctm);
1217  cover_entity.Render(context, pass);
1218 
1219  // Renders a green bounding rect of the target filter.
1220  Entity bounds_entity;
1221  std::unique_ptr<Geometry> bounds_geom = Geometry::MakeFillPath(
1222  flutter::DlPath::MakeRect(contents->GetCoverage(entity).value()));
1223  auto bounds_contents = std::make_shared<SolidColorContents>();
1224  bounds_contents->SetColor(bounds_color);
1225  bounds_contents->SetGeometry(bounds_geom.get());
1226  bounds_entity.SetContents(std::move(bounds_contents));
1227  bounds_entity.SetTransform(Matrix());
1228 
1229  bounds_entity.Render(context, pass);
1230 
1231  return true;
1232  };
1233  ASSERT_TRUE(OpenPlaygroundHere(callback));
1234 }

References impeller::Color::alpha, impeller::Color::Black(), impeller::FilterContents::kDilate, impeller::FilterContents::kErode, impeller::kPi, impeller::FilterInput::Make(), impeller::Geometry::MakeFillPath(), impeller::FilterContents::MakeMorphology(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [428/549]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryCoverage   
)

Definition at line 2153 of file entity_unittests.cc.

2153  {
2154  std::vector<Point> points = {{10, 20}, {100, 200}};
2155  PointFieldGeometry geometry(points.data(), 2, 5.0, false);
2156  ASSERT_EQ(geometry.GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2157  ASSERT_EQ(geometry.GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2158  Rect::MakeLTRB(35, 15, 135, 205));
2159 }

References impeller::PointFieldGeometry::GetCoverage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), and points.

◆ TEST_P() [429/549]

impeller::testing::TEST_P ( EntityTest  ,
RadialGradientContentsIsOpaque   
)

Definition at line 2094 of file entity_unittests.cc.

2094  {
2095  Matrix matrix;
2096  RadialGradientContents contents;
2097  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2098  contents.SetGeometry(geom.get());
2099 
2100  contents.SetColors({Color::CornflowerBlue()});
2101  EXPECT_TRUE(contents.IsOpaque(matrix));
2102  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2103  EXPECT_FALSE(contents.IsOpaque(matrix));
2104  contents.SetColors({Color::CornflowerBlue()});
2105  contents.SetTileMode(Entity::TileMode::kDecal);
2106  EXPECT_FALSE(contents.IsOpaque(matrix));
2107 
2108  // Create stroked path that required alpha coverage.
2109  geom = Geometry::MakeStrokePath(
2110  flutter::DlPathBuilder{}.MoveTo({0, 0}).LineTo({100, 100}).TakePath(),
2111  {.width = 0.05});
2112  contents.SetGeometry(geom.get());
2113  contents.SetColors({Color::CornflowerBlue()});
2114 
2115  EXPECT_FALSE(contents.IsOpaque(matrix));
2116 }

References impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Geometry::MakeStrokePath(), impeller::RadialGradientContents::SetColors(), impeller::ColorSourceContents::SetGeometry(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [430/549]

impeller::testing::TEST_P ( EntityTest  ,
RoundSuperellipseGetPositionBufferFlushes   
)

Definition at line 2650 of file entity_unittests.cc.

2650  {
2651  RenderTarget target;
2652  testing::MockRenderPass mock_pass(GetContext(), target);
2653 
2654  auto content_context = std::make_shared<FlushTestContentContext>(
2655  GetContext(), GetTypographerContext(),
2656  std::make_shared<FlushTestAllocator>());
2657  auto geometry =
2658  Geometry::MakeRoundSuperellipse(Rect::MakeLTRB(0, 0, 100, 100), 5);
2659  auto result = geometry->GetPositionBuffer(*content_context, {}, mock_pass);
2660 
2661  auto device_buffer = reinterpret_cast<const FlushTestDeviceBuffer*>(
2662  result.vertex_buffer.vertex_buffer.GetBuffer());
2663  EXPECT_TRUE(device_buffer->flush_called());
2664 }

References impeller::TRect< Scalar >::MakeLTRB(), and impeller::Geometry::MakeRoundSuperellipse().

◆ TEST_P() [431/549]

impeller::testing::TEST_P ( EntityTest  ,
RRectShadowTest   
)

Definition at line 1393 of file entity_unittests.cc.

1393  {
1394  auto callback = [&](ContentContext& context, RenderPass& pass) {
1395  static Color color = Color::Red();
1396  static float corner_radius = 100;
1397  static float blur_radius = 100;
1398  static bool show_coverage = false;
1399  static Color coverage_color = Color::Green().WithAlpha(0.2);
1400  static PlaygroundPoint top_left_point(Point(200, 200), 30, Color::White());
1401  static PlaygroundPoint bottom_right_point(Point(600, 400), 30,
1402  Color::White());
1403 
1404  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1405  ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
1406  ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
1407  ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
1408  ImGui::Checkbox("Show coverage", &show_coverage);
1409  if (show_coverage) {
1410  ImGui::ColorEdit4("Coverage color",
1411  reinterpret_cast<Scalar*>(&coverage_color));
1412  }
1413  ImGui::End();
1414 
1415  auto [top_left, bottom_right] =
1416  DrawPlaygroundLine(top_left_point, bottom_right_point);
1417  auto rect =
1418  Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1419 
1420  auto contents = std::make_unique<SolidRRectBlurContents>();
1421  contents->SetShape(rect, corner_radius);
1422  contents->SetColor(color);
1423  contents->SetSigma(Radius(blur_radius));
1424 
1425  Entity entity;
1426  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
1427  entity.SetContents(std::move(contents));
1428  entity.Render(context, pass);
1429 
1430  auto coverage = entity.GetCoverage();
1431  if (show_coverage && coverage.has_value()) {
1432  auto bounds_contents = std::make_unique<SolidColorContents>();
1433  auto geom = Geometry::MakeFillPath(
1434  flutter::DlPath::MakeRect(entity.GetCoverage().value()));
1435  bounds_contents->SetGeometry(geom.get());
1436  bounds_contents->SetColor(coverage_color.Premultiply());
1437  Entity bounds_entity;
1438  bounds_entity.SetContents(std::move(bounds_contents));
1439  bounds_entity.Render(context, pass);
1440  }
1441 
1442  return true;
1443  };
1444  ASSERT_TRUE(OpenPlaygroundHere(callback));
1445 }

References blur_radius, impeller::DrawPlaygroundLine(), impeller::Entity::GetCoverage(), impeller::Color::Green(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Premultiply(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [432/549]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffect   
)

Definition at line 1753 of file entity_unittests.cc.

1753  {
1754  auto runtime_stages =
1755  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1756  auto runtime_stage =
1757  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1758  ASSERT_TRUE(runtime_stage);
1759  ASSERT_TRUE(runtime_stage->IsDirty());
1760 
1761  bool expect_dirty = true;
1762 
1763  PipelineRef first_pipeline;
1764  std::unique_ptr<Geometry> geom = Geometry::MakeCover();
1765 
1766  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1767  EXPECT_EQ(runtime_stage->IsDirty(), expect_dirty);
1768 
1769  auto contents = std::make_shared<RuntimeEffectContents>();
1770  contents->SetGeometry(geom.get());
1771  contents->SetRuntimeStage(runtime_stage);
1772 
1773  struct FragUniforms {
1774  Vector2 iResolution;
1775  Scalar iTime;
1776  } frag_uniforms = {
1777  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1778  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1779  };
1780  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1781  uniform_data->resize(sizeof(FragUniforms));
1782  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1783  contents->SetUniformData(uniform_data);
1784 
1785  Entity entity;
1786  entity.SetContents(contents);
1787  bool result = contents->Render(context, entity, pass);
1788 
1789  if (expect_dirty) {
1790  first_pipeline = pass.GetCommands().back().pipeline;
1791  } else {
1792  EXPECT_EQ(pass.GetCommands().back().pipeline, first_pipeline);
1793  }
1794  expect_dirty = false;
1795  return result;
1796  };
1797 
1798  // Simulate some renders and hot reloading of the shader.
1799  auto content_context = GetContentContext();
1800  {
1801  RenderTarget target =
1802  content_context->GetRenderTargetCache()->CreateOffscreen(
1803  *content_context->GetContext(), {1, 1}, 1u);
1804 
1805  testing::MockRenderPass mock_pass(GetContext(), target);
1806  callback(*content_context, mock_pass);
1807  callback(*content_context, mock_pass);
1808 
1809  // Dirty the runtime stage.
1810  runtime_stages = OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1811  runtime_stage =
1812  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1813 
1814  ASSERT_TRUE(runtime_stage->IsDirty());
1815  expect_dirty = true;
1816 
1817  callback(*content_context, mock_pass);
1818  }
1819 }
raw_ptr< Pipeline< PipelineDescriptor > > PipelineRef
A raw ptr to a pipeline object.
Definition: pipeline.h:88

References impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [433/549]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanPrecache   
)

Definition at line 1868 of file entity_unittests.cc.

1868  {
1869  auto runtime_stages =
1870  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1871  auto runtime_stage =
1872  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1873  ASSERT_TRUE(runtime_stage);
1874  ASSERT_TRUE(runtime_stage->IsDirty());
1875 
1876  auto contents = std::make_shared<RuntimeEffectContents>();
1877  contents->SetRuntimeStage(runtime_stage);
1878 
1879  EXPECT_TRUE(contents->BootstrapShader(*GetContentContext()));
1880 }

References impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [434/549]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanSuccessfullyRender   
)

Definition at line 1821 of file entity_unittests.cc.

1821  {
1822  auto runtime_stages =
1823  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1824  auto runtime_stage =
1825  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1826  ASSERT_TRUE(runtime_stage);
1827  ASSERT_TRUE(runtime_stage->IsDirty());
1828 
1829  auto contents = std::make_shared<RuntimeEffectContents>();
1830  auto geom = Geometry::MakeCover();
1831  contents->SetGeometry(geom.get());
1832  contents->SetRuntimeStage(runtime_stage);
1833 
1834  struct FragUniforms {
1835  Vector2 iResolution;
1836  Scalar iTime;
1837  } frag_uniforms = {
1838  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1839  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1840  };
1841  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1842  uniform_data->resize(sizeof(FragUniforms));
1843  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1844  contents->SetUniformData(uniform_data);
1845 
1846  Entity entity;
1847  entity.SetContents(contents);
1848 
1849  // Create a render target with a depth-stencil, similar to how EntityPass
1850  // does.
1851  RenderTarget target =
1852  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
1853  *GetContext(), {GetWindowSize().width, GetWindowSize().height}, 1,
1854  "RuntimeEffect Texture");
1855  testing::MockRenderPass pass(GetContext(), target);
1856 
1857  ASSERT_TRUE(contents->Render(*GetContentContext(), entity, pass));
1858  ASSERT_EQ(pass.GetCommands().size(), 1u);
1859  const auto& command = pass.GetCommands()[0];
1860  ASSERT_TRUE(command.pipeline->GetDescriptor()
1861  .GetDepthStencilAttachmentDescriptor()
1862  .has_value());
1863  ASSERT_TRUE(command.pipeline->GetDescriptor()
1864  .GetFrontStencilAttachmentDescriptor()
1865  .has_value());
1866 }

References impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [435/549]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectSetsRightSizeWhenUniformIsStruct   
)

Definition at line 1882 of file entity_unittests.cc.

1882  {
1883  if (GetBackend() != PlaygroundBackend::kVulkan) {
1884  GTEST_SKIP() << "Test only applies to Vulkan";
1885  }
1886 
1887  auto runtime_stages =
1888  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1889  auto runtime_stage =
1890  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1891  ASSERT_TRUE(runtime_stage);
1892  ASSERT_TRUE(runtime_stage->IsDirty());
1893 
1894  auto contents = std::make_shared<RuntimeEffectContents>();
1895  auto geom = Geometry::MakeCover();
1896  contents->SetGeometry(geom.get());
1897  contents->SetRuntimeStage(runtime_stage);
1898 
1899  struct FragUniforms {
1900  Vector2 iResolution;
1901  Scalar iTime;
1902  } frag_uniforms = {
1903  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1904  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1905  };
1906  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1907  uniform_data->resize(sizeof(FragUniforms));
1908  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1909 
1910  auto buffer_view = RuntimeEffectContents::EmplaceVulkanUniform(
1911  uniform_data, GetContentContext()->GetTransientsDataBuffer(),
1912  runtime_stage->GetUniforms()[0],
1913  GetContentContext()
1914  ->GetTransientsDataBuffer()
1915  .GetMinimumUniformAlignment());
1916 
1917  // 16 bytes:
1918  // 8 bytes for iResolution
1919  // 4 bytes for iTime
1920  // 4 bytes padding
1921  EXPECT_EQ(buffer_view.GetRange().length, 16u);
1922 }

References buffer_view, impeller::RuntimeEffectContents::EmplaceVulkanUniform(), impeller::kVulkan, impeller::Geometry::MakeCover(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [436/549]

impeller::testing::TEST_P ( EntityTest  ,
SetBlendMode   
)

Definition at line 1236 of file entity_unittests.cc.

1236  {
1237  Entity entity;
1238  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSrcOver);
1239  entity.SetBlendMode(BlendMode::kClear);
1240  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kClear);
1241 }

References impeller::Entity::GetBlendMode(), impeller::kClear, impeller::kSrcOver, and impeller::Entity::SetBlendMode().

◆ TEST_P() [437/549]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorApplyColorFilter   
)

Definition at line 2499 of file entity_unittests.cc.

2499  {
2500  auto contents = SolidColorContents();
2501  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
2502  auto result = contents.ApplyColorFilter([](const Color& color) {
2503  return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
2504  });
2505  ASSERT_TRUE(result);
2506  ASSERT_COLOR_NEAR(contents.GetColor(),
2507  Color(0.424452, 0.828743, 0.79105, 0.9375));
2508 }

References ASSERT_COLOR_NEAR, impeller::Color::Blend(), impeller::Color::CornflowerBlue(), impeller::kScreen, and impeller::Color::LimeGreen().

◆ TEST_P() [438/549]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsIsOpaque   
)

Definition at line 2029 of file entity_unittests.cc.

2029  {
2030  Matrix matrix;
2031  SolidColorContents contents;
2032  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2033  contents.SetGeometry(geom.get());
2034 
2035  contents.SetColor(Color::CornflowerBlue());
2036  EXPECT_TRUE(contents.IsOpaque(matrix));
2037  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
2038  EXPECT_FALSE(contents.IsOpaque(matrix));
2039 
2040  // Create stroked path that required alpha coverage.
2041  geom = Geometry::MakeStrokePath(flutter::DlPath::MakeLine({0, 0}, {100, 100}),
2042  {.width = 0.05});
2043  contents.SetGeometry(geom.get());
2044  contents.SetColor(Color::CornflowerBlue());
2045 
2046  EXPECT_FALSE(contents.IsOpaque(matrix));
2047 }

References impeller::Color::CornflowerBlue(), impeller::SolidColorContents::IsOpaque(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Geometry::MakeStrokePath(), impeller::SolidColorContents::SetColor(), and impeller::ColorSourceContents::SetGeometry().

◆ TEST_P() [439/549]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetMiterLimit   
)

Definition at line 719 of file entity_unittests.cc.

719  {
720  {
721  auto geometry = Geometry::MakeStrokePath(flutter::DlPath{});
722  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
723  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
724  }
725 
726  {
727  auto geometry = Geometry::MakeStrokePath(flutter::DlPath{}, //
728  {
729  .width = 1.0f,
730  .miter_limit = 8.0f,
731  });
732  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
733  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
734  }
735 
736  {
737  auto geometry = Geometry::MakeStrokePath(flutter::DlPath{}, //
738  {
739  .width = 1.0f,
740  .miter_limit = -1.0f,
741  });
742  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
743  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
744  }
745 }

References impeller::Geometry::MakeStrokePath().

◆ TEST_P() [440/549]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetStrokeCapsAndJoins   
)

Definition at line 687 of file entity_unittests.cc.

687  {
688  {
689  auto geometry = Geometry::MakeStrokePath(flutter::DlPath{});
690  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
691  // Defaults.
692  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kButt);
693  ASSERT_EQ(path_geometry->GetStrokeJoin(), Join::kMiter);
694  }
695 
696  {
697  auto geometry = Geometry::MakeStrokePath(flutter::DlPath{}, //
698  {
699  .width = 1.0f,
700  .cap = Cap::kSquare,
701  .miter_limit = 4.0f,
702  });
703  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
704  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kSquare);
705  }
706 
707  {
708  auto geometry = Geometry::MakeStrokePath(flutter::DlPath{}, //
709  {
710  .width = 1.0f,
711  .cap = Cap::kRound,
712  .miter_limit = 4.0f,
713  });
714  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
715  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kRound);
716  }
717 }

References impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, and impeller::Geometry::MakeStrokePath().

◆ TEST_P() [441/549]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillCoverageIsCorrect   
)

Definition at line 1348 of file entity_unittests.cc.

1348  {
1349  // No transform
1350  {
1351  auto fill = std::make_shared<SolidColorContents>();
1352  fill->SetColor(Color::CornflowerBlue());
1353  auto expected = Rect::MakeLTRB(100, 110, 200, 220);
1354  auto geom = Geometry::MakeFillPath(flutter::DlPath::MakeRect(expected));
1355  fill->SetGeometry(geom.get());
1356 
1357  auto coverage = fill->GetCoverage({});
1358  ASSERT_TRUE(coverage.has_value());
1359  ASSERT_RECT_NEAR(coverage.value(), expected);
1360  }
1361 
1362  // Entity transform
1363  {
1364  auto fill = std::make_shared<SolidColorContents>();
1365  auto geom = Geometry::MakeFillPath(
1366  flutter::DlPath::MakeRect(Rect::MakeLTRB(100, 110, 200, 220)));
1367  fill->SetColor(Color::CornflowerBlue());
1368  fill->SetGeometry(geom.get());
1369 
1370  Entity entity;
1371  entity.SetTransform(Matrix::MakeTranslation(Vector2(4, 5)));
1372  entity.SetContents(std::move(fill));
1373 
1374  auto coverage = entity.GetCoverage();
1375  auto expected = Rect::MakeLTRB(104, 115, 204, 225);
1376  ASSERT_TRUE(coverage.has_value());
1377  ASSERT_RECT_NEAR(coverage.value(), expected);
1378  }
1379 
1380  // No coverage for fully transparent colors
1381  {
1382  auto fill = std::make_shared<SolidColorContents>();
1383  auto geom = Geometry::MakeFillPath(
1384  flutter::DlPath::MakeRect(Rect::MakeLTRB(100, 110, 200, 220)));
1385  fill->SetColor(Color::WhiteTransparent());
1386  fill->SetGeometry(geom.get());
1387 
1388  auto coverage = fill->GetCoverage({});
1389  ASSERT_FALSE(coverage.has_value());
1390  }
1391 }

References ASSERT_RECT_NEAR, impeller::Color::CornflowerBlue(), impeller::Entity::GetCoverage(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::Color::WhiteTransparent().

◆ TEST_P() [442/549]

impeller::testing::TEST_P ( EntityTest  ,
SolidStrokeCoverageIsCorrect   
)

Definition at line 1249 of file entity_unittests.cc.

1249  {
1250  {
1251  auto geometry = Geometry::MakeStrokePath(
1252  flutter::DlPath::MakeLine({0, 0}, {10, 10}), //
1253  {
1254  .width = 4.0f,
1255  .cap = Cap::kButt,
1256  .join = Join::kBevel,
1257  .miter_limit = 4.0f,
1258  });
1259 
1260  Entity entity;
1261  auto contents = std::make_unique<SolidColorContents>();
1262  contents->SetGeometry(geometry.get());
1263  contents->SetColor(Color::Black());
1264  entity.SetContents(std::move(contents));
1265  auto actual = entity.GetCoverage();
1266  auto expected = Rect::MakeLTRB(-2, -2, 12, 12);
1267 
1268  ASSERT_TRUE(actual.has_value());
1269  ASSERT_RECT_NEAR(actual.value(), expected);
1270  }
1271 
1272  // Cover the Cap::kSquare case.
1273  {
1274  auto geometry = Geometry::MakeStrokePath(
1275  flutter::DlPath::MakeLine({0, 0}, {10, 10}), //
1276  {
1277  .width = 4.0,
1278  .cap = Cap::kSquare,
1279  .join = Join::kBevel,
1280  .miter_limit = 4.0,
1281  });
1282 
1283  Entity entity;
1284  auto contents = std::make_unique<SolidColorContents>();
1285  contents->SetGeometry(geometry.get());
1286  contents->SetColor(Color::Black());
1287  entity.SetContents(std::move(contents));
1288  auto actual = entity.GetCoverage();
1289  auto expected =
1290  Rect::MakeLTRB(-sqrt(8), -sqrt(8), 10 + sqrt(8), 10 + sqrt(8));
1291 
1292  ASSERT_TRUE(actual.has_value());
1293  ASSERT_RECT_NEAR(actual.value(), expected);
1294  }
1295 
1296  // Cover the Join::kMiter case.
1297  {
1298  auto geometry = Geometry::MakeStrokePath(
1299  flutter::DlPath::MakeLine({0, 0}, {10, 10}), //
1300  {
1301  .width = 4.0f,
1302  .cap = Cap::kSquare,
1303  .join = Join::kMiter,
1304  .miter_limit = 2.0f,
1305  });
1306 
1307  Entity entity;
1308  auto contents = std::make_unique<SolidColorContents>();
1309  contents->SetGeometry(geometry.get());
1310  contents->SetColor(Color::Black());
1311  entity.SetContents(std::move(contents));
1312  auto actual = entity.GetCoverage();
1313  auto expected = Rect::MakeLTRB(-4, -4, 14, 14);
1314 
1315  ASSERT_TRUE(actual.has_value());
1316  ASSERT_RECT_NEAR(actual.value(), expected);
1317  }
1318 }

References ASSERT_RECT_NEAR, impeller::Color::Black(), impeller::kBevel, impeller::kButt, impeller::kMiter, impeller::kSquare, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Geometry::MakeStrokePath().

◆ TEST_P() [443/549]

impeller::testing::TEST_P ( EntityTest  ,
SpecializationConstantsAreAppliedToVariants   
)

Definition at line 2189 of file entity_unittests.cc.

2189  {
2190  auto content_context = GetContentContext();
2191 
2192  auto default_gyph = content_context->GetGlyphAtlasPipeline({
2193  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2194  .has_depth_stencil_attachments = false,
2195  });
2196  auto alt_gyph = content_context->GetGlyphAtlasPipeline(
2197  {.color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2198  .has_depth_stencil_attachments = true});
2199 
2200  EXPECT_NE(default_gyph, alt_gyph);
2201  EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2202  alt_gyph->GetDescriptor().GetSpecializationConstants());
2203 
2204  auto use_a8 = GetContext()->GetCapabilities()->GetDefaultGlyphAtlasFormat() ==
2205  PixelFormat::kA8UNormInt;
2206 
2207  std::vector<Scalar> expected_constants = {static_cast<Scalar>(use_a8)};
2208  EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2209  expected_constants);
2210 }

References impeller::kA8UNormInt, and impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [444/549]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilter   
)

Definition at line 1610 of file entity_unittests.cc.

1610  {
1611  auto image = CreateTextureForFixture("embarcadero.jpg");
1612  ASSERT_TRUE(image);
1613 
1614  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1615  auto filtered =
1616  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));
1617 
1618  // Define the entity that will serve as the control image as a Gaussian blur
1619  // filter with no filter at all.
1620  Entity entity_left;
1621  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1622  Matrix::MakeTranslation({100, 300}) *
1623  Matrix::MakeScale(Vector2{0.5, 0.5}));
1624  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1625  Sigma{0}, Sigma{0});
1626  entity_left.SetContents(unfiltered);
1627 
1628  // Define the entity that will be filtered from sRGB to linear.
1629  Entity entity_right;
1630  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1631  Matrix::MakeTranslation({500, 300}) *
1632  Matrix::MakeScale(Vector2{0.5, 0.5}));
1633  entity_right.SetContents(filtered);
1634  return entity_left.Render(context, pass) &&
1635  entity_right.Render(context, pass);
1636  };
1637 
1638  ASSERT_TRUE(OpenPlaygroundHere(callback));
1639 }

References impeller::FilterInput::Make(), impeller::FilterContents::MakeGaussianBlur(), impeller::Matrix::MakeScale(), impeller::ColorFilterContents::MakeSrgbToLinearFilter(), impeller::Matrix::MakeTranslation(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [445/549]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilterCoverageIsCorrect   
)

Definition at line 1588 of file entity_unittests.cc.

1588  {
1589  // Set up a simple color background.
1590  auto fill = std::make_shared<SolidColorContents>();
1591  auto geom = Geometry::MakeFillPath(
1592  flutter::DlPath::MakeRect(Rect::MakeXYWH(0, 0, 300, 400)));
1593  fill->SetGeometry(geom.get());
1594  fill->SetColor(Color::DeepPink());
1595 
1596  auto filter =
1597  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));
1598 
1599  Entity e;
1600  e.SetTransform(Matrix());
1601 
1602  // Confirm that the actual filter coverage matches the expected coverage.
1603  auto actual = filter->GetCoverage(e);
1604  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1605 
1606  ASSERT_TRUE(actual.has_value());
1607  ASSERT_RECT_NEAR(actual.value(), expected);
1608 }

References ASSERT_RECT_NEAR, impeller::Color::DeepPink(), impeller::FilterInput::Make(), impeller::Geometry::MakeFillPath(), impeller::ColorFilterContents::MakeSrgbToLinearFilter(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Entity::SetTransform().

◆ TEST_P() [446/549]

impeller::testing::TEST_P ( EntityTest  ,
StrokeCapAndJoinTest   
)

Definition at line 200 of file entity_unittests.cc.

200  {
201  const Point padding(300, 250);
202  const Point margin(140, 180);
203 
204  auto callback = [&](ContentContext& context, RenderPass& pass) {
205  // Slightly above sqrt(2) by default, so that right angles are just below
206  // the limit and acute angles are over the limit (causing them to get
207  // beveled).
208  static Scalar miter_limit = 1.41421357;
209  static Scalar width = 30;
210 
211  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
212  {
213  ImGui::SliderFloat("Miter limit", &miter_limit, 0, 30);
214  ImGui::SliderFloat("Stroke width", &width, 0, 100);
215  if (ImGui::Button("Reset")) {
216  miter_limit = 1.41421357;
217  width = 30;
218  }
219  }
220  ImGui::End();
221 
222  auto world_matrix = Matrix::MakeScale(GetContentScale());
223  auto render_path = [width = width, &context, &pass, &world_matrix](
224  const flutter::DlPath& path, Cap cap, Join join) {
225  auto contents = std::make_unique<SolidColorContents>();
226  std::unique_ptr<Geometry> geom =
227  Geometry::MakeStrokePath(path, {
228  .width = width,
229  .cap = cap,
230  .join = join,
231  .miter_limit = miter_limit,
232  });
233  contents->SetGeometry(geom.get());
234  contents->SetColor(Color::Red());
235 
236  Entity entity;
237  entity.SetTransform(world_matrix);
238  entity.SetContents(std::move(contents));
239 
240  auto coverage = entity.GetCoverage();
241  if (coverage.has_value()) {
242  auto bounds_contents = std::make_unique<SolidColorContents>();
243 
244  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(
245  flutter::DlPath::MakeRect(entity.GetCoverage().value()));
246 
247  bounds_contents->SetGeometry(geom.get());
248  bounds_contents->SetColor(Color::Green().WithAlpha(0.5));
249  Entity bounds_entity;
250  bounds_entity.SetContents(std::move(bounds_contents));
251  bounds_entity.Render(context, pass);
252  }
253 
254  entity.Render(context, pass);
255  };
256 
257  const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
258  e_def(75, 75);
259  const Scalar r = 30;
260  // Cap::kButt demo.
261  {
262  Point off = Point(0, 0) * padding + margin;
263  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
264  static PlaygroundPoint point_b(off + b_def, r, Color::White());
265  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
266  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
267  static PlaygroundPoint point_d(off + d_def, r, Color::White());
268  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
269  render_path(flutter::DlPathBuilder{} //
270  .MoveTo(a)
271  .CubicCurveTo(b, d, c)
272  .TakePath(),
273  Cap::kButt, Join::kBevel);
274  }
275 
276  // Cap::kSquare demo.
277  {
278  Point off = Point(1, 0) * padding + margin;
279  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
280  static PlaygroundPoint point_b(off + b_def, r, Color::White());
281  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
282  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
283  static PlaygroundPoint point_d(off + d_def, r, Color::White());
284  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
285  render_path(flutter::DlPathBuilder{} //
286  .MoveTo(a)
287  .CubicCurveTo(b, d, c)
288  .TakePath(),
289  Cap::kSquare, Join::kBevel);
290  }
291 
292  // Cap::kRound demo.
293  {
294  Point off = Point(2, 0) * padding + margin;
295  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
296  static PlaygroundPoint point_b(off + b_def, r, Color::White());
297  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
298  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
299  static PlaygroundPoint point_d(off + d_def, r, Color::White());
300  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
301  render_path(flutter::DlPathBuilder{} //
302  .MoveTo(a)
303  .CubicCurveTo(b, d, c)
304  .TakePath(),
305  Cap::kRound, Join::kBevel);
306  }
307 
308  // Join::kBevel demo.
309  {
310  Point off = Point(0, 1) * padding + margin;
311  static PlaygroundPoint point_a =
312  PlaygroundPoint(off + a_def, r, Color::White());
313  static PlaygroundPoint point_b =
314  PlaygroundPoint(off + e_def, r, Color::White());
315  static PlaygroundPoint point_c =
316  PlaygroundPoint(off + c_def, r, Color::White());
317  Point a = DrawPlaygroundPoint(point_a);
318  Point b = DrawPlaygroundPoint(point_b);
319  Point c = DrawPlaygroundPoint(point_c);
320  render_path(flutter::DlPathBuilder{} //
321  .MoveTo(a)
322  .LineTo(b)
323  .LineTo(c)
324  .Close()
325  .TakePath(),
326  Cap::kButt, Join::kBevel);
327  }
328 
329  // Join::kMiter demo.
330  {
331  Point off = Point(1, 1) * padding + margin;
332  static PlaygroundPoint point_a(off + a_def, r, Color::White());
333  static PlaygroundPoint point_b(off + e_def, r, Color::White());
334  static PlaygroundPoint point_c(off + c_def, r, Color::White());
335  Point a = DrawPlaygroundPoint(point_a);
336  Point b = DrawPlaygroundPoint(point_b);
337  Point c = DrawPlaygroundPoint(point_c);
338  render_path(flutter::DlPathBuilder{} //
339  .MoveTo(a)
340  .LineTo(b)
341  .LineTo(c)
342  .Close()
343  .TakePath(),
344  Cap::kButt, Join::kMiter);
345  }
346 
347  // Join::kRound demo.
348  {
349  Point off = Point(2, 1) * padding + margin;
350  static PlaygroundPoint point_a(off + a_def, r, Color::White());
351  static PlaygroundPoint point_b(off + e_def, r, Color::White());
352  static PlaygroundPoint point_c(off + c_def, r, Color::White());
353  Point a = DrawPlaygroundPoint(point_a);
354  Point b = DrawPlaygroundPoint(point_b);
355  Point c = DrawPlaygroundPoint(point_c);
356  render_path(flutter::DlPathBuilder{} //
357  .MoveTo(a)
358  .LineTo(b)
359  .LineTo(c)
360  .Close()
361  .TakePath(),
362  Cap::kButt, Join::kRound);
363  }
364 
365  return true;
366  };
367  ASSERT_TRUE(OpenPlaygroundHere(callback));
368 }
Vector2 padding
The halo padding in source space.
Join
An enum that describes ways to join two segments of a path.
Cap
An enum that describes ways to decorate the end of a path contour.

References impeller::saturated::b, impeller::Color::Black(), impeller::Close(), impeller::DrawPlaygroundLine(), impeller::DrawPlaygroundPoint(), impeller::Entity::GetCoverage(), impeller::Color::Green(), impeller::kBevel, impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, impeller::LineTo(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), padding, impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::Color::White().

◆ TEST_P() [447/549]

impeller::testing::TEST_P ( EntityTest  ,
StrokeWithTextureContents   
)

Definition at line 132 of file entity_unittests.cc.

132  {
133  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
134  flutter::DlPath path = flutter::DlPathBuilder{}
135  .MoveTo({100, 100})
136  .LineTo({100, 200})
137  .MoveTo({100, 300})
138  .LineTo({100, 400})
139  .MoveTo({100, 500})
140  .LineTo({100, 600})
141  .TakePath();
142 
143  Entity entity;
144  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
145  auto contents = std::make_unique<TiledTextureContents>();
146  std::unique_ptr<Geometry> geom =
147  Geometry::MakeStrokePath(path, {.width = 100.0f});
148  contents->SetGeometry(geom.get());
149  contents->SetTexture(bridge);
150  contents->SetTileModes(Entity::TileMode::kClamp, Entity::TileMode::kClamp);
151  entity.SetContents(std::move(contents));
152  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
153 }

References impeller::Entity::kClamp, impeller::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::MoveTo(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [448/549]

impeller::testing::TEST_P ( EntityTest  ,
SweepGradientContentsIsOpaque   
)

Definition at line 2118 of file entity_unittests.cc.

2118  {
2119  Matrix matrix;
2120  RadialGradientContents contents;
2121  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2122  contents.SetGeometry(geom.get());
2123 
2124  contents.SetColors({Color::CornflowerBlue()});
2125  EXPECT_TRUE(contents.IsOpaque(matrix));
2126  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2127  EXPECT_FALSE(contents.IsOpaque(matrix));
2128  contents.SetColors({Color::CornflowerBlue()});
2129  contents.SetTileMode(Entity::TileMode::kDecal);
2130  EXPECT_FALSE(contents.IsOpaque(matrix));
2131 
2132  // Create stroked path that required alpha coverage.
2133  geom = Geometry::MakeStrokePath(
2134  flutter::DlPathBuilder{}.MoveTo({0, 0}).LineTo({100, 100}).TakePath(),
2135  {.width = 0.05f});
2136  contents.SetGeometry(geom.get());
2137  contents.SetColors({Color::CornflowerBlue()});
2138 
2139  EXPECT_FALSE(contents.IsOpaque(matrix));
2140 }

References impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Geometry::MakeStrokePath(), impeller::RadialGradientContents::SetColors(), impeller::ColorSourceContents::SetGeometry(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [449/549]

impeller::testing::TEST_P ( EntityTest  ,
TextContentsCeilsGlyphScaleToDecimal   
)

Definition at line 2181 of file entity_unittests.cc.

2181  {
2182  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f), Rational(43, 100));
2183  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f), Rational(53, 100));
2184  ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f), Rational(21, 10));
2185  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f), Rational(0, 1));
2186  ASSERT_EQ(TextFrame::RoundScaledFontSize(100000000.0f), Rational(48, 1));
2187 }

References impeller::TextFrame::RoundScaledFontSize().

◆ TEST_P() [450/549]

impeller::testing::TEST_P ( EntityTest  ,
ThreeStrokesInOnePath   
)

Definition at line 110 of file entity_unittests.cc.

110  {
111  flutter::DlPath path = flutter::DlPathBuilder{}
112  .MoveTo({100, 100})
113  .LineTo({100, 200})
114  .MoveTo({100, 300})
115  .LineTo({100, 400})
116  .MoveTo({100, 500})
117  .LineTo({100, 600})
118  .TakePath();
119 
120  Entity entity;
121  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
122  auto contents = std::make_unique<SolidColorContents>();
123 
124  std::unique_ptr<Geometry> geom =
125  Geometry::MakeStrokePath(path, {.width = 5.0f});
126  contents->SetGeometry(geom.get());
127  contents->SetColor(Color::Red());
128  entity.SetContents(std::move(contents));
129  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
130 }

References impeller::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [451/549]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsIsOpaque   
)

Definition at line 2142 of file entity_unittests.cc.

2142  {
2143  Matrix matrix;
2144  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
2145  TiledTextureContents contents;
2146  contents.SetTexture(bay_bridge);
2147  // This is a placeholder test. Images currently never decompress as opaque
2148  // (whether in Flutter or the playground), and so this should currently always
2149  // return false in practice.
2150  EXPECT_FALSE(contents.IsOpaque(matrix));
2151 }

References impeller::TiledTextureContents::IsOpaque(), and impeller::TiledTextureContents::SetTexture().

◆ TEST_P() [452/549]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsRendersWithCorrectPipeline   
)

Definition at line 21 of file tiled_texture_contents_unittests.cc.

21  {
22  TextureDescriptor texture_desc;
23  texture_desc.size = {100, 100};
24  texture_desc.type = TextureType::kTexture2D;
25  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
26  texture_desc.storage_mode = StorageMode::kDevicePrivate;
27  auto texture =
28  GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
29 
30  auto geom = Geometry::MakeCover();
31  TiledTextureContents contents;
32  contents.SetTexture(texture);
33  contents.SetGeometry(geom.get());
34 
35  auto content_context = GetContentContext();
36  auto buffer = content_context->GetContext()->CreateCommandBuffer();
37  auto render_target =
38  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
39  *content_context->GetContext(), {100, 100},
40  /*mip_count=*/1);
41  auto render_pass = buffer->CreateRenderPass(render_target);
42  auto recording_pass = std::make_shared<RecordingRenderPass>(
43  render_pass, GetContext(), render_target);
44 
45  ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *recording_pass));
46  const std::vector<Command>& commands = recording_pass->GetCommands();
47 
48  ASSERT_EQ(commands.size(), 1u);
49 #ifdef IMPELLER_DEBUG
50  EXPECT_TRUE(commands[0].pipeline->GetDescriptor().GetLabel().find(
51  "TextureFill Pipeline") != std::string::npos);
52 #endif // IMPELLER_DEBUG
53  auto options = OptionsFromPassAndEntity(*recording_pass, {});
54  options.primitive_type = PrimitiveType::kTriangleStrip;
55  EXPECT_EQ(commands[0].pipeline,
56  GetContentContext()->GetTiledTexturePipeline(options));
57 
58  if (GetParam() == PlaygroundBackend::kMetal) {
59  recording_pass->EncodeCommands();
60  }
61 }
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition: contents.cc:34

References impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kMetal, impeller::kR8G8B8A8UNormInt, impeller::kTexture2D, impeller::kTriangleStrip, impeller::Geometry::MakeCover(), impeller::OptionsFromPassAndEntity(), impeller::ContentContextOptions::primitive_type, impeller::TiledTextureContents::Render(), impeller::ColorSourceContents::SetGeometry(), impeller::TiledTextureContents::SetTexture(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::type.

◆ TEST_P() [453/549]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsRendersWithCorrectPipelineExternalOES   
)

Definition at line 65 of file tiled_texture_contents_unittests.cc.

65  {
66  if (GetParam() != PlaygroundBackend::kOpenGLES) {
67  GTEST_SKIP()
68  << "External OES textures are only valid for the OpenGLES backend.";
69  }
70 
71  TextureDescriptor texture_desc;
72  texture_desc.size = {100, 100};
73  texture_desc.type = TextureType::kTextureExternalOES;
74  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
75  texture_desc.storage_mode = StorageMode::kDevicePrivate;
76  auto texture =
77  GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
78  auto contents = TextureContents::MakeRect(Rect::MakeSize(texture->GetSize()));
79  contents->SetTexture(texture);
80  contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
81  contents->SetStrictSourceRect(false);
82 
83  auto content_context = GetContentContext();
84  auto buffer = content_context->GetContext()->CreateCommandBuffer();
85  auto render_target =
86  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
87  *content_context->GetContext(), {100, 100},
88  /*mip_count=*/1);
89  auto render_pass = buffer->CreateRenderPass(render_target);
90 
91  ASSERT_TRUE(contents->Render(*GetContentContext(), {}, *render_pass));
92  const std::vector<Command>& commands = render_pass->GetCommands();
93 
94  ASSERT_EQ(commands.size(), 1u);
95 
96  auto options = OptionsFromPassAndEntity(*render_pass, {});
97  options.primitive_type = PrimitiveType::kTriangleStrip;
98  EXPECT_EQ(commands[0].pipeline,
99  GetContentContext()->GetTiledTextureExternalPipeline(options));
100 }

References impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kTextureExternalOES, impeller::kTriangleStrip, impeller::TextureContents::MakeRect(), impeller::TRect< Scalar >::MakeSize(), impeller::OptionsFromPassAndEntity(), impeller::ContentContextOptions::primitive_type, impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::type.

◆ TEST_P() [454/549]

impeller::testing::TEST_P ( EntityTest  ,
TriangleInsideASquare   
)

Definition at line 155 of file entity_unittests.cc.

155  {
156  auto callback = [&](ContentContext& context, RenderPass& pass) {
157  Point offset(100, 100);
158 
159  static PlaygroundPoint point_a(Point(10, 10) + offset, 20, Color::White());
160  Point a = DrawPlaygroundPoint(point_a);
161  static PlaygroundPoint point_b(Point(210, 10) + offset, 20, Color::White());
162  Point b = DrawPlaygroundPoint(point_b);
163  static PlaygroundPoint point_c(Point(210, 210) + offset, 20,
164  Color::White());
165  Point c = DrawPlaygroundPoint(point_c);
166  static PlaygroundPoint point_d(Point(10, 210) + offset, 20, Color::White());
167  Point d = DrawPlaygroundPoint(point_d);
168  static PlaygroundPoint point_e(Point(50, 50) + offset, 20, Color::White());
169  Point e = DrawPlaygroundPoint(point_e);
170  static PlaygroundPoint point_f(Point(100, 50) + offset, 20, Color::White());
171  Point f = DrawPlaygroundPoint(point_f);
172  static PlaygroundPoint point_g(Point(50, 150) + offset, 20, Color::White());
173  Point g = DrawPlaygroundPoint(point_g);
174  flutter::DlPath path = flutter::DlPathBuilder{}
175  .MoveTo(a)
176  .LineTo(b)
177  .LineTo(c)
178  .LineTo(d)
179  .Close()
180  .MoveTo(e)
181  .LineTo(f)
182  .LineTo(g)
183  .Close()
184  .TakePath();
185 
186  Entity entity;
187  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
188  auto contents = std::make_unique<SolidColorContents>();
189  std::unique_ptr<Geometry> geom =
190  Geometry::MakeStrokePath(path, {.width = 20.0});
191  contents->SetGeometry(geom.get());
192  contents->SetColor(Color::Red());
193  entity.SetContents(std::move(contents));
194 
195  return entity.Render(context, pass);
196  };
197  ASSERT_TRUE(OpenPlaygroundHere(callback));
198 }

References impeller::saturated::b, impeller::DrawPlaygroundPoint(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::Color::White().

◆ TEST_P() [455/549]

impeller::testing::TEST_P ( EntityTest  ,
YUVToRGBFilter   
)

Definition at line 1719 of file entity_unittests.cc.

1719  {
1720  if (GetParam() == PlaygroundBackend::kOpenGLES) {
1721  // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
1722  GTEST_SKIP()
1723  << "YUV to RGB filter is not supported on OpenGLES backend yet.";
1724  }
1725 
1726  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1727  YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
1728  YUVColorSpace::kBT601LimitedRange};
1729  for (int i = 0; i < 2; i++) {
1730  auto yuv_color_space = yuv_color_space_array[i];
1731  auto textures =
1732  CreateTestYUVTextures(GetContext().get(), yuv_color_space);
1733  auto filter_contents = FilterContents::MakeYUVToRGBFilter(
1734  textures[0], textures[1], yuv_color_space);
1735  Entity filter_entity;
1736  filter_entity.SetContents(filter_contents);
1737  auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
1738 
1739  Entity entity;
1740  auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
1741  contents->SetTexture(snapshot->texture);
1742  contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
1743  entity.SetContents(contents);
1744  entity.SetTransform(
1745  Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
1746  entity.Render(context, pass);
1747  }
1748  return true;
1749  };
1750  ASSERT_TRUE(OpenPlaygroundHere(callback));
1751 }
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures(Context *context, YUVColorSpace yuv_color_space)
YUVColorSpace
Definition: color.h:54

References CreateTestYUVTextures(), impeller::kBT601FullRange, impeller::kBT601LimitedRange, impeller::kOpenGLES, impeller::TRect< Scalar >::MakeLTRB(), impeller::TextureContents::MakeRect(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeTranslation(), impeller::FilterContents::MakeYUVToRGBFilter(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [456/549]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CalculateUVsSimple   
)

Definition at line 334 of file gaussian_blur_filter_contents_unittests.cc.

334  {
335  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
336  auto filter_input = FilterInput::Make(texture);
337  Entity entity;
338  Quad uvs = GaussianBlurFilterContents::CalculateUVs(
339  filter_input, entity, Rect::MakeSize(ISize(100, 100)), ISize(100, 100));
340  std::optional<Rect> uvs_bounds = Rect::MakePointBounds(uvs);
341  EXPECT_TRUE(uvs_bounds.has_value());
342  if (uvs_bounds.has_value()) {
343  EXPECT_TRUE(RectNear(uvs_bounds.value(), Rect::MakeXYWH(0, 0, 1, 1)));
344  }
345 }

References impeller::GaussianBlurFilterContents::CalculateUVs(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakePointBounds(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), and uvs.

◆ TEST_P() [457/549]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithEffectTransform   
)

Definition at line 186 of file gaussian_blur_filter_contents_unittests.cc.

186  {
187  Matrix effect_transform = Matrix::MakeScale({2.0, 2.0, 1.0});
188  fml::StatusOr<Scalar> sigma_radius_1 =
189  CalculateSigmaForBlurRadius(1.0, effect_transform);
190  ASSERT_TRUE(sigma_radius_1.ok());
191  GaussianBlurFilterContents contents(
192  /*sigma_x=*/sigma_radius_1.value(),
193  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
194  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
195  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
196  FilterInput::Vector inputs = {FilterInput::Make(texture)};
197  Entity entity;
198  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
199  std::optional<Rect> coverage =
200  contents.GetFilterCoverage(inputs, entity, effect_transform);
201  EXPECT_TRUE(coverage.has_value());
202  if (coverage.has_value()) {
203  EXPECT_RECT_NEAR(coverage.value(),
204  Rect::MakeLTRB(100 - 1, 100 - 1, 200 + 1, 200 + 1));
205  }
206 }

References EXPECT_RECT_NEAR, impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [458/549]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithTexture   
)

Definition at line 165 of file gaussian_blur_filter_contents_unittests.cc.

165  {
166  fml::StatusOr<Scalar> sigma_radius_1 =
167  CalculateSigmaForBlurRadius(1.0, Matrix());
168  ASSERT_TRUE(sigma_radius_1.ok());
169  GaussianBlurFilterContents contents(
170  /*sigma_X=*/sigma_radius_1.value(),
171  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
172  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
173  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
174  FilterInput::Vector inputs = {FilterInput::Make(texture)};
175  Entity entity;
176  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
177  std::optional<Rect> coverage =
178  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
179 
180  EXPECT_TRUE(coverage.has_value());
181  if (coverage.has_value()) {
182  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
183  }
184 }

References EXPECT_RECT_NEAR, impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [459/549]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverage   
)

Definition at line 238 of file gaussian_blur_filter_contents_unittests.cc.

238  {
239  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
240  fml::StatusOr<Scalar> sigma_radius_1 =
241  CalculateSigmaForBlurRadius(1.0, Matrix());
242  ASSERT_TRUE(sigma_radius_1.ok());
243  auto contents = std::make_unique<GaussianBlurFilterContents>(
244  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
245  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
246  contents->SetInputs({FilterInput::Make(texture)});
247  std::shared_ptr<ContentContext> renderer = GetContentContext();
248 
249  Entity entity;
250  std::optional<Entity> result =
251  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
252  EXPECT_TRUE(result.has_value());
253  if (result.has_value()) {
254  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSrcOver);
255  std::optional<Rect> result_coverage = result.value().GetCoverage();
256  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
257  EXPECT_TRUE(result_coverage.has_value());
258  EXPECT_TRUE(contents_coverage.has_value());
259  if (result_coverage.has_value() && contents_coverage.has_value()) {
260  EXPECT_TRUE(RectNear(contents_coverage.value(),
261  Rect::MakeLTRB(-1, -1, 101, 101)));
262  EXPECT_TRUE(
263  RectNear(result_coverage.value(), Rect::MakeLTRB(-1, -1, 101, 101)));
264  }
265  }
266 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSrcOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), and RectNear().

◆ TEST_P() [460/549]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageRotated   
)

Definition at line 301 of file gaussian_blur_filter_contents_unittests.cc.

302  {
303  std::shared_ptr<Texture> texture = MakeTexture(ISize(400, 300));
304  fml::StatusOr<Scalar> sigma_radius_1 =
305  CalculateSigmaForBlurRadius(1.0, Matrix());
306  auto contents = std::make_unique<GaussianBlurFilterContents>(
307  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
308  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
309  contents->SetInputs({FilterInput::Make(texture)});
310  std::shared_ptr<ContentContext> renderer = GetContentContext();
311 
312  Entity entity;
313  // Rotate around the top left corner, then push it over to (100, 100).
314  entity.SetTransform(Matrix::MakeTranslation({400, 100, 0}) *
315  Matrix::MakeRotationZ(Degrees(90.0)));
316  std::optional<Entity> result =
317  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
318  EXPECT_TRUE(result.has_value());
319  if (result.has_value()) {
320  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSrcOver);
321  std::optional<Rect> result_coverage = result.value().GetCoverage();
322  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
323  EXPECT_TRUE(result_coverage.has_value());
324  EXPECT_TRUE(contents_coverage.has_value());
325  if (result_coverage.has_value() && contents_coverage.has_value()) {
326  EXPECT_TRUE(RectNear(contents_coverage.value(),
327  Rect::MakeLTRB(99, 99, 401, 501)));
328  EXPECT_TRUE(
329  RectNear(result_coverage.value(), Rect::MakeLTRB(99, 99, 401, 501)));
330  }
331  }
332 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSrcOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [461/549]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 268 of file gaussian_blur_filter_contents_unittests.cc.

269  {
270  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
271  fml::StatusOr<Scalar> sigma_radius_1 =
272  CalculateSigmaForBlurRadius(1.0, Matrix());
273  ASSERT_TRUE(sigma_radius_1.ok());
274  auto contents = std::make_unique<GaussianBlurFilterContents>(
275  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
276  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
277  contents->SetInputs({FilterInput::Make(texture)});
278  std::shared_ptr<ContentContext> renderer = GetContentContext();
279 
280  Entity entity;
281  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
282  std::optional<Entity> result =
283  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
284 
285  EXPECT_TRUE(result.has_value());
286  if (result.has_value()) {
287  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSrcOver);
288  std::optional<Rect> result_coverage = result.value().GetCoverage();
289  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
290  EXPECT_TRUE(result_coverage.has_value());
291  EXPECT_TRUE(contents_coverage.has_value());
292  if (result_coverage.has_value() && contents_coverage.has_value()) {
293  EXPECT_TRUE(RectNear(contents_coverage.value(),
294  Rect::MakeLTRB(99, 199, 201, 301)));
295  EXPECT_TRUE(
296  RectNear(result_coverage.value(), Rect::MakeLTRB(99, 199, 201, 301)));
297  }
298  }
299 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSrcOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [462/549]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRect   
)

Definition at line 347 of file gaussian_blur_filter_contents_unittests.cc.

347  {
348  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
349  auto texture_contents = std::make_shared<TextureContents>();
350  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
351  texture_contents->SetTexture(texture);
352  texture_contents->SetDestinationRect(Rect::MakeXYWH(
353  50, 40, texture->GetSize().width, texture->GetSize().height));
354 
355  fml::StatusOr<Scalar> sigma_radius_1 =
356  CalculateSigmaForBlurRadius(1.0, Matrix());
357  auto contents = std::make_unique<GaussianBlurFilterContents>(
358  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
359  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
360  contents->SetInputs({FilterInput::Make(texture_contents)});
361  std::shared_ptr<ContentContext> renderer = GetContentContext();
362 
363  Entity entity;
364  std::optional<Entity> result =
365  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
366  EXPECT_TRUE(result.has_value());
367  if (result.has_value()) {
368  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSrcOver);
369  std::optional<Rect> result_coverage = result.value().GetCoverage();
370  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
371  EXPECT_TRUE(result_coverage.has_value());
372  EXPECT_TRUE(contents_coverage.has_value());
373  if (result_coverage.has_value() && contents_coverage.has_value()) {
374  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
375  EXPECT_TRUE(RectNear(result_coverage.value(),
376  Rect::MakeLTRB(49.f, 39.f, 151.f, 141.f)));
377  }
378  }
379 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSrcOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), and RectNear().

◆ TEST_P() [463/549]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRectScaled   
)

Definition at line 381 of file gaussian_blur_filter_contents_unittests.cc.

382  {
383  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
384  auto texture_contents = std::make_shared<TextureContents>();
385  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
386  texture_contents->SetTexture(texture);
387  texture_contents->SetDestinationRect(Rect::MakeXYWH(
388  50, 40, texture->GetSize().width, texture->GetSize().height));
389 
390  fml::StatusOr<Scalar> sigma_radius_1 =
391  CalculateSigmaForBlurRadius(1.0, Matrix());
392  auto contents = std::make_unique<GaussianBlurFilterContents>(
393  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
394  FilterContents::BlurStyle::kNormal,
395  /*mask_geometry=*/nullptr);
396  contents->SetInputs({FilterInput::Make(texture_contents)});
397  std::shared_ptr<ContentContext> renderer = GetContentContext();
398 
399  Entity entity;
400  entity.SetTransform(Matrix::MakeScale({2.0, 2.0, 1.0}));
401  std::optional<Entity> result =
402  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
403  EXPECT_TRUE(result.has_value());
404  if (result.has_value()) {
405  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSrcOver);
406  std::optional<Rect> result_coverage = result.value().GetCoverage();
407  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
408  EXPECT_TRUE(result_coverage.has_value());
409  EXPECT_TRUE(contents_coverage.has_value());
410  if (result_coverage.has_value() && contents_coverage.has_value()) {
411  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
412  // Scaling a blurred entity doesn't seem to scale the blur radius linearly
413  // when comparing results with rrect_blur. That's why this is not
414  // Rect::MakeXYWH(98.f, 78.f, 204.0f, 204.f).
415  EXPECT_TRUE(RectNear(contents_coverage.value(),
416  Rect::MakeXYWH(94.f, 74.f, 212.0f, 212.f)));
417  }
418  }
419 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSrcOver, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [464/549]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithEffectTransform   
)

Definition at line 421 of file gaussian_blur_filter_contents_unittests.cc.

421  {
422  Matrix effect_transform = Matrix::MakeScale({2.0, 2.0, 1.0});
423  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
424  auto texture_contents = std::make_shared<TextureContents>();
425  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
426  texture_contents->SetTexture(texture);
427  texture_contents->SetDestinationRect(Rect::MakeXYWH(
428  50, 40, texture->GetSize().width, texture->GetSize().height));
429 
430  fml::StatusOr<Scalar> sigma_radius_1 =
431  CalculateSigmaForBlurRadius(1.0, effect_transform);
432  ASSERT_TRUE(sigma_radius_1.ok());
433  auto contents = std::make_unique<GaussianBlurFilterContents>(
434  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
435  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
436  contents->SetInputs({FilterInput::Make(texture_contents)});
437  contents->SetEffectTransform(effect_transform);
438  std::shared_ptr<ContentContext> renderer = GetContentContext();
439 
440  Entity entity;
441  std::optional<Entity> result =
442  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
443  EXPECT_TRUE(result.has_value());
444  if (result.has_value()) {
445  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSrcOver);
446  std::optional<Rect> result_coverage = result.value().GetCoverage();
447  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
448  EXPECT_TRUE(result_coverage.has_value());
449  EXPECT_TRUE(contents_coverage.has_value());
450  if (result_coverage.has_value() && contents_coverage.has_value()) {
451  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
452  EXPECT_TRUE(RectNear(contents_coverage.value(),
453  Rect::MakeXYWH(49.f, 39.f, 102.f, 102.f)));
454  }
455  }
456 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSrcOver, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), and RectNear().

◆ TEST_P() [465/549]

impeller::testing::TEST_P ( HostBufferTest  ,
CanEmplace   
)

Definition at line 36 of file host_buffer_unittests.cc.

36  {
37  struct Length2 {
38  uint8_t pad[2];
39  };
40  static_assert(sizeof(Length2) == 2u);
41 
42  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
43  GetContext()->GetIdleWaiter(), 256);
44 
45  for (size_t i = 0; i < 12500; i++) {
46  auto view = buffer->Emplace(Length2{});
47  ASSERT_TRUE(view);
48  ASSERT_EQ(view.GetRange(), Range(i * sizeof(Length2), 2u));
49  }
50 }

References impeller::HostBuffer::Create().

◆ TEST_P() [466/549]

impeller::testing::TEST_P ( HostBufferTest  ,
CanEmplaceWithAlignment   
)

Definition at line 52 of file host_buffer_unittests.cc.

52  {
53  struct Length2 {
54  uint8_t pad[2];
55  };
56  static_assert(sizeof(Length2) == 2);
57  struct alignas(16) Align16 {
58  uint8_t pad[2];
59  };
60  static_assert(alignof(Align16) == 16);
61  static_assert(sizeof(Align16) == 16);
62 
63  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
64  GetContext()->GetIdleWaiter(), 256);
65  ASSERT_TRUE(buffer);
66 
67  {
68  auto view = buffer->Emplace(Length2{});
69  ASSERT_TRUE(view);
70  ASSERT_EQ(view.GetRange(), Range(0u, 2u));
71  }
72 
73  {
74  auto view = buffer->Emplace(Align16{});
75  ASSERT_TRUE(view);
76  ASSERT_EQ(view.GetRange().offset, 16u);
77  ASSERT_EQ(view.GetRange().length, 16u);
78  }
79  {
80  auto view = buffer->Emplace(Length2{});
81  ASSERT_TRUE(view);
82  ASSERT_EQ(view.GetRange(), Range(32u, 2u));
83  }
84 
85  {
86  auto view = buffer->Emplace(Align16{});
87  ASSERT_TRUE(view);
88  ASSERT_EQ(view.GetRange().offset, 48u);
89  ASSERT_EQ(view.GetRange().length, 16u);
90  }
91 }

References impeller::HostBuffer::Create().

◆ TEST_P() [467/549]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplaceWithFailingAllocationDoesntCrash   
)

Definition at line 222 of file host_buffer_unittests.cc.

222  {
223  ScopedValidationDisable disable;
224  std::shared_ptr<FailingAllocator> allocator =
225  std::make_shared<FailingAllocator>(GetContext()->GetResourceAllocator());
226  auto buffer =
227  HostBuffer::Create(allocator, GetContext()->GetIdleWaiter(), 256);
228 
229  auto view = buffer->Emplace(nullptr, kMagicFailingAllocation, 0);
230 
231  EXPECT_EQ(view.GetBuffer(), nullptr);
232  EXPECT_EQ(view.GetRange().offset, 0u);
233  EXPECT_EQ(view.GetRange().length, 0u);
234 }
static constexpr const size_t kMagicFailingAllocation

References impeller::HostBuffer::Create(), and kMagicFailingAllocation.

◆ TEST_P() [468/549]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplaceWithProcIsAligned   
)

Definition at line 180 of file host_buffer_unittests.cc.

180  {
181  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
182  GetContext()->GetIdleWaiter(), 256);
183 
184  BufferView view = buffer->Emplace(std::array<char, 21>());
185  EXPECT_EQ(view.GetRange(), Range(0, 21));
186 
187  view = buffer->Emplace(64, 16, [](uint8_t*) {});
188  EXPECT_EQ(view.GetRange(), Range(32, 64));
189 }

References impeller::HostBuffer::Create(), and impeller::BufferView::GetRange().

◆ TEST_P() [469/549]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBuffer   
)

Definition at line 135 of file host_buffer_unittests.cc.

135  {
136  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
137  GetContext()->GetIdleWaiter(), 256);
138 
139  // Emplace an amount larger than the block size, to verify that the host
140  // buffer does not create a buffer.
141  auto buffer_view = buffer->Emplace(nullptr, 1024000 + 10, 0);
142 
143  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
144  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
145  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
146 }

References buffer_view, and impeller::HostBuffer::Create().

◆ TEST_P() [470/549]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback   
)

Definition at line 121 of file host_buffer_unittests.cc.

122  {
123  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
124  GetContext()->GetIdleWaiter(), 256);
125 
126  // Emplace an amount larger than the block size, to verify that the host
127  // buffer does not create a buffer.
128  auto buffer_view = buffer->Emplace(1024000 + 10, 0, [](uint8_t* data) {});
129 
130  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
131  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
132  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
133 }

References buffer_view, impeller::HostBuffer::Create(), and data.

◆ TEST_P() [471/549]

impeller::testing::TEST_P ( HostBufferTest  ,
HostBufferInitialState   
)

Definition at line 93 of file host_buffer_unittests.cc.

93  {
94  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
95  GetContext()->GetIdleWaiter(), 256);
96 
97  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
98  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
99  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
100 }

References impeller::HostBuffer::Create().

◆ TEST_P() [472/549]

impeller::testing::TEST_P ( HostBufferTest  ,
IdleWaiter   
)

Definition at line 27 of file host_buffer_unittests.cc.

27  {
28  auto mock_idle_waiter = std::make_shared<MockIdleWaiter>();
29  {
30  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
31  mock_idle_waiter, 256);
32  EXPECT_CALL(*mock_idle_waiter, WaitIdle());
33  }
34 }

References impeller::HostBuffer::Create().

◆ TEST_P() [473/549]

impeller::testing::TEST_P ( HostBufferTest  ,
ResetIncrementsFrameCounter   
)

Definition at line 102 of file host_buffer_unittests.cc.

102  {
103  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
104  GetContext()->GetIdleWaiter(), 256);
105 
106  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
107 
108  buffer->Reset();
109  EXPECT_EQ(buffer->GetStateForTest().current_frame, 1u);
110 
111  buffer->Reset();
112  EXPECT_EQ(buffer->GetStateForTest().current_frame, 2u);
113 
114  buffer->Reset();
115  EXPECT_EQ(buffer->GetStateForTest().current_frame, 3u);
116 
117  buffer->Reset();
118  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
119 }

References impeller::HostBuffer::Create().

◆ TEST_P() [474/549]

impeller::testing::TEST_P ( HostBufferTest  ,
UnusedBuffersAreDiscardedWhenResetting   
)

Definition at line 148 of file host_buffer_unittests.cc.

148  {
149  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
150  GetContext()->GetIdleWaiter(), 256);
151 
152  // Emplace two large allocations to force the allocation of a second buffer.
153  auto buffer_view_a = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
154  auto buffer_view_b = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
155 
156  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 1u);
157  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
158  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
159 
160  // Reset until we get back to this frame.
161  for (auto i = 0; i < 4; i++) {
162  buffer->Reset();
163  }
164 
165  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
166  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
167  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
168 
169  // Now when we reset, the buffer should get dropped.
170  // Reset until we get back to this frame.
171  for (auto i = 0; i < 4; i++) {
172  buffer->Reset();
173  }
174 
175  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
176  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
177  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
178 }

References impeller::HostBuffer::Create(), and data.

◆ TEST_P() [475/549]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageClippedSubpassScale   
)

Definition at line 175 of file matrix_filter_contents_unittests.cc.

176  {
177  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
178  MatrixFilterContents contents;
179  contents.SetInputs({FilterInput::Make(texture)});
180  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
181  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
182  contents.SetRenderingMode(
183  Entity::RenderingMode::kSubpassAppendSnapshotTransform);
184 
185  Entity entity;
186  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
187 
188  std::shared_ptr<ContentContext> renderer = GetContentContext();
189  std::optional<Entity> result =
190  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
191  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
192  Rect::MakeXYWH(100, 200, 300, 300));
193 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::Entity::kSubpassAppendSnapshotTransform, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), impeller::MatrixFilterContents::SetRenderingMode(), and impeller::Entity::SetTransform().

◆ TEST_P() [476/549]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageClippedSubpassTranslate   
)

Definition at line 138 of file matrix_filter_contents_unittests.cc.

139  {
140  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
141  MatrixFilterContents contents;
142  contents.SetInputs({FilterInput::Make(texture)});
143  contents.SetMatrix(Matrix::MakeTranslation({50, 100, 0}));
144  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
145  contents.SetRenderingMode(
146  Entity::RenderingMode::kSubpassAppendSnapshotTransform);
147 
148  Entity entity;
149  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
150 
151  std::shared_ptr<ContentContext> renderer = GetContentContext();
152  std::optional<Entity> result =
153  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
154  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
155  Rect::MakeXYWH(200, 400, 100, 100));
156 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::Entity::kSubpassAppendSnapshotTransform, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), impeller::MatrixFilterContents::SetRenderingMode(), and impeller::Entity::SetTransform().

◆ TEST_P() [477/549]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageIdentity   
)

Definition at line 106 of file matrix_filter_contents_unittests.cc.

106  {
107  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
108  MatrixFilterContents contents;
109  contents.SetInputs({FilterInput::Make(texture)});
110 
111  Entity entity;
112  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
113 
114  std::shared_ptr<ContentContext> renderer = GetContentContext();
115  std::optional<Entity> result =
116  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
117  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
118  Rect::MakeXYWH(100, 200, 100, 100));
119 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::FilterInput::Make(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetInputs(), and impeller::Entity::SetTransform().

◆ TEST_P() [478/549]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageScale   
)

Definition at line 158 of file matrix_filter_contents_unittests.cc.

158  {
159  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
160  MatrixFilterContents contents;
161  contents.SetInputs({FilterInput::Make(texture)});
162  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
163  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
164 
165  Entity entity;
166  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
167 
168  std::shared_ptr<ContentContext> renderer = GetContentContext();
169  std::optional<Entity> result =
170  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
171  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
172  Rect::MakeXYWH(100, 200, 300, 300));
173 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), and impeller::Entity::SetTransform().

◆ TEST_P() [479/549]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageSubpassScale   
)

Definition at line 195 of file matrix_filter_contents_unittests.cc.

195  {
196  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
197  MatrixFilterContents contents;
198  contents.SetInputs({FilterInput::Make(texture)});
199  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
200  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
201  contents.SetRenderingMode(
202  Entity::RenderingMode::kSubpassPrependSnapshotTransform);
203 
204  Entity entity;
205  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
206 
207  std::shared_ptr<ContentContext> renderer = GetContentContext();
208  std::optional<Entity> result =
209  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
210  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
211  Rect::MakeXYWH(300, 600, 300, 300));
212 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::Entity::kSubpassPrependSnapshotTransform, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), impeller::MatrixFilterContents::SetRenderingMode(), and impeller::Entity::SetTransform().

◆ TEST_P() [480/549]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 121 of file matrix_filter_contents_unittests.cc.

121  {
122  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
123  MatrixFilterContents contents;
124  contents.SetInputs({FilterInput::Make(texture)});
125  contents.SetMatrix(Matrix::MakeTranslation({50, 100, 0}));
126  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
127 
128  Entity entity;
129  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
130 
131  std::shared_ptr<ContentContext> renderer = GetContentContext();
132  std::optional<Entity> result =
133  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
134  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
135  Rect::MakeXYWH(150, 300, 100, 100));
136 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), and impeller::Entity::SetTransform().

◆ TEST_P() [481/549]

impeller::testing::TEST_P ( PipelineCacheDataVKPlaygroundTest  ,
CanPersistAndRetrievePipelineCache   
)

Definition at line 117 of file pipeline_cache_data_vk_unittests.cc.

117  {
118  fml::ScopedTemporaryDirectory temp_dir;
119  const auto& surface_context = SurfaceContextVK::Cast(*GetContext());
120  const auto& context_vk = ContextVK::Cast(*surface_context.GetParent());
121  const auto& caps = CapabilitiesVK::Cast(*context_vk.GetCapabilities());
122 
123  {
124  auto cache = context_vk.GetDevice().createPipelineCacheUnique({});
125  ASSERT_EQ(cache.result, vk::Result::eSuccess);
126  ASSERT_FALSE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
127  ASSERT_TRUE(PipelineCacheDataPersist(
128  temp_dir.fd(), caps.GetPhysicalDeviceProperties(), cache.value));
129  }
130  ASSERT_TRUE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
131 
132  auto mapping = PipelineCacheDataRetrieve(temp_dir.fd(),
133  caps.GetPhysicalDeviceProperties());
134  ASSERT_NE(mapping, nullptr);
135  // Assert that the utility has stripped away the cache header giving us clean
136  // pipeline cache bootstrap information.
137  vk::PipelineCacheHeaderVersionOne vk_cache_header;
138  ASSERT_GE(mapping->GetSize(), sizeof(vk_cache_header));
139  std::memcpy(&vk_cache_header, mapping->GetMapping(), sizeof(vk_cache_header));
140  ASSERT_EQ(vk_cache_header.headerVersion,
141  vk::PipelineCacheHeaderVersion::eOne);
142 }
std::unique_ptr< fml::Mapping > PipelineCacheDataRetrieve(const fml::UniqueFD &cache_directory, const VkPhysicalDeviceProperties &props)
Retrieve the previously persisted pipeline cache data. This function provides integrity checks the Vu...

References impeller::BackendCast< CapabilitiesVK, Capabilities >::Cast(), impeller::BackendCast< ContextVK, Context >::Cast(), impeller::BackendCast< SurfaceContextVK, Context >::Cast(), impeller::PipelineCacheDataPersist(), and impeller::PipelineCacheDataRetrieve().

◆ TEST_P() [482/549]

impeller::testing::TEST_P ( PipelineCacheDataVKPlaygroundTest  ,
IntegrityChecksArePerformedOnPersistedData   
)

Definition at line 144 of file pipeline_cache_data_vk_unittests.cc.

145  {
146  fml::ScopedTemporaryDirectory temp_dir;
147  const auto& surface_context = SurfaceContextVK::Cast(*GetContext());
148  const auto& context_vk = ContextVK::Cast(*surface_context.GetParent());
149  const auto& caps = CapabilitiesVK::Cast(*context_vk.GetCapabilities());
150 
151  {
152  auto cache = context_vk.GetDevice().createPipelineCacheUnique({});
153  ASSERT_EQ(cache.result, vk::Result::eSuccess);
154  ASSERT_FALSE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
155  ASSERT_TRUE(PipelineCacheDataPersist(
156  temp_dir.fd(), caps.GetPhysicalDeviceProperties(), cache.value));
157  }
158  ASSERT_TRUE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
159  auto incompatible_caps = caps.GetPhysicalDeviceProperties();
160  // Simulate a driver version bump.
161  incompatible_caps.driverVersion =
162  caps.GetPhysicalDeviceProperties().driverVersion + 1u;
163  auto mapping = PipelineCacheDataRetrieve(temp_dir.fd(), incompatible_caps);
164  ASSERT_EQ(mapping, nullptr);
165 }

References impeller::BackendCast< CapabilitiesVK, Capabilities >::Cast(), impeller::BackendCast< ContextVK, Context >::Cast(), impeller::BackendCast< SurfaceContextVK, Context >::Cast(), impeller::PipelineCacheDataPersist(), and impeller::PipelineCacheDataRetrieve().

◆ TEST_P() [483/549]

impeller::testing::TEST_P ( RendererDartTest  ,
CanCreateRenderPassAndSubmit   
)

Definition at line 300 of file renderer_dart_unittests.cc.

300  {
301  ASSERT_TRUE(RenderDartToPlayground("canCreateRenderPassAndSubmit"));
302 }

◆ TEST_P() [484/549]

impeller::testing::TEST_P ( RendererDartTest  ,
CanCreateShaderLibrary   
)

Definition at line 292 of file renderer_dart_unittests.cc.

292  {
293  ASSERT_TRUE(RunDartFunction("canCreateShaderLibrary"));
294 }

◆ TEST_P() [485/549]

impeller::testing::TEST_P ( RendererDartTest  ,
CanInstantiateFlutterGPUContext   
)

These test entries correspond to Dart functions located in flutter/impeller/fixtures/dart_tests.dart

Definition at line 288 of file renderer_dart_unittests.cc.

288  {
289  ASSERT_TRUE(RunDartFunction("instantiateDefaultContext"));
290 }

◆ TEST_P() [486/549]

impeller::testing::TEST_P ( RendererDartTest  ,
CanReflectUniformStructs   
)

Definition at line 296 of file renderer_dart_unittests.cc.

296  {
297  ASSERT_TRUE(RunDartFunction("canReflectUniformStructs"));
298 }

◆ TEST_P() [487/549]

impeller::testing::TEST_P ( RendererDartTest  ,
CanRunDartInPlaygroundFrame   
)

Definition at line 273 of file renderer_dart_unittests.cc.

273  {
274  SinglePassCallback callback = [&](RenderPass& pass) {
275  ImGui::Begin("Dart test", nullptr);
276  ImGui::Text(
277  "This test executes Dart code during the playground frame callback.");
278  ImGui::End();
279 
280  return RunDartFunction("sayHi");
281  };
282  ASSERT_TRUE(OpenPlaygroundHere(callback));
283 }

◆ TEST_P() [488/549]

impeller::testing::TEST_P ( RendererTest  ,
ArrayUniforms   
)

Definition at line 1023 of file renderer_unittests.cc.

1023  {
1024  using VS = ArrayVertexShader;
1025  using FS = ArrayFragmentShader;
1026 
1027  auto context = GetContext();
1028  auto pipeline_descriptor =
1029  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
1030  ASSERT_TRUE(pipeline_descriptor.has_value());
1031  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1032  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1033  auto pipeline =
1034  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1035  ASSERT_TRUE(pipeline && pipeline->IsValid());
1036 
1037  SinglePassCallback callback = [&](RenderPass& pass) {
1038  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
1039  auto size = pass.GetRenderTargetSize();
1040 
1041  pass.SetPipeline(pipeline);
1042  pass.SetCommandLabel("Google Dots");
1043  VertexBufferBuilder<VS::PerVertexData> builder;
1044  builder.AddVertices({{Point()},
1045  {Point(0, size.height)},
1046  {Point(size.width, 0)},
1047  {Point(size.width, 0)},
1048  {Point(0, size.height)},
1049  {Point(size.width, size.height)}});
1050  pass.SetVertexBuffer(
1051  builder.CreateVertexBuffer(*data_host_buffer, *indexes_host_buffer));
1052 
1053  VS::FrameInfo frame_info;
1054  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1055  frame_info.mvp =
1056  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1057  VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
1058 
1059  auto time = GetSecondsElapsed();
1060  auto y_pos = [&time](float x) {
1061  return 400 + 10 * std::cos(time * 5 + x / 6);
1062  };
1063 
1064  FS::FragInfo fs_uniform = {
1065  .circle_positions = {Point(430, y_pos(0)), Point(480, y_pos(1)),
1066  Point(530, y_pos(2)), Point(580, y_pos(3))},
1067  .colors = {Color::MakeRGBA8(66, 133, 244, 255),
1068  Color::MakeRGBA8(219, 68, 55, 255),
1069  Color::MakeRGBA8(244, 180, 0, 255),
1070  Color::MakeRGBA8(15, 157, 88, 255)},
1071  };
1072  FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
1073 
1074  pass.Draw();
1075  data_host_buffer->Reset();
1076  return true;
1077  };
1078  OpenPlaygroundHere(callback);
1079 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Color::MakeRGBA8(), impeller::Matrix::MakeScale(), and x.

◆ TEST_P() [489/549]

impeller::testing::TEST_P ( RendererTest  ,
BabysFirstTriangle   
)

Definition at line 138 of file renderer_unittests.cc.

138  {
139  auto context = GetContext();
140  ASSERT_TRUE(context);
141 
142  // Declare a shorthand for the shaders we are going to use.
143  using VS = BabyVertexShader;
144  using FS = BabyFragmentShader;
145 
146  // Create a pipeline descriptor that uses the shaders together and default
147  // initializes the fixed function state.
148  //
149  // If the vertex shader outputs disagree with the fragment shader inputs, this
150  // will be a compile time error.
151  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
152  ASSERT_TRUE(desc.has_value());
153 
154  // Modify the descriptor for our environment. This is specific to our test.
155  desc->SetSampleCount(SampleCount::kCount4);
156  desc->SetStencilAttachmentDescriptors(std::nullopt);
157 
158  // Create a pipeline from our descriptor. This is expensive to do. So just do
159  // it once.
160  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
161 
162  // Specify the vertex buffer information.
163  VertexBufferBuilder<VS::PerVertexData> vertex_buffer_builder;
164  vertex_buffer_builder.AddVertices({
165  {{-0.5, -0.5}, Color::Red(), Color::Green()},
166  {{0.0, 0.5}, Color::Green(), Color::Blue()},
167  {{0.5, -0.5}, Color::Blue(), Color::Red()},
168  });
169 
170  auto vertex_buffer = vertex_buffer_builder.CreateVertexBuffer(
171  *context->GetResourceAllocator());
172 
173  SinglePassCallback callback = [&](RenderPass& pass) {
174  pass.SetPipeline(pipeline);
175  pass.SetVertexBuffer(vertex_buffer);
176 
177  FS::FragInfo frag_info;
178  frag_info.time = fml::TimePoint::Now().ToEpochDelta().ToSecondsF();
179 
180  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
181  FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(frag_info));
182 
183  return pass.Draw().ok();
184  };
185  OpenPlaygroundHere(callback);
186 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Color::Blue(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Color::Green(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), and impeller::Color::Red().

◆ TEST_P() [490/549]

impeller::testing::TEST_P ( RendererTest  ,
BindingNullTexturesDoesNotCrash   
)

Definition at line 1620 of file renderer_unittests.cc.

1620  {
1621  using FS = BoxFadeFragmentShader;
1622 
1623  auto context = GetContext();
1624  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
1625  auto command_buffer = context->CreateCommandBuffer();
1626 
1627  RenderTargetAllocator allocator(context->GetResourceAllocator());
1628  RenderTarget target = allocator.CreateOffscreen(*context, {1, 1}, 1);
1629 
1630  auto pass = command_buffer->CreateRenderPass(target);
1631  EXPECT_FALSE(FS::BindContents2(*pass, nullptr, sampler));
1632 }

References impeller::RenderTargetAllocator::CreateOffscreen().

◆ TEST_P() [491/549]

impeller::testing::TEST_P ( RendererTest  ,
CachesRenderPassAndFramebuffer   
)

Definition at line 17 of file render_pass_cache_unittests.cc.

17  {
18  if (GetBackend() != PlaygroundBackend::kVulkan) {
19  GTEST_SKIP() << "Test only applies to Vulkan";
20  }
21 
22  auto allocator = std::make_shared<RenderTargetAllocator>(
23  GetContext()->GetResourceAllocator());
24 
25  RenderTarget render_target =
26  allocator->CreateOffscreenMSAA(*GetContext(), {100, 100}, 1);
27  std::shared_ptr<Texture> resolve_texture =
28  render_target.GetColorAttachment(0).resolve_texture;
29  TextureVK& texture_vk = TextureVK::Cast(*resolve_texture);
30 
31  EXPECT_EQ(texture_vk.GetCachedFrameData(SampleCount::kCount4).framebuffer,
32  nullptr);
33  EXPECT_EQ(texture_vk.GetCachedFrameData(SampleCount::kCount4).render_pass,
34  nullptr);
35 
36  auto buffer = GetContext()->CreateCommandBuffer();
37  auto render_pass = buffer->CreateRenderPass(render_target);
38 
39  EXPECT_NE(texture_vk.GetCachedFrameData(SampleCount::kCount4).framebuffer,
40  nullptr);
41  EXPECT_NE(texture_vk.GetCachedFrameData(SampleCount::kCount4).render_pass,
42  nullptr);
43 
44  render_pass->EncodeCommands();
45  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer}).ok());
46 
47  // Can be reused without error.
48  auto buffer_2 = GetContext()->CreateCommandBuffer();
49  auto render_pass_2 = buffer_2->CreateRenderPass(render_target);
50 
51  EXPECT_TRUE(render_pass_2->EncodeCommands());
52  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_2}).ok());
53 }

References impeller::BackendCast< TextureVK, Texture >::Cast(), impeller::FramebufferAndRenderPass::framebuffer, impeller::TextureVK::GetCachedFrameData(), impeller::RenderTarget::GetColorAttachment(), impeller::kCount4, impeller::kVulkan, impeller::FramebufferAndRenderPass::render_pass, and impeller::Attachment::resolve_texture.

◆ TEST_P() [492/549]

impeller::testing::TEST_P ( RendererTest  ,
CachesRenderPassAndFramebufferMixed   
)

Definition at line 93 of file render_pass_cache_unittests.cc.

93  {
94  if (GetBackend() != PlaygroundBackend::kVulkan) {
95  GTEST_SKIP() << "Test only applies to Vulkan";
96  }
97 
98  auto allocator = std::make_shared<RenderTargetAllocator>(
99  GetContext()->GetResourceAllocator());
100 
101  RenderTarget render_target =
102  allocator->CreateOffscreenMSAA(*GetContext(), {100, 100}, 1);
103  std::shared_ptr<Texture> resolve_texture =
104  render_target.GetColorAttachment(0).resolve_texture;
105  TextureVK& texture_vk = TextureVK::Cast(*resolve_texture);
106 
107  EXPECT_EQ(texture_vk.GetCachedFrameData(SampleCount::kCount4).framebuffer,
108  nullptr);
109  EXPECT_EQ(texture_vk.GetCachedFrameData(SampleCount::kCount4).render_pass,
110  nullptr);
111 
112  auto buffer = GetContext()->CreateCommandBuffer();
113  auto render_pass = buffer->CreateRenderPass(render_target);
114 
115  EXPECT_NE(texture_vk.GetCachedFrameData(SampleCount::kCount4).framebuffer,
116  nullptr);
117  EXPECT_NE(texture_vk.GetCachedFrameData(SampleCount::kCount4).render_pass,
118  nullptr);
119 
120  render_pass->EncodeCommands();
121  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer}).ok());
122 
123  // Can be reused without error.
124  auto buffer_2 = GetContext()->CreateCommandBuffer();
125  auto render_pass_2 = buffer_2->CreateRenderPass(render_target);
126 
127  EXPECT_TRUE(render_pass_2->EncodeCommands());
128  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_2}).ok());
129 
130  // Now switch to single sample count and demonstrate no validation errors.
131  {
132  RenderTarget other_target;
133  ColorAttachment color0;
134  color0.load_action = LoadAction::kLoad;
135  color0.store_action = StoreAction::kStore;
136  color0.texture = resolve_texture;
137  other_target.SetColorAttachment(color0, 0);
138  other_target.SetDepthAttachment(std::nullopt);
139  other_target.SetStencilAttachment(std::nullopt);
140 
141  EXPECT_EQ(texture_vk.GetCachedFrameData(SampleCount::kCount1).framebuffer,
142  nullptr);
143  EXPECT_EQ(texture_vk.GetCachedFrameData(SampleCount::kCount1).render_pass,
144  nullptr);
145 
146  auto buffer_3 = GetContext()->CreateCommandBuffer();
147  auto render_pass_3 = buffer_3->CreateRenderPass(other_target);
148 
149  EXPECT_NE(texture_vk.GetCachedFrameData(SampleCount::kCount1).framebuffer,
150  nullptr);
151  EXPECT_NE(texture_vk.GetCachedFrameData(SampleCount::kCount1).render_pass,
152  nullptr);
153 
154  EXPECT_TRUE(render_pass_3->EncodeCommands());
155  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_3}).ok());
156  }
157 }

References impeller::BackendCast< TextureVK, Texture >::Cast(), impeller::FramebufferAndRenderPass::framebuffer, impeller::TextureVK::GetCachedFrameData(), impeller::RenderTarget::GetColorAttachment(), impeller::kCount1, impeller::kCount4, impeller::kLoad, impeller::kStore, impeller::kVulkan, impeller::Attachment::load_action, impeller::FramebufferAndRenderPass::render_pass, impeller::Attachment::resolve_texture, impeller::RenderTarget::SetColorAttachment(), impeller::RenderTarget::SetDepthAttachment(), impeller::RenderTarget::SetStencilAttachment(), impeller::Attachment::store_action, and impeller::Attachment::texture.

◆ TEST_P() [493/549]

impeller::testing::TEST_P ( RendererTest  ,
CachesRenderPassAndFramebufferNonMSAA   
)

Definition at line 55 of file render_pass_cache_unittests.cc.

55  {
56  if (GetBackend() != PlaygroundBackend::kVulkan) {
57  GTEST_SKIP() << "Test only applies to Vulkan";
58  }
59 
60  auto allocator = std::make_shared<RenderTargetAllocator>(
61  GetContext()->GetResourceAllocator());
62 
63  RenderTarget render_target =
64  allocator->CreateOffscreen(*GetContext(), {100, 100}, 1);
65  std::shared_ptr<Texture> color_texture =
66  render_target.GetColorAttachment(0).texture;
67  TextureVK& texture_vk = TextureVK::Cast(*color_texture);
68 
69  EXPECT_EQ(texture_vk.GetCachedFrameData(SampleCount::kCount1).framebuffer,
70  nullptr);
71  EXPECT_EQ(texture_vk.GetCachedFrameData(SampleCount::kCount1).render_pass,
72  nullptr);
73 
74  auto buffer = GetContext()->CreateCommandBuffer();
75  auto render_pass = buffer->CreateRenderPass(render_target);
76 
77  EXPECT_NE(texture_vk.GetCachedFrameData(SampleCount::kCount1).framebuffer,
78  nullptr);
79  EXPECT_NE(texture_vk.GetCachedFrameData(SampleCount::kCount1).render_pass,
80  nullptr);
81 
82  render_pass->EncodeCommands();
83  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer}).ok());
84 
85  // Can be reused without error.
86  auto buffer_2 = GetContext()->CreateCommandBuffer();
87  auto render_pass_2 = buffer_2->CreateRenderPass(render_target);
88 
89  EXPECT_TRUE(render_pass_2->EncodeCommands());
90  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_2}).ok());
91 }

References impeller::BackendCast< TextureVK, Texture >::Cast(), impeller::FramebufferAndRenderPass::framebuffer, impeller::TextureVK::GetCachedFrameData(), impeller::RenderTarget::GetColorAttachment(), impeller::kCount1, impeller::kVulkan, impeller::FramebufferAndRenderPass::render_pass, and impeller::Attachment::texture.

◆ TEST_P() [494/549]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToBuffer   
)

Definition at line 643 of file renderer_unittests.cc.

643  {
644  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
645  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
646  }
647  auto context = GetContext();
648  ASSERT_TRUE(context);
649 
650  using VS = MipmapsVertexShader;
651  using FS = MipmapsFragmentShader;
652  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
653  ASSERT_TRUE(desc.has_value());
654  desc->SetSampleCount(SampleCount::kCount4);
655  desc->SetStencilAttachmentDescriptors(std::nullopt);
656  auto mipmaps_pipeline =
657  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
658  ASSERT_TRUE(mipmaps_pipeline);
659 
660  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
661  auto boston = CreateTextureForFixture("boston.jpg");
662  ASSERT_TRUE(bridge && boston);
663  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
664  ASSERT_TRUE(sampler);
665 
666  TextureDescriptor texture_desc;
667  texture_desc.storage_mode = StorageMode::kHostVisible;
668  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
669  texture_desc.size = bridge->GetTextureDescriptor().size;
670  texture_desc.mip_count = 1u;
671  texture_desc.usage = TextureUsage::kRenderTarget |
672  TextureUsage::kShaderWrite | TextureUsage::kShaderRead;
673  DeviceBufferDescriptor device_buffer_desc;
674  device_buffer_desc.storage_mode = StorageMode::kHostVisible;
675  device_buffer_desc.size =
676  bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
677  auto device_buffer =
678  context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
679 
680  // Vertex buffer.
681  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
682  vertex_builder.SetLabel("Box");
683  auto size = Point(boston->GetSize());
684  vertex_builder.AddVertices({
685  {{0, 0}, {0.0, 0.0}}, // 1
686  {{size.x, 0}, {1.0, 0.0}}, // 2
687  {{size.x, size.y}, {1.0, 1.0}}, // 3
688  {{0, 0}, {0.0, 0.0}}, // 1
689  {{size.x, size.y}, {1.0, 1.0}}, // 3
690  {{0, size.y}, {0.0, 1.0}}, // 4
691  });
692  auto vertex_buffer =
693  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
694  ASSERT_TRUE(vertex_buffer);
695 
696  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
697  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
698  {
699  auto buffer = context->CreateCommandBuffer();
700  if (!buffer) {
701  return false;
702  }
703  buffer->SetLabel("Playground Command Buffer");
704  auto pass = buffer->CreateBlitPass();
705  if (!pass) {
706  return false;
707  }
708  pass->SetLabel("Playground Blit Pass");
709 
710  // Blit `bridge` to the top left corner of the texture.
711  pass->AddCopy(bridge, device_buffer);
712  pass->EncodeCommands();
713 
714  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
715  return false;
716  }
717  }
718 
719  {
720  auto buffer = context->CreateCommandBuffer();
721  if (!buffer) {
722  return false;
723  }
724  buffer->SetLabel("Playground Command Buffer");
725 
726  auto pass = buffer->CreateRenderPass(render_target);
727  if (!pass) {
728  return false;
729  }
730  pass->SetLabel("Playground Render Pass");
731  {
732  pass->SetCommandLabel("Image");
733  pass->SetPipeline(mipmaps_pipeline);
734  pass->SetVertexBuffer(vertex_buffer);
735 
736  VS::FrameInfo frame_info;
737  EXPECT_EQ(pass->GetOrthographicTransform(),
738  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
739  frame_info.mvp = pass->GetOrthographicTransform() *
740  Matrix::MakeScale(GetContentScale());
741  VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
742 
743  FS::FragInfo frag_info;
744  frag_info.lod = 0;
745  FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
746 
747  raw_ptr<const Sampler> sampler =
748  context->GetSamplerLibrary()->GetSampler({});
749  auto buffer_view = DeviceBuffer::AsBufferView(device_buffer);
750  auto texture =
751  context->GetResourceAllocator()->CreateTexture(texture_desc);
752  if (!texture->SetContents(device_buffer->OnGetContents(),
753  buffer_view.GetRange().length)) {
754  VALIDATION_LOG << "Could not upload texture to device memory";
755  return false;
756  }
757  FS::BindTex(*pass, texture, sampler);
758 
759  pass->Draw().ok();
760  }
761  pass->EncodeCommands();
762  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
763  return false;
764  }
765  }
766  data_host_buffer->Reset();
767  return true;
768  };
769  OpenPlaygroundHere(callback);
770 }
#define VALIDATION_LOG
Definition: validation.h:91

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::DeviceBuffer::AsBufferView(), buffer_view, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::kShaderWrite, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, impeller::TextureDescriptor::storage_mode, impeller::TextureDescriptor::usage, and VALIDATION_LOG.

◆ TEST_P() [495/549]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToTexture   
)

Definition at line 533 of file renderer_unittests.cc.

533  {
534  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
535  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
536  }
537  auto context = GetContext();
538  ASSERT_TRUE(context);
539 
540  using VS = MipmapsVertexShader;
541  using FS = MipmapsFragmentShader;
542  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
543  ASSERT_TRUE(desc.has_value());
544  desc->SetSampleCount(SampleCount::kCount4);
545  desc->SetStencilAttachmentDescriptors(std::nullopt);
546  auto mipmaps_pipeline =
547  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
548  ASSERT_TRUE(mipmaps_pipeline);
549 
550  TextureDescriptor texture_desc;
551  texture_desc.storage_mode = StorageMode::kHostVisible;
552  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
553  texture_desc.size = {800, 600};
554  texture_desc.mip_count = 1u;
555  texture_desc.usage = TextureUsage::kRenderTarget | TextureUsage::kShaderRead;
556  auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
557  ASSERT_TRUE(texture);
558 
559  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
560  auto boston = CreateTextureForFixture("boston.jpg");
561  ASSERT_TRUE(bridge && boston);
562  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
563  ASSERT_TRUE(sampler);
564 
565  // Vertex buffer.
566  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
567  vertex_builder.SetLabel("Box");
568  auto size = Point(boston->GetSize());
569  vertex_builder.AddVertices({
570  {{0, 0}, {0.0, 0.0}}, // 1
571  {{size.x, 0}, {1.0, 0.0}}, // 2
572  {{size.x, size.y}, {1.0, 1.0}}, // 3
573  {{0, 0}, {0.0, 0.0}}, // 1
574  {{size.x, size.y}, {1.0, 1.0}}, // 3
575  {{0, size.y}, {0.0, 1.0}}, // 4
576  });
577  auto vertex_buffer =
578  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
579  ASSERT_TRUE(vertex_buffer);
580 
581  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
582  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
583  auto buffer = context->CreateCommandBuffer();
584  if (!buffer) {
585  return false;
586  }
587  buffer->SetLabel("Playground Command Buffer");
588 
589  {
590  auto pass = buffer->CreateBlitPass();
591  if (!pass) {
592  return false;
593  }
594  pass->SetLabel("Playground Blit Pass");
595 
596  // Blit `bridge` to the top left corner of the texture.
597  pass->AddCopy(bridge, texture);
598 
599  if (!pass->EncodeCommands()) {
600  return false;
601  }
602  }
603 
604  {
605  auto pass = buffer->CreateRenderPass(render_target);
606  if (!pass) {
607  return false;
608  }
609  pass->SetLabel("Playground Render Pass");
610  {
611  pass->SetCommandLabel("Image");
612  pass->SetPipeline(mipmaps_pipeline);
613  pass->SetVertexBuffer(vertex_buffer);
614 
615  VS::FrameInfo frame_info;
616  EXPECT_EQ(pass->GetOrthographicTransform(),
617  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
618  frame_info.mvp = pass->GetOrthographicTransform() *
619  Matrix::MakeScale(GetContentScale());
620  VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
621 
622  FS::FragInfo frag_info;
623  frag_info.lod = 0;
624  FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
625 
626  auto sampler = context->GetSamplerLibrary()->GetSampler({});
627  FS::BindTex(*pass, texture, sampler);
628 
629  pass->Draw();
630  }
631  pass->EncodeCommands();
632  }
633 
634  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
635  return false;
636  }
637  data_host_buffer->Reset();
638  return true;
639  };
640  OpenPlaygroundHere(callback);
641 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::usage.

◆ TEST_P() [496/549]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateBoxPrimitive   
)

Definition at line 70 of file renderer_unittests.cc.

70  {
71  using VS = BoxFadeVertexShader;
72  using FS = BoxFadeFragmentShader;
73  auto context = GetContext();
74  ASSERT_TRUE(context);
75  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
76  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
77  ASSERT_TRUE(desc.has_value());
78  desc->SetSampleCount(SampleCount::kCount4);
79  desc->SetStencilAttachmentDescriptors(std::nullopt);
80 
81  // Vertex buffer.
82  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
83  vertex_builder.SetLabel("Box");
84  vertex_builder.AddVertices({
85  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
86  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
87  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
88  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
89  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
90  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
91  });
92  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
93  auto boston = CreateTextureForFixture("boston.jpg");
94  ASSERT_TRUE(bridge && boston);
95  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
96  ASSERT_TRUE(sampler);
97 
98  SinglePassCallback callback = [&](RenderPass& pass) {
99  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
100  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
101  static bool wireframe;
102  ImGui::Checkbox("Wireframe", &wireframe);
103  ImGui::End();
104 
105  desc->SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
106  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
107 
108  assert(pipeline && pipeline->IsValid());
109 
110  pass.SetCommandLabel("Box");
111  pass.SetPipeline(pipeline);
112  pass.SetVertexBuffer(
113  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()));
114 
115  VS::UniformBuffer uniforms;
116  EXPECT_EQ(pass.GetOrthographicTransform(),
117  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
118  uniforms.mvp =
119  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
120  VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
121 
122  FS::FrameInfo frame_info;
123  frame_info.current_time = GetSecondsElapsed();
124  frame_info.cursor_position = GetCursorPosition();
125  frame_info.window_size.x = GetWindowSize().width;
126  frame_info.window_size.y = GetWindowSize().height;
127 
128  FS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
129  FS::BindContents1(pass, boston, sampler);
130  FS::BindContents2(pass, bridge, sampler);
131 
132  data_host_buffer->Reset();
133  return pass.Draw().ok();
134  };
135  OpenPlaygroundHere(callback);
136 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::kFill, impeller::kLine, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [497/549]

impeller::testing::TEST_P ( RendererTest  ,
CanGenerateMipmaps   
)

Definition at line 772 of file renderer_unittests.cc.

772  {
773  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
774  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
775  }
776  auto context = GetContext();
777  ASSERT_TRUE(context);
778 
779  using VS = MipmapsVertexShader;
780  using FS = MipmapsFragmentShader;
781  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
782  ASSERT_TRUE(desc.has_value());
783  desc->SetSampleCount(SampleCount::kCount4);
784  desc->SetStencilAttachmentDescriptors(std::nullopt);
785  auto mipmaps_pipeline =
786  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
787  ASSERT_TRUE(mipmaps_pipeline);
788 
789  auto boston = CreateTextureForFixture("boston.jpg", true);
790  ASSERT_TRUE(boston);
791 
792  // Vertex buffer.
793  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
794  vertex_builder.SetLabel("Box");
795  auto size = Point(boston->GetSize());
796  vertex_builder.AddVertices({
797  {{0, 0}, {0.0, 0.0}}, // 1
798  {{size.x, 0}, {1.0, 0.0}}, // 2
799  {{size.x, size.y}, {1.0, 1.0}}, // 3
800  {{0, 0}, {0.0, 0.0}}, // 1
801  {{size.x, size.y}, {1.0, 1.0}}, // 3
802  {{0, size.y}, {0.0, 1.0}}, // 4
803  });
804  auto vertex_buffer =
805  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
806  ASSERT_TRUE(vertex_buffer);
807 
808  bool first_frame = true;
809  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
810  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
811  const char* mip_filter_names[] = {"Base", "Nearest", "Linear"};
812  const MipFilter mip_filters[] = {MipFilter::kBase, MipFilter::kNearest,
813  MipFilter::kLinear};
814  const char* min_filter_names[] = {"Nearest", "Linear"};
815  const MinMagFilter min_filters[] = {MinMagFilter::kNearest,
816  MinMagFilter::kLinear};
817 
818  // UI state.
819  static int selected_mip_filter = 1;
820  static int selected_min_filter = 0;
821  static float lod = 4.5;
822 
823  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
824  ImGui::Combo("Mip filter", &selected_mip_filter, mip_filter_names,
825  sizeof(mip_filter_names) / sizeof(char*));
826  ImGui::Combo("Min filter", &selected_min_filter, min_filter_names,
827  sizeof(min_filter_names) / sizeof(char*));
828  ImGui::SliderFloat("LOD", &lod, 0, boston->GetMipCount() - 1);
829  ImGui::End();
830 
831  auto buffer = context->CreateCommandBuffer();
832  if (!buffer) {
833  return false;
834  }
835  buffer->SetLabel("Playground Command Buffer");
836 
837  if (first_frame) {
838  auto pass = buffer->CreateBlitPass();
839  if (!pass) {
840  return false;
841  }
842  pass->SetLabel("Playground Blit Pass");
843 
844  pass->GenerateMipmap(boston, "Boston Mipmap");
845 
846  pass->EncodeCommands();
847  }
848 
849  first_frame = false;
850 
851  {
852  auto pass = buffer->CreateRenderPass(render_target);
853  if (!pass) {
854  return false;
855  }
856  pass->SetLabel("Playground Render Pass");
857  {
858  pass->SetCommandLabel("Image LOD");
859  pass->SetPipeline(mipmaps_pipeline);
860  pass->SetVertexBuffer(vertex_buffer);
861 
862  VS::FrameInfo frame_info;
863  EXPECT_EQ(pass->GetOrthographicTransform(),
864  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
865  frame_info.mvp = pass->GetOrthographicTransform() *
866  Matrix::MakeScale(GetContentScale());
867  VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
868 
869  FS::FragInfo frag_info;
870  frag_info.lod = lod;
871  FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
872 
873  SamplerDescriptor sampler_desc;
874  sampler_desc.mip_filter = mip_filters[selected_mip_filter];
875  sampler_desc.min_filter = min_filters[selected_min_filter];
876  raw_ptr<const Sampler> sampler =
877  context->GetSamplerLibrary()->GetSampler(sampler_desc);
878  FS::BindTex(*pass, boston, sampler);
879 
880  pass->Draw();
881  }
882  pass->EncodeCommands();
883  }
884 
885  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
886  return false;
887  }
888  data_host_buffer->Reset();
889  return true;
890  };
891  OpenPlaygroundHere(callback);
892 }
MipFilter
Options for selecting and filtering between mipmap levels.
Definition: formats.h:425
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
Definition: formats.h:415

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kBase, impeller::kCount4, impeller::kLinear, impeller::kNearest, impeller::kOpenGLES, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::SamplerDescriptor::min_filter, impeller::SamplerDescriptor::mip_filter, and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [498/549]

impeller::testing::TEST_P ( RendererTest  ,
CanLookupRenderTargetProperties   
)

Definition at line 1368 of file renderer_unittests.cc.

1368  {
1369  auto context = GetContext();
1370  auto cmd_buffer = context->CreateCommandBuffer();
1371  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1372  GetContext()->GetResourceAllocator());
1373 
1374  auto render_target = render_target_cache->CreateOffscreen(
1375  *context, {100, 100}, /*mip_count=*/1);
1376  auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1377 
1378  EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1379  EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1380  render_target.GetRenderTargetPixelFormat());
1381  EXPECT_EQ(render_pass->HasStencilAttachment(),
1382  render_target.GetStencilAttachment().has_value());
1383  EXPECT_EQ(render_pass->GetRenderTargetSize(),
1384  render_target.GetRenderTargetSize());
1385  render_pass->EncodeCommands();
1386 }

◆ TEST_P() [499/549]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderInstanced   
)

Definition at line 473 of file renderer_unittests.cc.

473  {
474  if (GetParam() == PlaygroundBackend::kOpenGLES) {
475  GTEST_SKIP() << "Instancing is not supported on OpenGL.";
476  }
477  using VS = InstancedDrawVertexShader;
478  using FS = InstancedDrawFragmentShader;
479 
480  VertexBufferBuilder<VS::PerVertexData> builder;
481  builder.AddVertices({
482  VS::PerVertexData{Point{10, 10}},
483  VS::PerVertexData{Point{10, 110}},
484  VS::PerVertexData{Point{110, 10}},
485  VS::PerVertexData{Point{10, 110}},
486  VS::PerVertexData{Point{110, 10}},
487  VS::PerVertexData{Point{110, 110}},
488  });
489 
490  ASSERT_NE(GetContext(), nullptr);
491  auto pipeline =
492  GetContext()
493  ->GetPipelineLibrary()
494  ->GetPipeline(PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(
495  *GetContext())
496  ->SetSampleCount(SampleCount::kCount4)
497  .SetStencilAttachmentDescriptors(std::nullopt))
498 
499  .Get();
500  ASSERT_TRUE(pipeline && pipeline->IsValid());
501 
502  static constexpr size_t kInstancesCount = 5u;
503  VS::InstanceInfo<kInstancesCount> instances;
504  for (size_t i = 0; i < kInstancesCount; i++) {
505  instances.colors[i] = Color::Random();
506  }
507 
508  ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
509  auto [data_host_buffer, indexes_host_buffer] =
510  createHostBuffers(GetContext());
511  pass.SetPipeline(pipeline);
512  pass.SetCommandLabel("InstancedDraw");
513 
514  VS::FrameInfo frame_info;
515  EXPECT_EQ(pass.GetOrthographicTransform(),
516  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
517  frame_info.mvp =
518  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
519  VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
520  VS::BindInstanceInfo(pass,
521  data_host_buffer->EmplaceStorageBuffer(instances));
522  pass.SetVertexBuffer(
523  builder.CreateVertexBuffer(*data_host_buffer, *indexes_host_buffer));
524 
525  pass.SetInstanceCount(kInstancesCount);
526  pass.Draw();
527 
528  data_host_buffer->Reset();
529  return true;
530  }));
531 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::RenderPass::Draw(), impeller::RenderPass::GetOrthographicTransform(), impeller::RenderPass::GetRenderTargetSize(), impeller::kCount4, impeller::kOpenGLES, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Color::Random(), impeller::RenderPass::SetCommandLabel(), impeller::RenderPass::SetInstanceCount(), impeller::RenderPass::SetPipeline(), and impeller::RenderPass::SetVertexBuffer().

◆ TEST_P() [500/549]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderMultiplePrimitives   
)

Definition at line 299 of file renderer_unittests.cc.

299  {
300  using VS = BoxFadeVertexShader;
301  using FS = BoxFadeFragmentShader;
302  auto context = GetContext();
303  ASSERT_TRUE(context);
304  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
305  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
306  ASSERT_TRUE(desc.has_value());
307  desc->SetSampleCount(SampleCount::kCount4);
308  desc->SetStencilAttachmentDescriptors(std::nullopt);
309  auto box_pipeline =
310  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
311  ASSERT_TRUE(box_pipeline);
312 
313  // Vertex buffer.
314  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
315  vertex_builder.SetLabel("Box");
316  vertex_builder.AddVertices({
317  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
318  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
319  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
320  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
321  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
322  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
323  });
324  auto vertex_buffer =
325  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
326  ASSERT_TRUE(vertex_buffer);
327 
328  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
329  auto boston = CreateTextureForFixture("boston.jpg");
330  ASSERT_TRUE(bridge && boston);
331  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
332  ASSERT_TRUE(sampler);
333 
334  SinglePassCallback callback = [&](RenderPass& pass) {
335  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
336  for (size_t i = 0; i < 1; i++) {
337  for (size_t j = 0; j < 1; j++) {
338  pass.SetCommandLabel("Box");
339  pass.SetPipeline(box_pipeline);
340  pass.SetVertexBuffer(vertex_buffer);
341 
342  FS::FrameInfo frame_info;
343  frame_info.current_time = GetSecondsElapsed();
344  frame_info.cursor_position = GetCursorPosition();
345  frame_info.window_size.x = GetWindowSize().width;
346  frame_info.window_size.y = GetWindowSize().height;
347 
348  FS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
349  FS::BindContents1(pass, boston, sampler);
350  FS::BindContents2(pass, bridge, sampler);
351 
352  VS::UniformBuffer uniforms;
353  EXPECT_EQ(pass.GetOrthographicTransform(),
354  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
355  uniforms.mvp = pass.GetOrthographicTransform() *
356  Matrix::MakeScale(GetContentScale()) *
357  Matrix::MakeTranslation({i * 50.0f, j * 50.0f, 0.0f});
358  VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
359  if (!pass.Draw().ok()) {
360  return false;
361  }
362  }
363  }
364 
365  data_host_buffer->Reset();
366  return true;
367  };
368  OpenPlaygroundHere(callback);
369 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [501/549]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderPerspectiveCube   
)

Definition at line 188 of file renderer_unittests.cc.

188  {
189  using VS = ColorsVertexShader;
190  using FS = ColorsFragmentShader;
191  auto context = GetContext();
192  ASSERT_TRUE(context);
193  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
194  ASSERT_TRUE(desc.has_value());
195  desc->SetCullMode(CullMode::kBackFace);
196  desc->SetWindingOrder(WindingOrder::kCounterClockwise);
197  desc->SetSampleCount(SampleCount::kCount4);
198  desc->ClearStencilAttachments();
199 
200  // Setup the vertex layout to take two bindings. The first for positions and
201  // the second for colors.
202  auto vertex_desc = std::make_shared<VertexDescriptor>();
203  ShaderStageIOSlot position_slot = VS::kInputPosition;
204  ShaderStageIOSlot color_slot = VS::kInputColor;
205  position_slot.binding = 0;
206  position_slot.offset = 0;
207  color_slot.binding = 1;
208  color_slot.offset = 0;
209  const std::vector<ShaderStageIOSlot> io_slots = {position_slot, color_slot};
210  const std::vector<ShaderStageBufferLayout> layouts = {
211  ShaderStageBufferLayout{.stride = 12u, .binding = 0},
212  ShaderStageBufferLayout{.stride = 16u, .binding = 1}};
213  vertex_desc->RegisterDescriptorSetLayouts(VS::kDescriptorSetLayouts);
214  vertex_desc->RegisterDescriptorSetLayouts(FS::kDescriptorSetLayouts);
215  vertex_desc->SetStageInputs(io_slots, layouts);
216  desc->SetVertexDescriptor(std::move(vertex_desc));
217  auto pipeline =
218  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
219  ASSERT_TRUE(pipeline);
220 
221  struct Cube {
222  Vector3 positions[8] = {
223  // -Z
224  {-1, -1, -1},
225  {1, -1, -1},
226  {1, 1, -1},
227  {-1, 1, -1},
228  // +Z
229  {-1, -1, 1},
230  {1, -1, 1},
231  {1, 1, 1},
232  {-1, 1, 1},
233  };
234  Color colors[8] = {
235  Color::Red(), Color::Yellow(), Color::Green(), Color::Blue(),
236  Color::Green(), Color::Blue(), Color::Red(), Color::Yellow(),
237  };
238  uint16_t indices[36] = {
239  1, 5, 2, 2, 5, 6, // +X
240  4, 0, 7, 7, 0, 3, // -X
241  4, 5, 0, 0, 5, 1, // +Y
242  3, 2, 7, 7, 2, 6, // -Y
243  5, 4, 6, 6, 4, 7, // +Z
244  0, 1, 3, 3, 1, 2, // -Z
245  };
246  } cube;
247 
248  auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
249  reinterpret_cast<uint8_t*>(&cube), sizeof(cube));
250 
251  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
252  ASSERT_TRUE(sampler);
253 
254  Vector3 euler_angles;
255  SinglePassCallback callback = [&](RenderPass& pass) {
256  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
257  static Degrees fov_y(60);
258  static Scalar distance = 10;
259 
260  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
261  ImGui::SliderFloat("Field of view", &fov_y.degrees, 0, 180);
262  ImGui::SliderFloat("Camera distance", &distance, 0, 30);
263  ImGui::End();
264 
265  pass.SetCommandLabel("Perspective Cube");
266  pass.SetPipeline(pipeline);
267 
268  std::array<BufferView, 2> vertex_buffers = {
269  BufferView(device_buffer,
270  Range(offsetof(Cube, positions), sizeof(Cube::positions))),
271  BufferView(device_buffer,
272  Range(offsetof(Cube, colors), sizeof(Cube::colors))),
273  };
274 
275  BufferView index_buffer(
276  device_buffer, Range(offsetof(Cube, indices), sizeof(Cube::indices)));
277  pass.SetVertexBuffer(vertex_buffers.data(), vertex_buffers.size());
278  pass.SetElementCount(36);
279  pass.SetIndexBuffer(index_buffer, IndexType::k16bit);
280 
281  VS::UniformBuffer uniforms;
282  Scalar time = GetSecondsElapsed();
283  euler_angles = Vector3(0.19 * time, 0.7 * time, 0.43 * time);
284 
285  uniforms.mvp =
286  Matrix::MakePerspective(fov_y, pass.GetRenderTargetSize(), 0, 10) *
287  Matrix::MakeTranslation({0, 0, distance}) *
288  Matrix::MakeRotationX(Radians(euler_angles.x)) *
289  Matrix::MakeRotationY(Radians(euler_angles.y)) *
290  Matrix::MakeRotationZ(Radians(euler_angles.z));
291  VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
292 
293  data_host_buffer->Reset();
294  return pass.Draw().ok();
295  };
296  OpenPlaygroundHere(callback);
297 }

References impeller::ShaderStageIOSlot::binding, impeller::Color::Blue(), impeller::Degrees::degrees, impeller::saturated::distance, impeller::Color::Green(), impeller::k16bit, impeller::kBackFace, impeller::kCount4, impeller::kCounterClockwise, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakePerspective(), impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), impeller::ShaderStageIOSlot::offset, impeller::Color::Red(), impeller::ShaderStageBufferLayout::stride, impeller::Vector3::x, impeller::Vector3::y, impeller::Color::Yellow(), and impeller::Vector3::z.

◆ TEST_P() [502/549]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderToTexture   
)

Definition at line 371 of file renderer_unittests.cc.

371  {
372  using VS = BoxFadeVertexShader;
373  using FS = BoxFadeFragmentShader;
374  auto context = GetContext();
375  ASSERT_TRUE(context);
376  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
377  auto pipeline_desc =
378  BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
379  pipeline_desc->SetSampleCount(SampleCount::kCount1);
380  pipeline_desc->ClearDepthAttachment();
381  pipeline_desc->SetStencilPixelFormat(PixelFormat::kS8UInt);
382 
383  ASSERT_TRUE(pipeline_desc.has_value());
384  auto box_pipeline =
385  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
386  ASSERT_TRUE(box_pipeline);
387  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
388 
389  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
390  vertex_builder.SetLabel("Box");
391  vertex_builder.AddVertices({
392  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
393  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
394  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
395  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
396  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
397  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
398  });
399  auto vertex_buffer =
400  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
401  ASSERT_TRUE(vertex_buffer);
402 
403  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
404  auto boston = CreateTextureForFixture("boston.jpg");
405  ASSERT_TRUE(bridge && boston);
406  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
407  ASSERT_TRUE(sampler);
408 
409  std::shared_ptr<RenderPass> r2t_pass;
410  auto cmd_buffer = context->CreateCommandBuffer();
411  ASSERT_TRUE(cmd_buffer);
412  {
413  ColorAttachment color0;
414  color0.load_action = LoadAction::kClear;
415  color0.store_action = StoreAction::kStore;
416 
417  TextureDescriptor texture_descriptor;
418  ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u), nullptr);
419  texture_descriptor.format =
420  pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
421  texture_descriptor.storage_mode = StorageMode::kHostVisible;
422  texture_descriptor.size = {400, 400};
423  texture_descriptor.mip_count = 1u;
424  texture_descriptor.usage = TextureUsage::kRenderTarget;
425 
426  color0.texture =
427  context->GetResourceAllocator()->CreateTexture(texture_descriptor);
428 
429  ASSERT_TRUE(color0.IsValid());
430 
431  color0.texture->SetLabel("r2t_target");
432 
433  StencilAttachment stencil0;
434  stencil0.load_action = LoadAction::kClear;
435  stencil0.store_action = StoreAction::kDontCare;
436  TextureDescriptor stencil_texture_desc;
437  stencil_texture_desc.storage_mode = StorageMode::kDeviceTransient;
438  stencil_texture_desc.size = texture_descriptor.size;
439  stencil_texture_desc.format = PixelFormat::kS8UInt;
440  stencil_texture_desc.usage = TextureUsage::kRenderTarget;
441  stencil0.texture =
442  context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
443 
444  RenderTarget r2t_desc;
445  r2t_desc.SetColorAttachment(color0, 0u);
446  r2t_desc.SetStencilAttachment(stencil0);
447  r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
448  ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
449  }
450 
451  r2t_pass->SetCommandLabel("Box");
452  r2t_pass->SetPipeline(box_pipeline);
453  r2t_pass->SetVertexBuffer(vertex_buffer);
454 
455  FS::FrameInfo frame_info;
456  frame_info.current_time = GetSecondsElapsed();
457  frame_info.cursor_position = GetCursorPosition();
458  frame_info.window_size.x = GetWindowSize().width;
459  frame_info.window_size.y = GetWindowSize().height;
460 
461  FS::BindFrameInfo(*r2t_pass, data_host_buffer->EmplaceUniform(frame_info));
462  FS::BindContents1(*r2t_pass, boston, sampler);
463  FS::BindContents2(*r2t_pass, bridge, sampler);
464 
465  VS::UniformBuffer uniforms;
466  uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) *
467  Matrix::MakeTranslation({50.0f, 50.0f, 0.0f});
468  VS::BindUniformBuffer(*r2t_pass, data_host_buffer->EmplaceUniform(uniforms));
469  ASSERT_TRUE(r2t_pass->Draw().ok());
470  ASSERT_TRUE(r2t_pass->EncodeCommands());
471 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::TextureDescriptor::format, impeller::Attachment::IsValid(), impeller::kClear, impeller::kCount1, impeller::kDeviceTransient, impeller::kDontCare, impeller::kHostVisible, impeller::kRenderTarget, impeller::kS8UInt, impeller::kStore, impeller::Attachment::load_action, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeTranslation(), impeller::TextureDescriptor::mip_count, impeller::RenderTarget::SetColorAttachment(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::RenderTarget::SetStencilAttachment(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, impeller::Attachment::texture, and impeller::TextureDescriptor::usage.

◆ TEST_P() [503/549]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneThenSwizzleWithSubpasses   
)

Definition at line 1511 of file renderer_unittests.cc.

1511  {
1512  // Define shader types
1513  using TextureVS = TextureVertexShader;
1514  using TextureFS = TextureFragmentShader;
1515 
1516  using SwizzleVS = SepiaVertexShader;
1517  using SwizzleFS = SwizzleFragmentShader;
1518 
1519  using SepiaVS = SepiaVertexShader;
1520  using SepiaFS = SepiaFragmentShader;
1521 
1522  auto context = GetContext();
1523  ASSERT_TRUE(context);
1524 
1525  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1526  GTEST_SKIP() << "This test uses framebuffer fetch and the backend doesn't "
1527  "support it.";
1528  return;
1529  }
1530 
1531  // Create pipelines.
1532  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1533  auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1534  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1535 
1536  ASSERT_TRUE(texture_pipeline);
1537  ASSERT_TRUE(swizzle_pipeline);
1538  ASSERT_TRUE(sepia_pipeline);
1539 
1540  // Vertex buffer builders.
1541  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1542  texture_vtx_builder.AddVertices({
1543  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1544  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1545  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1546  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1547  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1548  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1549  });
1550 
1551  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1552  sepia_vtx_builder.AddVertices({
1553  {{100, 100, 0.0}}, // 1
1554  {{800, 100, 0.0}}, // 2
1555  {{800, 800, 0.0}}, // 3
1556  {{100, 100, 0.0}}, // 1
1557  {{800, 800, 0.0}}, // 3
1558  {{100, 800, 0.0}}, // 4
1559  });
1560 
1561  auto boston = CreateTextureForFixture("boston.jpg");
1562  ASSERT_TRUE(boston);
1563 
1564  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1565  ASSERT_TRUE(sampler);
1566 
1567  SinglePassCallback callback = [&](RenderPass& pass) {
1568  auto data_buffer = HostBuffer::Create(
1569  context->GetResourceAllocator(), context->GetIdleWaiter(),
1570  context->GetCapabilities()->GetMinimumUniformAlignment());
1571 
1572  // Draw the texture.
1573  {
1574  pass.SetPipeline(texture_pipeline);
1575  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1576  *context->GetResourceAllocator()));
1577  TextureVS::UniformBuffer uniforms;
1578  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1579  Matrix::MakeScale(GetContentScale());
1580  TextureVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1581  TextureFS::BindTextureContents(pass, boston, sampler);
1582  if (!pass.Draw().ok()) {
1583  return false;
1584  }
1585  }
1586 
1587  // Draw the sepia toner.
1588  {
1589  pass.SetPipeline(sepia_pipeline);
1590  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1591  *context->GetResourceAllocator()));
1592  SepiaVS::UniformBuffer uniforms;
1593  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1594  Matrix::MakeScale(GetContentScale());
1595  SepiaVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1596  if (!pass.Draw().ok()) {
1597  return false;
1598  }
1599  }
1600 
1601  // Draw the swizzle.
1602  {
1603  pass.SetPipeline(swizzle_pipeline);
1604  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1605  *context->GetResourceAllocator()));
1606  SwizzleVS::UniformBuffer uniforms;
1607  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1608  Matrix::MakeScale(GetContentScale());
1609  SwizzleVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1610  if (!pass.Draw().ok()) {
1611  return false;
1612  }
1613  }
1614 
1615  return true;
1616  };
1617  OpenPlaygroundHere(callback);
1618 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [504/549]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneWithSubpasses   
)

Definition at line 1421 of file renderer_unittests.cc.

1421  {
1422  // Define shader types
1423  using TextureVS = TextureVertexShader;
1424  using TextureFS = TextureFragmentShader;
1425 
1426  using SepiaVS = SepiaVertexShader;
1427  using SepiaFS = SepiaFragmentShader;
1428 
1429  auto context = GetContext();
1430  ASSERT_TRUE(context);
1431 
1432  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1433  GTEST_SKIP() << "This test uses framebuffer fetch and the backend doesn't "
1434  "support it.";
1435  return;
1436  }
1437 
1438  // Create pipelines.
1439  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1440  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1441 
1442  ASSERT_TRUE(texture_pipeline);
1443  ASSERT_TRUE(sepia_pipeline);
1444 
1445  // Vertex buffer builders.
1446  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1447  texture_vtx_builder.AddVertices({
1448  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1449  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1450  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1451  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1452  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1453  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1454  });
1455 
1456  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1457  sepia_vtx_builder.AddVertices({
1458  {{100, 100, 0.0}}, // 1
1459  {{800, 100, 0.0}}, // 2
1460  {{800, 800, 0.0}}, // 3
1461  {{100, 100, 0.0}}, // 1
1462  {{800, 800, 0.0}}, // 3
1463  {{100, 800, 0.0}}, // 4
1464  });
1465 
1466  auto boston = CreateTextureForFixture("boston.jpg");
1467  ASSERT_TRUE(boston);
1468 
1469  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1470  ASSERT_TRUE(sampler);
1471 
1472  SinglePassCallback callback = [&](RenderPass& pass) {
1473  auto buffer = HostBuffer::Create(
1474  context->GetResourceAllocator(), context->GetIdleWaiter(),
1475  context->GetCapabilities()->GetMinimumUniformAlignment());
1476 
1477  // Draw the texture.
1478  {
1479  pass.SetPipeline(texture_pipeline);
1480  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1481  *context->GetResourceAllocator()));
1482  TextureVS::UniformBuffer uniforms;
1483  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1484  Matrix::MakeScale(GetContentScale());
1485  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1486  TextureFS::BindTextureContents(pass, boston, sampler);
1487  if (!pass.Draw().ok()) {
1488  return false;
1489  }
1490  }
1491 
1492  // Draw the sepia toner.
1493  {
1494  pass.SetPipeline(sepia_pipeline);
1495  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1496  *context->GetResourceAllocator()));
1497  SepiaVS::UniformBuffer uniforms;
1498  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1499  Matrix::MakeScale(GetContentScale());
1500  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1501  if (!pass.Draw().ok()) {
1502  return false;
1503  }
1504  }
1505 
1506  return true;
1507  };
1508  OpenPlaygroundHere(callback);
1509 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [505/549]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexBehavior   
)

Definition at line 1139 of file renderer_unittests.cc.

1139  {
1140  using VS = BoxFadeVertexShader;
1141 
1142  // Do not create any index buffer if no indices were provided.
1143  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1144  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::kNone);
1145 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::kNone.

◆ TEST_P() [506/549]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexSize   
)

Definition at line 1129 of file renderer_unittests.cc.

1129  {
1130  using VS = BoxFadeVertexShader;
1131 
1132  // Default to 16bit index buffer size, as this is a reasonable default and
1133  // supported on all backends without extensions.
1134  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1135  vertex_builder.AppendIndex(0u);
1136  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::k16bit);
1137 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::k16bit.

◆ TEST_P() [507/549]

impeller::testing::TEST_P ( RendererTest  ,
InactiveUniforms   
)

Definition at line 1081 of file renderer_unittests.cc.

1081  {
1082  using VS = InactiveUniformsVertexShader;
1083  using FS = InactiveUniformsFragmentShader;
1084 
1085  auto context = GetContext();
1086  auto pipeline_descriptor =
1087  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
1088  ASSERT_TRUE(pipeline_descriptor.has_value());
1089  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1090  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1091  auto pipeline =
1092  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1093  ASSERT_TRUE(pipeline && pipeline->IsValid());
1094 
1095  SinglePassCallback callback = [&](RenderPass& pass) {
1096  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
1097  auto size = pass.GetRenderTargetSize();
1098 
1099  pass.SetPipeline(pipeline);
1100  pass.SetCommandLabel("Inactive Uniform");
1101 
1102  VertexBufferBuilder<VS::PerVertexData> builder;
1103  builder.AddVertices({{Point()},
1104  {Point(0, size.height)},
1105  {Point(size.width, 0)},
1106  {Point(size.width, 0)},
1107  {Point(0, size.height)},
1108  {Point(size.width, size.height)}});
1109  pass.SetVertexBuffer(
1110  builder.CreateVertexBuffer(*data_host_buffer, *indexes_host_buffer));
1111 
1112  VS::FrameInfo frame_info;
1113  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1114  frame_info.mvp =
1115  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1116  VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
1117 
1118  FS::FragInfo fs_uniform = {.unused_color = Color::Red(),
1119  .color = Color::Green()};
1120  FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
1121 
1122  pass.Draw().ok();
1123  data_host_buffer->Reset();
1124  return true;
1125  };
1126  OpenPlaygroundHere(callback);
1127 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Color::Green(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), and impeller::Color::Red().

◆ TEST_P() [508/549]

impeller::testing::TEST_P ( RendererTest  ,
Planet   
)

Definition at line 957 of file renderer_unittests.cc.

957  {
958  using VS = PlanetVertexShader;
959  using FS = PlanetFragmentShader;
960 
961  auto context = GetContext();
962  auto pipeline_descriptor =
963  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
964  ASSERT_TRUE(pipeline_descriptor.has_value());
965  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
966  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
967  auto pipeline =
968  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
969  ASSERT_TRUE(pipeline && pipeline->IsValid());
970 
971  SinglePassCallback callback = [&](RenderPass& pass) {
972  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
973  static Scalar speed = 0.1;
974  static Scalar planet_size = 550.0;
975  static bool show_normals = false;
976  static bool show_noise = false;
977  static Scalar seed_value = 42.0;
978 
979  auto size = pass.GetRenderTargetSize();
980 
981  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
982  ImGui::SliderFloat("Speed", &speed, 0.0, 10.0);
983  ImGui::SliderFloat("Planet Size", &planet_size, 0.1, 1000);
984  ImGui::Checkbox("Show Normals", &show_normals);
985  ImGui::Checkbox("Show Noise", &show_noise);
986  ImGui::InputFloat("Seed Value", &seed_value);
987  ImGui::End();
988 
989  pass.SetPipeline(pipeline);
990  pass.SetCommandLabel("Planet scene");
991  VertexBufferBuilder<VS::PerVertexData> builder;
992  builder.AddVertices({{Point()},
993  {Point(0, size.height)},
994  {Point(size.width, 0)},
995  {Point(size.width, 0)},
996  {Point(0, size.height)},
997  {Point(size.width, size.height)}});
998  pass.SetVertexBuffer(
999  builder.CreateVertexBuffer(*data_host_buffer, *indexes_host_buffer));
1000 
1001  VS::FrameInfo frame_info;
1002  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1003  frame_info.mvp = pass.GetOrthographicTransform();
1004  VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
1005 
1006  FS::FragInfo fs_uniform;
1007  fs_uniform.resolution = Point(size);
1008  fs_uniform.time = GetSecondsElapsed();
1009  fs_uniform.speed = speed;
1010  fs_uniform.planet_size = planet_size;
1011  fs_uniform.show_normals = show_normals ? 1.0 : 0.0;
1012  fs_uniform.show_noise = show_noise ? 1.0 : 0.0;
1013  fs_uniform.seed_value = seed_value;
1014  FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
1015 
1016  pass.Draw().ok();
1017  data_host_buffer->Reset();
1018  return true;
1019  };
1020  OpenPlaygroundHere(callback);
1021 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), and impeller::Matrix::MakeOrthographic().

◆ TEST_P() [509/549]

impeller::testing::TEST_P ( RendererTest  ,
RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat   
)

Definition at line 1388 of file renderer_unittests.cc.

1389  {
1390  auto context = GetContext();
1391  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1392  GetContext()->GetResourceAllocator());
1393 
1394  RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1395  *context, {100, 100}, /*mip_count=*/1);
1396  EXPECT_EQ(render_target.GetDepthAttachment()
1397  ->texture->GetTextureDescriptor()
1398  .format,
1399  GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1400 }

References impeller::RenderTarget::GetDepthAttachment().

◆ TEST_P() [510/549]

impeller::testing::TEST_P ( RendererTest  ,
StencilMask   
)

Definition at line 1217 of file renderer_unittests.cc.

1217  {
1218  using VS = BoxFadeVertexShader;
1219  using FS = BoxFadeFragmentShader;
1220  auto context = GetContext();
1221  ASSERT_TRUE(context);
1222  using BoxFadePipelineBuilder = PipelineBuilder<VS, FS>;
1223  auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1224  ASSERT_TRUE(desc.has_value());
1225 
1226  // Vertex buffer.
1227  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1228  vertex_builder.SetLabel("Box");
1229  vertex_builder.AddVertices({
1230  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1231  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1232  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1233  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1234  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1235  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1236  });
1237  auto vertex_buffer =
1238  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
1239  ASSERT_TRUE(vertex_buffer);
1240 
1241  desc->SetSampleCount(SampleCount::kCount4);
1242  desc->SetStencilAttachmentDescriptors(std::nullopt);
1243 
1244  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1245  auto boston = CreateTextureForFixture("boston.jpg");
1246  ASSERT_TRUE(bridge && boston);
1247  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
1248  ASSERT_TRUE(sampler);
1249 
1250  static bool mirror = false;
1251  static int stencil_reference_write = 0xFF;
1252  static int stencil_reference_read = 0x1;
1253  std::vector<uint8_t> stencil_contents;
1254  static int last_stencil_contents_reference_value = 0;
1255  static int current_front_compare =
1256  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1257  static int current_back_compare =
1258  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1259 
1260  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
1261  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
1262  auto buffer = context->CreateCommandBuffer();
1263  if (!buffer) {
1264  return false;
1265  }
1266  buffer->SetLabel("Playground Command Buffer");
1267 
1268  {
1269  // Configure the stencil attachment for the test.
1270  RenderTarget::AttachmentConfig stencil_config;
1271  stencil_config.load_action = LoadAction::kLoad;
1272  stencil_config.store_action = StoreAction::kDontCare;
1273  stencil_config.storage_mode = StorageMode::kHostVisible;
1274  render_target.SetupDepthStencilAttachments(
1275  *context, *context->GetResourceAllocator(),
1276  render_target.GetRenderTargetSize(), true, "stencil", stencil_config);
1277  // Fill the stencil buffer with an checkerboard pattern.
1278  const auto target_width = render_target.GetRenderTargetSize().width;
1279  const auto target_height = render_target.GetRenderTargetSize().height;
1280  const size_t target_size = target_width * target_height;
1281  if (stencil_contents.size() != target_size ||
1282  last_stencil_contents_reference_value != stencil_reference_write) {
1283  stencil_contents.resize(target_size);
1284  last_stencil_contents_reference_value = stencil_reference_write;
1285  for (int y = 0; y < target_height; y++) {
1286  for (int x = 0; x < target_width; x++) {
1287  const auto index = y * target_width + x;
1288  const auto kCheckSize = 64;
1289  const auto value =
1290  (((y / kCheckSize) + (x / kCheckSize)) % 2 == 0) *
1291  stencil_reference_write;
1292  stencil_contents[index] = value;
1293  }
1294  }
1295  }
1296  if (!render_target.GetStencilAttachment()->texture->SetContents(
1297  stencil_contents.data(), stencil_contents.size(), 0, false)) {
1298  VALIDATION_LOG << "Could not upload stencil contents to device memory";
1299  return false;
1300  }
1301  auto pass = buffer->CreateRenderPass(render_target);
1302  if (!pass) {
1303  return false;
1304  }
1305  pass->SetLabel("Stencil Buffer");
1306  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1307  ImGui::SliderInt("Stencil Write Value", &stencil_reference_write, 0,
1308  0xFF);
1309  ImGui::SliderInt("Stencil Compare Value", &stencil_reference_read, 0,
1310  0xFF);
1311  ImGui::Checkbox("Back face mode", &mirror);
1312  ImGui::ListBox("Front face compare function", &current_front_compare,
1313  CompareFunctionUI().labels(), CompareFunctionUI().size());
1314  ImGui::ListBox("Back face compare function", &current_back_compare,
1315  CompareFunctionUI().labels(), CompareFunctionUI().size());
1316  ImGui::End();
1317 
1318  StencilAttachmentDescriptor front;
1319  front.stencil_compare =
1320  CompareFunctionUI().FunctionOf(current_front_compare);
1321  StencilAttachmentDescriptor back;
1322  back.stencil_compare =
1323  CompareFunctionUI().FunctionOf(current_back_compare);
1324  desc->SetStencilAttachmentDescriptors(front, back);
1325  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1326 
1327  assert(pipeline && pipeline->IsValid());
1328 
1329  pass->SetCommandLabel("Box");
1330  pass->SetPipeline(pipeline);
1331  pass->SetStencilReference(stencil_reference_read);
1332  pass->SetVertexBuffer(vertex_buffer);
1333 
1334  VS::UniformBuffer uniforms;
1335  EXPECT_EQ(pass->GetOrthographicTransform(),
1336  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
1337  uniforms.mvp = pass->GetOrthographicTransform() *
1338  Matrix::MakeScale(GetContentScale());
1339  if (mirror) {
1340  uniforms.mvp = Matrix::MakeScale(Vector2(-1, 1)) * uniforms.mvp;
1341  }
1342  VS::BindUniformBuffer(*pass, data_host_buffer->EmplaceUniform(uniforms));
1343 
1344  FS::FrameInfo frame_info;
1345  frame_info.current_time = GetSecondsElapsed();
1346  frame_info.cursor_position = GetCursorPosition();
1347  frame_info.window_size.x = GetWindowSize().width;
1348  frame_info.window_size.y = GetWindowSize().height;
1349 
1350  FS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
1351  FS::BindContents1(*pass, boston, sampler);
1352  FS::BindContents2(*pass, bridge, sampler);
1353  if (!pass->Draw().ok()) {
1354  return false;
1355  }
1356  pass->EncodeCommands();
1357  }
1358 
1359  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1360  return false;
1361  }
1362  data_host_buffer->Reset();
1363  return true;
1364  };
1365  OpenPlaygroundHere(callback);
1366 }
CompareFunction FunctionOf(int index) const
int IndexOf(CompareFunction func) const
static const CompareFunctionUIData & CompareFunctionUI()

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), CompareFunctionUI(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::testing::CompareFunctionUIData::FunctionOf(), impeller::testing::CompareFunctionUIData::IndexOf(), impeller::kCount4, impeller::kDontCare, impeller::kHostVisible, impeller::kLessEqual, impeller::kLoad, impeller::RenderTarget::AttachmentConfig::load_action, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::StencilAttachmentDescriptor::stencil_compare, impeller::RenderTarget::AttachmentConfig::storage_mode, impeller::RenderTarget::AttachmentConfig::store_action, VALIDATION_LOG, value, and x.

◆ TEST_P() [511/549]

impeller::testing::TEST_P ( RendererTest  ,
TheImpeller   
)

Definition at line 894 of file renderer_unittests.cc.

894  {
895  using VS = ImpellerVertexShader;
896  using FS = ImpellerFragmentShader;
897 
898  auto context = GetContext();
899  auto pipeline_descriptor =
900  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
901  ASSERT_TRUE(pipeline_descriptor.has_value());
902  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
903  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
904  auto pipeline =
905  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
906  ASSERT_TRUE(pipeline && pipeline->IsValid());
907 
908  auto blue_noise = CreateTextureForFixture("blue_noise.png");
909  SamplerDescriptor noise_sampler_desc;
910  noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
911  noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat;
912  raw_ptr<const Sampler> noise_sampler =
913  context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
914 
915  auto cube_map = CreateTextureCubeForFixture(
916  {"table_mountain_px.png", "table_mountain_nx.png",
917  "table_mountain_py.png", "table_mountain_ny.png",
918  "table_mountain_pz.png", "table_mountain_nz.png"});
919  raw_ptr<const Sampler> cube_map_sampler =
920  context->GetSamplerLibrary()->GetSampler({});
921 
922  SinglePassCallback callback = [&](RenderPass& pass) {
923  auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
924  auto size = pass.GetRenderTargetSize();
925 
926  pass.SetPipeline(pipeline);
927  pass.SetCommandLabel("Impeller SDF scene");
928  VertexBufferBuilder<VS::PerVertexData> builder;
929  builder.AddVertices({{Point()},
930  {Point(0, size.height)},
931  {Point(size.width, 0)},
932  {Point(size.width, 0)},
933  {Point(0, size.height)},
934  {Point(size.width, size.height)}});
935  pass.SetVertexBuffer(
936  builder.CreateVertexBuffer(*data_host_buffer, *indexes_host_buffer));
937 
938  VS::FrameInfo frame_info;
939  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
940  frame_info.mvp = pass.GetOrthographicTransform();
941  VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
942 
943  FS::FragInfo fs_uniform;
944  fs_uniform.texture_size = Point(size);
945  fs_uniform.time = GetSecondsElapsed();
946  FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
947  FS::BindBlueNoise(pass, blue_noise, noise_sampler);
948  FS::BindCubeMap(pass, cube_map, cube_map_sampler);
949 
950  pass.Draw().ok();
951  data_host_buffer->Reset();
952  return true;
953  };
954  OpenPlaygroundHere(callback);
955 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::SamplerDescriptor::height_address_mode, impeller::kCount4, impeller::kRepeat, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), and impeller::SamplerDescriptor::width_address_mode.

◆ TEST_P() [512/549]

impeller::testing::TEST_P ( RendererTest  ,
VertexBufferBuilder   
)

Definition at line 1147 of file renderer_unittests.cc.

1147  {
1148  // Does not create index buffer if one is provided.
1149  using VS = BoxFadeVertexShader;
1150  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1151  vertex_builder.SetLabel("Box");
1152  vertex_builder.AddVertices({
1153  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1154  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1155  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1156  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1157  });
1158  vertex_builder.AppendIndex(0);
1159  vertex_builder.AppendIndex(1);
1160  vertex_builder.AppendIndex(2);
1161  vertex_builder.AppendIndex(1);
1162  vertex_builder.AppendIndex(2);
1163  vertex_builder.AppendIndex(3);
1164 
1165  ASSERT_EQ(vertex_builder.GetIndexCount(), 6u);
1166  ASSERT_EQ(vertex_builder.GetVertexCount(), 4u);
1167 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexCount(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetVertexCount(), and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [513/549]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachedTextureGetsNewAttachmentConfig   
)

Definition at line 123 of file render_target_cache_unittests.cc.

123  {
124  auto render_target_cache = RenderTargetCache(
125  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
126 
127  render_target_cache.Start();
128  RenderTarget::AttachmentConfig color_attachment_config =
129  RenderTarget::kDefaultColorAttachmentConfig;
130  RenderTarget target1 = render_target_cache.CreateOffscreen(
131  *GetContext(), {100, 100}, 1, "Offscreen1", color_attachment_config);
132  render_target_cache.End();
133 
134  render_target_cache.Start();
135  color_attachment_config.clear_color = Color::Red();
136  RenderTarget target2 = render_target_cache.CreateOffscreen(
137  *GetContext(), {100, 100}, 1, "Offscreen2", color_attachment_config);
138  render_target_cache.End();
139 
140  ColorAttachment color1 = target1.GetColorAttachment(0);
141  ColorAttachment color2 = target2.GetColorAttachment(0);
142  // The second color attachment should reuse the first attachment's texture
143  // but with attributes from the second AttachmentConfig.
144  EXPECT_EQ(color2.texture, color1.texture);
145  EXPECT_EQ(color2.clear_color, Color::Red());
146 }

References impeller::ColorAttachment::clear_color, impeller::RenderTarget::AttachmentConfig::clear_color, impeller::RenderTarget::GetColorAttachment(), impeller::RenderTarget::kDefaultColorAttachmentConfig, impeller::Color::Red(), and impeller::Attachment::texture.

◆ TEST_P() [514/549]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachesUsedTexturesAcrossFrames   
)

Definition at line 53 of file render_target_cache_unittests.cc.

53  {
54  auto render_target_cache = RenderTargetCache(
55  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
56 
57  render_target_cache.Start();
58  // Create two render targets of the same exact size/shape. Both should be
59  // marked as used this frame, so the cached data set will contain two.
60  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
61  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
62 
63  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
64 
65  render_target_cache.End();
66  render_target_cache.Start();
67 
68  // Next frame, only create one texture. The set will still contain two,
69  // but one will be removed at the end of the frame.
70  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
71  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
72 
73  render_target_cache.End();
74  EXPECT_EQ(render_target_cache.CachedTextureCount(), 1u);
75 }

◆ TEST_P() [515/549]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachesUsedTexturesAcrossFramesWithKeepAlive   
)

Definition at line 77 of file render_target_cache_unittests.cc.

77  {
78  auto render_target_cache = RenderTargetCache(
79  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/3);
80 
81  render_target_cache.Start();
82  // Create two render targets of the same exact size/shape. Both should be
83  // marked as used this frame, so the cached data set will contain two.
84  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
85  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
86 
87  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
88 
89  render_target_cache.End();
90  render_target_cache.Start();
91 
92  // The unused texture is kept alive until the keep alive countdown
93  // reaches 0.
94  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
95 
96  for (auto i = 0; i < 3; i++) {
97  render_target_cache.Start();
98  render_target_cache.End();
99  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
100  }
101  // After the countdown has elapsed the texture is removed.
102  render_target_cache.Start();
103  render_target_cache.End();
104  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
105 }

◆ TEST_P() [516/549]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CreateWithEmptySize   
)

Definition at line 148 of file render_target_cache_unittests.cc.

148  {
149  auto render_target_cache = RenderTargetCache(
150  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
151 
152  render_target_cache.Start();
153  RenderTarget empty_target =
154  render_target_cache.CreateOffscreen(*GetContext(), {100, 0}, 1);
155  RenderTarget empty_target_msaa =
156  render_target_cache.CreateOffscreenMSAA(*GetContext(), {0, 0}, 1);
157  render_target_cache.End();
158 
159  {
160  ScopedValidationDisable disable_validation;
161  EXPECT_FALSE(empty_target.IsValid());
162  EXPECT_FALSE(empty_target_msaa.IsValid());
163  }
164 }

References impeller::RenderTarget::IsValid().

◆ TEST_P() [517/549]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
DoesNotPersistFailedAllocations   
)

Definition at line 107 of file render_target_cache_unittests.cc.

107  {
108  ScopedValidationDisable disable;
109  auto allocator = std::make_shared<TestAllocator>();
110  auto render_target_cache =
111  RenderTargetCache(allocator, /*keep_alive_frame_count=*/0);
112 
113  render_target_cache.Start();
114  allocator->should_fail = true;
115 
116  auto render_target =
117  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
118 
119  EXPECT_FALSE(render_target.IsValid());
120  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
121 }

◆ TEST_P() [518/549]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanCreatePipelineFromRuntimeStage   
)

Definition at line 315 of file runtime_stage_unittests.cc.

315  {
316  auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
317  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
318 
319  ASSERT_TRUE(stage);
320  ASSERT_NE(stage, nullptr);
321  ASSERT_TRUE(RegisterStage(*stage));
322  auto library = GetContext()->GetShaderLibrary();
323  using VS = RuntimeEffectVertexShader;
324  PipelineDescriptor desc;
325  desc.SetLabel("Runtime Stage InkSparkle");
326  desc.AddStageEntrypoint(
327  library->GetFunction(VS::kEntrypointName, ShaderStage::kVertex));
328  desc.AddStageEntrypoint(
329  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment));
330  auto vertex_descriptor = std::make_shared<VertexDescriptor>();
331  vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs,
332  VS::kInterleavedBufferLayout);
333 
334  std::array<DescriptorSetLayout, 2> descriptor_set_layouts = {
335  VS::kDescriptorSetLayouts[0],
336  DescriptorSetLayout{
337  .binding = 64u,
338  .descriptor_type = DescriptorType::kUniformBuffer,
339  .shader_stage = ShaderStage::kFragment,
340  },
341  };
342  vertex_descriptor->RegisterDescriptorSetLayouts(descriptor_set_layouts);
343 
344  desc.SetVertexDescriptor(std::move(vertex_descriptor));
345  ColorAttachmentDescriptor color0;
346  color0.format = GetContext()->GetCapabilities()->GetDefaultColorFormat();
347  StencilAttachmentDescriptor stencil0;
348  stencil0.stencil_compare = CompareFunction::kEqual;
349  desc.SetColorAttachmentDescriptor(0u, color0);
350  desc.SetStencilAttachmentDescriptors(stencil0);
351  const auto stencil_fmt =
352  GetContext()->GetCapabilities()->GetDefaultStencilFormat();
353  desc.SetStencilPixelFormat(stencil_fmt);
354  auto pipeline = GetContext()->GetPipelineLibrary()->GetPipeline(desc).Get();
355  ASSERT_NE(pipeline, nullptr);
356 }

References impeller::PipelineDescriptor::AddStageEntrypoint(), impeller::DescriptorSetLayout::binding, impeller::ColorAttachmentDescriptor::format, impeller::kEqual, impeller::kFragment, impeller::kUniformBuffer, impeller::kVertex, impeller::PlaygroundBackendToRuntimeStageBackend(), impeller::PipelineDescriptor::SetColorAttachmentDescriptor(), impeller::PipelineDescriptor::SetLabel(), impeller::PipelineDescriptor::SetStencilAttachmentDescriptors(), impeller::PipelineDescriptor::SetStencilPixelFormat(), impeller::PipelineDescriptor::SetVertexDescriptor(), and impeller::StencilAttachmentDescriptor::stencil_compare.

◆ TEST_P() [519/549]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniforms   
)

Definition at line 56 of file runtime_stage_unittests.cc.

56  {
57  const std::shared_ptr<fml::Mapping> fixture =
58  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
59  ASSERT_TRUE(fixture);
60  ASSERT_GT(fixture->GetSize(), 0u);
61  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
62  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
63 
64  ASSERT_TRUE(stage->IsValid());
65  switch (GetBackend()) {
66  case PlaygroundBackend::kMetal:
67  [[fallthrough]];
68  case PlaygroundBackend::kOpenGLES: {
69  ASSERT_EQ(stage->GetUniforms().size(), 17u);
70  {
71  auto uni = stage->GetUniform("u_color");
72  ASSERT_NE(uni, nullptr);
73  EXPECT_EQ(uni->dimensions.rows, 4u);
74  EXPECT_EQ(uni->dimensions.cols, 1u);
75  EXPECT_EQ(uni->location, 0u);
76  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
77  }
78  {
79  auto uni = stage->GetUniform("u_alpha");
80  ASSERT_NE(uni, nullptr);
81  EXPECT_EQ(uni->dimensions.rows, 1u);
82  EXPECT_EQ(uni->dimensions.cols, 1u);
83  EXPECT_EQ(uni->location, 1u);
84  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
85  }
86  {
87  auto uni = stage->GetUniform("u_sparkle_color");
88  ASSERT_NE(uni, nullptr);
89  EXPECT_EQ(uni->dimensions.rows, 4u);
90  EXPECT_EQ(uni->dimensions.cols, 1u);
91  EXPECT_EQ(uni->location, 2u);
92  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
93  }
94  {
95  auto uni = stage->GetUniform("u_sparkle_alpha");
96  ASSERT_NE(uni, nullptr);
97  EXPECT_EQ(uni->dimensions.rows, 1u);
98  EXPECT_EQ(uni->dimensions.cols, 1u);
99  EXPECT_EQ(uni->location, 3u);
100  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
101  }
102  {
103  auto uni = stage->GetUniform("u_blur");
104  ASSERT_NE(uni, nullptr);
105  EXPECT_EQ(uni->dimensions.rows, 1u);
106  EXPECT_EQ(uni->dimensions.cols, 1u);
107  EXPECT_EQ(uni->location, 4u);
108  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
109  }
110  {
111  auto uni = stage->GetUniform("u_radius_scale");
112  ASSERT_NE(uni, nullptr);
113  EXPECT_EQ(uni->dimensions.rows, 1u);
114  EXPECT_EQ(uni->dimensions.cols, 1u);
115  EXPECT_EQ(uni->location, 6u);
116  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
117  }
118  {
119  auto uni = stage->GetUniform("u_max_radius");
120  ASSERT_NE(uni, nullptr);
121  EXPECT_EQ(uni->dimensions.rows, 1u);
122  EXPECT_EQ(uni->dimensions.cols, 1u);
123  EXPECT_EQ(uni->location, 7u);
124  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
125  }
126  {
127  auto uni = stage->GetUniform("u_resolution_scale");
128  ASSERT_NE(uni, nullptr);
129  EXPECT_EQ(uni->dimensions.rows, 2u);
130  EXPECT_EQ(uni->dimensions.cols, 1u);
131  EXPECT_EQ(uni->location, 8u);
132  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
133  }
134  {
135  auto uni = stage->GetUniform("u_noise_scale");
136  ASSERT_NE(uni, nullptr);
137  EXPECT_EQ(uni->dimensions.rows, 2u);
138  EXPECT_EQ(uni->dimensions.cols, 1u);
139  EXPECT_EQ(uni->location, 9u);
140  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
141  }
142  {
143  auto uni = stage->GetUniform("u_noise_phase");
144  ASSERT_NE(uni, nullptr);
145  EXPECT_EQ(uni->dimensions.rows, 1u);
146  EXPECT_EQ(uni->dimensions.cols, 1u);
147  EXPECT_EQ(uni->location, 10u);
148  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
149  }
150 
151  {
152  auto uni = stage->GetUniform("u_circle1");
153  ASSERT_NE(uni, nullptr);
154  EXPECT_EQ(uni->dimensions.rows, 2u);
155  EXPECT_EQ(uni->dimensions.cols, 1u);
156  EXPECT_EQ(uni->location, 11u);
157  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
158  }
159  {
160  auto uni = stage->GetUniform("u_circle2");
161  ASSERT_NE(uni, nullptr);
162  EXPECT_EQ(uni->dimensions.rows, 2u);
163  EXPECT_EQ(uni->dimensions.cols, 1u);
164  EXPECT_EQ(uni->location, 12u);
165  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
166  }
167  {
168  auto uni = stage->GetUniform("u_circle3");
169  ASSERT_NE(uni, nullptr);
170  EXPECT_EQ(uni->dimensions.rows, 2u);
171  EXPECT_EQ(uni->dimensions.cols, 1u);
172  EXPECT_EQ(uni->location, 13u);
173  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
174  }
175  {
176  auto uni = stage->GetUniform("u_rotation1");
177  ASSERT_NE(uni, nullptr);
178  EXPECT_EQ(uni->dimensions.rows, 2u);
179  EXPECT_EQ(uni->dimensions.cols, 1u);
180  EXPECT_EQ(uni->location, 14u);
181  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
182  }
183  {
184  auto uni = stage->GetUniform("u_rotation2");
185  ASSERT_NE(uni, nullptr);
186  EXPECT_EQ(uni->dimensions.rows, 2u);
187  EXPECT_EQ(uni->dimensions.cols, 1u);
188  EXPECT_EQ(uni->location, 15u);
189  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
190  }
191  {
192  auto uni = stage->GetUniform("u_rotation3");
193  ASSERT_NE(uni, nullptr);
194  EXPECT_EQ(uni->dimensions.rows, 2u);
195  EXPECT_EQ(uni->dimensions.cols, 1u);
196  EXPECT_EQ(uni->location, 16u);
197  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
198  }
199  break;
200  }
201  case PlaygroundBackend::kVulkan: {
202  EXPECT_EQ(stage->GetUniforms().size(), 1u);
203  auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
204  ASSERT_TRUE(uni);
205  EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
206  EXPECT_EQ(uni->struct_float_count, 32u);
207 
208  // There are 36 4 byte chunks in the UBO: 32 for the 32 floats, and 4 for
209  // padding. Initialize a vector as if they'll all be floats, then manually
210  // set the few padding bytes. If the shader changes, the padding locations
211  // will change as well. For example, if `u_alpha` was moved to the end,
212  // three bytes of padding could potentially be dropped - or if some of the
213  // scalar floats were changed to vec2 or vec4s, or if any vec3s are
214  // introduced.
215  // This means 36 * 4 = 144 bytes total.
216 
217  EXPECT_EQ(uni->GetSize(), 144u);
218  std::vector<uint8_t> layout(uni->GetSize() / sizeof(float), 1);
219  layout[5] = 0;
220  layout[6] = 0;
221  layout[7] = 0;
222  layout[23] = 0;
223 
224  EXPECT_THAT(uni->struct_layout, ::testing::ElementsAreArray(layout));
225  break;
226  }
227  }
228 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFloat, impeller::kMetal, impeller::kOpenGLES, impeller::kStruct, impeller::kVulkan, impeller::RuntimeStage::kVulkanUBOName, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [520/549]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniformsSamplerAfterUBO   
)

Definition at line 255 of file runtime_stage_unittests.cc.

255  {
256  if (GetBackend() != PlaygroundBackend::kVulkan) {
257  GTEST_SKIP() << "Test only relevant for Vulkan";
258  }
259  const std::shared_ptr<fml::Mapping> fixture =
260  flutter::testing::OpenFixtureAsMapping(
261  "uniforms_and_sampler_2.frag.iplr");
262  ASSERT_TRUE(fixture);
263  ASSERT_GT(fixture->GetSize(), 0u);
264  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
265  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
266 
267  EXPECT_EQ(stage->GetUniforms().size(), 2u);
268  auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
269  ASSERT_TRUE(uni);
270  // Struct must be offset at 45.
271  EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
272  EXPECT_EQ(uni->binding, 64u);
273  // Sampler should be offset at 64 but due to current bug
274  // has offset of 0, the correct offset is computed at runtime.
275  auto sampler_uniform = stage->GetUniform("u_texture");
276  EXPECT_EQ(sampler_uniform->type, RuntimeUniformType::kSampledImage);
277  EXPECT_EQ(sampler_uniform->binding, 65u);
278 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kSampledImage, impeller::kStruct, impeller::kVulkan, impeller::RuntimeStage::kVulkanUBOName, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [521/549]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniformsSamplerBeforeUBO   
)

Definition at line 230 of file runtime_stage_unittests.cc.

230  {
231  if (GetBackend() != PlaygroundBackend::kVulkan) {
232  GTEST_SKIP() << "Test only relevant for Vulkan";
233  }
234  const std::shared_ptr<fml::Mapping> fixture =
235  flutter::testing::OpenFixtureAsMapping(
236  "uniforms_and_sampler_1.frag.iplr");
237  ASSERT_TRUE(fixture);
238  ASSERT_GT(fixture->GetSize(), 0u);
239  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
240  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
241 
242  EXPECT_EQ(stage->GetUniforms().size(), 2u);
243  auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
244  ASSERT_TRUE(uni);
245  // Struct must be offset at 65.
246  EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
247  EXPECT_EQ(uni->binding, 65u);
248  // Sampler should be offset at 64 but due to current bug
249  // has offset of 0, the correct offset is computed at runtime.
250  auto sampler_uniform = stage->GetUniform("u_texture");
251  EXPECT_EQ(sampler_uniform->type, RuntimeUniformType::kSampledImage);
252  EXPECT_EQ(sampler_uniform->binding, 64u);
253 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kSampledImage, impeller::kStruct, impeller::kVulkan, impeller::RuntimeStage::kVulkanUBOName, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [522/549]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadValidBlob   
)

Definition at line 29 of file runtime_stage_unittests.cc.

29  {
30  const std::shared_ptr<fml::Mapping> fixture =
31  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
32  ASSERT_TRUE(fixture);
33  ASSERT_GT(fixture->GetSize(), 0u);
34  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
35  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
36  ASSERT_TRUE(stage->IsValid());
37  ASSERT_EQ(stage->GetShaderStage(), RuntimeShaderStage::kFragment);
38 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFragment, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [523/549]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRegisterStage   
)

Definition at line 280 of file runtime_stage_unittests.cc.

280  {
281  const std::shared_ptr<fml::Mapping> fixture =
282  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
283  ASSERT_TRUE(fixture);
284  ASSERT_GT(fixture->GetSize(), 0u);
285  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
286  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
287  ASSERT_TRUE(stage->IsValid());
288  std::promise<bool> registration;
289  auto future = registration.get_future();
290  auto library = GetContext()->GetShaderLibrary();
291  library->RegisterFunction(
292  stage->GetEntrypoint(), //
293  ToShaderStage(stage->GetShaderStage()), //
294  stage->GetCodeMapping(), //
295  fml::MakeCopyable([reg = std::move(registration)](bool result) mutable {
296  reg.set_value(result);
297  }));
298  ASSERT_TRUE(future.get());
299  {
300  auto function =
301  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
302  ASSERT_NE(function, nullptr);
303  }
304 
305  // Check if unregistering works.
306 
307  library->UnregisterFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
308  {
309  auto function =
310  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
311  ASSERT_EQ(function, nullptr);
312  }
313 }
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
Definition: shader_types.h:29

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFragment, impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::ToShaderStage().

◆ TEST_P() [524/549]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRejectInvalidBlob   
)

Definition at line 40 of file runtime_stage_unittests.cc.

40  {
41  ScopedValidationDisable disable_validation;
42  const std::shared_ptr<fml::Mapping> fixture =
43  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
44  ASSERT_TRUE(fixture);
45  auto junk_allocation = std::make_shared<Allocation>();
46  ASSERT_TRUE(junk_allocation->Truncate(Bytes{fixture->GetSize()}, false));
47  // Not meant to be secure. Just reject obviously bad blobs using magic
48  // numbers.
49  ::memset(junk_allocation->GetBuffer(), 127,
50  junk_allocation->GetLength().GetByteSize());
51  auto stages = RuntimeStage::DecodeRuntimeStages(
52  CreateMappingFromAllocation(junk_allocation));
53  ASSERT_FALSE(stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())]);
54 }
std::shared_ptr< fml::Mapping > CreateMappingFromAllocation(const std::shared_ptr< Allocation > &allocation)
Creates a mapping from allocation.
Definition: allocation.cc:99

References impeller::CreateMappingFromAllocation(), impeller::RuntimeStage::DecodeRuntimeStages(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [525/549]

impeller::testing::TEST_P ( RuntimeStageTest  ,
ContainsExpectedShaderTypes   
)

Definition at line 358 of file runtime_stage_unittests.cc.

358  {
359  auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
360  // Right now, SkSL gets implicitly bundled regardless of what the build rule
361  // for this test requested. After
362  // https://github.com/flutter/flutter/issues/138919, this may require a build
363  // rule change or a new test.
364  EXPECT_TRUE(stages[RuntimeStageBackend::kSkSL]);
365 
366  EXPECT_TRUE(stages[RuntimeStageBackend::kOpenGLES]);
367  EXPECT_TRUE(stages[RuntimeStageBackend::kMetal]);
368  EXPECT_TRUE(stages[RuntimeStageBackend::kVulkan]);
369 }

References impeller::kMetal, impeller::kOpenGLES, impeller::kSkSL, and impeller::kVulkan.

◆ TEST_P() [526/549]

impeller::testing::TEST_P ( SwapchainTransientsMTLTest  ,
CanAllocateSwapchainTextures   
)

Definition at line 27 of file swapchain_transients_mtl_unittests.mm.

27  {
28  const auto& transients = std::make_shared<SwapchainTransientsMTL>(
29  GetContext()->GetResourceAllocator());
30 
31  transients->SetSizeAndFormat({1, 1}, PixelFormat::kB8G8R8A8UNormInt);
32 
33  auto resolve = transients->GetResolveTexture();
34  EXPECT_NE(resolve, nullptr);
35  EXPECT_NE(transients->GetMSAATexture(), nullptr);
36  EXPECT_NE(transients->GetDepthStencilTexture(), nullptr);
37 
38  // Texture properties are correct for resolve.
39  EXPECT_EQ(resolve->GetTextureDescriptor().size, ISize(1, 1));
40  EXPECT_EQ(resolve->GetTextureDescriptor().format,
41  PixelFormat::kB8G8R8A8UNormInt);
42  EXPECT_EQ(resolve->GetTextureDescriptor().sample_count, SampleCount::kCount1);
43  EXPECT_EQ(resolve->GetTextureDescriptor().storage_mode,
44  StorageMode::kDevicePrivate);
45 
46  // Texture properties are correct for MSAA.
47  auto msaa = transients->GetMSAATexture();
48  EXPECT_EQ(msaa->GetTextureDescriptor().size, ISize(1, 1));
49  EXPECT_EQ(msaa->GetTextureDescriptor().format,
50  PixelFormat::kB8G8R8A8UNormInt);
51  EXPECT_EQ(msaa->GetTextureDescriptor().sample_count, SampleCount::kCount4);
52  EXPECT_EQ(msaa->GetTextureDescriptor().storage_mode,
53  StorageMode::kDeviceTransient);
54 
55  // Texture properties are correct for Depth+Stencil.
56  auto depth_stencil = transients->GetDepthStencilTexture();
57  EXPECT_EQ(depth_stencil->GetTextureDescriptor().size, ISize(1, 1));
58  EXPECT_EQ(depth_stencil->GetTextureDescriptor().format,
59  PixelFormat::kD32FloatS8UInt);
60  EXPECT_EQ(depth_stencil->GetTextureDescriptor().sample_count,
61  SampleCount::kCount4);
62  EXPECT_EQ(depth_stencil->GetTextureDescriptor().storage_mode,
63  StorageMode::kDeviceTransient);
64 
65  // Textures are cached.
66  EXPECT_EQ(transients->GetResolveTexture(), resolve);
67 
68  // Texture cache is invalidated when size changes.
69  transients->SetSizeAndFormat({2, 2}, PixelFormat::kB8G8R8A8UNormInt);
70  EXPECT_NE(resolve, transients->GetResolveTexture());
71  resolve = transients->GetResolveTexture();
72 
73  // Texture cache is invalidated when pixel format changes.
74  transients->SetSizeAndFormat({2, 2}, PixelFormat::kB10G10R10A10XR);
75  EXPECT_NE(resolve, transients->GetResolveTexture());
76 }

References impeller::kB10G10R10A10XR, impeller::kB8G8R8A8UNormInt, impeller::kCount1, impeller::kCount4, impeller::kD32FloatS8UInt, impeller::kDevicePrivate, and impeller::kDeviceTransient.

◆ TEST_P() [527/549]

impeller::testing::TEST_P ( TextContentsTest  ,
MaintainsShape   
)

Definition at line 184 of file text_contents_unittests.cc.

184  {
185  std::shared_ptr<TextFrame> text_frame =
186  MakeTextFrame("th", "ahem.ttf", TextOptions{.font_size = 50});
187 
188  std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
189  std::shared_ptr<GlyphAtlasContext> atlas_context =
190  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
191  std::shared_ptr<HostBuffer> data_host_buffer = HostBuffer::Create(
192  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
193  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
194  ASSERT_TRUE(context && context->IsValid());
195 
196  for (int i = 0; i <= 1000; ++i) {
197  Rational font_scale(440 + i, 1000.0);
198  Rect position_rect[2];
199  Rect uv_rect[2];
200 
201  {
202  std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData> data(12);
203 
204  std::shared_ptr<GlyphAtlas> atlas =
205  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
206  GlyphAtlas::Type::kAlphaBitmap, font_scale,
207  atlas_context, text_frame, /*offset=*/{0, 0});
208  ISize texture_size = atlas->GetTexture()->GetSize();
209 
210  TextContents::ComputeVertexData(
211  data.data(), text_frame, static_cast<Scalar>(font_scale),
212  /*entity_transform=*/
213  Matrix::MakeScale({static_cast<Scalar>(font_scale),
214  static_cast<Scalar>(font_scale), 1}),
215  /*offset=*/Vector2(0, 0),
216  /*glyph_properties=*/std::nullopt, atlas);
217  position_rect[0] = PerVertexDataPositionToRect(data.begin());
218  uv_rect[0] = PerVertexDataUVToRect(data.begin(), texture_size);
219  position_rect[1] = PerVertexDataPositionToRect(data.begin() + 4);
220  uv_rect[1] = PerVertexDataUVToRect(data.begin() + 4, texture_size);
221  }
222  EXPECT_NEAR(GetAspectRatio(position_rect[1]), GetAspectRatio(uv_rect[1]),
223  0.001)
224  << i;
225  }
226 }
static std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, const TypographerContext *typographer_context, HostBuffer &data_host_buffer, GlyphAtlas::Type type, Rational scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::shared_ptr< TextFrame > &frame)

References impeller::TextContents::ComputeVertexData(), impeller::HostBuffer::Create(), CreateGlyphAtlas(), data, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::Matrix::MakeScale().

◆ TEST_P() [528/549]

impeller::testing::TEST_P ( TextContentsTest  ,
SimpleComputeVertexData   
)

Definition at line 110 of file text_contents_unittests.cc.

110  {
111 #ifndef FML_OS_MACOSX
112  GTEST_SKIP() << "Results aren't stable across linux and macos.";
113 #endif
114 
115  std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData> data(4);
116 
117  std::shared_ptr<TextFrame> text_frame =
118  MakeTextFrame("1", "ahem.ttf", TextOptions{.font_size = 50});
119 
120  std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
121  std::shared_ptr<GlyphAtlasContext> atlas_context =
122  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
123  std::shared_ptr<HostBuffer> data_host_buffer = HostBuffer::Create(
124  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
125  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
126  ASSERT_TRUE(context && context->IsValid());
127  std::shared_ptr<GlyphAtlas> atlas =
128  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
129  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/Rational(1, 1),
130  atlas_context, text_frame, /*offset=*/{0, 0});
131 
132  ISize texture_size = atlas->GetTexture()->GetSize();
133  TextContents::ComputeVertexData(data.data(), text_frame, /*scale=*/1.0,
134  /*entity_transform=*/Matrix(),
135  /*offset=*/Vector2(0, 0),
136  /*glyph_properties=*/std::nullopt, atlas);
137 
138  Rect position_rect = PerVertexDataPositionToRect(data.begin());
139  Rect uv_rect = PerVertexDataUVToRect(data.begin(), texture_size);
140  // The -1 offset comes from Skia in `ComputeGlyphSize`. So since the font size
141  // is 50, the math appears to be to get back a 50x50 rect and apply 1 pixel
142  // of padding.
143  EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-1, -41, 52, 52));
144  EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 52, 52));
145 }

References impeller::TextContents::ComputeVertexData(), impeller::HostBuffer::Create(), CreateGlyphAtlas(), data, EXPECT_RECT_NEAR, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [529/549]

impeller::testing::TEST_P ( TextContentsTest  ,
SimpleComputeVertexData2x   
)

Definition at line 147 of file text_contents_unittests.cc.

147  {
148 #ifndef FML_OS_MACOSX
149  GTEST_SKIP() << "Results aren't stable across linux and macos.";
150 #endif
151 
152  std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData> data(4);
153  std::shared_ptr<TextFrame> text_frame =
154  MakeTextFrame("1", "ahem.ttf", TextOptions{.font_size = 50});
155 
156  std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
157  std::shared_ptr<GlyphAtlasContext> atlas_context =
158  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
159  std::shared_ptr<HostBuffer> data_host_buffer = HostBuffer::Create(
160  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
161  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
162  ASSERT_TRUE(context && context->IsValid());
163  Rational font_scale(2, 1);
164  std::shared_ptr<GlyphAtlas> atlas =
165  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
166  GlyphAtlas::Type::kAlphaBitmap, font_scale,
167  atlas_context, text_frame, /*offset=*/{0, 0});
168 
169  ISize texture_size = atlas->GetTexture()->GetSize();
170  TextContents::ComputeVertexData(
171  data.data(), text_frame, static_cast<Scalar>(font_scale),
172  /*entity_transform=*/
173  Matrix::MakeScale({static_cast<Scalar>(font_scale),
174  static_cast<Scalar>(font_scale), 1}),
175  /*offset=*/Vector2(0, 0),
176  /*glyph_properties=*/std::nullopt, atlas);
177 
178  Rect position_rect = PerVertexDataPositionToRect(data.begin());
179  Rect uv_rect = PerVertexDataUVToRect(data.begin(), texture_size);
180  EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-1, -81, 102, 102));
181  EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 102, 102));
182 }

References impeller::TextContents::ComputeVertexData(), impeller::HostBuffer::Create(), CreateGlyphAtlas(), data, EXPECT_RECT_NEAR, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), impeller::Matrix::MakeScale(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [530/549]

impeller::testing::TEST_P ( TextContentsTest  ,
SimpleSubpixel   
)

Definition at line 228 of file text_contents_unittests.cc.

228  {
229 #ifndef FML_OS_MACOSX
230  GTEST_SKIP() << "Results aren't stable across linux and macos.";
231 #endif
232 
233  std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData> data(4);
234 
235  std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
236  "1", "ahem.ttf", TextOptions{.font_size = 50, .is_subpixel = true});
237 
238  std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
239  std::shared_ptr<GlyphAtlasContext> atlas_context =
240  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
241  std::shared_ptr<HostBuffer> data_host_buffer = HostBuffer::Create(
242  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
243  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
244  ASSERT_TRUE(context && context->IsValid());
245  Point offset = Point(0.5, 0);
246  std::shared_ptr<GlyphAtlas> atlas =
247  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
248  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/Rational(1),
249  atlas_context, text_frame, offset);
250 
251  ISize texture_size = atlas->GetTexture()->GetSize();
252  TextContents::ComputeVertexData(
253  data.data(), text_frame, /*scale=*/1.0,
254  /*entity_transform=*/Matrix::MakeTranslation(offset), offset,
255  /*glyph_properties=*/std::nullopt, atlas);
256 
257  Rect position_rect = PerVertexDataPositionToRect(data.begin());
258  Rect uv_rect = PerVertexDataUVToRect(data.begin(), texture_size);
259  // The values at Point(0, 0).
260  // EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-1, -41, 52, 52));
261  // EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 52, 52));
262  EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-2, -41, 54, 52));
263  EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 54, 52));
264 }

References impeller::TextContents::ComputeVertexData(), impeller::HostBuffer::Create(), CreateGlyphAtlas(), data, EXPECT_RECT_NEAR, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), impeller::Matrix::MakeTranslation(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [531/549]

impeller::testing::TEST_P ( TextContentsTest  ,
SimpleSubpixel26   
)

Definition at line 311 of file text_contents_unittests.cc.

311  {
312 #ifndef FML_OS_MACOSX
313  GTEST_SKIP() << "Results aren't stable across linux and macos.";
314 #endif
315 
316  std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData> data(4);
317 
318  std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
319  "1", "ahem.ttf", TextOptions{.font_size = 50, .is_subpixel = true});
320 
321  std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
322  std::shared_ptr<GlyphAtlasContext> atlas_context =
323  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
324  std::shared_ptr<HostBuffer> data_host_buffer = HostBuffer::Create(
325  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
326  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
327  ASSERT_TRUE(context && context->IsValid());
328  Point offset = Point(0.26, 0);
329  std::shared_ptr<GlyphAtlas> atlas =
330  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
331  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/Rational(1),
332  atlas_context, text_frame, offset);
333 
334  ISize texture_size = atlas->GetTexture()->GetSize();
335  TextContents::ComputeVertexData(
336  data.data(), text_frame, /*scale=*/1.0,
337  /*entity_transform=*/Matrix::MakeTranslation(offset), offset,
338  /*glyph_properties=*/std::nullopt, atlas);
339 
340  Rect position_rect = PerVertexDataPositionToRect(data.begin());
341  Rect uv_rect = PerVertexDataUVToRect(data.begin(), texture_size);
342  // The values without subpixel.
343  // EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-1, -41, 52, 52));
344  // EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 52, 52));
345  EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-2, -41, 54, 52));
346  EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 54, 52));
347 }

References impeller::TextContents::ComputeVertexData(), impeller::HostBuffer::Create(), CreateGlyphAtlas(), data, EXPECT_RECT_NEAR, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), impeller::Matrix::MakeTranslation(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [532/549]

impeller::testing::TEST_P ( TextContentsTest  ,
SimpleSubpixel3x   
)

Definition at line 266 of file text_contents_unittests.cc.

266  {
267 #ifndef FML_OS_MACOSX
268  GTEST_SKIP() << "Results aren't stable across linux and macos.";
269 #endif
270 
271  std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData> data(4);
272 
273  std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
274  "1", "ahem.ttf", TextOptions{.font_size = 50, .is_subpixel = true});
275 
276  std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
277  std::shared_ptr<GlyphAtlasContext> atlas_context =
278  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
279  std::shared_ptr<HostBuffer> data_host_buffer = HostBuffer::Create(
280  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
281  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
282  ASSERT_TRUE(context && context->IsValid());
283  Rational font_scale(3, 1);
284  Point offset = {0.16667, 0};
285  std::shared_ptr<GlyphAtlas> atlas =
286  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
287  GlyphAtlas::Type::kAlphaBitmap, font_scale,
288  atlas_context, text_frame, offset);
289 
290  ISize texture_size = atlas->GetTexture()->GetSize();
291  TextContents::ComputeVertexData(
292  data.data(), text_frame, static_cast<Scalar>(font_scale),
293  /*entity_transform=*/
294  Matrix::MakeTranslation(offset) *
295  Matrix::MakeScale({static_cast<Scalar>(font_scale),
296  static_cast<Scalar>(font_scale), 1}),
297  offset,
298  /*glyph_properties=*/std::nullopt, atlas);
299 
300  Rect position_rect = PerVertexDataPositionToRect(data.begin());
301  Rect uv_rect = PerVertexDataUVToRect(data.begin(), texture_size);
302  // Values at Point(0, 0)
303  // EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-1, -121, 152, 152));
304  // EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 152, 152));
305  EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-2, -121, 154, 152))
306  << "position size:" << position_rect.GetSize();
307  EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 154, 152))
308  << "position size:" << position_rect.GetSize();
309 }

References impeller::TextContents::ComputeVertexData(), impeller::HostBuffer::Create(), CreateGlyphAtlas(), data, EXPECT_RECT_NEAR, impeller::TRect< T >::GetSize(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [533/549]

impeller::testing::TEST_P ( TextContentsTest  ,
SimpleSubpixel80   
)

Definition at line 349 of file text_contents_unittests.cc.

349  {
350 #ifndef FML_OS_MACOSX
351  GTEST_SKIP() << "Results aren't stable across linux and macos.";
352 #endif
353 
354  std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData> data(4);
355 
356  std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
357  "1", "ahem.ttf", TextOptions{.font_size = 50, .is_subpixel = true});
358 
359  std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
360  std::shared_ptr<GlyphAtlasContext> atlas_context =
361  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
362  std::shared_ptr<HostBuffer> data_host_buffer = HostBuffer::Create(
363  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
364  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
365  ASSERT_TRUE(context && context->IsValid());
366  Point offset = Point(0.80, 0);
367  std::shared_ptr<GlyphAtlas> atlas =
368  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
369  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/Rational(1),
370  atlas_context, text_frame, offset);
371 
372  ISize texture_size = atlas->GetTexture()->GetSize();
373  TextContents::ComputeVertexData(
374  data.data(), text_frame, /*scale=*/1.0,
375  /*entity_transform=*/Matrix::MakeTranslation(offset), offset,
376  /*glyph_properties=*/std::nullopt, atlas);
377 
378  Rect position_rect = PerVertexDataPositionToRect(data.begin());
379  Rect uv_rect = PerVertexDataUVToRect(data.begin(), texture_size);
380  // The values without subpixel.
381  // EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-1, -41, 52, 52));
382  // EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 52, 52));
383  EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-2, -41, 54, 52));
384  EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 54, 52));
385 }

References impeller::TextContents::ComputeVertexData(), impeller::HostBuffer::Create(), CreateGlyphAtlas(), data, EXPECT_RECT_NEAR, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), impeller::Matrix::MakeTranslation(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [534/549]

impeller::testing::TEST_P ( TypographerTest  ,
CanConvertTextBlob   
)

Definition at line 62 of file typographer_unittests.cc.

62  {
63  SkFont font = flutter::testing::CreateTestFontOfSize(12);
64  auto blob = SkTextBlob::MakeFromString(
65  "the quick brown fox jumped over the lazy dog.", font);
66  ASSERT_TRUE(blob);
67  auto frame = MakeTextFrameFromTextBlobSkia(blob);
68  ASSERT_EQ(frame->GetRunCount(), 1u);
69  for (const auto& run : frame->GetRuns()) {
70  ASSERT_TRUE(run.IsValid());
71  ASSERT_EQ(run.GetGlyphCount(), 45u);
72  }
73 }

References impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [535/549]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateGlyphAtlas   
)

Definition at line 80 of file typographer_unittests.cc.

80  {
81  auto context = TypographerContextSkia::Make();
82  auto atlas_context =
83  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
84  auto data_host_buffer = HostBuffer::Create(
85  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
86  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
87  ASSERT_TRUE(context && context->IsValid());
88  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
89  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
90  ASSERT_TRUE(blob);
91  auto atlas =
92  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
93  GlyphAtlas::Type::kAlphaBitmap, Rational(1),
94  atlas_context, MakeTextFrameFromTextBlobSkia(blob));
95 
96  ASSERT_NE(atlas, nullptr);
97  ASSERT_NE(atlas->GetTexture(), nullptr);
98  ASSERT_EQ(atlas->GetType(), GlyphAtlas::Type::kAlphaBitmap);
99  ASSERT_EQ(atlas->GetGlyphCount(), 4llu);
100 
101  std::optional<impeller::ScaledFont> first_scaled_font;
102  std::optional<impeller::SubpixelGlyph> first_glyph;
103  Rect first_rect;
104  atlas->IterateGlyphs([&](const ScaledFont& scaled_font,
105  const SubpixelGlyph& glyph,
106  const Rect& rect) -> bool {
107  first_scaled_font = scaled_font;
108  first_glyph = glyph;
109  first_rect = rect;
110  return false;
111  });
112 
113  ASSERT_TRUE(first_scaled_font.has_value());
114  ASSERT_TRUE(atlas
115  ->FindFontGlyphBounds(
116  {first_scaled_font.value(), first_glyph.value()})
117  .has_value());
118 }
static std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, const TypographerContext *typographer_context, HostBuffer &data_host_buffer, GlyphAtlas::Type type, Rational scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::vector< std::shared_ptr< TextFrame >> &frames, const std::vector< std::optional< GlyphProperties >> &properties)

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [536/549]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateRenderContext   
)

Definition at line 75 of file typographer_unittests.cc.

75  {
76  auto context = TypographerContextSkia::Make();
77  ASSERT_TRUE(context && context->IsValid());
78 }

References impeller::TypographerContextSkia::Make().

◆ TEST_P() [537/549]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasIsRecycledIfUnchanged   
)

Definition at line 183 of file typographer_unittests.cc.

183  {
184  auto context = TypographerContextSkia::Make();
185  auto atlas_context =
186  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
187  auto data_host_buffer = HostBuffer::Create(
188  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
189  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
190  ASSERT_TRUE(context && context->IsValid());
191  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
192  auto blob = SkTextBlob::MakeFromString("spooky skellingtons", sk_font);
193  ASSERT_TRUE(blob);
194  auto atlas =
195  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
196  GlyphAtlas::Type::kAlphaBitmap, Rational(1),
197  atlas_context, MakeTextFrameFromTextBlobSkia(blob));
198  ASSERT_NE(atlas, nullptr);
199  ASSERT_NE(atlas->GetTexture(), nullptr);
200  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
201 
202  // now attempt to re-create an atlas with the same text blob.
203 
204  auto next_atlas =
205  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
206  GlyphAtlas::Type::kAlphaBitmap, Rational(1),
207  atlas_context, MakeTextFrameFromTextBlobSkia(blob));
208  ASSERT_EQ(atlas, next_atlas);
209  ASSERT_EQ(atlas_context->GetGlyphAtlas(), atlas);
210 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [538/549]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecycledIfUnchanged   
)

Definition at line 262 of file typographer_unittests.cc.

262  {
263  auto data_host_buffer = HostBuffer::Create(
264  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
265  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
266  auto context = TypographerContextSkia::Make();
267  auto atlas_context =
268  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
269  ASSERT_TRUE(context && context->IsValid());
270  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
271  auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
272  ASSERT_TRUE(blob);
273  auto atlas =
274  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
275  GlyphAtlas::Type::kAlphaBitmap, Rational(1),
276  atlas_context, MakeTextFrameFromTextBlobSkia(blob));
277  auto old_packer = atlas_context->GetRectPacker();
278 
279  ASSERT_NE(atlas, nullptr);
280  ASSERT_NE(atlas->GetTexture(), nullptr);
281  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
282 
283  auto* first_texture = atlas->GetTexture().get();
284 
285  // Now create a new glyph atlas with a nearly identical blob.
286 
287  auto blob2 = SkTextBlob::MakeFromString("spooky 2", sk_font);
288  auto next_atlas =
289  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
290  GlyphAtlas::Type::kAlphaBitmap, Rational(1),
291  atlas_context, MakeTextFrameFromTextBlobSkia(blob2));
292  ASSERT_EQ(atlas, next_atlas);
293  auto* second_texture = next_atlas->GetTexture().get();
294 
295  auto new_packer = atlas_context->GetRectPacker();
296 
297  ASSERT_EQ(second_texture, first_texture);
298  ASSERT_EQ(old_packer, new_packer);
299 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [539/549]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureWillGrowTilMaxTextureSize   
)

Definition at line 434 of file typographer_unittests.cc.

434  {
435  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
436  GTEST_SKIP() << "Atlas growth isn't supported for OpenGLES currently.";
437  }
438 
439  auto data_host_buffer = HostBuffer::Create(
440  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
441  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
442  auto context = TypographerContextSkia::Make();
443  auto atlas_context =
444  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
445  ASSERT_TRUE(context && context->IsValid());
446  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
447  auto blob = SkTextBlob::MakeFromString("A", sk_font);
448  ASSERT_TRUE(blob);
449  auto atlas =
450  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
451  GlyphAtlas::Type::kAlphaBitmap, Rational(1),
452  atlas_context, MakeTextFrameFromTextBlobSkia(blob));
453  // Continually append new glyphs until the glyph size grows to the maximum.
454  // Note that the sizes here are more or less experimentally determined, but
455  // the important expectation is that the atlas size will shrink again after
456  // growing to the maximum size.
457  constexpr ISize expected_sizes[13] = {
458  {4096, 4096}, //
459  {4096, 4096}, //
460  {4096, 8192}, //
461  {4096, 8192}, //
462  {4096, 8192}, //
463  {4096, 8192}, //
464  {4096, 16384}, //
465  {4096, 16384}, //
466  {4096, 16384}, //
467  {4096, 16384}, //
468  {4096, 16384}, //
469  {4096, 16384}, //
470  {4096, 4096} // Shrinks!
471  };
472 
473  SkFont sk_font_small = flutter::testing::CreateTestFontOfSize(10);
474 
475  for (int i = 0; i < 13; i++) {
476  SkTextBlobBuilder builder;
477 
478  auto add_char = [&](const SkFont& sk_font, char c) {
479  int count = sk_font.countText(&c, 1, SkTextEncoding::kUTF8);
480  auto buffer = builder.allocRunPos(sk_font, count);
481  sk_font.textToGlyphs(&c, 1, SkTextEncoding::kUTF8, buffer.glyphs, count);
482  sk_font.getPos(buffer.glyphs, count, buffer.points(), {0, 0});
483  };
484 
485  SkFont sk_font = flutter::testing::CreateTestFontOfSize(50 + i);
486  add_char(sk_font, 'A');
487  add_char(sk_font_small, 'B');
488  auto blob = builder.make();
489 
490  atlas =
491  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
492  GlyphAtlas::Type::kAlphaBitmap, Rational(50 + i, 1),
493  atlas_context, MakeTextFrameFromTextBlobSkia(blob));
494  ASSERT_TRUE(!!atlas);
495  EXPECT_EQ(atlas->GetTexture()->GetTextureDescriptor().size,
496  expected_sizes[i]);
497  }
498 
499  // The final atlas should contain both the "A" glyph (which was not present
500  // in the previous atlas) and the "B" glyph (which existed in the previous
501  // atlas).
502  ASSERT_EQ(atlas->GetGlyphCount(), 2u);
503 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::kOpenGLES, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [540/549]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithLotsOfdUniqueGlyphSize   
)

Definition at line 212 of file typographer_unittests.cc.

212  {
213  auto data_host_buffer = HostBuffer::Create(
214  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
215  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
216  auto context = TypographerContextSkia::Make();
217  auto atlas_context =
218  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
219  ASSERT_TRUE(context && context->IsValid());
220 
221  const char* test_string =
222  "QWERTYUIOPASDFGHJKLZXCVBNMqewrtyuiopasdfghjklzxcvbnm,.<>[]{};':"
223  "2134567890-=!@#$%^&*()_+"
224  "œ∑´®†¥¨ˆøπ““‘‘åß∂ƒ©˙∆˚¬…æ≈ç√∫˜µ≤≥≥≥≥÷¡™£¢∞§¶•ªº–≠⁄€‹›fifl‡°·‚—±Œ„´‰Á¨Ø∏”’/"
225  "* Í˝ */¸˛Ç◊ı˜Â¯˘¿";
226 
227  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
228  auto blob = SkTextBlob::MakeFromString(test_string, sk_font);
229  ASSERT_TRUE(blob);
230 
231  size_t size_count = 8;
232  std::vector<std::shared_ptr<TextFrame>> frames;
233  for (size_t index = 0; index < size_count; index += 1) {
234  frames.push_back(MakeTextFrameFromTextBlobSkia(blob));
235  frames.back()->SetPerFrameData(Rational(6 * index, 10), {0, 0}, Matrix(),
236  {});
237  };
238  auto atlas =
239  context->CreateGlyphAtlas(*GetContext(), GlyphAtlas::Type::kAlphaBitmap,
240  *data_host_buffer, atlas_context, frames);
241  ASSERT_NE(atlas, nullptr);
242  ASSERT_NE(atlas->GetTexture(), nullptr);
243 
244  std::set<uint16_t> unique_glyphs;
245  std::vector<uint16_t> total_glyphs;
246  atlas->IterateGlyphs([&](const ScaledFont& scaled_font,
247  const SubpixelGlyph& glyph, const Rect& rect) {
248  unique_glyphs.insert(glyph.glyph.index);
249  total_glyphs.push_back(glyph.glyph.index);
250  return true;
251  });
252 
253  // These numbers may be different due to subpixel positions.
254  EXPECT_LE(unique_glyphs.size() * size_count, atlas->GetGlyphCount());
255  EXPECT_EQ(total_glyphs.size(), atlas->GetGlyphCount());
256 
257  EXPECT_TRUE(atlas->GetGlyphCount() > 0);
258  EXPECT_TRUE(atlas->GetTexture()->GetSize().width > 0);
259  EXPECT_TRUE(atlas->GetTexture()->GetSize().height > 0);
260 }

References impeller::HostBuffer::Create(), impeller::SubpixelGlyph::glyph, impeller::Glyph::index, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [541/549]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithOddUniqueGlyphSize   
)

Definition at line 161 of file typographer_unittests.cc.

161  {
162  auto context = TypographerContextSkia::Make();
163  auto atlas_context =
164  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
165  auto data_host_buffer = HostBuffer::Create(
166  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
167  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
168  ASSERT_TRUE(context && context->IsValid());
169  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
170  auto blob = SkTextBlob::MakeFromString("AGH", sk_font);
171  ASSERT_TRUE(blob);
172  auto atlas =
173  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
174  GlyphAtlas::Type::kAlphaBitmap, Rational(1),
175  atlas_context, MakeTextFrameFromTextBlobSkia(blob));
176  ASSERT_NE(atlas, nullptr);
177  ASSERT_NE(atlas->GetTexture(), nullptr);
178 
179  EXPECT_EQ(atlas->GetTexture()->GetSize().width, 4096u);
180  EXPECT_EQ(atlas->GetTexture()->GetSize().height, 1024u);
181 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [542/549]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsIgnoredForNonEmojiFonts   
)

Definition at line 337 of file typographer_unittests.cc.

337  {
338  auto data_host_buffer = HostBuffer::Create(
339  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
340  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
341  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
342  sk_sp<SkTypeface> typeface =
343  font_mgr->matchFamilyStyle("Arial", SkFontStyle::Normal());
344  SkFont sk_font(typeface, 0.5f);
345 
346  auto context = TypographerContextSkia::Make();
347  auto atlas_context =
348  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kColorBitmap);
349 
350  // Create two frames with the same character and a different color, but as a
351  // non-emoji font the text frame constructor will ignore it.
352  auto frame =
353  MakeTextFrameFromTextBlobSkia(SkTextBlob::MakeFromString("A", sk_font));
354  auto frame_2 =
355  MakeTextFrameFromTextBlobSkia(SkTextBlob::MakeFromString("A", sk_font));
356  std::vector<std::optional<GlyphProperties>> properties = {
357  GlyphProperties{},
358  GlyphProperties{},
359  };
360 
361  auto next_atlas =
362  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
363  GlyphAtlas::Type::kColorBitmap, Rational(1),
364  atlas_context, {frame, frame_2}, properties);
365 
366  EXPECT_EQ(next_atlas->GetGlyphCount(), 1u);
367 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [543/549]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsPartOfCacheKey   
)

Definition at line 301 of file typographer_unittests.cc.

301  {
302  auto data_host_buffer = HostBuffer::Create(
303  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
304  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
305 #if FML_OS_MACOSX
306  auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
307 #else
308  auto mapping = flutter::testing::OpenFixtureAsSkData("NotoColorEmoji.ttf");
309 #endif
310  ASSERT_TRUE(mapping);
311  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
312  SkFont emoji_font(font_mgr->makeFromData(mapping), 50.0);
313 
314  auto context = TypographerContextSkia::Make();
315  auto atlas_context =
316  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kColorBitmap);
317 
318  // Create two frames with the same character and a different color, expect
319  // that it adds a character.
320  auto frame = MakeTextFrameFromTextBlobSkia(
321  SkTextBlob::MakeFromString("😂", emoji_font));
322  auto frame_2 = MakeTextFrameFromTextBlobSkia(
323  SkTextBlob::MakeFromString("😂", emoji_font));
324  std::vector<std::optional<GlyphProperties>> properties = {
325  GlyphProperties{.color = Color::Red()},
326  GlyphProperties{.color = Color::Blue()},
327  };
328 
329  auto next_atlas =
330  CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
331  GlyphAtlas::Type::kColorBitmap, Rational(1),
332  atlas_context, {frame, frame_2}, properties);
333 
334  EXPECT_EQ(next_atlas->GetGlyphCount(), 2u);
335 }

References impeller::Color::Blue(), impeller::GlyphProperties::color, impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), impeller::MakeTextFrameFromTextBlobSkia(), and impeller::Color::Red().

◆ TEST_P() [544/549]

impeller::testing::TEST_P ( TypographerTest  ,
InvalidAtlasForcesRepopulation   
)

Definition at line 628 of file typographer_unittests.cc.

628  {
629  SkFont font = flutter::testing::CreateTestFontOfSize(12);
630  auto blob = SkTextBlob::MakeFromString(
631  "the quick brown fox jumped over the lazy dog.", font);
632  ASSERT_TRUE(blob);
633  auto frame = MakeTextFrameFromTextBlobSkia(blob);
634 
635  EXPECT_FALSE(frame->IsFrameComplete());
636 
637  auto context = TypographerContextSkia::Make();
638  auto atlas_context =
639  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
640  auto data_host_buffer = HostBuffer::Create(
641  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
642  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
643 
644  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
645  GlyphAtlas::Type::kAlphaBitmap,
646  /*scale=*/Rational(1), atlas_context, frame);
647 
648  // The glyph position in the atlas was not known when this value
649  // was recorded. It is marked as a placeholder.
650  EXPECT_TRUE(frame->IsFrameComplete());
651  EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
652  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
653  // OpenGLES must always increase the atlas backend if the texture grows.
654  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
655  } else {
656  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
657  }
658 
659  auto second_context = TypographerContextSkia::Make();
660  auto second_atlas_context =
661  second_context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
662 
663  EXPECT_FALSE(second_atlas_context->GetGlyphAtlas()->IsValid());
664 
665  atlas = CreateGlyphAtlas(*GetContext(), second_context.get(),
666  *data_host_buffer, GlyphAtlas::Type::kAlphaBitmap,
667  /*scale=*/Rational(1), second_atlas_context, frame);
668 
669  EXPECT_TRUE(second_atlas_context->GetGlyphAtlas()->IsValid());
670 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::kOpenGLES, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [545/549]

impeller::testing::TEST_P ( TypographerTest  ,
LazyAtlasTracksColor   
)

Definition at line 120 of file typographer_unittests.cc.

120  {
121  auto data_host_buffer = HostBuffer::Create(
122  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
123  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
124 #if FML_OS_MACOSX
125  auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
126 #else
127  auto mapping = flutter::testing::OpenFixtureAsSkData("NotoColorEmoji.ttf");
128 #endif
129  ASSERT_TRUE(mapping);
130  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
131  SkFont emoji_font(font_mgr->makeFromData(mapping), 50.0);
132  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
133 
134  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
135  ASSERT_TRUE(blob);
136  auto frame = MakeTextFrameFromTextBlobSkia(blob);
137 
138  ASSERT_FALSE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
139 
140  LazyGlyphAtlas lazy_atlas(TypographerContextSkia::Make());
141 
142  lazy_atlas.AddTextFrame(frame, Rational(1), {0, 0}, Matrix(), {});
143 
145  SkTextBlob::MakeFromString("😀 ", emoji_font));
146 
147  ASSERT_TRUE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
148 
149  lazy_atlas.AddTextFrame(frame, Rational(1), {0, 0}, Matrix(), {});
150 
151  // Creates different atlases for color and red bitmap.
152  auto color_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
153  *GetContext(), *data_host_buffer, GlyphAtlas::Type::kColorBitmap);
154 
155  auto bitmap_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
156  *GetContext(), *data_host_buffer, GlyphAtlas::Type::kAlphaBitmap);
157 
158  ASSERT_FALSE(color_atlas == bitmap_atlas);
159 }

References impeller::LazyGlyphAtlas::AddTextFrame(), impeller::HostBuffer::Create(), impeller::LazyGlyphAtlas::CreateOrGetGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [546/549]

impeller::testing::TEST_P ( TypographerTest  ,
RectanglePackerAddsNonoverlapingRectangles   
)

Definition at line 369 of file typographer_unittests.cc.

369  {
370  auto packer = RectanglePacker::Factory(200, 100);
371  ASSERT_NE(packer, nullptr);
372  ASSERT_EQ(packer->PercentFull(), 0);
373 
374  const SkIRect packer_area = SkIRect::MakeXYWH(0, 0, 200, 100);
375 
376  IPoint16 first_output = {-1, -1}; // Fill with sentinel values
377  ASSERT_TRUE(packer->AddRect(20, 20, &first_output));
378  // Make sure the rectangle is placed such that it is inside the bounds of
379  // the packer's area.
380  const SkIRect first_rect =
381  SkIRect::MakeXYWH(first_output.x(), first_output.y(), 20, 20);
382  ASSERT_TRUE(SkIRect::Intersects(packer_area, first_rect));
383 
384  // Initial area was 200 x 100 = 20_000
385  // We added 20x20 = 400. 400 / 20_000 == 0.02 == 2%
386  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.02));
387 
388  IPoint16 second_output = {-1, -1};
389  ASSERT_TRUE(packer->AddRect(140, 90, &second_output));
390  const SkIRect second_rect =
391  SkIRect::MakeXYWH(second_output.x(), second_output.y(), 140, 90);
392  // Make sure the rectangle is placed such that it is inside the bounds of
393  // the packer's area but not in the are of the first rectangle.
394  ASSERT_TRUE(SkIRect::Intersects(packer_area, second_rect));
395  ASSERT_FALSE(SkIRect::Intersects(first_rect, second_rect));
396 
397  // We added another 90 x 140 = 12_600 units, now taking us to 13_000
398  // 13_000 / 20_000 == 0.65 == 65%
399  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.65));
400 
401  // There's enough area to add this rectangle, but no space big enough for
402  // the 50 units of width.
403  IPoint16 output;
404  ASSERT_FALSE(packer->AddRect(50, 50, &output));
405  // Should be unchanged.
406  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.65));
407 
408  packer->Reset();
409  // Should be empty now.
410  ASSERT_EQ(packer->PercentFull(), 0);
411 }
bool NumberNear(double a, double b)

References impeller::RectanglePacker::Factory(), NumberNear(), impeller::IPoint16::x(), and impeller::IPoint16::y().

◆ TEST_P() [547/549]

impeller::testing::TEST_P ( TypographerTest  ,
TextFrameAtlasGenerationTracksState   
)

Definition at line 575 of file typographer_unittests.cc.

575  {
576  SkFont font = flutter::testing::CreateTestFontOfSize(12);
577  auto blob = SkTextBlob::MakeFromString(
578  "the quick brown fox jumped over the lazy dog.", font);
579  ASSERT_TRUE(blob);
580  auto frame = MakeTextFrameFromTextBlobSkia(blob);
581 
582  EXPECT_FALSE(frame->IsFrameComplete());
583 
584  auto context = TypographerContextSkia::Make();
585  auto atlas_context =
586  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
587  auto data_host_buffer = HostBuffer::Create(
588  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
589  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
590 
591  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
592  GlyphAtlas::Type::kAlphaBitmap,
593  /*scale=*/Rational(1), atlas_context, frame);
594 
595  // The glyph position in the atlas was not known when this value
596  // was recorded. It is marked as a placeholder.
597  EXPECT_TRUE(frame->IsFrameComplete());
598  EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
599  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
600  // OpenGLES must always increase the atlas backend if the texture grows.
601  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
602  } else {
603  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
604  }
605 
606  atlas = CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
607  GlyphAtlas::Type::kAlphaBitmap,
608  /*scale=*/Rational(1), atlas_context, frame);
609 
610  // The second time the glyph is rendered, the bounds are correcly known.
611  EXPECT_TRUE(frame->IsFrameComplete());
612  EXPECT_FALSE(frame->GetFrameBounds(0).is_placeholder);
613  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
614  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
615  } else {
616  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
617  }
618 
619  // Force increase the generation.
620  atlas_context->GetGlyphAtlas()->SetAtlasGeneration(2u);
621  atlas = CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
622  GlyphAtlas::Type::kAlphaBitmap,
623  /*scale=*/Rational(1), atlas_context, frame);
624 
625  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 2u);
626 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::kOpenGLES, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [548/549]

impeller::testing::TEST_P ( TypographerTest  ,
TextFrameInitialBoundsArePlaceholder   
)

Definition at line 505 of file typographer_unittests.cc.

505  {
506  SkFont font = flutter::testing::CreateTestFontOfSize(12);
507  auto blob = SkTextBlob::MakeFromString(
508  "the quick brown fox jumped over the lazy dog.", font);
509  ASSERT_TRUE(blob);
510  auto frame = MakeTextFrameFromTextBlobSkia(blob);
511 
512  EXPECT_FALSE(frame->IsFrameComplete());
513 
514  auto context = TypographerContextSkia::Make();
515  auto atlas_context =
516  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
517  auto data_host_buffer = HostBuffer::Create(
518  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
519  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
520 
521  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
522  GlyphAtlas::Type::kAlphaBitmap,
523  /*scale=*/Rational(1), atlas_context, frame);
524 
525  // The glyph position in the atlas was not known when this value
526  // was recorded. It is marked as a placeholder.
527  EXPECT_TRUE(frame->IsFrameComplete());
528  EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
529 
530  atlas = CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
531  GlyphAtlas::Type::kAlphaBitmap,
532  /*scale=*/Rational(1), atlas_context, frame);
533 
534  // The second time the glyph is rendered, the bounds are correcly known.
535  EXPECT_TRUE(frame->IsFrameComplete());
536  EXPECT_FALSE(frame->GetFrameBounds(0).is_placeholder);
537 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [549/549]

impeller::testing::TEST_P ( TypographerTest  ,
TextFrameInvalidationWithScale   
)

Definition at line 539 of file typographer_unittests.cc.

539  {
540  SkFont font = flutter::testing::CreateTestFontOfSize(12);
541  auto blob = SkTextBlob::MakeFromString(
542  "the quick brown fox jumped over the lazy dog.", font);
543  ASSERT_TRUE(blob);
544  auto frame = MakeTextFrameFromTextBlobSkia(blob);
545 
546  EXPECT_FALSE(frame->IsFrameComplete());
547 
548  auto context = TypographerContextSkia::Make();
549  auto atlas_context =
550  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
551  auto data_host_buffer = HostBuffer::Create(
552  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
553  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
554 
555  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
556  GlyphAtlas::Type::kAlphaBitmap,
557  /*scale=*/Rational(1), atlas_context, frame);
558 
559  // The glyph position in the atlas was not known when this value
560  // was recorded. It is marked as a placeholder.
561  EXPECT_TRUE(frame->IsFrameComplete());
562  EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
563 
564  // Change the scale and the glyph data will still be a placeholder, as the
565  // old data is no longer valid.
566  atlas = CreateGlyphAtlas(*GetContext(), context.get(), *data_host_buffer,
567  GlyphAtlas::Type::kAlphaBitmap,
568  /*scale=*/Rational(2), atlas_context, frame);
569 
570  // The second time the glyph is rendered, the bounds are correcly known.
571  EXPECT_TRUE(frame->IsFrameComplete());
572  EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
573 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ toColor()

flutter::DlColor impeller::testing::toColor ( const float *  components)

Definition at line 39 of file dl_unittests.cc.

39  {
40  return flutter::DlColor(Color::ToIColor(
41  Color(components[0], components[1], components[2], components[3])));
42 }

References impeller::Color::ToIColor().

Referenced by TEST_P().

Variable Documentation

◆ golden_cubic_and_quad_points

std::vector<Point> impeller::testing::golden_cubic_and_quad_points

Definition at line 15 of file golden_paths.h.

◆ kFontFixture

constexpr std::string_view impeller::testing::kFontFixture
staticconstexpr
Initial value:
=
"NotoColorEmoji.ttf"

Definition at line 376 of file aiks_dl_text_unittests.cc.

Referenced by TEST_P().

◆ kMagicFailingAllocation

constexpr const size_t impeller::testing::kMagicFailingAllocation = 1024000 * 2
staticconstexpr

◆ kPaintVariations

const std::map<std::string, MaskBlurTestConfig> impeller::testing::kPaintVariations
static

Definition at line 586 of file aiks_dl_blur_unittests.cc.