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  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 (StringsTest, CanSPrintF)
 
 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, CanRenderColoredRect)
 
 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, 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 (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)
 
 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 (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)
 
 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 &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 &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 43 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/11]

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

◆ CAPABILITY_TEST() [2/11]

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

◆ CAPABILITY_TEST() [3/11]

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

◆ CAPABILITY_TEST() [4/11]

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

◆ CAPABILITY_TEST() [5/11]

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

◆ CAPABILITY_TEST() [6/11]

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

◆ CAPABILITY_TEST() [7/11]

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

◆ CAPABILITY_TEST() [8/11]

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

◆ CAPABILITY_TEST() [9/11]

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

◆ CAPABILITY_TEST() [10/11]

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

◆ CAPABILITY_TEST() [11/11]

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

◆ CompareFunctionUI()

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

Definition at line 1220 of file renderer_unittests.cc.

1220  {
1221  static CompareFunctionUIData data;
1222  return data;
1223 }
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 1413 of file renderer_unittests.cc.

1414  {
1415  using TexturePipelineBuilder = PipelineBuilder<VertexShader, FragmentShader>;
1416  auto pipeline_desc =
1417  TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1418  if (!pipeline_desc.has_value()) {
1419  return nullptr;
1420  }
1421  pipeline_desc->SetSampleCount(SampleCount::kCount4);
1422  pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
1423  auto pipeline =
1424  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
1425  if (!pipeline || !pipeline->IsValid()) {
1426  return nullptr;
1427  }
1428  return pipeline;
1429 }

References impeller::kCount4.

◆ CreateGlyphAtlas() [1/2]

static std::shared_ptr<GlyphAtlas> impeller::testing::CreateGlyphAtlas ( Context context,
const TypographerContext typographer_context,
HostBuffer 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, 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 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, 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 25 of file canvas_unittests.cc.

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

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 1657 of file entity_unittests.cc.

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

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

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

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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/523]

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

Definition at line 264 of file base_unittests.cc.

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

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

◆ TEST() [29/523]

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

Definition at line 255 of file base_unittests.cc.

255  {
256  auto wrapper = std::make_shared<NoExceptionPromise<int>>();
257  std::future future = wrapper->get_future();
258 
259  // Destroy the empty promise with the future still pending. Verify that the
260  // process does not abort while destructing the promise.
261  wrapper.reset();
262 }

◆ TEST() [30/523]

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

Definition at line 248 of file base_unittests.cc.

248  {
249  NoExceptionPromise<int> wrapper;
250  std::future future = wrapper.get_future();
251  wrapper.set_value(123);
252  ASSERT_EQ(future.get(), 123);
253 }

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

◆ TEST() [31/523]

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:54

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

◆ TEST() [32/523]

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() [33/523]

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() [34/523]

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() [35/523]

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

Definition at line 33 of file capabilities_unittests.cc.

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

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

◆ TEST() [36/523]

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

Definition at line 51 of file capabilities_unittests.cc.

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

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

◆ TEST() [37/523]

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

Definition at line 61 of file capabilities_unittests.cc.

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

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

◆ TEST() [38/523]

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

Definition at line 42 of file capabilities_unittests.cc.

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

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

◆ TEST() [39/523]

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

Definition at line 70 of file capabilities_unittests.cc.

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

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

◆ TEST() [40/523]

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

Definition at line 79 of file capabilities_unittests.cc.

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

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

◆ TEST() [41/523]

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() [42/523]

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() [43/523]

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() [44/523]

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() [45/523]

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() [46/523]

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() [47/523]

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() [48/523]

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() [49/523]

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() [50/523]

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() [51/523]

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

Definition at line 203 of file base_unittests.cc.

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

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

◆ TEST() [52/523]

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

Definition at line 158 of file base_unittests.cc.

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

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

◆ TEST() [53/523]

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

Definition at line 120 of file base_unittests.cc.

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

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

◆ TEST() [54/523]

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

Definition at line 141 of file base_unittests.cc.

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

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

◆ TEST() [55/523]

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

Definition at line 97 of file base_unittests.cc.

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

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

◆ TEST() [56/523]

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() [57/523]

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() [58/523]

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() [59/523]

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() [60/523]

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() [61/523]

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() [62/523]

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() [63/523]

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() [64/523]

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() [65/523]

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() [66/523]

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() [67/523]

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() [68/523]

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() [69/523]

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() [70/523]

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() [71/523]

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() [72/523]

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() [73/523]

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() [74/523]

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() [75/523]

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() [76/523]

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() [77/523]

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() [78/523]

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() [79/523]

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() [80/523]

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() [81/523]

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() [82/523]

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() [83/523]

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() [84/523]

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() [85/523]

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() [86/523]

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() [87/523]

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() [88/523]

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() [89/523]

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() [90/523]

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() [91/523]

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() [92/523]

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() [93/523]

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() [94/523]

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() [95/523]

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() [96/523]

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() [97/523]

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() [98/523]

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:792

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() [99/523]

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() [100/523]

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() [101/523]

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() [102/523]

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() [103/523]

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() [104/523]

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() [105/523]

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() [106/523]

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:622

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

◆ TEST() [107/523]

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() [108/523]

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() [109/523]

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() [110/523]

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() [111/523]

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() [112/523]

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() [113/523]

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() [114/523]

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() [115/523]

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() [116/523]

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() [117/523]

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() [118/523]

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() [119/523]

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() [120/523]

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() [121/523]

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() [122/523]

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() [123/523]

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() [124/523]

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() [125/523]

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() [126/523]

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() [127/523]

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() [128/523]

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() [129/523]

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() [130/523]

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() [131/523]

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() [132/523]

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() [133/523]

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() [134/523]

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() [135/523]

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() [136/523]

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() [137/523]

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() [138/523]

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() [139/523]

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() [140/523]

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() [141/523]

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() [142/523]

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() [143/523]

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() [144/523]

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() [145/523]

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() [146/523]

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() [147/523]

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() [148/523]

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() [149/523]

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() [150/523]

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() [151/523]

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() [152/523]

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() [153/523]

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() [154/523]

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() [155/523]

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() [156/523]

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() [157/523]

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() [158/523]

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() [159/523]

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() [160/523]

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() [161/523]

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() [162/523]

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() [163/523]

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() [164/523]

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() [165/523]

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() [166/523]

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() [167/523]

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() [168/523]

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() [169/523]

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() [170/523]

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() [171/523]

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() [172/523]

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() [173/523]

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() [174/523]

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() [175/523]

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() [176/523]

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() [177/523]

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() [178/523]

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() [179/523]

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() [180/523]

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() [181/523]

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() [182/523]

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() [183/523]

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() [184/523]

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() [185/523]

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() [186/523]

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() [187/523]

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() [188/523]

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() [189/523]

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() [190/523]

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() [191/523]

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() [192/523]

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() [193/523]

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() [194/523]

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() [195/523]

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() [196/523]

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() [197/523]

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() [198/523]

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() [199/523]

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() [200/523]

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() [201/523]

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() [202/523]

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() [203/523]

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() [204/523]

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() [205/523]

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() [206/523]

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() [207/523]

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() [208/523]

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() [209/523]

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() [210/523]

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() [211/523]

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() [212/523]

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() [213/523]

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() [214/523]

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() [215/523]

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() [216/523]

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() [217/523]

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() [218/523]

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() [219/523]

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() [220/523]

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() [221/523]

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() [222/523]

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() [223/523]

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() [224/523]

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() [225/523]

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() [226/523]

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() [227/523]

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() [228/523]

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() [229/523]

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() [230/523]

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() [231/523]

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() [232/523]

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() [233/523]

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() [234/523]

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() [235/523]

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() [236/523]

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() [237/523]

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() [238/523]

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() [239/523]

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() [240/523]

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() [241/523]

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() [242/523]

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() [243/523]

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() [244/523]

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() [245/523]

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() [246/523]

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() [247/523]

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() [248/523]

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() [249/523]

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() [250/523]

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() [251/523]

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() [252/523]

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() [253/523]

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() [254/523]

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() [255/523]

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() [256/523]

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() [257/523]

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() [258/523]

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() [259/523]

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() [260/523]

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() [261/523]

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() [262/523]

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() [263/523]

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() [264/523]

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() [265/523]

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() [266/523]

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() [267/523]

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() [268/523]

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() [269/523]

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() [270/523]

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() [271/523]

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() [272/523]

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() [273/523]

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() [274/523]

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() [275/523]

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() [276/523]

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() [277/523]

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() [278/523]

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() [279/523]

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() [280/523]

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() [281/523]

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() [282/523]

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() [283/523]

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() [284/523]

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() [285/523]

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() [286/523]

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() [287/523]

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() [288/523]

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() [289/523]

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() [290/523]

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() [291/523]

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() [292/523]

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() [293/523]

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() [294/523]

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() [295/523]

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() [296/523]

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() [297/523]

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() [298/523]

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() [299/523]

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() [300/523]

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() [301/523]

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() [302/523]

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:795

References impeller::saturated::b, and impeller::TRect< T >::MakeLTRB().

◆ TEST() [303/523]

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() [304/523]

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() [305/523]

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() [306/523]

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() [307/523]

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() [308/523]

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() [309/523]

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() [310/523]

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() [311/523]

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() [312/523]

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() [313/523]

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() [314/523]

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() [315/523]

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() [316/523]

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() [317/523]

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() [318/523]

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() [319/523]

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() [320/523]

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() [321/523]

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() [322/523]

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() [323/523]

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() [324/523]

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() [325/523]

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() [326/523]

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() [327/523]

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() [328/523]

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() [329/523]

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() [330/523]

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() [331/523]

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() [332/523]

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() [333/523]

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() [334/523]

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() [335/523]

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() [336/523]

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() [337/523]

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() [338/523]

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() [339/523]

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() [340/523]

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() [341/523]

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() [342/523]

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() [343/523]

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() [344/523]

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() [345/523]

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() [346/523]

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() [347/523]

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() [348/523]

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() [349/523]

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() [350/523]

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() [351/523]

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() [352/523]

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() [353/523]

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() [354/523]

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() [355/523]

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() [356/523]

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() [357/523]

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() [358/523]

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() [359/523]

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() [360/523]

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() [361/523]

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() [362/523]

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() [363/523]

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() [364/523]

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() [365/523]

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() [366/523]

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() [367/523]

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() [368/523]

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() [369/523]

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() [370/523]

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() [371/523]

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() [372/523]

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() [373/523]

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() [374/523]

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() [375/523]

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() [376/523]

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() [377/523]

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() [378/523]

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() [379/523]

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() [380/523]

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() [381/523]

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() [382/523]

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() [383/523]

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() [384/523]

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() [385/523]

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() [386/523]

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() [387/523]

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() [388/523]

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() [389/523]

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() [390/523]

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() [391/523]

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() [392/523]

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() [393/523]

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() [394/523]

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() [395/523]

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() [396/523]

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() [397/523]

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() [398/523]

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() [399/523]

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() [400/523]

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() [401/523]

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() [402/523]

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() [403/523]

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() [404/523]

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() [405/523]

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() [406/523]

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() [407/523]

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() [408/523]

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() [409/523]

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() [410/523]

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() [411/523]

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() [412/523]

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() [413/523]

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() [414/523]

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() [415/523]

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() [416/523]

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() [417/523]

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() [418/523]

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() [419/523]

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() [420/523]

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() [421/523]

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() [422/523]

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() [423/523]

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() [424/523]

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() [425/523]

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() [426/523]

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() [427/523]

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() [428/523]

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() [429/523]

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() [430/523]

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() [431/523]

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() [432/523]

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() [433/523]

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() [434/523]

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() [435/523]

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() [436/523]

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() [437/523]

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() [438/523]

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() [439/523]

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() [440/523]

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() [441/523]

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() [442/523]

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() [443/523]

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() [444/523]

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() [445/523]

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() [446/523]

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() [447/523]

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() [448/523]

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() [449/523]

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() [450/523]

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() [451/523]

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() [452/523]

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() [453/523]

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() [454/523]

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() [455/523]

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() [456/523]

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() [457/523]

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() [458/523]

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() [459/523]

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() [460/523]

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() [461/523]

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() [462/523]

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() [463/523]

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() [464/523]

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() [465/523]

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() [466/523]

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() [467/523]

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() [468/523]

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() [469/523]

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() [470/523]

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() [471/523]

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() [472/523]

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() [473/523]

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() [474/523]

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() [475/523]

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() [476/523]

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() [477/523]

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() [478/523]

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() [479/523]

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() [480/523]

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() [481/523]

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() [482/523]

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() [483/523]

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() [484/523]

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() [485/523]

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() [486/523]

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() [487/523]

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() [488/523]

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() [489/523]

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() [490/523]

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() [491/523]

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() [492/523]

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() [493/523]

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() [494/523]

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() [495/523]

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() [496/523]

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() [497/523]

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() [498/523]

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() [499/523]

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() [500/523]

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() [501/523]

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() [502/523]

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() [503/523]

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() [504/523]

impeller::testing::TEST ( StringsTest  ,
CanSPrintF   
)

Definition at line 84 of file base_unittests.cc.

84  {
85  ASSERT_EQ(SPrintF("%sx%d", "Hello", 12), "Hellox12");
86  ASSERT_EQ(SPrintF(""), "");
87  ASSERT_EQ(SPrintF("Hello"), "Hello");
88  ASSERT_EQ(SPrintF("%sx%.2f", "Hello", 12.122222), "Hellox12.12");
89 }
std::string SPrintF(const char *format,...)
Definition: strings.cc:12

References impeller::SPrintF().

◆ TEST() [505/523]

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() [506/523]

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() [507/523]

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() [508/523]

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() [509/523]

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() [510/523]

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() [511/523]

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() [512/523]

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() [513/523]

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() [514/523]

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() [515/523]

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() [516/523]

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() [517/523]

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() [518/523]

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() [519/523]

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() [520/523]

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() [521/523]

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() [522/523]

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() [523/523]

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/545]

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/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownBackdropId   
)

Definition at line 175 of file canvas_unittests.cc.

175  {
176  ContentContext context(GetContext(), nullptr);
177  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
178  GTEST_SKIP() << "Test requires device with framebuffer fetch";
179  }
180  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
181  /*requires_readback=*/true);
182  // 3 backdrop filters all with same id.
183  std::unordered_map<int64_t, BackdropData> data;
184  data[1] = BackdropData{.backdrop_count = 3};
185  canvas->SetBackdropData(data, 3);
186 
187  auto blur =
188  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
189 
190  EXPECT_TRUE(canvas->RequiresReadback());
191  canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
192  {.color = Color::Azure()});
193  canvas->SaveLayer({}, std::nullopt, blur.get(),
194  ContentBoundsPromise::kContainsContents,
195  /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
196  /*backdrop_id=*/1);
197  canvas->Restore();
198  EXPECT_FALSE(canvas->RequiresReadback());
199 
200  canvas->SaveLayer({}, std::nullopt, blur.get(),
201  ContentBoundsPromise::kContainsContents,
202  /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
203  /*backdrop_id=*/1);
204  canvas->Restore();
205  EXPECT_FALSE(canvas->RequiresReadback());
206 
207  canvas->SaveLayer({}, std::nullopt, blur.get(),
208  ContentBoundsPromise::kContainsContents,
209  /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
210  /*backdrop_id=*/1);
211  canvas->Restore();
212  EXPECT_FALSE(canvas->RequiresReadback());
213 }
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/545]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownBackdropIdMixed   
)

Definition at line 215 of file canvas_unittests.cc.

215  {
216  ContentContext context(GetContext(), nullptr);
217  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
218  GTEST_SKIP() << "Test requires device with framebuffer fetch";
219  }
220  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
221  /*requires_readback=*/true);
222  // 3 backdrop filters, 2 with same id.
223  std::unordered_map<int64_t, BackdropData> data;
224  data[1] = BackdropData{.backdrop_count = 2};
225  canvas->SetBackdropData(data, 3);
226 
227  auto blur =
228  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
229 
230  EXPECT_TRUE(canvas->RequiresReadback());
231  canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
232  {.color = Color::Azure()});
233  canvas->SaveLayer({}, std::nullopt, blur.get(),
234  ContentBoundsPromise::kContainsContents, 1, false);
235  canvas->Restore();
236  EXPECT_TRUE(canvas->RequiresReadback());
237 
238  canvas->SaveLayer({}, std::nullopt, blur.get(),
239  ContentBoundsPromise::kContainsContents, 1, false, 1);
240  canvas->Restore();
241  EXPECT_FALSE(canvas->RequiresReadback());
242 
243  canvas->SaveLayer({}, std::nullopt, blur.get(),
244  ContentBoundsPromise::kContainsContents, 1, false, 1);
245  canvas->Restore();
246  EXPECT_FALSE(canvas->RequiresReadback());
247 }

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/545]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownNormal   
)

Definition at line 140 of file canvas_unittests.cc.

140  {
141  ContentContext context(GetContext(), nullptr);
142  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
143  GTEST_SKIP() << "Test requires device with framebuffer fetch";
144  }
145  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
146  /*requires_readback=*/true);
147  // 3 backdrop filters
148  canvas->SetBackdropData({}, 3);
149 
150  auto blur =
151  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
152  flutter::DlRect rect = flutter::DlRect::MakeLTRB(0, 0, 50, 50);
153 
154  EXPECT_TRUE(canvas->RequiresReadback());
155  canvas->DrawRect(rect, {.color = Color::Azure()});
156  canvas->SaveLayer({}, rect, blur.get(),
157  ContentBoundsPromise::kContainsContents,
158  /*total_content_depth=*/1);
159  canvas->Restore();
160  EXPECT_TRUE(canvas->RequiresReadback());
161 
162  canvas->SaveLayer({}, rect, blur.get(),
163  ContentBoundsPromise::kContainsContents,
164  /*total_content_depth=*/1);
165  canvas->Restore();
166  EXPECT_TRUE(canvas->RequiresReadback());
167 
168  canvas->SaveLayer({}, rect, blur.get(),
169  ContentBoundsPromise::kContainsContents,
170  /*total_content_depth=*/1);
171  canvas->Restore();
172  EXPECT_FALSE(canvas->RequiresReadback());
173 }
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/545]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownWithNestedSaveLayers   
)

Definition at line 252 of file canvas_unittests.cc.

252  {
253  ContentContext context(GetContext(), nullptr);
254  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
255  GTEST_SKIP() << "Test requires device with framebuffer fetch";
256  }
257  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
258  /*requires_readback=*/true);
259 
260  canvas->SetBackdropData({}, 2);
261 
262  auto blur =
263  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
264 
265  EXPECT_TRUE(canvas->RequiresReadback());
266  canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
267  {.color = Color::Azure()});
268  canvas->SaveLayer({}, std::nullopt, blur.get(),
269  ContentBoundsPromise::kContainsContents,
270  /*total_content_depth=*/3);
271 
272  // This filter is nested in the first saveLayer. We cannot restore to onscreen
273  // here.
274  canvas->SaveLayer({}, std::nullopt, blur.get(),
275  ContentBoundsPromise::kContainsContents,
276  /*total_content_depth=*/1);
277  canvas->Restore();
278  EXPECT_TRUE(canvas->RequiresReadback());
279 
280  canvas->Restore();
281  EXPECT_TRUE(canvas->RequiresReadback());
282 }

References impeller::Color::Azure(), CreateTestCanvas(), impeller::ContentContext::GetDeviceCapabilities(), impeller::kContainsContents, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Capabilities::SupportsFramebufferFetch().

◆ TEST_P() [7/545]

impeller::testing::TEST_P ( AiksTest  ,
BackdropFilterOverUnclosedClip   
)

Definition at line 2080 of file aiks_dl_basic_unittests.cc.

2080  {
2081  DisplayListBuilder builder;
2082 
2083  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
2084  builder.Save();
2085  {
2086  builder.ClipRect(DlRect::MakeLTRB(100, 100, 800, 800));
2087 
2088  builder.Save();
2089  {
2090  builder.ClipRect(DlRect::MakeLTRB(600, 600, 800, 800));
2091  builder.DrawPaint(DlPaint().setColor(DlColor::kRed()));
2092  builder.DrawPaint(DlPaint().setColor(DlColor::kBlue().withAlphaF(0.5)));
2093  builder.ClipRect(DlRect::MakeLTRB(700, 700, 750, 800));
2094  builder.DrawPaint(DlPaint().setColor(DlColor::kRed().withAlphaF(0.5)));
2095  }
2096  builder.Restore();
2097 
2098  auto image_filter = DlImageFilter::MakeBlur(10, 10, DlTileMode::kDecal);
2099  builder.SaveLayer(std::nullopt, nullptr, image_filter.get());
2100  }
2101  builder.Restore();
2102  builder.DrawCircle(DlPoint(100, 100), 100,
2103  DlPaint().setColor(DlColor::kAqua()));
2104 
2105  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
2106 }

◆ TEST_P() [8/545]

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/545]

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/545]

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/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
BlurGradientWithOpacity   
)

Definition at line 1344 of file aiks_dl_blur_unittests.cc.

1344  {
1345  DisplayListBuilder builder;
1346  builder.Scale(GetContentScale().x, GetContentScale().y);
1347 
1348  std::vector<DlColor> colors = {DlColor(0xFFFF0000), DlColor(0xFF00FF00)};
1349  std::vector<Scalar> stops = {0.0, 1.0};
1350 
1351  auto gradient = DlColorSource::MakeLinear(
1352  {0, 0}, {400, 400}, 2, colors.data(), stops.data(), DlTileMode::kClamp);
1353 
1354  DlPaint save_paint;
1355  save_paint.setOpacity(0.5);
1356  builder.SaveLayer(std::nullopt, &save_paint);
1357 
1358  DlPaint paint;
1359  paint.setColorSource(gradient);
1360  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1));
1361  builder.DrawRect(DlRect::MakeXYWH(100, 100, 200, 200), paint);
1362 
1363  builder.Restore();
1364 
1365  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1366 }

References x.

◆ TEST_P() [13/545]

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/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
BlurredRectangleWithShader   
)

Definition at line 1197 of file aiks_dl_blur_unittests.cc.

1197  {
1198  DisplayListBuilder builder;
1199  builder.Scale(GetContentScale().x, GetContentScale().y);
1200 
1201  auto paint_lines = [&builder](Scalar dx, Scalar dy, DlPaint paint) {
1202  auto draw_line = [&builder, &paint](DlPoint a, DlPoint b) {
1203  DlPath line = DlPath::MakeLine(a, b);
1204  builder.DrawPath(line, paint);
1205  };
1206  paint.setStrokeWidth(5);
1207  paint.setDrawStyle(DlDrawStyle::kStroke);
1208  draw_line(DlPoint(dx + 100, dy + 100), DlPoint(dx + 200, dy + 200));
1209  draw_line(DlPoint(dx + 100, dy + 200), DlPoint(dx + 200, dy + 100));
1210  draw_line(DlPoint(dx + 150, dy + 100), DlPoint(dx + 200, dy + 150));
1211  draw_line(DlPoint(dx + 100, dy + 150), DlPoint(dx + 150, dy + 200));
1212  };
1213 
1214  AiksContext renderer(GetContext(), nullptr);
1215  DisplayListBuilder recorder_builder;
1216  for (int x = 0; x < 5; ++x) {
1217  for (int y = 0; y < 5; ++y) {
1218  DlRect rect = DlRect::MakeXYWH(x * 20, y * 20, 20, 20);
1219  DlPaint paint;
1220  paint.setColor(((x + y) & 1) == 0 ? DlColor::kYellow()
1221  : DlColor::kBlue());
1222 
1223  recorder_builder.DrawRect(rect, paint);
1224  }
1225  }
1226  auto texture =
1227  DisplayListToTexture(recorder_builder.Build(), {100, 100}, renderer);
1228 
1229  auto image_source = DlColorSource::MakeImage(
1230  DlImageImpeller::Make(texture), DlTileMode::kRepeat, DlTileMode::kRepeat);
1231  auto blur_filter = DlImageFilter::MakeBlur(5, 5, DlTileMode::kDecal);
1232 
1233  DlPaint paint;
1234  paint.setColor(DlColor::kDarkGreen());
1235  builder.DrawRect(DlRect::MakeLTRB(0, 0, 300, 600), paint);
1236 
1237  paint.setColorSource(image_source);
1238  builder.DrawRect(DlRect::MakeLTRB(100, 100, 200, 200), paint);
1239 
1240  paint.setColorSource(nullptr);
1241  paint.setColor(DlColor::kRed());
1242  builder.DrawRect(DlRect::MakeLTRB(300, 0, 600, 600), paint);
1243 
1244  paint.setColorSource(image_source);
1245  paint.setImageFilter(blur_filter);
1246  builder.DrawRect(DlRect::MakeLTRB(400, 100, 500, 200), paint);
1247 
1248  paint.setImageFilter(nullptr);
1249  paint_lines(0, 300, paint);
1250 
1251  paint.setImageFilter(blur_filter);
1252  paint_lines(300, 300, paint);
1253 
1254  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1255 }

References impeller::saturated::b, impeller::DisplayListToTexture(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [16/545]

impeller::testing::TEST_P ( AiksTest  ,
CanConvertTriangleFanToTriangles   
)

Definition at line 157 of file aiks_dl_vertices_unittests.cc.

157  {
158  constexpr Scalar hexagon_radius = 125;
159  auto hex_start = Point(200.0, -hexagon_radius + 200.0);
160  auto center_to_flat = 1.73 / 2 * hexagon_radius;
161 
162  // clang-format off
163  std::vector<DlPoint> vertices = {
164  DlPoint(hex_start.x, hex_start.y),
165  DlPoint(hex_start.x + center_to_flat, hex_start.y + 0.5 * hexagon_radius),
166  DlPoint(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
167  DlPoint(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
168  DlPoint(hex_start.x, hex_start.y + 2 * hexagon_radius),
169  DlPoint(hex_start.x, hex_start.y + 2 * hexagon_radius),
170  DlPoint(hex_start.x - center_to_flat, hex_start.y + 1.5 * 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 + 0.5 * hexagon_radius)
173  };
174  // clang-format on
175  auto paint = flutter::DlPaint(flutter::DlColor::kDarkGrey());
176  auto dl_vertices = flutter::DlVertices::Make(
177  flutter::DlVertexMode::kTriangleFan, vertices.size(), vertices.data(),
178  nullptr, nullptr);
179  flutter::DisplayListBuilder builder;
180  builder.DrawVertices(dl_vertices, flutter::DlBlendMode::kSrcOver, paint);
181  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
182 }

◆ TEST_P() [17/545]

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/545]

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/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaint   
)

Definition at line 404 of file aiks_dl_basic_unittests.cc.

404  {
405  auto medium_turquoise =
406  DlColor::RGBA(72.0f / 255.0f, 209.0f / 255.0f, 204.0f / 255.0f, 1.0f);
407 
408  DisplayListBuilder builder;
409  builder.Scale(0.2, 0.2);
410  builder.DrawPaint(DlPaint().setColor(medium_turquoise));
411  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
412 }

◆ TEST_P() [21/545]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintMultipleTimes   
)

Definition at line 414 of file aiks_dl_basic_unittests.cc.

414  {
415  auto medium_turquoise =
416  DlColor::RGBA(72.0f / 255.0f, 209.0f / 255.0f, 204.0f / 255.0f, 1.0f);
417  auto orange_red =
418  DlColor::RGBA(255.0f / 255.0f, 69.0f / 255.0f, 0.0f / 255.0f, 1.0f);
419 
420  DisplayListBuilder builder;
421  builder.Scale(0.2, 0.2);
422  builder.DrawPaint(DlPaint().setColor(medium_turquoise));
423  builder.DrawPaint(DlPaint().setColor(orange_red.modulateOpacity(0.5f)));
424  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
425 }

◆ TEST_P() [22/545]

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/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPerspectiveTransformWithClips   
)

Definition at line 1307 of file aiks_dl_basic_unittests.cc.

1307  {
1308  // Avoiding `GetSecondsElapsed()` to reduce risk of golden flakiness.
1309  int time = 0;
1310  auto callback = [&]() -> sk_sp<DisplayList> {
1311  DisplayListBuilder builder;
1312 
1313  builder.Save();
1314  {
1315  builder.Translate(300, 300);
1316 
1317  // 1. Draw/restore a clip before drawing the image, which will get drawn
1318  // to the depth buffer behind the image.
1319  builder.Save();
1320  {
1321  DlPaint paint;
1322  paint.setColor(DlColor::kGreen());
1323  builder.DrawPaint(paint);
1324  builder.ClipRect(DlRect::MakeLTRB(-180, -180, 180, 180),
1325  DlClipOp::kDifference);
1326 
1327  paint.setColor(DlColor::kBlack());
1328  builder.DrawPaint(paint);
1329  }
1330  builder.Restore(); // Restore rectangle difference clip.
1331 
1332  builder.Save();
1333  {
1334  // 2. Draw an oval clip that applies to the image, which will get drawn
1335  // in front of the image on the depth buffer.
1336  builder.ClipOval(DlRect::MakeLTRB(-200, -200, 200, 200));
1337 
1338  Matrix result =
1339  Matrix(1.0, 0.0, 0.0, 0.0, //
1340  0.0, 1.0, 0.0, 0.0, //
1341  0.0, 0.0, 1.0, 0.003, //
1342  0.0, 0.0, 0.0, 1.0) *
1343  Matrix::MakeRotationY({Radians{-1.0f + (time++ / 60.0f)}});
1344 
1345  // 3. Draw the rotating image with a perspective transform.
1346  builder.Transform(result);
1347 
1348  auto image =
1349  DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
1350  auto position =
1351  -DlPoint(image->GetSize().width, image->GetSize().height) * 0.5;
1352  builder.DrawImage(image, position, {});
1353  }
1354  builder.Restore(); // Restore oval intersect clip.
1355 
1356  // 4. Draw a semi-translucent blue circle atop all previous draws.
1357  DlPaint paint;
1358  paint.setColor(DlColor::kBlue().modulateOpacity(0.4));
1359  builder.DrawCircle(DlPoint(), 230, paint);
1360  }
1361  builder.Restore(); // Restore translation.
1362 
1363  return builder.Build();
1364  };
1365  ASSERT_TRUE(OpenPlaygroundHere(callback));
1366 }

References impeller::DlImageImpeller::Make(), impeller::Matrix::MakeRotationY(), and impeller::Matrix::Transform().

◆ TEST_P() [25/545]

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/545]

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/545]

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/545]

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/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformFullScreenMSAA   
)

Definition at line 1648 of file aiks_dl_basic_unittests.cc.

1648  {
1649  DisplayListBuilder builder;
1650 
1651  DlPaint paint;
1652  paint.setColor(DlColor::kRed());
1653  builder.DrawCircle(DlPoint(250, 250), 125, paint);
1654 
1655  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1656 }

◆ TEST_P() [31/545]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSaveLayerWithBounds   
)

Definition at line 1669 of file aiks_dl_basic_unittests.cc.

1669  {
1670  DisplayListBuilder builder;
1671 
1672  DlPaint save;
1673  save.setColor(DlColor::kBlack());
1674 
1675  DlRect save_bounds = DlRect::MakeXYWH(0, 0, 50, 50);
1676  builder.SaveLayer(save_bounds, &save);
1677 
1678  DlPaint paint;
1679  paint.setColor(DlColor::kRed());
1680  builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), paint);
1681  paint.setColor(DlColor::kGreen());
1682  builder.DrawRect(DlRect::MakeXYWH(10, 10, 100, 100), paint);
1683  paint.setColor(DlColor::kBlue());
1684  builder.DrawRect(DlRect::MakeXYWH(20, 20, 100, 100), paint);
1685 
1686  builder.Restore();
1687 
1688  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1689 }

◆ TEST_P() [32/545]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated   
)

Definition at line 1570 of file aiks_dl_basic_unittests.cc.

1571  {
1572  DisplayListBuilder builder;
1573 
1574  DlPaint red;
1575  red.setColor(DlColor::kRed());
1576 
1577  DlPaint green;
1578  green.setColor(DlColor::kGreen());
1579 
1580  DlPaint blue;
1581  blue.setColor(DlColor::kBlue());
1582 
1583  DlPaint save;
1584  save.setColor(DlColor::kBlack().modulateOpacity(0.5));
1585 
1586  DlRect huge_bounds = DlRect::MakeXYWH(0, 0, 100000, 100000);
1587  builder.SaveLayer(huge_bounds, &save);
1588 
1589  builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), red);
1590  builder.DrawRect(DlRect::MakeXYWH(10, 10, 100, 100), green);
1591  builder.DrawRect(DlRect::MakeXYWH(20, 20, 100, 100), blue);
1592 
1593  builder.Restore();
1594 
1595  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1596 }

◆ TEST_P() [33/545]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSkew   
)

Definition at line 1658 of file aiks_dl_basic_unittests.cc.

1658  {
1659  DisplayListBuilder builder;
1660 
1661  DlPaint red;
1662  red.setColor(DlColor::kRed());
1663  builder.Skew(2, 5);
1664  builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), red);
1665 
1666  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1667 }

◆ TEST_P() [34/545]

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/545]

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/545]

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/545]

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/545]

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:50

References impeller::saturated::b, impeller::DrawPlaygroundLine(), and impeller::Color::White().

◆ TEST_P() [39/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedBackdropFilter   
)

Definition at line 1268 of file aiks_dl_basic_unittests.cc.

1268  {
1269  DisplayListBuilder builder;
1270 
1271  builder.Scale(GetContentScale().x, GetContentScale().y);
1272 
1273  // Draw something interesting in the background.
1274  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
1275  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
1276  std::vector<Scalar> stops = {
1277  0.0,
1278  1.0,
1279  };
1280  DlPaint paint;
1281  paint.setColorSource(DlColorSource::MakeLinear(
1282  /*start_point=*/DlPoint(0, 0), //
1283  /*end_point=*/DlPoint(100, 100), //
1284  /*stop_count=*/2, //
1285  /*colors=*/colors.data(), //
1286  /*stops=*/stops.data(), //
1287  /*tile_mode=*/DlTileMode::kRepeat //
1288  ));
1289 
1290  builder.DrawPaint(paint);
1291 
1292  DlRect clip_rect = DlRect::MakeLTRB(50, 50, 400, 300);
1293  DlRoundRect clip_rrect = DlRoundRect::MakeRectXY(clip_rect, 100, 100);
1294 
1295  // Draw a clipped SaveLayer, where the clip coverage and SaveLayer size are
1296  // the same.
1297  builder.ClipRoundRect(clip_rrect, DlClipOp::kIntersect);
1298 
1299  DlPaint save_paint;
1300  auto backdrop_filter = DlImageFilter::MakeColorFilter(
1301  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kExclusion));
1302  builder.SaveLayer(clip_rect, &save_paint, backdrop_filter.get());
1303 
1304  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1305 }

References x.

◆ TEST_P() [41/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedLayers   
)

Definition at line 1903 of file aiks_dl_basic_unittests.cc.

1903  {
1904  DisplayListBuilder builder;
1905 
1906  DlPaint paint;
1907  paint.setColor(DlColor::kWhite());
1908  builder.DrawPaint(paint);
1909 
1910  // Draw a green circle on the screen.
1911  {
1912  // Increase the clip depth for the savelayer to contend with.
1913  DlPath path = DlPath::MakeCircle(DlPoint(100, 100), 50);
1914  builder.ClipPath(path);
1915 
1916  DlRect bounds = DlRect::MakeXYWH(50, 50, 100, 100);
1917  DlPaint save_paint;
1918  builder.SaveLayer(bounds, &save_paint);
1919 
1920  // Fill the layer with white.
1921  paint.setColor(DlColor::kWhite());
1922  builder.DrawRect(DlRect::MakeSize(DlSize(400, 400)), paint);
1923  // Fill the layer with green, but do so with a color blend that can't be
1924  // collapsed into the parent pass.
1925  paint.setColor(DlColor::kGreen());
1926  paint.setBlendMode(DlBlendMode::kHardLight);
1927  builder.DrawRect(DlRect::MakeSize(DlSize(400, 400)), paint);
1928  }
1929 
1930  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1931 }

◆ TEST_P() [43/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedRuntimeEffects   
)

Definition at line 39 of file aiks_dl_runtime_effect_unittests.cc.

39  {
40  struct FragUniforms {
41  Vector2 iResolution;
42  Scalar iTime;
43  } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
44  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
45  uniform_data->resize(sizeof(FragUniforms));
46  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
47 
48  DlPaint paint;
49  paint.setColorSource(
50  MakeRuntimeEffect(this, "runtime_stage_example.frag.iplr", uniform_data));
51 
52  DisplayListBuilder builder;
53  builder.Save();
54  builder.ClipRoundRect(
55  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 400, 400), 10.0, 10.0),
56  DlClipOp::kIntersect);
57  builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
58  builder.Restore();
59 
60  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
61 }

◆ TEST_P() [44/545]

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/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColorFilterWithInvertColors   
)

Definition at line 62 of file aiks_dl_basic_unittests.cc.

62  {
63  DisplayListBuilder builder;
64  DlPaint paint;
65  paint.setColor(DlColor::kRed());
66  paint.setColorFilter(
67  DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
68  paint.setInvertColors(true);
69 
70  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), paint);
71  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
72 }

◆ TEST_P() [47/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColorFilterWithInvertColorsDrawPaint   
)

Definition at line 74 of file aiks_dl_basic_unittests.cc.

74  {
75  DisplayListBuilder builder;
76  DlPaint paint;
77  paint.setColor(DlColor::kRed());
78  paint.setColorFilter(
79  DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
80  paint.setInvertColors(true);
81 
82  builder.DrawPaint(paint);
83  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
84 }

◆ TEST_P() [48/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferentShapesWithSameColorSource   
)

Definition at line 351 of file aiks_dl_basic_unittests.cc.

351  {
352  DisplayListBuilder builder;
353  DlPaint paint;
354 
355  DlColor colors[2] = {
356  DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
357  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0),
358  };
359  DlScalar stops[2] = {
360  0.0,
361  1.0,
362  };
363 
364  paint.setColorSource(DlColorSource::MakeLinear(
365  /*start_point=*/DlPoint(0, 0), //
366  /*end_point=*/DlPoint(100, 100), //
367  /*stop_count=*/2, //
368  /*colors=*/colors, //
369  /*stops=*/stops, //
370  /*tile_mode=*/DlTileMode::kRepeat //
371  ));
372 
373  builder.Save();
374  builder.Translate(100, 100);
375  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), paint);
376  builder.Restore();
377 
378  builder.Save();
379  builder.Translate(100, 400);
380  builder.DrawCircle(DlPoint(100, 100), 100, paint);
381  builder.Restore();
382  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
383 }
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:23

◆ TEST_P() [56/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrame   
)

Definition at line 382 of file aiks_dl_text_unittests.cc.

382  {
383  DisplayListBuilder builder;
384 
385  DlPaint paint;
386  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
387  builder.DrawPaint(paint);
388 
389  ASSERT_TRUE(RenderTextInCanvasSkia(
390  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
391  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
392 }
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/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrameWithAlpha   
)

Definition at line 410 of file aiks_dl_text_unittests.cc.

410  {
411  DisplayListBuilder builder;
412 
413  DlPaint paint;
414  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
415  builder.DrawPaint(paint);
416 
417  ASSERT_TRUE(RenderTextInCanvasSkia(
418  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
419  {.color = DlColor::kBlack().modulateOpacity(0.5)}));
420  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
421 }

References kFontFixture, and RenderTextInCanvasSkia().

◆ TEST_P() [58/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrameWithBlur   
)

Definition at line 394 of file aiks_dl_text_unittests.cc.

394  {
395  DisplayListBuilder builder;
396 
397  builder.Scale(GetContentScale().x, GetContentScale().y);
398  DlPaint paint;
399  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
400  builder.DrawPaint(paint);
401 
402  ASSERT_TRUE(RenderTextInCanvasSkia(
403  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
404  TextRenderOptions{
405  .color = DlColor::kBlue(),
406  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
407  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
408 }

References impeller::testing::TextRenderOptions::color, kFontFixture, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [59/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderImage   
)

Definition at line 38 of file aiks_dl_basic_unittests.cc.

38  {
39  DisplayListBuilder builder;
40  DlPaint paint;
41  paint.setColor(DlColor::kRed());
42  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
43  builder.DrawImage(image, DlPoint(100.0, 100.0),
44  DlImageSampling::kNearestNeighbor, &paint);
45  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
46 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [66/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderImageRect   
)

Definition at line 211 of file aiks_dl_basic_unittests.cc.

211  {
212  DisplayListBuilder builder;
213  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
214 
215  DlISize image_half_size =
216  DlISize(image->GetSize().width * 0.5f, image->GetSize().height * 0.5f);
217 
218  // Render the bottom right quarter of the source image in a stretched rect.
219  auto source_rect = DlRect::MakeSize(image_half_size);
220  source_rect =
221  source_rect.Shift(image_half_size.width, image_half_size.height);
222 
223  builder.DrawImageRect(image, source_rect,
224  DlRect::MakeXYWH(100, 100, 600, 600),
225  DlImageSampling::kNearestNeighbor);
226  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
227 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [67/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderInvertedImageWithColorFilter   
)

Definition at line 48 of file aiks_dl_basic_unittests.cc.

48  {
49  DisplayListBuilder builder;
50  DlPaint paint;
51  paint.setColor(DlColor::kRed());
52  paint.setColorFilter(
53  DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
54  paint.setInvertColors(true);
55  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
56 
57  builder.DrawImage(image, DlPoint(100.0, 100.0),
58  DlImageSampling::kNearestNeighbor, &paint);
59  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
60 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [68/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderItalicizedText   
)

Definition at line 362 of file aiks_dl_text_unittests.cc.

362  {
363  DisplayListBuilder builder;
364 
365  DlPaint paint;
366  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
367  builder.DrawPaint(paint);
368 
369  ASSERT_TRUE(RenderTextInCanvasSkia(
370  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
371  "HomemadeApple.ttf"));
372  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
373 }

References RenderTextInCanvasSkia().

◆ TEST_P() [69/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

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/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMultipleBackdropBlurWithSingleBackdropIdDifferentLayers   
)

Definition at line 1308 of file aiks_dl_blur_unittests.cc.

1309  {
1310  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
1311 
1312  DisplayListBuilder builder;
1313 
1314  DlPaint paint;
1315  builder.DrawImage(image, DlPoint(50.0, 50.0),
1316  DlImageSampling::kNearestNeighbor, &paint);
1317 
1318  for (int i = 0; i < 6; i++) {
1319  if (i != 0) {
1320  DlPaint paint;
1321  paint.setColor(DlColor::kWhite().withAlphaF(0.95));
1322  builder.SaveLayer(std::nullopt, &paint);
1323  }
1324  DlRoundRect rrect = DlRoundRect::MakeRectXY(
1325  DlRect::MakeXYWH(50 + (i * 100), 250, 100, 100), 20, 20);
1326  builder.Save();
1327  builder.ClipRoundRect(rrect);
1328 
1329  DlPaint save_paint;
1330  save_paint.setBlendMode(DlBlendMode::kSrc);
1331  auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
1332  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get(),
1333  /*backdrop_id=*/1);
1334  builder.Restore();
1335  builder.Restore();
1336  if (i != 0) {
1337  builder.Restore();
1338  }
1339  }
1340 
1341  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1342 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [88/545]

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() [89/545]

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() [90/545]

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() [91/545]

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() [92/545]

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() [93/545]

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() [94/545]

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() [95/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRoundedRectWithNonUniformRadii   
)

Definition at line 385 of file aiks_dl_basic_unittests.cc.

385  {
386  DisplayListBuilder builder;
387  DlPaint paint;
388  paint.setColor(DlColor::kRed());
389 
390  RoundingRadii radii = {
391  .top_left = DlSize(50, 25),
392  .top_right = DlSize(25, 50),
393  .bottom_left = DlSize(25, 50),
394  .bottom_right = DlSize(50, 25),
395  };
396  DlRoundRect rrect =
397  DlRoundRect::MakeRectRadii(DlRect::MakeXYWH(100, 100, 500, 500), radii);
398 
399  builder.DrawRoundRect(rrect, paint);
400 
401  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
402 }

References impeller::RoundingRadii::top_left.

◆ TEST_P() [96/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRuntimeEffectFilter   
)

Definition at line 84 of file aiks_dl_runtime_effect_unittests.cc.

84  {
85  auto runtime_stages =
86  OpenAssetAsRuntimeStage("runtime_stage_filter_example.frag.iplr");
87 
88  std::shared_ptr<RuntimeStage> runtime_stage =
89  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
90  ASSERT_TRUE(runtime_stage);
91  ASSERT_TRUE(runtime_stage->IsDirty());
92 
93  std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
94  nullptr,
95  };
96  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
97  uniform_data->resize(sizeof(Vector2));
98 
99  DlPaint paint;
100  paint.setColor(DlColor::kAqua());
101  paint.setImageFilter(DlImageFilter::MakeRuntimeEffect(
102  DlRuntimeEffect::MakeImpeller(runtime_stage), sampler_inputs,
103  uniform_data));
104 
105  DisplayListBuilder builder;
106  builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
107 
108  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
109 }
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition: playground.h:33

References impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [97/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSimpleClips   
)

Definition at line 249 of file aiks_dl_basic_unittests.cc.

249  {
250  DisplayListBuilder builder;
251  builder.Scale(GetContentScale().x, GetContentScale().y);
252  DlPaint paint;
253 
254  paint.setColor(DlColor::kWhite());
255  builder.DrawPaint(paint);
256 
257  auto draw = [&builder](const DlPaint& paint, Scalar x, Scalar y) {
258  builder.Save();
259  builder.Translate(x, y);
260  {
261  builder.Save();
262  builder.ClipRect(DlRect::MakeLTRB(50, 50, 150, 150));
263  builder.DrawPaint(paint);
264  builder.Restore();
265  }
266  {
267  builder.Save();
268  builder.ClipOval(DlRect::MakeLTRB(200, 50, 300, 150));
269  builder.DrawPaint(paint);
270  builder.Restore();
271  }
272  {
273  builder.Save();
274  builder.ClipRoundRect(
275  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(50, 200, 150, 300), 20, 20));
276  builder.DrawPaint(paint);
277  builder.Restore();
278  }
279  {
280  builder.Save();
281  builder.ClipRoundRect(DlRoundRect::MakeRectXY(
282  DlRect::MakeLTRB(200, 230, 300, 270), 20, 20));
283  builder.DrawPaint(paint);
284  builder.Restore();
285  }
286  {
287  builder.Save();
288  builder.ClipRoundRect(DlRoundRect::MakeRectXY(
289  DlRect::MakeLTRB(230, 200, 270, 300), 20, 20));
290  builder.DrawPaint(paint);
291  builder.Restore();
292  }
293  builder.Restore();
294  };
295 
296  paint.setColor(DlColor::kBlue());
297  draw(paint, 0, 0);
298 
299  DlColor gradient_colors[7] = {
300  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
301  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
302  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
303  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
304  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
305  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
306  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
307  };
308  Scalar stops[7] = {
309  0.0,
310  (1.0 / 6.0) * 1,
311  (1.0 / 6.0) * 2,
312  (1.0 / 6.0) * 3,
313  (1.0 / 6.0) * 4,
314  (1.0 / 6.0) * 5,
315  1.0,
316  };
317  auto texture = CreateTextureForFixture("airplane.jpg",
318  /*enable_mipmapping=*/true);
319  auto image = DlImageImpeller::Make(texture);
320 
321  paint.setColorSource(DlColorSource::MakeRadial(
322  DlPoint(500, 600), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
323  draw(paint, 0, 300);
324 
325  paint.setColorSource(
326  DlColorSource::MakeImage(image, DlTileMode::kRepeat, DlTileMode::kRepeat,
327  DlImageSampling::kNearestNeighbor));
328  draw(paint, 300, 0);
329 
330  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
331 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [98/545]

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() [99/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokedTextFrame   
)

Definition at line 126 of file aiks_dl_text_unittests.cc.

126  {
127  DisplayListBuilder builder;
128 
129  DlPaint paint;
130  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
131  builder.DrawPaint(paint);
132 
133  ASSERT_TRUE(RenderTextInCanvasSkia(
134  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
135  "Roboto-Regular.ttf",
136  {
137  .stroke = true,
138  }));
139  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
140 }

References RenderTextInCanvasSkia().

◆ TEST_P() [100/545]

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() [101/545]

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() [102/545]

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() [103/545]

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() [104/545]

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() [105/545]

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() [106/545]

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() [107/545]

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() [108/545]

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() [109/545]

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() [110/545]

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() [111/545]

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() [112/545]

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() [113/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrame   
)

Definition at line 97 of file aiks_dl_text_unittests.cc.

97  {
98  DisplayListBuilder builder;
99 
100  DlPaint paint;
101  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
102  builder.DrawPaint(paint);
103  ASSERT_TRUE(RenderTextInCanvasSkia(
104  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
105  "Roboto-Regular.ttf"));
106 
107  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
108 }

References RenderTextInCanvasSkia().

◆ TEST_P() [114/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithFractionScaling   
)

Definition at line 251 of file aiks_dl_text_unittests.cc.

251  {
252  Scalar fine_scale = 0.f;
253  bool is_subpixel = false;
254  auto callback = [&]() -> sk_sp<DisplayList> {
255  if (AiksTest::ImGuiBegin("Controls", nullptr,
256  ImGuiWindowFlags_AlwaysAutoResize)) {
257  ImGui::SliderFloat("Fine Scale", &fine_scale, -1, 1);
258  ImGui::Checkbox("subpixel", &is_subpixel);
259  ImGui::End();
260  }
261 
262  DisplayListBuilder builder;
263  DlPaint paint;
264  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
265  builder.DrawPaint(paint);
266  Scalar scale = 2.625 + fine_scale;
267  builder.Scale(scale, scale);
268  RenderTextInCanvasSkia(GetContext(), builder,
269  "the quick brown fox jumped over the lazy dog!.?",
270  "Roboto-Regular.ttf",
271  TextRenderOptions{.is_subpixel = is_subpixel});
272  return builder.Build();
273  };
274 
275  ASSERT_TRUE(OpenPlaygroundHere(callback));
276 }
bool is_subpixel

References impeller::testing::TextRenderOptions::is_subpixel, is_subpixel, and RenderTextInCanvasSkia().

◆ TEST_P() [115/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithHalfScaling   
)

Definition at line 158 of file aiks_dl_text_unittests.cc.

158  {
159  DisplayListBuilder builder;
160 
161  DlPaint paint;
162  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
163  builder.DrawPaint(paint);
164  builder.Scale(0.5, 0.5);
165 
166  ASSERT_TRUE(RenderTextInCanvasSkia(
167  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
168  "Roboto-Regular.ttf"));
169  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
170 }

References RenderTextInCanvasSkia().

◆ TEST_P() [116/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithInvertedTransform   
)

Definition at line 110 of file aiks_dl_text_unittests.cc.

110  {
111  DisplayListBuilder builder;
112 
113  DlPaint paint;
114  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
115  builder.DrawPaint(paint);
116  builder.Translate(1000, 0);
117  builder.Scale(-1, 1);
118 
119  ASSERT_TRUE(RenderTextInCanvasSkia(
120  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
121  "Roboto-Regular.ttf"));
122 
123  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
124 }

References RenderTextInCanvasSkia().

◆ TEST_P() [117/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithScalingOverflow   
)

Definition at line 222 of file aiks_dl_text_unittests.cc.

222  {
223  Scalar scale = 60.0;
224  Scalar offsetx = -500.0;
225  Scalar offsety = 700.0;
226  auto callback = [&]() -> sk_sp<DisplayList> {
227  if (AiksTest::ImGuiBegin("Controls", nullptr,
228  ImGuiWindowFlags_AlwaysAutoResize)) {
229  ImGui::SliderFloat("scale", &scale, 1.f, 300.f);
230  ImGui::SliderFloat("offsetx", &offsetx, -600.f, 100.f);
231  ImGui::SliderFloat("offsety", &offsety, 600.f, 2048.f);
232  ImGui::End();
233  }
234  DisplayListBuilder builder;
235  builder.Scale(GetContentScale().x, GetContentScale().y);
236  DlPaint paint;
237  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
238  builder.DrawPaint(paint);
239  builder.Scale(scale, scale);
240 
242  GetContext(), builder, "test", "Roboto-Regular.ttf",
243  TextRenderOptions{
244  .position = DlPoint(offsetx / scale, offsety / scale),
245  });
246  return builder.Build();
247  };
248  ASSERT_TRUE(OpenPlaygroundHere(callback));
249 }

References impeller::testing::TextRenderOptions::position, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [118/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextInSaveLayer   
)

Definition at line 423 of file aiks_dl_text_unittests.cc.

423  {
424  DisplayListBuilder builder;
425 
426  DlPaint paint;
427  paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
428  builder.DrawPaint(paint);
429 
430  builder.Translate(100, 100);
431  builder.Scale(0.5, 0.5);
432 
433  // Blend the layer with the parent pass using kClear to expose the coverage.
434  paint.setBlendMode(DlBlendMode::kClear);
435  builder.SaveLayer(std::nullopt, &paint);
436  ASSERT_TRUE(RenderTextInCanvasSkia(
437  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
438  "Roboto-Regular.ttf"));
439  builder.Restore();
440 
441  // Render the text again over the cleared coverage rect.
442  ASSERT_TRUE(RenderTextInCanvasSkia(
443  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
444  "Roboto-Regular.ttf"));
445 
446  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
447 }

References RenderTextInCanvasSkia().

◆ TEST_P() [119/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextOutsideBoundaries   
)

Definition at line 449 of file aiks_dl_text_unittests.cc.

449  {
450  DisplayListBuilder builder;
451  builder.Translate(200, 150);
452 
453  // Construct the text blob.
454  auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
455  ASSERT_NE(mapping, nullptr);
456 
457  Scalar font_size = 80;
458  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
459  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
460 
461  DlPaint text_paint;
462  text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
463 
464  struct {
465  DlPoint position;
466  const char* text;
467  } text[] = {{DlPoint(0, 0), "0F0F0F0"},
468  {DlPoint(1, 2), "789"},
469  {DlPoint(1, 3), "456"},
470  {DlPoint(1, 4), "123"},
471  {DlPoint(0, 6), "0F0F0F0"}};
472  for (auto& t : text) {
473  builder.Save();
474  builder.Translate(t.position.x * font_size * 2,
475  t.position.y * font_size * 1.1);
476  {
477  auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
478  ASSERT_NE(blob, nullptr);
479  auto frame = MakeTextFrameFromTextBlobSkia(blob);
480  builder.DrawTextFrame(frame, 0, 0, text_paint);
481  }
482  builder.Restore();
483  }
484 
485  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
486 }
Scalar font_size

References font_size, and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [120/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextStrokeWidth   
)

Definition at line 142 of file aiks_dl_text_unittests.cc.

142  {
143  DisplayListBuilder builder;
144 
145  DlPaint paint;
146  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
147  builder.DrawPaint(paint);
148 
149  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "LMNOP VWXYZ",
150  "Roboto-Medium.ttf",
151  {
152  .stroke = true,
153  .stroke_width = 4,
154  }));
155  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
156 }

References RenderTextInCanvasSkia().

◆ TEST_P() [121/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextWithLargePerspectiveTransform   
)

Definition at line 546 of file aiks_dl_text_unittests.cc.

546  {
547  // Verifies that text scales are clamped to work around
548  // https://github.com/flutter/flutter/issues/136112 .
549 
550  DisplayListBuilder builder;
551 
552  DlPaint save_paint;
553  builder.SaveLayer(std::nullopt, &save_paint);
554  builder.Transform(Matrix(2000, 0, 0, 0, //
555  0, 2000, 0, 0, //
556  0, 0, -1, 9000, //
557  0, 0, -1, 7000 //
558  ));
559 
560  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
561  "Roboto-Regular.ttf"));
562  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
563 }

References RenderTextInCanvasSkia().

◆ TEST_P() [122/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextWithPerspectiveTransformInSublist   
)

Definition at line 565 of file aiks_dl_text_unittests.cc.

565  {
566  DisplayListBuilder text_builder;
567  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), text_builder, "Hello world",
568  "Roboto-Regular.ttf"));
569  auto text_display_list = text_builder.Build();
570 
571  DisplayListBuilder builder;
572 
573  Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0, //
574  0.0, 2.0, 0.0, 0.0, //
575  0.0, 0.0, 1.0, 0.0, //
576  0.0, 0.002, 0.0, 1.0);
577 
578  DlPaint save_paint;
579  DlRect window_bounds =
580  DlRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
581  builder.SaveLayer(window_bounds, &save_paint);
582  builder.Transform(matrix);
583  builder.DrawDisplayList(text_display_list, 1.0f);
584  builder.Restore();
585 
586  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
587 }

References RenderTextInCanvasSkia().

◆ TEST_P() [123/545]

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() [124/545]

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() [125/545]

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() [126/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureClamp   
)

Definition at line 190 of file aiks_dl_basic_unittests.cc.

190  {
191  CanRenderTiledTexture(this, DlTileMode::kClamp);
192 }

◆ TEST_P() [127/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureClampWithTranslate   
)

Definition at line 206 of file aiks_dl_basic_unittests.cc.

206  {
207  CanRenderTiledTexture(this, DlTileMode::kClamp,
208  Matrix::MakeTranslation({172.f, 172.f, 0.f}));
209 }

References impeller::Matrix::MakeTranslation().

◆ TEST_P() [128/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureDecal   
)

Definition at line 202 of file aiks_dl_basic_unittests.cc.

202  {
203  CanRenderTiledTexture(this, DlTileMode::kDecal);
204 }

◆ TEST_P() [129/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureMirror   
)

Definition at line 198 of file aiks_dl_basic_unittests.cc.

198  {
199  CanRenderTiledTexture(this, DlTileMode::kMirror);
200 }

◆ TEST_P() [130/545]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureRepeat   
)

Definition at line 194 of file aiks_dl_basic_unittests.cc.

194  {
195  CanRenderTiledTexture(this, DlTileMode::kRepeat);
196 }

◆ TEST_P() [131/545]

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() [132/545]

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() [133/545]

impeller::testing::TEST_P ( AiksTest  ,
CanSaveLayerStandalone   
)

Definition at line 333 of file aiks_dl_basic_unittests.cc.

333  {
334  DisplayListBuilder builder;
335 
336  DlPaint red;
337  red.setColor(DlColor::kRed());
338 
339  DlPaint alpha;
340  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
341 
342  builder.SaveLayer(std::nullopt, &alpha);
343 
344  builder.DrawCircle(DlPoint(125, 125), 125, red);
345 
346  builder.Restore();
347 
348  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
349 }

◆ TEST_P() [134/545]

impeller::testing::TEST_P ( AiksTest  ,
CanvasCanPushPopCTM   
)

Definition at line 111 of file canvas_unittests.cc.

111  {
112  ContentContext context(GetContext(), nullptr);
113  auto canvas = CreateTestCanvas(context);
114 
115  ASSERT_EQ(canvas->GetSaveCount(), 1u);
116  ASSERT_EQ(canvas->Restore(), false);
117 
118  canvas->Translate(Size{100, 100});
119  canvas->Save(10);
120  ASSERT_EQ(canvas->GetSaveCount(), 2u);
121  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
122  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
123  ASSERT_TRUE(canvas->Restore());
124  ASSERT_EQ(canvas->GetSaveCount(), 1u);
125  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
126  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
127 }

References ASSERT_MATRIX_NEAR, CreateTestCanvas(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [135/545]

impeller::testing::TEST_P ( AiksTest  ,
CanvasCTMCanBeUpdated   
)

Definition at line 129 of file canvas_unittests.cc.

129  {
130  ContentContext context(GetContext(), nullptr);
131  auto canvas = CreateTestCanvas(context);
132 
133  Matrix identity;
134  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(), identity);
135  canvas->Translate(Size{100, 100});
136  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
137  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
138 }

References ASSERT_MATRIX_NEAR, CreateTestCanvas(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [136/545]

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() [137/545]

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() [138/545]

impeller::testing::TEST_P ( AiksTest  ,
ClearColorOptimizationWhenSubpassIsBiggerThanParentPass   
)

Definition at line 1514 of file aiks_dl_basic_unittests.cc.

1514  {
1515  SetWindowSize({400, 400});
1516  DisplayListBuilder builder;
1517 
1518  builder.Scale(GetContentScale().x, GetContentScale().y);
1519 
1520  DlPaint paint;
1521  paint.setColor(DlColor::kRed());
1522  builder.DrawRect(DlRect::MakeLTRB(200, 200, 300, 300), paint);
1523 
1524  paint.setImageFilter(DlImageFilter::MakeMatrix(DlMatrix::MakeScale({2, 2, 1}),
1525  DlImageSampling::kLinear));
1526  builder.SaveLayer(std::nullopt, &paint);
1527  // Draw a rectangle that would fully cover the parent pass size, but not
1528  // the subpass that it is rendered in.
1529  paint.setColor(DlColor::kGreen());
1530  builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 400), paint);
1531  // Draw a bigger rectangle to force the subpass to be bigger.
1532 
1533  paint.setColor(DlColor::kRed());
1534  builder.DrawRect(DlRect::MakeLTRB(0, 0, 800, 800), paint);
1535  builder.Restore();
1536 
1537  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1538 }

References x.

◆ TEST_P() [139/545]

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() [140/545]

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:9

References impeller::DrawPlaygroundPoint(), impeller::Color::Green(), and impeller::Sigma::sigma.

◆ TEST_P() [141/545]

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() [142/545]

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() [143/545]

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() [144/545]

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() [145/545]

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() [146/545]

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() [147/545]

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() [148/545]

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() [149/545]

impeller::testing::TEST_P ( AiksTest  ,
CoordinateConversionsAreCorrect   
)

Definition at line 1612 of file aiks_dl_basic_unittests.cc.

1612  {
1613  DisplayListBuilder builder;
1614 
1615  // Render a texture directly.
1616  {
1617  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
1618 
1619  builder.Save();
1620  builder.Translate(100, 200);
1621  builder.Scale(0.5, 0.5);
1622  builder.DrawImage(image, DlPoint(100.0, 100.0),
1623  DlImageSampling::kNearestNeighbor);
1624  builder.Restore();
1625  }
1626 
1627  // Render an offscreen rendered texture.
1628  {
1629  DlPaint alpha;
1630  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
1631 
1632  builder.SaveLayer(std::nullopt, &alpha);
1633 
1634  DlPaint paint;
1635  paint.setColor(DlColor::kRed());
1636  builder.DrawRect(DlRect::MakeXYWH(000, 000, 100, 100), paint);
1637  paint.setColor(DlColor::kGreen());
1638  builder.DrawRect(DlRect::MakeXYWH(020, 020, 100, 100), paint);
1639  paint.setColor(DlColor::kBlue());
1640  builder.DrawRect(DlRect::MakeXYWH(040, 040, 100, 100), paint);
1641 
1642  builder.Restore();
1643  }
1644 
1645  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1646 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [150/545]

impeller::testing::TEST_P ( AiksTest  ,
CoverageOriginShouldBeAccountedForInSubpasses   
)

Definition at line 1793 of file aiks_dl_basic_unittests.cc.

1793  {
1794  auto callback = [&]() -> sk_sp<DisplayList> {
1795  DisplayListBuilder builder;
1796  builder.Scale(GetContentScale().x, GetContentScale().y);
1797 
1798  DlPaint alpha;
1799  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
1800 
1801  auto current = Point{25, 25};
1802  const auto offset = Point{25, 25};
1803  const auto size = Size(100, 100);
1804 
1805  static PlaygroundPoint point_a(Point(40, 40), 10, Color::White());
1806  static PlaygroundPoint point_b(Point(160, 160), 10, Color::White());
1807  auto [b0, b1] = DrawPlaygroundLine(point_a, point_b);
1808  DlRect bounds = DlRect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
1809 
1810  DlPaint stroke_paint;
1811  stroke_paint.setColor(DlColor::kYellow());
1812  stroke_paint.setStrokeWidth(5);
1813  stroke_paint.setDrawStyle(DlDrawStyle::kStroke);
1814  builder.DrawRect(bounds, stroke_paint);
1815 
1816  builder.SaveLayer(bounds, &alpha);
1817 
1818  DlPaint paint;
1819  paint.setColor(DlColor::kRed());
1820  builder.DrawRect(
1821  DlRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1822 
1823  paint.setColor(DlColor::kGreen());
1824  current += offset;
1825  builder.DrawRect(
1826  DlRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1827 
1828  paint.setColor(DlColor::kBlue());
1829  current += offset;
1830  builder.DrawRect(
1831  DlRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1832 
1833  builder.Restore();
1834 
1835  return builder.Build();
1836  };
1837 
1838  ASSERT_TRUE(OpenPlaygroundHere(callback));
1839 }

References impeller::DrawPlaygroundLine(), and impeller::Color::White().

◆ TEST_P() [151/545]

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() [152/545]

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() [153/545]

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() [154/545]

impeller::testing::TEST_P ( AiksTest  ,
DifferenceClipsMustRenderIdenticallyAcrossBackends   
)

Definition at line 631 of file aiks_dl_text_unittests.cc.

631  {
632  DisplayListBuilder builder;
633 
634  DlPaint paint;
635  DlColor clear_color(1.0, 0.5, 0.5, 0.5, DlColorSpace::kSRGB);
636  paint.setColor(clear_color);
637  builder.DrawPaint(paint);
638 
639  DlMatrix identity = {
640  1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
641  0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
642  };
643  builder.Save();
644  builder.Transform(identity);
645 
646  DlRect frame = DlRect::MakeLTRB(1.0, 1.0, 1278.0, 763.0);
647  DlColor white(1.0, 1.0, 1.0, 1.0, DlColorSpace::kSRGB);
648  paint.setColor(white);
649  builder.DrawRect(frame, paint);
650 
651  builder.Save();
652  builder.ClipRect(frame, DlClipOp::kIntersect);
653 
654  DlMatrix rect_xform = {
655  0.8241262, 0.56640625, 0.0, 0.0, -0.56640625, 0.8241262, 0.0, 0.0,
656  0.0, 0.0, 1.0, 0.0, 271.1137, 489.4733, 0.0, 1.0,
657  };
658  builder.Save();
659  builder.Transform(rect_xform);
660 
661  DlRect rect = DlRect::MakeLTRB(0.0, 0.0, 100.0, 100.0);
662  DlColor bluish(1.0, 0.184, 0.501, 0.929, DlColorSpace::kSRGB);
663  paint.setColor(bluish);
664  DlRoundRect rrect = DlRoundRect::MakeRectRadius(rect, 18.0);
665  builder.DrawRoundRect(rrect, paint);
666 
667  builder.Save();
668  builder.ClipRect(rect, DlClipOp::kIntersect);
669  builder.Restore();
670 
671  builder.Restore();
672 
673  DlMatrix path_xform = {
674  1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
675  0.0, 0.0, 1.0, 0.0, 675.0, 279.5, 0.0, 1.0,
676  };
677  builder.Save();
678  builder.Transform(path_xform);
679 
680  DlPathBuilder path_builder;
681  path_builder.MoveTo(DlPoint(87.5, 349.5));
682  path_builder.LineTo(DlPoint(25.0, 29.5));
683  path_builder.LineTo(DlPoint(150.0, 118.0));
684  path_builder.LineTo(DlPoint(25.0, 118.0));
685  path_builder.LineTo(DlPoint(150.0, 29.5));
686  path_builder.Close();
687  DlPath path = path_builder.TakePath();
688 
689  DlColor fill_color(1.0, 1.0, 0.0, 0.0, DlColorSpace::kSRGB);
690  DlColor stroke_color(1.0, 0.0, 0.0, 0.0, DlColorSpace::kSRGB);
691  paint.setColor(fill_color);
692  paint.setDrawStyle(DlDrawStyle::kFill);
693  builder.DrawPath(path, paint);
694 
695  paint.setColor(stroke_color);
696  paint.setStrokeWidth(2.0);
697  paint.setDrawStyle(DlDrawStyle::kStroke);
698  builder.DrawPath(path, paint);
699 
700  builder.Restore();
701  builder.Restore();
702  builder.Restore();
703 
704  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
705 }

◆ TEST_P() [155/545]

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() [156/545]

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() [157/545]

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() [158/545]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometryBlend   
)

Definition at line 201 of file aiks_dl_atlas_unittests.cc.

201  {
202  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
203 
204  std::vector<DlColor> colors;
205  colors.reserve(texture_coordinates.size());
206  for (auto i = 0u; i < texture_coordinates.size(); i++) {
207  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
208  }
209  DlAtlasGeometry geom(
210  atlas->impeller_texture(), transforms.data(), texture_coordinates.data(),
211  colors.data(), transforms.size(), BlendMode::kSrcOver, {}, std::nullopt);
212 
213  EXPECT_TRUE(geom.ShouldUseBlend());
214  EXPECT_FALSE(geom.ShouldSkip());
215 
216  ContentContext context(GetContext(), nullptr);
217  auto vertex_buffer =
218  geom.CreateBlendVertexBuffer(context.GetTransientsBuffer());
219 
220  EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
221  EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
222 }

References impeller::DlAtlasGeometry::CreateBlendVertexBuffer(), impeller::ContentContext::GetTransientsBuffer(), impeller::kNone, impeller::kSrcOver, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [159/545]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometryColorButNoBlend   
)

Definition at line 224 of file aiks_dl_atlas_unittests.cc.

224  {
225  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
226 
227  std::vector<DlColor> colors;
228  colors.reserve(texture_coordinates.size());
229  for (auto i = 0u; i < texture_coordinates.size(); i++) {
230  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
231  }
232  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
233  texture_coordinates.data(), colors.data(),
234  transforms.size(), BlendMode::kSrc, {}, std::nullopt);
235 
236  // Src blend mode means that colors would be ignored, even if provided.
237  EXPECT_FALSE(geom.ShouldUseBlend());
238  EXPECT_FALSE(geom.ShouldSkip());
239 }

References impeller::kSrc, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [160/545]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometryNoBlendRenamed   
)

Definition at line 183 of file aiks_dl_atlas_unittests.cc.

183  {
184  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
185 
186  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
187  texture_coordinates.data(), nullptr, transforms.size(),
188  BlendMode::kSrcOver, {}, std::nullopt);
189 
190  EXPECT_FALSE(geom.ShouldUseBlend());
191  EXPECT_FALSE(geom.ShouldSkip());
192 
193  ContentContext context(GetContext(), nullptr);
194  auto vertex_buffer =
195  geom.CreateSimpleVertexBuffer(context.GetTransientsBuffer());
196 
197  EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
198  EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
199 }

References impeller::DlAtlasGeometry::CreateSimpleVertexBuffer(), impeller::ContentContext::GetTransientsBuffer(), impeller::kNone, impeller::kSrcOver, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [161/545]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometrySkip   
)

Definition at line 241 of file aiks_dl_atlas_unittests.cc.

241  {
242  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
243 
244  std::vector<DlColor> colors;
245  colors.reserve(texture_coordinates.size());
246  for (auto i = 0u; i < texture_coordinates.size(); i++) {
247  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
248  }
249  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
250  texture_coordinates.data(), colors.data(),
251  transforms.size(), BlendMode::kClear, {}, std::nullopt);
252  EXPECT_TRUE(geom.ShouldSkip());
253 }

References impeller::kClear, and impeller::DlAtlasGeometry::ShouldSkip().

◆ TEST_P() [162/545]

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() [163/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasAdvancedAndTransform   
)

Definition at line 137 of file aiks_dl_atlas_unittests.cc.

137  {
138  DisplayListBuilder builder;
139  // Draws the image as four squares stiched together.
140  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
141 
142  builder.Scale(0.25, 0.25);
143  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
144  /*colors=*/nullptr, /*count=*/4, DlBlendMode::kModulate,
145  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
146 
147  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
148 }

◆ TEST_P() [164/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasNoColor   
)

Definition at line 60 of file aiks_dl_atlas_unittests.cc.

60  {
61  DisplayListBuilder builder;
62  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
63 
64  builder.Scale(GetContentScale().x, GetContentScale().y);
65  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
66  /*colors=*/nullptr, /*count=*/4, DlBlendMode::kSrcOver,
67  DlImageSampling::kNearestNeighbor, nullptr);
68 
69  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
70 }

References x.

◆ TEST_P() [165/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasNoColorFullSize   
)

Definition at line 120 of file aiks_dl_atlas_unittests.cc.

120  {
121  auto atlas = DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
122  auto size = atlas->impeller_texture()->GetSize();
123  std::vector<DlRect> texture_coordinates = {
124  DlRect::MakeLTRB(0, 0, size.width, size.height)};
125  std::vector<RSTransform> transforms = {MakeTranslation(0, 0)};
126 
127  DisplayListBuilder builder;
128  builder.Scale(GetContentScale().x, GetContentScale().y);
129  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
130  /*colors=*/nullptr, /*count=*/1, DlBlendMode::kSrcOver,
131  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
132 
133  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
134 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [166/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasPlusWideGamut   
)

Definition at line 166 of file aiks_dl_atlas_unittests.cc.

166  {
167  DisplayListBuilder builder;
168  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
169  PixelFormat::kB10G10R10A10XR);
170 
171  // Draws the image as four squares stiched together.
172  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
173  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
174  DlColor::kBlue(), DlColor::kYellow()};
175 
176  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
177  colors.data(), /*count=*/4, DlBlendMode::kPlus,
178  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
179 
180  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
181 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [167/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorAdvanced   
)

Definition at line 72 of file aiks_dl_atlas_unittests.cc.

72  {
73  DisplayListBuilder builder;
74  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
75 
76  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
77  DlColor::kBlue(), DlColor::kYellow()};
78 
79  builder.Scale(GetContentScale().x, GetContentScale().y);
80  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
81  colors.data(), /*count=*/4, DlBlendMode::kModulate,
82  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
83 
84  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
85 }

References x.

◆ TEST_P() [168/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorAdvancedAndTransform   
)

Definition at line 151 of file aiks_dl_atlas_unittests.cc.

151  {
152  DisplayListBuilder builder;
153  // Draws the image as four squares stiched together.
154  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
155  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
156  DlColor::kBlue(), DlColor::kYellow()};
157 
158  builder.Scale(0.25, 0.25);
159  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
160  colors.data(), /*count=*/4, DlBlendMode::kModulate,
161  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
162 
163  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
164 }

◆ TEST_P() [169/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorSimple   
)

Definition at line 87 of file aiks_dl_atlas_unittests.cc.

87  {
88  DisplayListBuilder builder;
89  // Draws the image as four squares stiched together.
90  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
91 
92  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
93  DlColor::kBlue(), DlColor::kYellow()};
94 
95  builder.Scale(GetContentScale().x, GetContentScale().y);
96  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
97  colors.data(), /*count=*/4, DlBlendMode::kSrcATop,
98  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
99 
100  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
101 }

References x.

◆ TEST_P() [170/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithOpacity   
)

Definition at line 103 of file aiks_dl_atlas_unittests.cc.

103  {
104  DisplayListBuilder builder;
105  // Draws the image as four squares stiched together slightly
106  // opaque
107  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
108 
109  DlPaint paint;
110  paint.setAlpha(128);
111  builder.Scale(GetContentScale().x, GetContentScale().y);
112  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
113  /*colors=*/nullptr, 4, DlBlendMode::kSrcOver,
114  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr,
115  &paint);
116 
117  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
118 }

References x.

◆ TEST_P() [171/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawImageRectSrcOutsideBounds   
)

Definition at line 229 of file aiks_dl_basic_unittests.cc.

229  {
230  DisplayListBuilder builder;
231  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
232 
233  // Use a source rect that is partially outside the bounds of the image.
234  auto source_rect = DlRect::MakeXYWH(
235  image->GetSize().width * 0.25f, image->GetSize().height * 0.4f,
236  image->GetSize().width, image->GetSize().height);
237 
238  auto dest_rect = DlRect::MakeXYWH(100, 100, 600, 600);
239 
240  DlPaint paint;
241  paint.setColor(DlColor::kMidGrey());
242  builder.DrawRect(dest_rect, paint);
243 
244  builder.DrawImageRect(image, source_rect, dest_rect,
245  DlImageSampling::kNearestNeighbor);
246  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
247 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [172/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawImageRectWithBlendColorFilter   
)

Definition at line 255 of file aiks_dl_atlas_unittests.cc.

255  {
256  sk_sp<DlImageImpeller> texture =
257  DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
258 
259  DisplayListBuilder builder;
260  DlPaint paint = DlPaint().setColorFilter(DlColorFilter::MakeBlend(
261  DlColor::kRed().withAlphaF(0.4), DlBlendMode::kSrcOver));
262 
263  DlMatrix filter_matrix = DlMatrix();
264  auto filter = flutter::DlMatrixImageFilter(filter_matrix,
265  flutter::DlImageSampling::kLinear);
266  DlPaint paint_with_filter = paint;
267  paint_with_filter.setImageFilter(&filter);
268 
269  // Compare porter-duff blend modes.
270  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
271  // Uses image filter to disable atlas conversion.
272  builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
273  DlRect::MakeLTRB(0, 0, 500, 500), {},
274  &paint_with_filter);
275 
276  // Uses atlas conversion.
277  builder.Translate(600, 0);
278  builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
279  DlRect::MakeLTRB(0, 0, 500, 500), {}, &paint);
280 
281  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
282 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [173/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawImageRectWithMatrixColorFilter   
)

Definition at line 284 of file aiks_dl_atlas_unittests.cc.

284  {
285  sk_sp<DlImageImpeller> texture =
286  DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
287 
288  DisplayListBuilder builder;
289  static const constexpr ColorMatrix kColorInversion = {
290  .array = {
291  -1.0, 0, 0, 1.0, 0, //
292  0, -1.0, 0, 1.0, 0, //
293  0, 0, -1.0, 1.0, 0, //
294  1.0, 1.0, 1.0, 1.0, 0 //
295  }};
296  DlPaint paint = DlPaint().setColorFilter(
297  DlColorFilter::MakeMatrix(kColorInversion.array));
298 
299  DlMatrix filter_matrix = DlMatrix();
300  auto filter = flutter::DlMatrixImageFilter(filter_matrix,
301  flutter::DlImageSampling::kLinear);
302  DlPaint paint_with_filter = paint;
303  paint_with_filter.setImageFilter(&filter);
304 
305  // Compare inverting color matrix filter.
306  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
307  // Uses image filter to disable atlas conversion.
308  builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
309  DlRect::MakeLTRB(0, 0, 500, 500), {},
310  &paint_with_filter);
311 
312  // Uses atlas conversion.
313  builder.Translate(600, 0);
314  builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
315  DlRect::MakeLTRB(0, 0, 500, 500), {}, &paint);
316 
317  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
318 }
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() [174/545]

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() [175/545]

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() [176/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintTransformsBounds   
)

Definition at line 63 of file aiks_dl_runtime_effect_unittests.cc.

63  {
64  struct FragUniforms {
65  Size size;
66  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
67  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
68  uniform_data->resize(sizeof(FragUniforms));
69  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
70 
71  DlPaint paint;
72  paint.setColorSource(
73  MakeRuntimeEffect(this, "gradient.frag.iplr", uniform_data));
74 
75  DisplayListBuilder builder;
76  builder.Save();
77  builder.Scale(GetContentScale().x, GetContentScale().y);
78  builder.DrawPaint(paint);
79  builder.Restore();
80 
81  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
82 }

References impeller::TSize< Scalar >::MakeWH(), and x.

◆ TEST_P() [177/545]

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() [178/545]

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() [179/545]

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() [180/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawScaledTextWithPerspectiveNoSaveLayer   
)

Definition at line 507 of file aiks_dl_text_unittests.cc.

507  {
508  DisplayListBuilder builder;
509 
510  Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
511  0.0, 1.0, 0.0, 0.0, //
512  0.0, 0.0, 1.0, 0.01, //
513  0.0, 0.0, 0.0, 1.0) * //
514  Matrix::MakeRotationY({Degrees{10}});
515 
516  builder.Transform(matrix);
517 
518  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
519  "Roboto-Regular.ttf"));
520  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
521 }

References RenderTextInCanvasSkia(), and impeller::Matrix::Transform().

◆ TEST_P() [181/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawScaledTextWithPerspectiveSaveLayer   
)

Definition at line 523 of file aiks_dl_text_unittests.cc.

523  {
524  DisplayListBuilder builder;
525 
526  Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
527  0.0, 1.0, 0.0, 0.0, //
528  0.0, 0.0, 1.0, 0.01, //
529  0.0, 0.0, 0.0, 1.0) * //
530  Matrix::MakeRotationY({Degrees{10}});
531 
532  DlPaint save_paint;
533  DlRect window_bounds =
534  DlRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
535  // Note: bounds were not needed by the AIKS version, which may indicate a bug.
536  builder.SaveLayer(window_bounds, &save_paint);
537  builder.Transform(matrix);
538 
539  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
540  "Roboto-Regular.ttf"));
541 
542  builder.Restore();
543  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
544 }

References RenderTextInCanvasSkia().

◆ TEST_P() [182/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesImageSourceWithTextureCoordinates   
)

Definition at line 271 of file aiks_dl_vertices_unittests.cc.

271  {
272  auto texture = CreateTextureForFixture("embarcadero.jpg");
273  auto dl_image = DlImageImpeller::Make(texture);
274  std::vector<DlPoint> positions = {
275  DlPoint(100, 300),
276  DlPoint(200, 100),
277  DlPoint(300, 300),
278  };
279  std::vector<DlPoint> texture_coordinates = {
280  DlPoint(0, 0),
281  DlPoint(100, 200),
282  DlPoint(200, 100),
283  };
284 
285  auto vertices = flutter::DlVertices::Make(
286  flutter::DlVertexMode::kTriangles, 3, positions.data(),
287  texture_coordinates.data(), /*colors=*/nullptr);
288 
289  flutter::DisplayListBuilder builder;
290  flutter::DlPaint paint;
291 
292  auto image_source = flutter::DlColorSource::MakeImage(
293  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
294 
295  paint.setColorSource(image_source);
296  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
297 
298  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
299 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [183/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending   
)

Definition at line 301 of file aiks_dl_vertices_unittests.cc.

302  {
303  auto texture = CreateTextureForFixture("embarcadero.jpg");
304  auto dl_image = DlImageImpeller::Make(texture);
305  std::vector<DlPoint> positions = {
306  DlPoint(100, 300),
307  DlPoint(200, 100),
308  DlPoint(300, 300),
309  };
310  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
311  flutter::DlColor::kGreen(),
312  flutter::DlColor::kWhite()};
313  std::vector<DlPoint> texture_coordinates = {
314  DlPoint(0, 0),
315  DlPoint(100, 200),
316  DlPoint(200, 100),
317  };
318 
319  auto vertices = flutter::DlVertices::Make(
320  flutter::DlVertexMode::kTriangles, 3, positions.data(),
321  texture_coordinates.data(), colors.data());
322 
323  flutter::DisplayListBuilder builder;
324  flutter::DlPaint paint;
325 
326  auto image_source = flutter::DlColorSource::MakeImage(
327  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
328 
329  paint.setColorSource(image_source);
330  builder.DrawVertices(vertices, flutter::DlBlendMode::kModulate, paint);
331 
332  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
333 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [184/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithEmptySize   
)

Definition at line 284 of file canvas_unittests.cc.

284  {
285  RenderCallback callback = [&](RenderTarget& render_target) {
286  ContentContext context(GetContext(), nullptr);
287  Canvas canvas(context, render_target, true, false);
288 
289  std::vector<flutter::DlPoint> vertex_coordinates = {
290  flutter::DlPoint(0, 0),
291  flutter::DlPoint(600, 0),
292  flutter::DlPoint(0, 600),
293  };
294  std::vector<flutter::DlPoint> texture_coordinates = {
295  flutter::DlPoint(0, 0),
296  flutter::DlPoint(500, 0),
297  flutter::DlPoint(0, 500),
298  };
299  std::vector<uint16_t> indices = {0, 1, 2};
300  flutter::DlVertices::Builder vertices_builder(
301  flutter::DlVertexMode::kTriangleStrip, vertex_coordinates.size(),
302  flutter::DlVertices::Builder::kHasTextureCoordinates, indices.size());
303  vertices_builder.store_vertices(vertex_coordinates.data());
304  vertices_builder.store_indices(indices.data());
305  vertices_builder.store_texture_coordinates(texture_coordinates.data());
306  auto vertices = vertices_builder.build();
307 
308  // The start and end points of the gradient form an empty rectangle.
309  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
310  flutter::DlColor::kRed()};
311  std::vector<Scalar> stops = {0.0, 1.0};
312  auto gradient = flutter::DlColorSource::MakeLinear(
313  {0, 0}, {0, 600}, 2, colors.data(), stops.data(),
314  flutter::DlTileMode::kClamp);
315 
316  Paint paint;
317  paint.color_source = gradient.get();
318  canvas.DrawVertices(std::make_shared<DlVerticesGeometry>(vertices, context),
319  BlendMode::kSrcOver, paint);
320 
321  canvas.EndReplay();
322  return true;
323  };
324 
325  ASSERT_TRUE(Playground::OpenPlaygroundHere(callback));
326 }

References impeller::Paint::color_source, impeller::Canvas::DrawVertices(), impeller::Canvas::EndReplay(), impeller::kSrcOver, and impeller::Playground::OpenPlaygroundHere().

◆ TEST_P() [185/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithoutIndices   
)

Definition at line 210 of file aiks_dl_vertices_unittests.cc.

210  {
211  std::vector<DlPoint> positions = {
212  DlPoint(100, 300),
213  DlPoint(200, 100),
214  DlPoint(300, 300),
215  };
216 
217  auto vertices = flutter::DlVertices::Make(
218  flutter::DlVertexMode::kTriangles, 3, positions.data(),
219  /*texture_coordinates=*/nullptr, /*colors=*/nullptr);
220 
221  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
222  flutter::DlColor::kRed()};
223  const float stops[2] = {0.0, 1.0};
224 
225  auto linear = flutter::DlColorSource::MakeLinear(
226  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
227  flutter::DlTileMode::kRepeat);
228 
229  flutter::DisplayListBuilder builder;
230  flutter::DlPaint paint;
231 
232  paint.setColorSource(linear);
233  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
234 
235  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
236 }

◆ TEST_P() [186/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithTextureCoordinates   
)

Definition at line 238 of file aiks_dl_vertices_unittests.cc.

238  {
239  std::vector<DlPoint> positions = {
240  DlPoint(100, 300),
241  DlPoint(200, 100),
242  DlPoint(300, 300),
243  };
244  std::vector<DlPoint> texture_coordinates = {
245  DlPoint(300, 100),
246  DlPoint(100, 200),
247  DlPoint(300, 300),
248  };
249 
250  auto vertices = flutter::DlVertices::Make(
251  flutter::DlVertexMode::kTriangles, 3, positions.data(),
252  texture_coordinates.data(), /*colors=*/nullptr);
253 
254  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
255  flutter::DlColor::kRed()};
256  const float stops[2] = {0.0, 1.0};
257 
258  auto linear = flutter::DlColorSource::MakeLinear(
259  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
260  flutter::DlTileMode::kRepeat);
261 
262  flutter::DisplayListBuilder builder;
263  flutter::DlPaint paint;
264 
265  paint.setColorSource(linear);
266  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
267 
268  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
269 }

◆ TEST_P() [187/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesPremultipliesColors   
)

Definition at line 358 of file aiks_dl_vertices_unittests.cc.

358  {
359  std::vector<DlPoint> positions = {
360  DlPoint(100, 300),
361  DlPoint(200, 100),
362  DlPoint(300, 300),
363  DlPoint(200, 500),
364  };
365  auto color = flutter::DlColor::kBlue().withAlpha(0x99);
366  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
367  std::vector<flutter::DlColor> colors = {color, color, color, color};
368 
369  auto vertices = flutter::DlVertices::Make(
370  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
371  /*texture_coordinates=*/nullptr, colors.data(), indices.size(),
372  indices.data());
373 
374  flutter::DisplayListBuilder builder;
375  flutter::DlPaint paint;
376  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
377  paint.setColor(flutter::DlColor::kRed());
378 
379  builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 400), paint);
380  builder.DrawVertices(vertices, flutter::DlBlendMode::kDst, paint);
381 
382  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
383 }

◆ TEST_P() [188/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesSolidColorTrianglesWithIndices   
)

Definition at line 335 of file aiks_dl_vertices_unittests.cc.

335  {
336  std::vector<DlPoint> positions = {
337  DlPoint(100, 300),
338  DlPoint(200, 100),
339  DlPoint(300, 300),
340  DlPoint(200, 500),
341  };
342  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
343 
344  auto vertices = flutter::DlVertices::Make(
345  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
346  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
347  indices.data());
348 
349  flutter::DisplayListBuilder builder;
350  flutter::DlPaint paint;
351 
352  paint.setColor(flutter::DlColor::kRed());
353  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
354 
355  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
356 }

◆ TEST_P() [189/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesSolidColorTrianglesWithoutIndices   
)

Definition at line 184 of file aiks_dl_vertices_unittests.cc.

184  {
185  // Use negative coordinates and then scale the transform by -1, -1 to make
186  // sure coverage is taking the transform into account.
187  std::vector<DlPoint> positions = {
188  DlPoint(-100, -300),
189  DlPoint(-200, -100),
190  DlPoint(-300, -300),
191  };
192  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
193  flutter::DlColor::kGreen(),
194  flutter::DlColor::kWhite()};
195 
196  auto vertices = flutter::DlVertices::Make(
197  flutter::DlVertexMode::kTriangles, 3, positions.data(),
198  /*texture_coordinates=*/nullptr, colors.data());
199 
200  flutter::DisplayListBuilder builder;
201  flutter::DlPaint paint;
202 
203  paint.setColor(flutter::DlColor::kRed().modulateOpacity(0.5));
204  builder.Scale(-1, -1);
205  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
206 
207  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
208 }

◆ TEST_P() [190/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesTextureCoordinatesWithFragmentShader   
)

Definition at line 417 of file aiks_dl_vertices_unittests.cc.

417  {
418  std::vector<DlPoint> positions_lt = {
419  DlPoint(0, 0), //
420  DlPoint(50, 0), //
421  DlPoint(0, 50), //
422  DlPoint(50, 50), //
423  };
424 
425  auto vertices_lt = flutter::DlVertices::Make(
426  flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
427  positions_lt.data(),
428  /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
429  /*index_count=*/0,
430  /*indices=*/nullptr);
431 
432  std::vector<DlPoint> positions_rt = {
433  DlPoint(50, 0), //
434  DlPoint(100, 0), //
435  DlPoint(50, 50), //
436  DlPoint(100, 50), //
437  };
438 
439  auto vertices_rt = flutter::DlVertices::Make(
440  flutter::DlVertexMode::kTriangleStrip, positions_rt.size(),
441  positions_rt.data(),
442  /*texture_coordinates=*/positions_rt.data(), /*colors=*/nullptr,
443  /*index_count=*/0,
444  /*indices=*/nullptr);
445 
446  std::vector<DlPoint> positions_lb = {
447  DlPoint(0, 50), //
448  DlPoint(50, 50), //
449  DlPoint(0, 100), //
450  DlPoint(50, 100), //
451  };
452 
453  auto vertices_lb = flutter::DlVertices::Make(
454  flutter::DlVertexMode::kTriangleStrip, positions_lb.size(),
455  positions_lb.data(),
456  /*texture_coordinates=*/positions_lb.data(), /*colors=*/nullptr,
457  /*index_count=*/0,
458  /*indices=*/nullptr);
459 
460  std::vector<DlPoint> positions_rb = {
461  DlPoint(50, 50), //
462  DlPoint(100, 50), //
463  DlPoint(50, 100), //
464  DlPoint(100, 100), //
465  };
466 
467  auto vertices_rb = flutter::DlVertices::Make(
468  flutter::DlVertexMode::kTriangleStrip, positions_rb.size(),
469  positions_rb.data(),
470  /*texture_coordinates=*/positions_rb.data(), /*colors=*/nullptr,
471  /*index_count=*/0,
472  /*indices=*/nullptr);
473 
474  flutter::DisplayListBuilder builder;
475  flutter::DlPaint paint;
476  flutter::DlPaint rect_paint;
477  rect_paint.setColor(DlColor::kBlue());
478 
479  auto runtime_stages =
480  OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");
481 
482  auto runtime_stage =
483  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
484  ASSERT_TRUE(runtime_stage);
485 
486  auto runtime_effect = DlRuntimeEffect::MakeImpeller(runtime_stage);
487  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
488  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
489  runtime_effect, {}, uniform_data);
490 
491  paint.setColorSource(color_source);
492 
493  builder.Scale(GetContentScale().x, GetContentScale().y);
494  builder.Save();
495  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), rect_paint);
496  builder.DrawVertices(vertices_lt, flutter::DlBlendMode::kSrcOver, paint);
497  builder.DrawVertices(vertices_rt, flutter::DlBlendMode::kSrcOver, paint);
498  builder.DrawVertices(vertices_lb, flutter::DlBlendMode::kSrcOver, paint);
499  builder.DrawVertices(vertices_rb, flutter::DlBlendMode::kSrcOver, paint);
500  builder.Restore();
501 
502  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
503 }

References impeller::PlaygroundBackendToRuntimeStageBackend(), and x.

◆ TEST_P() [191/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesTextureCoordinatesWithFragmentShaderNonZeroOrigin   
)

Definition at line 507 of file aiks_dl_vertices_unittests.cc.

508  {
509  std::vector<DlPoint> positions_lt = {
510  DlPoint(200, 200), //
511  DlPoint(250, 200), //
512  DlPoint(200, 250), //
513  DlPoint(250, 250), //
514  };
515 
516  auto vertices = flutter::DlVertices::Make(
517  flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
518  positions_lt.data(),
519  /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
520  /*index_count=*/0,
521  /*indices=*/nullptr);
522 
523  flutter::DisplayListBuilder builder;
524  flutter::DlPaint paint;
525  flutter::DlPaint rect_paint;
526  rect_paint.setColor(DlColor::kBlue());
527 
528  auto runtime_stages =
529  OpenAssetAsRuntimeStage("runtime_stage_position.frag.iplr");
530 
531  auto runtime_stage =
532  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
533  ASSERT_TRUE(runtime_stage);
534 
535  auto runtime_effect = DlRuntimeEffect::MakeImpeller(runtime_stage);
536  auto rect_data = std::vector<Rect>{Rect::MakeLTRB(200, 200, 250, 250)};
537 
538  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
539  uniform_data->resize(rect_data.size() * sizeof(Rect));
540  memcpy(uniform_data->data(), rect_data.data(), uniform_data->size());
541 
542  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
543  runtime_effect, {}, uniform_data);
544 
545  paint.setColorSource(color_source);
546 
547  builder.Scale(GetContentScale().x, GetContentScale().y);
548  builder.DrawRect(DlRect::MakeLTRB(200, 200, 250, 250), rect_paint);
549  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
550 
551  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
552 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::PlaygroundBackendToRuntimeStageBackend(), and x.

◆ TEST_P() [192/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesWithEmptyTextureCoordinates   
)

Definition at line 328 of file canvas_unittests.cc.

328  {
329  auto runtime_stages =
330  OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");
331 
332  auto runtime_stage =
333  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
334  ASSERT_TRUE(runtime_stage);
335 
336  auto runtime_effect = flutter::DlRuntimeEffect::MakeImpeller(runtime_stage);
337  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
338  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
339  runtime_effect, {}, uniform_data);
340 
341  RenderCallback callback = [&](RenderTarget& render_target) {
342  ContentContext context(GetContext(), nullptr);
343  Canvas canvas(context, render_target, true, false);
344 
345  std::vector<flutter::DlPoint> vertex_coordinates = {
346  flutter::DlPoint(100, 100),
347  flutter::DlPoint(300, 100),
348  flutter::DlPoint(100, 300),
349  };
350  // The bounding box of the texture coordinates is empty.
351  std::vector<flutter::DlPoint> texture_coordinates = {
352  flutter::DlPoint(0, 0),
353  flutter::DlPoint(0, 100),
354  flutter::DlPoint(0, 0),
355  };
356  std::vector<uint16_t> indices = {0, 1, 2};
357  flutter::DlVertices::Builder vertices_builder(
358  flutter::DlVertexMode::kTriangleStrip, vertex_coordinates.size(),
359  flutter::DlVertices::Builder::kHasTextureCoordinates, indices.size());
360  vertices_builder.store_vertices(vertex_coordinates.data());
361  vertices_builder.store_indices(indices.data());
362  vertices_builder.store_texture_coordinates(texture_coordinates.data());
363  auto vertices = vertices_builder.build();
364 
365  Paint paint;
366  paint.color_source = color_source.get();
367  canvas.DrawVertices(std::make_shared<DlVerticesGeometry>(vertices, context),
368  BlendMode::kSrcOver, paint);
369 
370  canvas.EndReplay();
371  return true;
372  };
373 
374  ASSERT_TRUE(Playground::OpenPlaygroundHere(callback));
375 }

References impeller::Paint::color_source, impeller::Canvas::DrawVertices(), impeller::Canvas::EndReplay(), impeller::kSrcOver, impeller::Playground::OpenPlaygroundHere(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [193/545]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesWithInvalidIndices   
)

Definition at line 385 of file aiks_dl_vertices_unittests.cc.

385  {
386  std::vector<DlPoint> positions = {
387  DlPoint(100, 300),
388  DlPoint(200, 100),
389  DlPoint(300, 300),
390  DlPoint(200, 500),
391  };
392  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3, 99, 100, 101};
393 
394  auto vertices = flutter::DlVertices::Make(
395  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
396  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
397  indices.data());
398 
399  EXPECT_EQ(vertices->GetBounds(), DlRect::MakeLTRB(100, 100, 300, 500));
400 
401  flutter::DisplayListBuilder builder;
402  flutter::DlPaint paint;
403  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
404  paint.setColor(flutter::DlColor::kRed());
405 
406  builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 400), paint);
407  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrc, paint);
408 
409  AiksContext renderer(GetContext(), nullptr);
410  std::shared_ptr<Texture> image =
411  DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
412  EXPECT_TRUE(image);
413 }

References impeller::DisplayListToTexture().

◆ TEST_P() [194/545]

impeller::testing::TEST_P ( AiksTest  ,
EmptySaveLayerIgnoresPaint   
)

Definition at line 1540 of file aiks_dl_basic_unittests.cc.

1540  {
1541  DisplayListBuilder builder;
1542  builder.Scale(GetContentScale().x, GetContentScale().y);
1543 
1544  DlPaint paint;
1545  paint.setColor(DlColor::kRed());
1546  builder.DrawPaint(paint);
1547  builder.ClipRect(DlRect::MakeXYWH(100, 100, 200, 200));
1548  paint.setColor(DlColor::kBlue());
1549  builder.SaveLayer(std::nullopt, &paint);
1550  builder.Restore();
1551 
1552  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1553 }

References x.

◆ TEST_P() [195/545]

impeller::testing::TEST_P ( AiksTest  ,
EmptySaveLayerRendersWithClear   
)

Definition at line 1555 of file aiks_dl_basic_unittests.cc.

1555  {
1556  DisplayListBuilder builder;
1557  builder.Scale(GetContentScale().x, GetContentScale().y);
1558  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
1559  builder.DrawImage(image, DlPoint(10, 10), {});
1560  builder.ClipRect(DlRect::MakeXYWH(100, 100, 200, 200));
1561 
1562  DlPaint paint;
1563  paint.setBlendMode(DlBlendMode::kClear);
1564  builder.SaveLayer(std::nullopt, &paint);
1565  builder.Restore();
1566 
1567  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1568 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [196/545]

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() [197/545]

impeller::testing::TEST_P ( AiksTest  ,
FastEllipticalRRectMaskBlursRenderCorrectly   
)

Definition at line 1957 of file aiks_dl_basic_unittests.cc.

1957  {
1958  DisplayListBuilder builder;
1959 
1960  builder.Scale(GetContentScale().x, GetContentScale().y);
1961  DlPaint paint;
1962  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1));
1963 
1964  DlPaint save_paint;
1965  save_paint.setColor(DlColor::kWhite());
1966  builder.DrawPaint(save_paint);
1967 
1968  paint.setColor(DlColor::kBlue());
1969  for (int i = 0; i < 5; i++) {
1970  Scalar y = i * 125;
1971  Scalar y_radius = i * 15;
1972  for (int j = 0; j < 5; j++) {
1973  Scalar x = j * 125;
1974  Scalar x_radius = j * 15;
1975  builder.DrawRoundRect(
1976  DlRoundRect::MakeRectXY(
1977  DlRect::MakeXYWH(x + 50, y + 50, 100.0f, 100.0f), //
1978  x_radius, y_radius),
1979  paint);
1980  }
1981  }
1982 
1983  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1984 }

References x.

◆ TEST_P() [198/545]

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() [199/545]

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() [200/545]

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() [201/545]

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() [202/545]

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() [203/545]

impeller::testing::TEST_P ( AiksTest  ,
FilledArcsRenderCorrectly   
)

Definition at line 791 of file aiks_dl_basic_unittests.cc.

791  {
792  DisplayListBuilder builder;
793  builder.Scale(GetContentScale().x, GetContentScale().y);
794  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
795 
796  DlPaint paint;
797  paint.setColor(DlColor::kBlue());
798 
799  RenderArcFarm(builder, paint,
800  {
801  .use_center = false,
802  .full_circles = false,
803  });
804 
805  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
806 }

References x.

◆ TEST_P() [204/545]

impeller::testing::TEST_P ( AiksTest  ,
FilledArcsRenderCorrectlyWithCenter   
)

Definition at line 808 of file aiks_dl_basic_unittests.cc.

808  {
809  DisplayListBuilder builder;
810  builder.Scale(GetContentScale().x, GetContentScale().y);
811  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
812 
813  DlPaint paint;
814  paint.setColor(DlColor::kBlue());
815 
816  RenderArcFarm(builder, paint,
817  {
818  .use_center = true,
819  .full_circles = false,
820  });
821 
822  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
823 }

References x.

◆ TEST_P() [205/545]

impeller::testing::TEST_P ( AiksTest  ,
FilledCirclesRenderCorrectly   
)

Definition at line 562 of file aiks_dl_basic_unittests.cc.

562  {
563  DisplayListBuilder builder;
564  builder.Scale(GetContentScale().x, GetContentScale().y);
565  DlPaint paint;
566  const int color_count = 3;
567  DlColor colors[color_count] = {
568  DlColor::kBlue(),
569  DlColor::kGreen(),
570  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
571  };
572 
573  paint.setColor(DlColor::kWhite());
574  builder.DrawPaint(paint);
575 
576  int c_index = 0;
577  int radius = 600;
578  while (radius > 0) {
579  paint.setColor(colors[(c_index++) % color_count]);
580  builder.DrawCircle(DlPoint(10, 10), radius, paint);
581  if (radius > 30) {
582  radius -= 10;
583  } else {
584  radius -= 2;
585  }
586  }
587 
588  DlColor gradient_colors[7] = {
589  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
590  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
591  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
592  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
593  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
594  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
595  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
596  };
597  DlScalar stops[7] = {
598  0.0,
599  (1.0 / 6.0) * 1,
600  (1.0 / 6.0) * 2,
601  (1.0 / 6.0) * 3,
602  (1.0 / 6.0) * 4,
603  (1.0 / 6.0) * 5,
604  1.0,
605  };
606  auto texture = CreateTextureForFixture("airplane.jpg",
607  /*enable_mipmapping=*/true);
608  auto image = DlImageImpeller::Make(texture);
609 
610  paint.setColorSource(DlColorSource::MakeRadial(
611  DlPoint(500, 600), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
612  builder.DrawCircle(DlPoint(500, 600), 100, paint);
613 
614  DlMatrix local_matrix = DlMatrix::MakeTranslation({700, 200});
615  paint.setColorSource(DlColorSource::MakeImage(
616  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
617  DlImageSampling::kNearestNeighbor, &local_matrix));
618  builder.DrawCircle(DlPoint(800, 300), 100, paint);
619 
620  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
621 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [206/545]

impeller::testing::TEST_P ( AiksTest  ,
FilledEllipsesRenderCorrectly   
)

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  int long_radius = 600;
705  int short_radius = 600;
706  while (long_radius > 0 && short_radius > 0) {
707  paint.setColor(colors[(c_index++) % color_count]);
708  builder.DrawOval(DlRect::MakeXYWH(10 - long_radius, 10 - short_radius,
709  long_radius * 2, short_radius * 2),
710  paint);
711  builder.DrawOval(DlRect::MakeXYWH(1000 - short_radius, 750 - long_radius,
712  short_radius * 2, long_radius * 2),
713  paint);
714  if (short_radius > 30) {
715  short_radius -= 10;
716  long_radius -= 5;
717  } else {
718  short_radius -= 2;
719  long_radius -= 1;
720  }
721  }
722 
723  DlColor gradient_colors[7] = {
724  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
725  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
726  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
727  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
728  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
729  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
730  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
731  };
732  DlScalar stops[7] = {
733  0.0,
734  (1.0 / 6.0) * 1,
735  (1.0 / 6.0) * 2,
736  (1.0 / 6.0) * 3,
737  (1.0 / 6.0) * 4,
738  (1.0 / 6.0) * 5,
739  1.0,
740  };
741  auto texture = CreateTextureForFixture("airplane.jpg",
742  /*enable_mipmapping=*/true);
743  auto image = DlImageImpeller::Make(texture);
744 
745  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
746 
747  paint.setColorSource(DlColorSource::MakeRadial(
748  DlPoint(300, 650), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
749  builder.DrawOval(DlRect::MakeXYWH(200, 625, 200, 50), paint);
750  builder.DrawOval(DlRect::MakeXYWH(275, 550, 50, 200), paint);
751 
752  DlMatrix local_matrix = DlMatrix::MakeTranslation({610, 15});
753  paint.setColorSource(DlColorSource::MakeImage(
754  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
755  DlImageSampling::kNearestNeighbor, &local_matrix));
756  builder.DrawOval(DlRect::MakeXYWH(610, 90, 200, 50), paint);
757  builder.DrawOval(DlRect::MakeXYWH(685, 15, 50, 200), paint);
758 
759  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
760 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [207/545]

impeller::testing::TEST_P ( AiksTest  ,
FilledRoundRectPathsRenderCorrectly   
)

Definition at line 1691 of file aiks_dl_basic_unittests.cc.

1691  {
1692  DisplayListBuilder builder;
1693  builder.Scale(GetContentScale().x, GetContentScale().y);
1694 
1695  DlPaint paint;
1696  const int color_count = 3;
1697  DlColor colors[color_count] = {
1698  DlColor::kBlue(),
1699  DlColor::kGreen(),
1700  DlColor::ARGB(1.0, 220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f),
1701  };
1702 
1703  paint.setColor(DlColor::kWhite());
1704  builder.DrawPaint(paint);
1705 
1706  auto draw_rrect_as_path = [&builder](const DlRect& rect, Scalar x, Scalar y,
1707  const DlPaint& paint) {
1708  builder.DrawPath(DlPath::MakeRoundRectXY(rect, x, y), paint);
1709  };
1710 
1711  int c_index = 0;
1712  for (int i = 0; i < 4; i++) {
1713  for (int j = 0; j < 4; j++) {
1714  paint.setColor(colors[(c_index++) % color_count]);
1715  draw_rrect_as_path(DlRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1716  i * 5 + 10, j * 5 + 10, paint);
1717  }
1718  }
1719  paint.setColor(colors[(c_index++) % color_count]);
1720  draw_rrect_as_path(DlRect::MakeXYWH(10, 420, 380, 80), 40, 40, paint);
1721  paint.setColor(colors[(c_index++) % color_count]);
1722  draw_rrect_as_path(DlRect::MakeXYWH(410, 20, 80, 380), 40, 40, paint);
1723 
1724  std::vector<DlColor> gradient_colors = {
1725  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
1726  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
1727  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
1728  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
1729  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
1730  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
1731  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0)};
1732  std::vector<Scalar> stops = {
1733  0.0,
1734  (1.0 / 6.0) * 1,
1735  (1.0 / 6.0) * 2,
1736  (1.0 / 6.0) * 3,
1737  (1.0 / 6.0) * 4,
1738  (1.0 / 6.0) * 5,
1739  1.0,
1740  };
1741  auto texture = DlImageImpeller::Make(
1742  CreateTextureForFixture("airplane.jpg",
1743  /*enable_mipmapping=*/true));
1744 
1745  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1746  paint.setColorSource(DlColorSource::MakeRadial(
1747  /*center=*/DlPoint(550, 550),
1748  /*radius=*/75,
1749  /*stop_count=*/gradient_colors.size(),
1750  /*colors=*/gradient_colors.data(),
1751  /*stops=*/stops.data(),
1752  /*tile_mode=*/DlTileMode::kMirror));
1753  for (int i = 1; i <= 10; i++) {
1754  int j = 11 - i;
1755  draw_rrect_as_path(DlRect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1756  550 + i * 20, 550 + j * 20),
1757  i * 10, j * 10, paint);
1758  }
1759  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1760  paint.setColorSource(DlColorSource::MakeRadial(
1761  /*center=*/DlPoint(200, 650),
1762  /*radius=*/75,
1763  /*stop_count=*/gradient_colors.size(),
1764  /*colors=*/gradient_colors.data(),
1765  /*stops=*/stops.data(),
1766  /*tile_mode=*/DlTileMode::kMirror));
1767  draw_rrect_as_path(DlRect::MakeLTRB(100, 610, 300, 690), 40, 40, paint);
1768  draw_rrect_as_path(DlRect::MakeLTRB(160, 550, 240, 750), 40, 40, paint);
1769 
1770  auto matrix = DlMatrix::MakeTranslation({520, 20});
1771  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1772  paint.setColorSource(DlColorSource::MakeImage(
1773  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1774  DlImageSampling::kMipmapLinear, &matrix));
1775  for (int i = 1; i <= 10; i++) {
1776  int j = 11 - i;
1777  draw_rrect_as_path(DlRect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1778  720 + i * 20, 220 + j * 20),
1779  i * 10, j * 10, paint);
1780  }
1781  matrix = DlMatrix::MakeTranslation({800, 300});
1782  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1783  paint.setColorSource(DlColorSource::MakeImage(
1784  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1785  DlImageSampling::kMipmapLinear, &matrix));
1786 
1787  draw_rrect_as_path(DlRect::MakeLTRB(800, 410, 1000, 490), 40, 40, paint);
1788  draw_rrect_as_path(DlRect::MakeLTRB(860, 350, 940, 550), 40, 40, paint);
1789 
1790  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1791 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [208/545]

impeller::testing::TEST_P ( AiksTest  ,
FilledRoundRectsRenderCorrectly   
)

Definition at line 1095 of file aiks_dl_basic_unittests.cc.

1095  {
1096  DisplayListBuilder builder;
1097  builder.Scale(GetContentScale().x, GetContentScale().y);
1098  DlPaint paint;
1099  const int color_count = 3;
1100  DlColor colors[color_count] = {
1101  DlColor::kBlue(),
1102  DlColor::kGreen(),
1103  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
1104  };
1105 
1106  paint.setColor(DlColor::kWhite());
1107  builder.DrawPaint(paint);
1108 
1109  int c_index = 0;
1110  for (int i = 0; i < 4; i++) {
1111  for (int j = 0; j < 4; j++) {
1112  paint.setColor(colors[(c_index++) % color_count]);
1113  builder.DrawRoundRect(
1114  DlRoundRect::MakeRectXY(
1115  DlRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80), //
1116  i * 5 + 10, j * 5 + 10),
1117  paint);
1118  }
1119  }
1120  paint.setColor(colors[(c_index++) % color_count]);
1121  builder.DrawRoundRect(
1122  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(10, 420, 380, 80), 40, 40),
1123  paint);
1124  paint.setColor(colors[(c_index++) % color_count]);
1125  builder.DrawRoundRect(
1126  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(410, 20, 80, 380), 40, 40),
1127  paint);
1128 
1129  DlColor gradient_colors[7] = {
1130  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
1131  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
1132  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
1133  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
1134  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
1135  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
1136  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
1137  };
1138  DlScalar stops[7] = {
1139  0.0,
1140  (1.0 / 6.0) * 1,
1141  (1.0 / 6.0) * 2,
1142  (1.0 / 6.0) * 3,
1143  (1.0 / 6.0) * 4,
1144  (1.0 / 6.0) * 5,
1145  1.0,
1146  };
1147  auto texture = CreateTextureForFixture("airplane.jpg",
1148  /*enable_mipmapping=*/true);
1149  auto image = DlImageImpeller::Make(texture);
1150 
1151  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1152  paint.setColorSource(DlColorSource::MakeRadial(
1153  DlPoint(550, 550), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
1154  for (int i = 1; i <= 10; i++) {
1155  int j = 11 - i;
1156  builder.DrawRoundRect(
1157  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1158  550 + i * 20, 550 + j * 20),
1159  i * 10, j * 10),
1160  paint);
1161  }
1162 
1163  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1164  paint.setColorSource(DlColorSource::MakeRadial(
1165  DlPoint(200, 650), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
1166  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1167  builder.DrawRoundRect(
1168  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(100, 610, 300, 690), 40, 40),
1169  paint);
1170  builder.DrawRoundRect(
1171  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(160, 550, 240, 750), 40, 40),
1172  paint);
1173 
1174  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1175  DlMatrix local_matrix = DlMatrix::MakeTranslation({520, 20});
1176  paint.setColorSource(DlColorSource::MakeImage(
1177  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
1178  DlImageSampling::kNearestNeighbor, &local_matrix));
1179  for (int i = 1; i <= 10; i++) {
1180  int j = 11 - i;
1181  builder.DrawRoundRect(
1182  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1183  720 + i * 20, 220 + j * 20),
1184  i * 10, j * 10),
1185  paint);
1186  }
1187 
1188  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1189  local_matrix = DlMatrix::MakeTranslation({800, 300});
1190  paint.setColorSource(DlColorSource::MakeImage(
1191  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
1192  DlImageSampling::kNearestNeighbor, &local_matrix));
1193  builder.DrawRoundRect(
1194  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(800, 410, 1000, 490), 40, 40),
1195  paint);
1196  builder.DrawRoundRect(
1197  DlRoundRect::MakeRectXY(DlRect::MakeLTRB(860, 350, 940, 550), 40, 40),
1198  paint);
1199 
1200  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1201 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [209/545]

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() [210/545]

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() [211/545]

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() [212/545]

impeller::testing::TEST_P ( AiksTest  ,
FormatSRGB   
)

Definition at line 1604 of file aiks_dl_basic_unittests.cc.

1604  {
1605  PixelFormat pixel_format =
1606  GetContext()->GetCapabilities()->GetDefaultColorFormat();
1607  EXPECT_TRUE(pixel_format == PixelFormat::kR8G8B8A8UNormInt ||
1608  pixel_format == PixelFormat::kB8G8R8A8UNormInt)
1609  << "pixel format: " << PixelFormatToString(pixel_format);
1610 }
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() [213/545]

impeller::testing::TEST_P ( AiksTest  ,
FormatWideGamut   
)

Definition at line 1599 of file aiks_dl_basic_unittests.cc.

1599  {
1600  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
1601  PixelFormat::kB10G10R10A10XR);
1602 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [214/545]

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() [215/545]

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() [216/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAnimatedBackdrop   
)

Definition at line 851 of file aiks_dl_blur_unittests.cc.

851  {
852  // This test is for checking out how stable rendering is when content is
853  // translated underneath a blur. Animating under a blur can cause
854  // *shimmering* to happen as a result of pixel alignment.
855  // See also: https://github.com/flutter/flutter/issues/140193
856  auto boston =
857  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
858  ASSERT_TRUE(boston);
859  int64_t count = 0;
860  Scalar sigma = 20.0;
861  Scalar freq = 0.1;
862  Scalar amp = 50.0;
863  auto callback = [&]() -> sk_sp<DisplayList> {
864  if (AiksTest::ImGuiBegin("Controls", nullptr,
865  ImGuiWindowFlags_AlwaysAutoResize)) {
866  ImGui::SliderFloat("Sigma", &sigma, 0, 200);
867  ImGui::SliderFloat("Frequency", &freq, 0.01, 2.0);
868  ImGui::SliderFloat("Amplitude", &amp, 1, 100);
869  ImGui::End();
870  }
871 
872  DisplayListBuilder builder;
873  builder.Scale(GetContentScale().x, GetContentScale().y);
874  Scalar y = amp * sin(freq * 2.0 * M_PI * count / 60);
875  builder.DrawImage(DlImageImpeller::Make(boston),
876  DlPoint(1024 / 2 - boston->GetSize().width / 2,
877  (768 / 2 - boston->GetSize().height / 2) + y),
878  DlImageSampling::kMipmapLinear);
879  static PlaygroundPoint point_a(Point(100, 100), 20, Color::Red());
880  static PlaygroundPoint point_b(Point(900, 700), 20, Color::Red());
881  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
882 
883  builder.ClipRect(
884  DlRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
885  builder.ClipRect(DlRect::MakeLTRB(100, 100, 900, 700));
886 
887  DlPaint paint;
888  paint.setBlendMode(DlBlendMode::kSrc);
889 
890  auto backdrop_filter =
891  DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
892  builder.SaveLayer(std::nullopt, &paint, backdrop_filter.get());
893  count += 1;
894  return builder.Build();
895  };
896  ASSERT_TRUE(OpenPlaygroundHere(callback));
897 }

References impeller::DrawPlaygroundLine(), impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), impeller::Color::Red(), and x.

◆ TEST_P() [217/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAtPeripheryHorizontal   
)

Definition at line 822 of file aiks_dl_blur_unittests.cc.

822  {
823  DisplayListBuilder builder;
824 
825  builder.Scale(GetContentScale().x, GetContentScale().y);
826  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
827  builder.DrawImageRect(
828  DlImageImpeller::Make(boston),
829  DlRect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
830  DlRect::MakeLTRB(0, 0, GetWindowSize().width, 100),
831  DlImageSampling::kNearestNeighbor);
832 
833  DlPaint paint;
834  paint.setColor(DlColor::kMagenta());
835 
836  DlRoundRect rrect = DlRoundRect::MakeRectXY(
837  DlRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10);
838  builder.DrawRoundRect(rrect, paint);
839  builder.ClipRect(DlRect::MakeLTRB(0, 50, GetWindowSize().width, 150));
840 
841  DlPaint save_paint;
842  save_paint.setBlendMode(DlBlendMode::kSrc);
843 
844  auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
845  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
846 
847  builder.Restore();
848  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
849 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [218/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAtPeripheryVertical   
)

Definition at line 794 of file aiks_dl_blur_unittests.cc.

794  {
795  DisplayListBuilder builder;
796 
797  DlPaint paint;
798  builder.Scale(GetContentScale().x, GetContentScale().y);
799 
800  paint.setColor(DlColor::kLimeGreen());
801  DlRoundRect rrect = DlRoundRect::MakeRectXY(
802  DlRect::MakeLTRB(0, 0, GetWindowSize().width, 100), 10, 10);
803  builder.DrawRoundRect(rrect, paint);
804 
805  paint.setColor(DlColor::kMagenta());
806  rrect = DlRoundRect::MakeRectXY(
807  DlRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10);
808  builder.DrawRoundRect(rrect, paint);
809  builder.ClipRect(DlRect::MakeLTRB(100, 0, 200, GetWindowSize().height));
810 
811  DlPaint save_paint;
812  save_paint.setBlendMode(DlBlendMode::kSrc);
813 
814  auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
815 
816  builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
817  builder.Restore();
818 
819  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
820 }

References x.

◆ TEST_P() [219/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurBackdropTinyMipMap   
)

Definition at line 1285 of file aiks_dl_blur_unittests.cc.

1285  {
1286  AiksContext renderer(GetContext(), nullptr);
1287  for (int32_t i = 1; i < 5; ++i) {
1288  DisplayListBuilder builder;
1289 
1290  ISize clip_size = ISize(i, i);
1291  builder.Save();
1292  builder.ClipRect(
1293  DlRect::MakeXYWH(400, 400, clip_size.width, clip_size.height));
1294 
1295  DlPaint paint;
1296  paint.setColor(DlColor::kGreen());
1297  auto blur_filter = DlImageFilter::MakeBlur(0.1, 0.1, DlTileMode::kDecal);
1298  paint.setImageFilter(blur_filter);
1299 
1300  builder.DrawCircle(DlPoint(400, 400), 200, paint);
1301  builder.Restore();
1302 
1303  auto image = DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
1304  EXPECT_TRUE(image) << " length " << i;
1305  }
1306 }

References impeller::DisplayListToTexture(), impeller::TSize< T >::height, and impeller::TSize< T >::width.

◆ TEST_P() [220/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurOneDimension   
)

Definition at line 1097 of file aiks_dl_blur_unittests.cc.

1097  {
1098  DisplayListBuilder builder;
1099 
1100  builder.Scale(GetContentScale().x, GetContentScale().y);
1101  builder.Scale(0.5, 0.5);
1102 
1103  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1104  builder.DrawImage(DlImageImpeller::Make(boston), DlPoint(100, 100), {});
1105 
1106  DlPaint paint;
1107  paint.setBlendMode(DlBlendMode::kSrc);
1108 
1109  auto backdrop_filter = DlImageFilter::MakeBlur(50, 0, DlTileMode::kClamp);
1110  builder.SaveLayer(std::nullopt, &paint, backdrop_filter.get());
1111  builder.Restore();
1112  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1113 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [221/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedAndClipped   
)

Definition at line 1119 of file aiks_dl_blur_unittests.cc.

1119  {
1120  DisplayListBuilder builder;
1121 
1122  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1123  Rect bounds =
1124  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1125 
1126  DlPaint paint;
1127  paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
1128 
1129  Vector2 image_center = Vector2(bounds.GetSize() / 2);
1130  Vector2 clip_size = {150, 75};
1131  Vector2 center = Vector2(1024, 768) / 2;
1132  builder.Scale(GetContentScale().x, GetContentScale().y);
1133 
1134  auto clip_bounds =
1135  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size);
1136  builder.ClipRect(DlRect::MakeLTRB(clip_bounds.GetLeft(), clip_bounds.GetTop(),
1137  clip_bounds.GetRight(),
1138  clip_bounds.GetBottom()));
1139  builder.Translate(center.x, center.y);
1140  builder.Scale(0.6, 0.6);
1141  builder.Rotate(25);
1142 
1143  auto dst_rect = bounds.Shift(-image_center);
1144  builder.DrawImageRect(
1145  DlImageImpeller::Make(boston), /*src=*/
1146  DlRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(), bounds.GetRight(),
1147  bounds.GetBottom()),
1148  /*dst=*/
1149  DlRect::MakeLTRB(dst_rect.GetLeft(), dst_rect.GetTop(),
1150  dst_rect.GetRight(), dst_rect.GetBottom()),
1151  DlImageSampling::kMipmapLinear, &paint);
1152 
1153  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1154 }
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() [222/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedAndClippedInteractive   
)

Definition at line 1042 of file aiks_dl_blur_unittests.cc.

1042  {
1043  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1044 
1045  auto callback = [&]() -> sk_sp<DisplayList> {
1046  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1047  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
1048  DlTileMode::kMirror, DlTileMode::kDecal};
1049 
1050  static float rotation = 0;
1051  static float scale = 0.6;
1052  static int selected_tile_mode = 3;
1053 
1054  if (AiksTest::ImGuiBegin("Controls", nullptr,
1055  ImGuiWindowFlags_AlwaysAutoResize)) {
1056  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
1057  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
1058  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1059  sizeof(tile_mode_names) / sizeof(char*));
1060  ImGui::End();
1061  }
1062 
1063  DisplayListBuilder builder;
1064  Rect bounds =
1065  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1066  Vector2 image_center = Vector2(bounds.GetSize() / 2);
1067  DlPaint paint;
1068  paint.setImageFilter(
1069  DlImageFilter::MakeBlur(20, 20, tile_modes[selected_tile_mode]));
1070 
1071  static PlaygroundPoint point_a(Point(362, 309), 20, Color::Red());
1072  static PlaygroundPoint point_b(Point(662, 459), 20, Color::Red());
1073  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
1074  Vector2 center = Vector2(1024, 768) / 2;
1075 
1076  builder.Scale(GetContentScale().x, GetContentScale().y);
1077  builder.ClipRect(
1078  DlRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
1079  builder.Translate(center.x, center.y);
1080  builder.Scale(scale, scale);
1081  builder.Rotate(rotation);
1082 
1083  DlRect sk_bounds = DlRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(),
1084  bounds.GetRight(), bounds.GetBottom());
1085  Rect dest = bounds.Shift(-image_center);
1086  DlRect sk_dst = DlRect::MakeLTRB(dest.GetLeft(), dest.GetTop(),
1087  dest.GetRight(), dest.GetBottom());
1088  builder.DrawImageRect(DlImageImpeller::Make(boston), /*src=*/sk_bounds,
1089  /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor,
1090  &paint);
1091  return builder.Build();
1092  };
1093 
1094  ASSERT_TRUE(OpenPlaygroundHere(callback));
1095 }
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
Definition: rect.h:606

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() [223/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedNonUniform   
)

Definition at line 1156 of file aiks_dl_blur_unittests.cc.

1156  {
1157  auto callback = [&]() -> sk_sp<DisplayList> {
1158  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1159  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
1160  DlTileMode::kMirror, DlTileMode::kDecal};
1161 
1162  static float rotation = 45;
1163  static float scale = 0.6;
1164  static int selected_tile_mode = 3;
1165 
1166  if (AiksTest::ImGuiBegin("Controls", nullptr,
1167  ImGuiWindowFlags_AlwaysAutoResize)) {
1168  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
1169  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
1170  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1171  sizeof(tile_mode_names) / sizeof(char*));
1172  ImGui::End();
1173  }
1174 
1175  DisplayListBuilder builder;
1176 
1177  DlPaint paint;
1178  paint.setColor(DlColor::kGreen());
1179  paint.setImageFilter(
1180  DlImageFilter::MakeBlur(50, 0, tile_modes[selected_tile_mode]));
1181 
1182  Vector2 center = Vector2(1024, 768) / 2;
1183  builder.Scale(GetContentScale().x, GetContentScale().y);
1184  builder.Translate(center.x, center.y);
1185  builder.Scale(scale, scale);
1186  builder.Rotate(rotation);
1187 
1188  DlRoundRect rrect =
1189  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(-100, -100, 200, 200), 10, 10);
1190  builder.DrawRoundRect(rrect, paint);
1191  return builder.Build();
1192  };
1193 
1194  ASSERT_TRUE(OpenPlaygroundHere(callback));
1195 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::TPoint< T >::Rotate(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [224/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurScaledAndClipped   
)

Definition at line 1009 of file aiks_dl_blur_unittests.cc.

1009  {
1010  DisplayListBuilder builder;
1011  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1012  Rect bounds =
1013  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1014  Vector2 image_center = Vector2(bounds.GetSize() / 2);
1015 
1016  DlPaint paint;
1017  paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
1018 
1019  Vector2 clip_size = {150, 75};
1020  Vector2 center = Vector2(1024, 768) / 2;
1021  builder.Scale(GetContentScale().x, GetContentScale().y);
1022 
1023  auto rect =
1024  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size);
1025  builder.ClipRect(DlRect::MakeLTRB(rect.GetLeft(), rect.GetTop(),
1026  rect.GetRight(), rect.GetBottom()));
1027  builder.Translate(center.x, center.y);
1028  builder.Scale(0.6, 0.6);
1029 
1030  DlRect sk_bounds = DlRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(),
1031  bounds.GetRight(), bounds.GetBottom());
1032  Rect dest = bounds.Shift(-image_center);
1033  DlRect sk_dst = DlRect::MakeLTRB(dest.GetLeft(), dest.GetTop(),
1034  dest.GetRight(), dest.GetBottom());
1035  builder.DrawImageRect(DlImageImpeller::Make(boston), /*src=*/sk_bounds,
1036  /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor,
1037  &paint);
1038 
1039  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1040 }

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() [225/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurSolidColorTinyMipMap   
)

Definition at line 1260 of file aiks_dl_blur_unittests.cc.

1260  {
1261  AiksContext renderer(GetContext(), nullptr);
1262 
1263  for (int32_t i = 1; i < 5; ++i) {
1264  DisplayListBuilder builder;
1265  Scalar fi = i;
1266  DlPathBuilder path_builder;
1267  path_builder.MoveTo(DlPoint(100, 100));
1268  path_builder.LineTo(DlPoint(100 + fi, 100 + fi));
1269 
1270  DlPaint paint;
1271  paint.setColor(DlColor::kChartreuse());
1272  auto blur_filter = DlImageFilter::MakeBlur(0.1, 0.1, DlTileMode::kClamp);
1273  paint.setImageFilter(blur_filter);
1274 
1275  builder.DrawPath(path_builder.TakePath(), paint);
1276 
1277  auto image = DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
1278  EXPECT_TRUE(image) << " length " << i;
1279  }
1280 }

References impeller::DisplayListToTexture().

◆ TEST_P() [226/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleInner   
)

Definition at line 649 of file aiks_dl_blur_unittests.cc.

649  {
650  DisplayListBuilder builder;
651  builder.Scale(GetContentScale().x, GetContentScale().y);
652 
653  DlPaint paint;
654  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1));
655  builder.DrawPaint(paint);
656 
657  paint.setColor(DlColor::kGreen());
658  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30));
659 
660  DlPathBuilder path_builder;
661  path_builder.MoveTo(DlPoint(200, 200));
662  path_builder.LineTo(DlPoint(300, 400));
663  path_builder.LineTo(DlPoint(100, 400));
664  path_builder.Close();
665 
666  builder.DrawPath(path_builder.TakePath(), paint);
667 
668  // Draw another thing to make sure the clip area is reset.
669  DlPaint red;
670  red.setColor(DlColor::kRed());
671  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
672 
673  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
674 }

References x.

◆ TEST_P() [227/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleInnerGradient   
)

Definition at line 899 of file aiks_dl_blur_unittests.cc.

899  {
900  DisplayListBuilder builder;
901 
902  builder.Scale(GetContentScale().x, GetContentScale().y);
903 
904  DlPaint paint;
905  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
906  builder.DrawPaint(paint);
907 
908  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
909  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
910  std::vector<Scalar> stops = {0.0, 1.0};
911 
912  paint = DlPaint{};
913  paint.setColorSource(DlColorSource::MakeLinear(
914  /*start_point=*/{0, 0},
915  /*end_point=*/{200, 200},
916  /*stop_count=*/colors.size(),
917  /*colors=*/colors.data(),
918  /*stops=*/stops.data(),
919  /*tile_mode=*/DlTileMode::kMirror));
920  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30));
921 
922  DlPathBuilder path_builder;
923  path_builder.MoveTo(DlPoint(200, 200));
924  path_builder.LineTo(DlPoint(300, 400));
925  path_builder.LineTo(DlPoint(100, 400));
926  path_builder.Close();
927  builder.DrawPath(path_builder.TakePath(), paint);
928 
929  // Draw another thing to make sure the clip area is reset.
930  DlPaint red;
931  red.setColor(DlColor::kRed());
932  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
933 
934  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
935 }

References x.

◆ TEST_P() [228/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleOuter   
)

Definition at line 676 of file aiks_dl_blur_unittests.cc.

676  {
677  DisplayListBuilder builder;
678  builder.Scale(GetContentScale().x, GetContentScale().y);
679 
680  DlPaint paint;
681  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
682  builder.DrawPaint(paint);
683 
684  paint.setColor(DlColor::kGreen());
685  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30));
686 
687  DlPathBuilder path_builder;
688  path_builder.MoveTo(DlPoint(200, 200));
689  path_builder.LineTo(DlPoint(300, 400));
690  path_builder.LineTo(DlPoint(100, 400));
691  path_builder.Close();
692 
693  builder.DrawPath(path_builder.TakePath(), paint);
694 
695  // Draw another thing to make sure the clip area is reset.
696  DlPaint red;
697  red.setColor(DlColor::kRed());
698  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
699 
700  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
701 }

References x.

◆ TEST_P() [229/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleOuterGradient   
)

Definition at line 973 of file aiks_dl_blur_unittests.cc.

973  {
974  DisplayListBuilder builder;
975  builder.Scale(GetContentScale().x, GetContentScale().y);
976 
977  DlPaint paint;
978  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
979  builder.DrawPaint(paint);
980 
981  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
982  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
983  std::vector<Scalar> stops = {0.0, 1.0};
984 
985  paint = DlPaint{};
986  paint.setColorSource(DlColorSource::MakeLinear(
987  /*start_point=*/{0, 0},
988  /*end_point=*/{200, 200},
989  /*stop_count=*/colors.size(),
990  /*colors=*/colors.data(),
991  /*stops=*/stops.data(),
992  /*tile_mode=*/DlTileMode::kMirror));
993  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30));
994 
995  DlPathBuilder path_builder;
996  path_builder.MoveTo(DlPoint(200, 200));
997  path_builder.LineTo(DlPoint(300, 400));
998  path_builder.LineTo(DlPoint(100, 400));
999  path_builder.Close();
1000  builder.DrawPath(path_builder.TakePath(), paint);
1001 
1002  // Draw another thing to make sure the clip area is reset.
1003  DlPaint red;
1004  red.setColor(DlColor::kRed());
1005  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
1006  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1007 }

References x.

◆ TEST_P() [230/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleSolid   
)

Definition at line 703 of file aiks_dl_blur_unittests.cc.

703  {
704  DisplayListBuilder builder;
705  builder.Scale(GetContentScale().x, GetContentScale().y);
706 
707  DlPaint paint;
708  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
709  builder.DrawPaint(paint);
710 
711  paint.setColor(DlColor::kGreen());
712  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30));
713 
714  DlPathBuilder path_builder;
715  path_builder.MoveTo(DlPoint(200, 200));
716  path_builder.LineTo(DlPoint(300, 400));
717  path_builder.LineTo(DlPoint(100, 400));
718  path_builder.Close();
719 
720  builder.DrawPath(path_builder.TakePath(), paint);
721 
722  // Draw another thing to make sure the clip area is reset.
723  DlPaint red;
724  red.setColor(DlColor::kRed());
725  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
726 
727  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
728 }

References x.

◆ TEST_P() [231/545]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleSolidGradient   
)

Definition at line 937 of file aiks_dl_blur_unittests.cc.

937  {
938  DisplayListBuilder builder;
939  builder.Scale(GetContentScale().x, GetContentScale().y);
940 
941  DlPaint paint;
942  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
943  builder.DrawPaint(paint);
944 
945  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
946  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
947  std::vector<Scalar> stops = {0.0, 1.0};
948 
949  paint = DlPaint{};
950  paint.setColorSource(DlColorSource::MakeLinear(
951  /*start_point=*/{0, 0},
952  /*end_point=*/{200, 200},
953  /*stop_count=*/colors.size(),
954  /*colors=*/colors.data(),
955  /*stops=*/stops.data(),
956  /*tile_mode=*/DlTileMode::kMirror));
957  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30));
958 
959  DlPathBuilder path_builder;
960  path_builder.MoveTo(DlPoint(200, 200));
961  path_builder.LineTo(DlPoint(300, 400));
962  path_builder.LineTo(DlPoint(100, 400));
963  path_builder.Close();
964  builder.DrawPath(path_builder.TakePath(), paint);
965 
966  // Draw another thing to make sure the clip area is reset.
967  DlPaint red;
968  red.setColor(DlColor::kRed());
969  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
970  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
971 }

References x.

◆ TEST_P() [232/545]

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() [233/545]

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() [234/545]

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() [235/545]

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() [236/545]

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() [237/545]

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() [238/545]

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() [239/545]

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() [240/545]

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() [241/545]

impeller::testing::TEST_P ( AiksTest  ,
ImageColorSourceEffectTransform   
)

Definition at line 1368 of file aiks_dl_basic_unittests.cc.

1368  {
1369  // Compare with https://fiddle.skia.org/c/6cdc5aefb291fda3833b806ca347a885
1370 
1371  DisplayListBuilder builder;
1372  auto texture = DlImageImpeller::Make(CreateTextureForFixture("monkey.png"));
1373 
1374  DlPaint paint;
1375  paint.setColor(DlColor::kWhite());
1376  builder.DrawPaint(paint);
1377 
1378  // Translation
1379  {
1380  DlMatrix matrix = DlMatrix::MakeTranslation({50, 50});
1381  DlPaint paint;
1382  paint.setColorSource(DlColorSource::MakeImage(
1383  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1384  DlImageSampling::kNearestNeighbor, &matrix));
1385 
1386  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), paint);
1387  }
1388 
1389  // Rotation/skew
1390  {
1391  builder.Save();
1392  builder.Rotate(45);
1393  DlPaint paint;
1394 
1395  Matrix matrix(1, -1, 0, 0, //
1396  1, 1, 0, 0, //
1397  0, 0, 1, 0, //
1398  0, 0, 0, 1);
1399  paint.setColorSource(DlColorSource::MakeImage(
1400  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1401  DlImageSampling::kNearestNeighbor, &matrix));
1402  builder.DrawRect(DlRect::MakeLTRB(100, 0, 200, 100), paint);
1403  builder.Restore();
1404  }
1405 
1406  // Scale
1407  {
1408  builder.Save();
1409  builder.Translate(100, 0);
1410  builder.Scale(100, 100);
1411  DlPaint paint;
1412 
1413  DlMatrix matrix = DlMatrix::MakeScale({0.005, 0.005, 1});
1414  paint.setColorSource(DlColorSource::MakeImage(
1415  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1416  DlImageSampling::kNearestNeighbor, &matrix));
1417 
1418  builder.DrawRect(DlRect::MakeLTRB(0, 0, 1, 1), paint);
1419  builder.Restore();
1420  }
1421 
1422  // Perspective
1423  {
1424  builder.Save();
1425  builder.Translate(150, 150);
1426  DlPaint paint;
1427 
1428  DlMatrix matrix =
1429  DlMatrix::MakePerspective(Radians{0.5}, ISize{200, 200}, 0.05, 1);
1430  paint.setColorSource(DlColorSource::MakeImage(
1431  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1432  DlImageSampling::kNearestNeighbor, &matrix));
1433 
1434  builder.DrawRect(DlRect::MakeLTRB(0, 0, 200, 200), paint);
1435  builder.Restore();
1436  }
1437 
1438  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1439 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [242/545]

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() [243/545]

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() [244/545]

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() [245/545]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurDoesntStretchContents   
)

Definition at line 759 of file aiks_dl_blur_unittests.cc.

759  {
760  Scalar sigma = 70;
761  auto callback = [&]() -> sk_sp<DisplayList> {
762  if (AiksTest::ImGuiBegin("Controls", nullptr,
763  ImGuiWindowFlags_AlwaysAutoResize)) {
764  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
765  ImGui::End();
766  }
767 
768  DisplayListBuilder builder;
769  builder.Scale(GetContentScale().x, GetContentScale().y);
770 
771  DlPaint paint;
772  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
773  builder.DrawPaint(paint);
774 
775  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
776 
777  builder.Transform(Matrix::MakeTranslation({100, 100}) *
778  Matrix::MakeScale({0.5, 0.5, 1.0f}));
779 
780  paint.setColorSource(DlColorSource::MakeImage(
781  DlImageImpeller::Make(boston), DlTileMode::kRepeat, DlTileMode::kRepeat,
782  DlImageSampling::kMipmapLinear));
783  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
784 
785  builder.DrawRect(DlRect::MakeXYWH(0, 0, boston->GetSize().width,
786  boston->GetSize().height),
787  paint);
788 
789  return builder.Build();
790  };
791  ASSERT_TRUE(OpenPlaygroundHere(callback));
792 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and x.

◆ TEST_P() [246/545]

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() [247/545]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurTexture   
)

Definition at line 730 of file aiks_dl_blur_unittests.cc.

730  {
731  Scalar sigma = 30;
732  auto callback = [&]() -> sk_sp<DisplayList> {
733  if (AiksTest::ImGuiBegin("Controls", nullptr,
734  ImGuiWindowFlags_AlwaysAutoResize)) {
735  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
736  ImGui::End();
737  }
738 
739  DisplayListBuilder builder;
740  builder.Scale(GetContentScale().x, GetContentScale().y);
741 
742  DlPaint paint;
743  paint.setColor(DlColor::kGreen());
744  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
745 
746  builder.DrawImage(
747  DlImageImpeller::Make(CreateTextureForFixture("boston.jpg")),
748  DlPoint(200, 200), DlImageSampling::kNearestNeighbor, &paint);
749 
750  DlPaint red;
751  red.setColor(DlColor::kRed());
752  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
753 
754  return builder.Build();
755  };
756  ASSERT_TRUE(OpenPlaygroundHere(callback));
757 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [248/545]

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() [249/545]

impeller::testing::TEST_P ( AiksTest  ,
MassiveScaleConvertToPath   
)

Definition at line 195 of file aiks_dl_text_unittests.cc.

195  {
196  Scalar scale = 16.0;
197  auto callback = [&]() -> sk_sp<DisplayList> {
198  if (AiksTest::ImGuiBegin("Controls", nullptr,
199  ImGuiWindowFlags_AlwaysAutoResize)) {
200  ImGui::SliderFloat("Scale", &scale, 4, 20);
201  ImGui::End();
202  }
203 
204  DisplayListBuilder builder;
205  DlPaint paint;
206  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
207  builder.DrawPaint(paint);
208 
209  builder.Scale(scale, scale);
211  GetContext(), builder, "HELLO", "Roboto-Regular.ttf",
212  TextRenderOptions{.font_size = 16,
213  .color = (16 * scale >= 250) ? DlColor::kYellow()
214  : DlColor::kOrange(),
215  .position = DlPoint(0, 20)});
216  return builder.Build();
217  };
218 
219  ASSERT_TRUE(OpenPlaygroundHere(callback));
220 }

References impeller::testing::TextRenderOptions::font_size, and RenderTextInCanvasSkia().

◆ TEST_P() [250/545]

impeller::testing::TEST_P ( AiksTest  ,
MassiveScalingMatrixImageFilter   
)

Definition at line 2012 of file aiks_dl_basic_unittests.cc.

2012  {
2013  if (GetBackend() == PlaygroundBackend::kVulkan) {
2014  GTEST_SKIP() << "Swiftshader is running out of memory on this example.";
2015  }
2016  DisplayListBuilder builder(DlRect::MakeSize(DlSize(1000, 1000)));
2017 
2018  auto filter = DlImageFilter::MakeMatrix(
2019  DlMatrix::MakeScale({0.001, 0.001, 1}), DlImageSampling::kLinear);
2020 
2021  DlPaint paint;
2022  paint.setImageFilter(filter);
2023  builder.SaveLayer(std::nullopt, &paint);
2024  {
2025  DlPaint paint;
2026  paint.setColor(DlColor::kRed());
2027  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100000, 100000), paint);
2028  }
2029  builder.Restore();
2030 
2031  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
2032 }

References impeller::kVulkan.

◆ TEST_P() [251/545]

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() [252/545]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen   
)

Definition at line 1491 of file aiks_dl_basic_unittests.cc.

1492  {
1493  DisplayListBuilder builder;
1494  builder.Scale(GetContentScale().x, GetContentScale().y);
1495  builder.Translate(100, 100);
1496  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
1497  // +300 translation applied by a SaveLayer image filter.
1498 
1499  DlPaint paint;
1500  paint.setImageFilter(DlImageFilter::MakeMatrix(
1501  DlMatrix::MakeTranslation({300, 0}) * DlMatrix::MakeScale({2, 2, 1}),
1502  DlImageSampling::kNearestNeighbor));
1503  builder.SaveLayer(std::nullopt, &paint);
1504 
1505  DlPaint circle_paint;
1506  circle_paint.setColor(DlColor::kGreen());
1507  builder.DrawCircle(DlPoint(-150, 0), 50, circle_paint);
1508  builder.Restore();
1509 
1510  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1511 }

References x.

◆ TEST_P() [253/545]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen   
)

Definition at line 1470 of file aiks_dl_basic_unittests.cc.

1470  {
1471  DisplayListBuilder builder;
1472  builder.Scale(GetContentScale().x, GetContentScale().y);
1473  builder.Translate(100, 100);
1474  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
1475  // +300 translation applied by a SaveLayer image filter.
1476  DlPaint paint;
1477  DlMatrix translate = DlMatrix::MakeTranslation({300, 0});
1478  paint.setImageFilter(
1479  DlImageFilter::MakeMatrix(translate, DlImageSampling::kLinear));
1480  builder.SaveLayer(std::nullopt, &paint);
1481 
1482  DlPaint circle_paint;
1483  circle_paint.setColor(DlColor::kGreen());
1484  builder.DrawCircle(DlPoint(-300, 0), 100, circle_paint);
1485  builder.Restore();
1486 
1487  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1488 }

References x.

◆ TEST_P() [254/545]

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() [255/545]

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() [256/545]

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() [257/545]

impeller::testing::TEST_P ( AiksTest  ,
MultipleTextWithShadowCache   
)

Definition at line 803 of file aiks_dl_text_unittests.cc.

803  {
804  DisplayListBuilder builder;
805  builder.Scale(GetContentScale().x, GetContentScale().y);
806  DlPaint paint;
807  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
808  builder.DrawPaint(paint);
809 
810  AiksContext aiks_context(GetContext(),
811  std::make_shared<TypographerContextSkia>());
812  // Cache empty
813  EXPECT_EQ(aiks_context.GetContentContext()
814  .GetTextShadowCache()
815  .GetCacheSizeForTesting(),
816  0u);
817 
818  for (auto i = 0; i < 5; i++) {
819  ASSERT_TRUE(RenderTextInCanvasSkia(
820  GetContext(), builder, "Hello World", kFontFixture,
821  TextRenderOptions{
822  .color = DlColor::kBlue(),
823  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
824  }
825 
826  DisplayListToTexture(builder.Build(), {400, 400}, aiks_context);
827 
828  // Text should be cached. Each text gets its own entry as we don't analyze the
829  // strings.
830  EXPECT_EQ(aiks_context.GetContentContext()
831  .GetTextShadowCache()
832  .GetCacheSizeForTesting(),
833  5u);
834 }

References impeller::testing::TextRenderOptions::color, impeller::DisplayListToTexture(), impeller::TextShadowCache::GetCacheSizeForTesting(), impeller::AiksContext::GetContentContext(), impeller::ContentContext::GetTextShadowCache(), kFontFixture, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [258/545]

impeller::testing::TEST_P ( AiksTest  ,
NoDimplesInRRectPath   
)

Definition at line 2034 of file aiks_dl_basic_unittests.cc.

2034  {
2035  Scalar width = 200.f;
2036  Scalar height = 60.f;
2037  Scalar corner = 1.f;
2038  auto callback = [&]() -> sk_sp<DisplayList> {
2039  if (AiksTest::ImGuiBegin("Controls", nullptr,
2040  ImGuiWindowFlags_AlwaysAutoResize)) {
2041  ImGui::SliderFloat("width", &width, 0, 200);
2042  ImGui::SliderFloat("height", &height, 0, 200);
2043  ImGui::SliderFloat("corner", &corner, 0, 1);
2044  ImGui::End();
2045  }
2046 
2047  DisplayListBuilder builder;
2048  builder.Scale(GetContentScale().x, GetContentScale().y);
2049 
2050  DlPaint background_paint;
2051  background_paint.setColor(DlColor(1, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
2052  builder.DrawPaint(background_paint);
2053 
2054  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue()};
2055  std::vector<Scalar> stops = {0.0, 1.0};
2056 
2057  DlPaint paint;
2058  auto gradient = DlColorSource::MakeLinear(DlPoint(0, 0), DlPoint(200, 200),
2059  2, colors.data(), stops.data(),
2060  DlTileMode::kClamp);
2061  paint.setColorSource(gradient);
2062  paint.setColor(DlColor::kWhite());
2063  paint.setDrawStyle(DlDrawStyle::kStroke);
2064  paint.setStrokeWidth(20);
2065 
2066  builder.Save();
2067  builder.Translate(100, 100);
2068 
2069  Scalar corner_x = ((1 - corner) * 50) + 50;
2070  Scalar corner_y = corner * 50 + 50;
2071  DlRoundRect rrect = DlRoundRect::MakeRectXY(
2072  DlRect::MakeXYWH(0, 0, width, height), corner_x, corner_y);
2073  builder.DrawRoundRect(rrect, paint);
2074  builder.Restore();
2075  return builder.Build();
2076  };
2077  ASSERT_TRUE(OpenPlaygroundHere(callback));
2078 }

References impeller::AiksPlayground::ImGuiBegin(), and x.

◆ TEST_P() [259/545]

impeller::testing::TEST_P ( AiksTest  ,
NonSquareFilledArcsRenderCorrectly   
)

Definition at line 825 of file aiks_dl_basic_unittests.cc.

825  {
826  DisplayListBuilder builder;
827  builder.Scale(GetContentScale().x, GetContentScale().y);
828  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
829 
830  DlPaint paint;
831  paint.setColor(DlColor::kBlue());
832 
833  RenderArcFarm(builder, paint,
834  {
835  .use_center = false,
836  .full_circles = false,
837  .vertical_scale = 0.8f,
838  });
839 
840  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
841 }

References x.

◆ TEST_P() [260/545]

impeller::testing::TEST_P ( AiksTest  ,
NonSquareFilledArcsRenderCorrectlyWithCenter   
)

Definition at line 843 of file aiks_dl_basic_unittests.cc.

843  {
844  DisplayListBuilder builder;
845  builder.Scale(GetContentScale().x, GetContentScale().y);
846  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
847 
848  DlPaint paint;
849  paint.setColor(DlColor::kBlue());
850 
851  RenderArcFarm(builder, paint,
852  {
853  .use_center = true,
854  .full_circles = false,
855  .vertical_scale = 0.8f,
856  });
857 
858  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
859 }

References x.

◆ TEST_P() [261/545]

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() [262/545]

impeller::testing::TEST_P ( AiksTest  ,
PipelineBlendSingleParameter   
)

Definition at line 1986 of file aiks_dl_basic_unittests.cc.

1986  {
1987  DisplayListBuilder builder;
1988 
1989  // Should render a green square in the middle of a blue circle.
1990  DlPaint paint;
1991  builder.SaveLayer(std::nullopt, &paint);
1992  {
1993  builder.Translate(100, 100);
1994  paint.setColor(DlColor::kBlue());
1995  builder.DrawCircle(DlPoint(200, 200), 200, paint);
1996  builder.ClipRect(DlRect::MakeXYWH(100, 100, 200, 200));
1997 
1998  paint.setColor(DlColor::kGreen());
1999  paint.setBlendMode(DlBlendMode::kSrcOver);
2000  paint.setImageFilter(DlImageFilter::MakeColorFilter(
2001  DlColorFilter::MakeBlend(DlColor::kWhite(), DlBlendMode::kDst)));
2002  builder.DrawCircle(DlPoint(200, 200), 200, paint);
2003  builder.Restore();
2004  }
2005 
2006  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
2007 }

◆ TEST_P() [263/545]

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() [264/545]

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() [265/545]

impeller::testing::TEST_P ( AiksTest  ,
RoundSuperellipseShadowComparison   
)

Definition at line 389 of file canvas_unittests.cc.

389  {
390  // Config
391  Size default_size(600, 400);
392  Point left_center(400, 700);
393  Point right_center(1300, 700);
394  Color color = Color::Red();
395 
396  // Convert `color` to a `color_source`. This forces
397  // `canvas.DrawRoundSuperellipse` to use the regular shadow algorithm
398  // (blurring) instead of the fast shadow algorithm.
399  std::shared_ptr<flutter::DlColorSource> color_source;
400  {
401  flutter::DlColor dl_color = flutter::DlColor(color.ToARGB());
402  std::vector<flutter::DlColor> colors = {dl_color, dl_color};
403  std::vector<Scalar> stops = {0.0, 1.0};
404  color_source = flutter::DlColorSource::MakeLinear(
405  {0, 0}, {1000, 1000}, 2, colors.data(), stops.data(),
406  flutter::DlTileMode::kClamp);
407  }
408 
409  auto RectMakeCenterHalfSize = [](Point center, Point half_size) {
410  Size size(half_size.x * 2, half_size.y * 2);
411  return Rect::MakeOriginSize(center - half_size, size);
412  };
413 
414  RenderCallback callback = [&](RenderTarget& render_target) {
415  ContentContext context(GetContext(), nullptr);
416  Canvas canvas(context, render_target, true, false);
417  // Somehow there's a scaling factor between PlaygroundPoint and Canvas.
418  Matrix ctm = Matrix::MakeScale(Vector2(1, 1) * 0.5);
419  Matrix i_ctm = ctm.Invert();
420 
421  static Scalar sigma = 0.05;
422  static Scalar radius = 200;
423 
424  // Define the ImGui
425  ImGui::Begin("Shadow", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
426  {
427  ImGui::SliderFloat("Sigma", &sigma, 0, 100);
428  ImGui::SliderFloat("Radius", &radius, 0, 1000);
429  }
430  ImGui::End();
431 
432  static PlaygroundPoint right_reference_var(
433  ctm * (right_center + default_size / 2), 30, Color::White());
434  Point right_reference = i_ctm * DrawPlaygroundPoint(right_reference_var);
435  Point half_size = (right_reference - right_center).Abs();
436  Rect left_bounds = RectMakeCenterHalfSize(left_center, half_size);
437  Rect right_bounds = RectMakeCenterHalfSize(right_center, half_size);
438 
439  Paint paint{
440  .color = color,
441  .mask_blur_descriptor =
442  Paint::MaskBlurDescriptor{
443  .sigma = Sigma(sigma),
444  },
445  };
446 
447  // Left: Draw with canvas
448  canvas.DrawRoundSuperellipse(
449  RoundSuperellipse::MakeRectRadius(left_bounds, radius), paint);
450 
451  // Right: Direct draw
452  paint.color_source = color_source.get();
453  canvas.DrawRoundSuperellipse(
454  RoundSuperellipse::MakeRectRadius(right_bounds, radius), paint);
455 
456  canvas.EndReplay();
457  return true;
458  };
459 
460  ASSERT_TRUE(Playground::OpenPlaygroundHere(callback));
461 }

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() [266/545]

impeller::testing::TEST_P ( AiksTest  ,
RuntimeEffectWithInvalidSamplerDoesNotCrash   
)

Definition at line 111 of file aiks_dl_runtime_effect_unittests.cc.

111  {
112  ScopedValidationDisable disable_validation;
113 
114  // Create a sampler that is not usable as an input to the runtime effect.
115  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
116  flutter::DlColor::kRed()};
117  const float stops[2] = {0.0, 1.0};
118  auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
119  2, colors.data(), stops,
120  flutter::DlTileMode::kClamp);
121  std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
122  linear,
123  };
124 
125  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
126  uniform_data->resize(sizeof(Vector2));
127 
128  DlPaint paint;
129  paint.setColorSource(
130  MakeRuntimeEffect(this, "runtime_stage_filter_example.frag.iplr",
131  uniform_data, sampler_inputs));
132 
133  DisplayListBuilder builder;
134  builder.DrawPaint(paint);
135 
136  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
137 }

◆ TEST_P() [267/545]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerDrawsBehindSubsequentEntities   
)

Definition at line 1841 of file aiks_dl_basic_unittests.cc.

1841  {
1842  // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
1843  DisplayListBuilder builder;
1844  DlPaint paint;
1845 
1846  paint.setColor(DlColor::kBlack());
1847  DlRect rect = DlRect::MakeXYWH(25, 25, 25, 25);
1848  builder.DrawRect(rect, paint);
1849 
1850  builder.Translate(10, 10);
1851 
1852  DlPaint save_paint;
1853  builder.SaveLayer(std::nullopt, &save_paint);
1854 
1855  paint.setColor(DlColor::kGreen());
1856  builder.DrawRect(rect, paint);
1857 
1858  builder.Restore();
1859 
1860  builder.Translate(10, 10);
1861  paint.setColor(DlColor::kRed());
1862  builder.DrawRect(rect, paint);
1863 
1864  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1865 }

◆ TEST_P() [268/545]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerFiltersScaleWithTransform   
)

Definition at line 1933 of file aiks_dl_basic_unittests.cc.

1933  {
1934  DisplayListBuilder builder;
1935 
1936  builder.Scale(GetContentScale().x, GetContentScale().y);
1937  builder.Translate(100, 100);
1938 
1939  auto texture = DlImageImpeller::Make(CreateTextureForFixture("boston.jpg"));
1940  auto draw_image_layer = [&builder, &texture](const DlPaint& paint) {
1941  builder.SaveLayer(std::nullopt, &paint);
1942  builder.DrawImage(texture, DlPoint(), DlImageSampling::kLinear);
1943  builder.Restore();
1944  };
1945 
1946  DlPaint effect_paint;
1947  effect_paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 6));
1948  draw_image_layer(effect_paint);
1949 
1950  builder.Translate(300, 300);
1951  builder.Scale(3, 3);
1952  draw_image_layer(effect_paint);
1953 
1954  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1955 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [269/545]

impeller::testing::TEST_P ( AiksTest  ,
ScaledK   
)

Definition at line 173 of file aiks_dl_text_unittests.cc.

173  {
174  DisplayListBuilder builder;
175  DlPaint paint;
176  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
177  builder.DrawPaint(paint);
178  for (int i = 0; i < 6; ++i) {
179  builder.Save();
180  builder.Translate(300 * i, 0);
181  Scalar scale = 0.445 - (i / 1000.f);
182  builder.Scale(scale, scale);
184  GetContext(), builder, "k", "Roboto-Regular.ttf",
185  TextRenderOptions{.font_size = 600, .position = DlPoint(10, 500)});
187  GetContext(), builder, "k", "Roboto-Regular.ttf",
188  TextRenderOptions{.font_size = 300, .position = DlPoint(10, 800)});
189  builder.Restore();
190  }
191  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
192 }

References impeller::testing::TextRenderOptions::font_size, and RenderTextInCanvasSkia().

◆ TEST_P() [270/545]

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() [271/545]

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() [272/545]

impeller::testing::TEST_P ( AiksTest  ,
SiblingSaveLayerBoundsAreRespected   
)

Definition at line 1867 of file aiks_dl_basic_unittests.cc.

1867  {
1868  DisplayListBuilder builder;
1869  DlPaint paint;
1870  DlRect rect = DlRect::MakeXYWH(0, 0, 1000, 1000);
1871 
1872  // Black, green, and red squares offset by [10, 10].
1873  {
1874  DlPaint save_paint;
1875  DlRect bounds = DlRect::MakeXYWH(25, 25, 25, 25);
1876  builder.SaveLayer(bounds, &save_paint);
1877  paint.setColor(DlColor::kBlack());
1878  builder.DrawRect(rect, paint);
1879  builder.Restore();
1880  }
1881 
1882  {
1883  DlPaint save_paint;
1884  DlRect bounds = DlRect::MakeXYWH(35, 35, 25, 25);
1885  builder.SaveLayer(bounds, &save_paint);
1886  paint.setColor(DlColor::kGreen());
1887  builder.DrawRect(rect, paint);
1888  builder.Restore();
1889  }
1890 
1891  {
1892  DlPaint save_paint;
1893  DlRect bounds = DlRect::MakeXYWH(45, 45, 25, 25);
1894  builder.SaveLayer(bounds, &save_paint);
1895  paint.setColor(DlColor::kRed());
1896  builder.DrawRect(rect, paint);
1897  builder.Restore();
1898  }
1899 
1900  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1901 }

◆ TEST_P() [273/545]

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() [274/545]

impeller::testing::TEST_P ( AiksTest  ,
SingleIconShadowTest   
)

Definition at line 836 of file aiks_dl_text_unittests.cc.

836  {
837  DisplayListBuilder builder;
838  builder.Scale(GetContentScale().x, GetContentScale().y);
839  DlPaint paint;
840  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
841  builder.DrawPaint(paint);
842 
843  AiksContext aiks_context(GetContext(),
844  std::make_shared<TypographerContextSkia>());
845  // Cache empty
846  EXPECT_EQ(aiks_context.GetContentContext()
847  .GetTextShadowCache()
848  .GetCacheSizeForTesting(),
849  0u);
850 
851  // Create font instance outside loop so all draws use identical font instance.
852  auto c_font_fixture = std::string(kFontFixture);
853  auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
854  ASSERT_TRUE(mapping);
855  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
856  SkFont sk_font(font_mgr->makeFromData(mapping), 50);
857 
858  for (auto i = 0; i < 10; i++) {
859  ASSERT_TRUE(RenderTextInCanvasSkia(
860  GetContext(), builder, "A", kFontFixture,
861  TextRenderOptions{
862  .color = DlColor::kBlue(),
863  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)},
864  sk_font));
865  }
866 
867  DisplayListToTexture(builder.Build(), {400, 400}, aiks_context);
868 
869  // Text should be cached. All 10 glyphs use the same cache entry.
870  EXPECT_EQ(aiks_context.GetContentContext()
871  .GetTextShadowCache()
872  .GetCacheSizeForTesting(),
873  1u);
874 }

References impeller::testing::TextRenderOptions::color, impeller::DisplayListToTexture(), impeller::TextShadowCache::GetCacheSizeForTesting(), impeller::AiksContext::GetContentContext(), impeller::ContentContext::GetTextShadowCache(), kFontFixture, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [275/545]

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() [276/545]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorCirclesOvalsRRectsMaskBlurCorrectly   
)

Definition at line 1203 of file aiks_dl_basic_unittests.cc.

1203  {
1204  DisplayListBuilder builder;
1205  builder.Scale(GetContentScale().x, GetContentScale().y);
1206  DlPaint paint;
1207  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1.0f));
1208 
1209  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
1210 
1211  paint.setColor(
1212  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f));
1213  Scalar y = 100.0f;
1214  for (int i = 0; i < 5; i++) {
1215  Scalar x = (i + 1) * 100;
1216  Scalar radius = x / 10.0f;
1217  builder.DrawRect(DlRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1218  radius, 60.0f - radius),
1219  paint);
1220  }
1221 
1222  paint.setColor(DlColor::kBlue());
1223  y += 100.0f;
1224  for (int i = 0; i < 5; i++) {
1225  Scalar x = (i + 1) * 100;
1226  Scalar radius = x / 10.0f;
1227  builder.DrawCircle(DlPoint(x + 25, y + 25), radius, paint);
1228  }
1229 
1230  paint.setColor(DlColor::kGreen());
1231  y += 100.0f;
1232  for (int i = 0; i < 5; i++) {
1233  Scalar x = (i + 1) * 100;
1234  Scalar radius = x / 10.0f;
1235  builder.DrawOval(DlRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1236  radius, 60.0f - radius),
1237  paint);
1238  }
1239 
1240  paint.setColor(
1241  DlColor::RGBA(128.0f / 255.0f, 0.0f / 255.0f, 128.0f / 255.0f, 1.0f));
1242  y += 100.0f;
1243  for (int i = 0; i < 5; i++) {
1244  Scalar x = (i + 1) * 100;
1245  Scalar radius = x / 20.0f;
1246  builder.DrawRoundRect(
1247  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(x, y, 60.0f, 60.0f), //
1248  radius, radius),
1249  paint);
1250  }
1251 
1252  paint.setColor(
1253  DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f));
1254  y += 100.0f;
1255  for (int i = 0; i < 5; i++) {
1256  Scalar x = (i + 1) * 100;
1257  Scalar radius = x / 20.0f;
1258  builder.DrawRoundRect(
1259  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(x, y, 60.0f, 60.0f), //
1260  radius, 5.0f),
1261  paint);
1262  }
1263 
1264  auto dl = builder.Build();
1265  ASSERT_TRUE(OpenPlaygroundHere(dl));
1266 }

References x.

◆ TEST_P() [277/545]

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() [278/545]

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() [279/545]

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() [280/545]

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() [281/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsCoverFullArcWithButtEnds   
)

Definition at line 1054 of file aiks_dl_basic_unittests.cc.

1054  {
1055  // This test compares the rendering of a full circle arc against a partial
1056  // arc by drawing a one over the other in high contrast. If the partial
1057  // arc misses any pixels that were drawn by the full arc, there will be
1058  // some "pixel dirt" around the missing "erased" parts of the arcs. This
1059  // case arises while rendering a CircularProgressIndicator with a background
1060  // color where we want the rendering of the background full arc to hit the
1061  // same pixels around the edges as the partial arc that covers it.
1062  //
1063  // In this case we draw a full blue circle and then draw a partial arc
1064  // over it in the background color (white).
1065 
1066  DisplayListBuilder builder;
1067  builder.Scale(GetContentScale().x, GetContentScale().y);
1068  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
1069 
1070  DlPaint paint;
1071  paint.setDrawStyle(DlDrawStyle::kStroke);
1072  paint.setStrokeWidth(6.0f);
1073  paint.setStrokeCap(DlStrokeCap::kButt);
1074  paint.setColor(DlColor::kBlue());
1075 
1076  // First draw full circles in blue to establish the pixels to be erased
1077  RenderArcFarm(builder, paint,
1078  {
1079  .use_center = false,
1080  .full_circles = true,
1081  });
1082 
1083  paint.setColor(DlColor::kWhite());
1084 
1085  // Then draw partial arcs in white over the circles to "erase" them
1086  RenderArcFarm(builder, paint,
1087  {
1088  .use_center = false,
1089  .full_circles = false,
1090  });
1091 
1092  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1093 }

References x.

◆ TEST_P() [282/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithBevelJoinsAndCenter   
)

Definition at line 921 of file aiks_dl_basic_unittests.cc.

921  {
922  DisplayListBuilder builder;
923  builder.Scale(GetContentScale().x, GetContentScale().y);
924  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
925 
926  DlPaint paint;
927  paint.setDrawStyle(DlDrawStyle::kStroke);
928  paint.setStrokeWidth(6.0f);
929  paint.setStrokeJoin(DlStrokeJoin::kBevel);
930  paint.setColor(DlColor::kBlue());
931 
932  RenderArcFarm(builder, paint,
933  {
934  .use_center = true,
935  .full_circles = false,
936  .sweeps_over_360 = true,
937  });
938 
939  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
940 }

References x.

◆ TEST_P() [283/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithButtEnds   
)

Definition at line 861 of file aiks_dl_basic_unittests.cc.

861  {
862  DisplayListBuilder builder;
863  builder.Scale(GetContentScale().x, GetContentScale().y);
864  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
865 
866  DlPaint paint;
867  paint.setDrawStyle(DlDrawStyle::kStroke);
868  paint.setStrokeWidth(6.0f);
869  paint.setStrokeCap(DlStrokeCap::kButt);
870  paint.setColor(DlColor::kBlue());
871 
872  RenderArcFarm(builder, paint,
873  {
874  .use_center = false,
875  .full_circles = false,
876  });
877 
878  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
879 }

References x.

◆ TEST_P() [284/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithMiterJoinsAndCenter   
)

Definition at line 942 of file aiks_dl_basic_unittests.cc.

942  {
943  DisplayListBuilder builder;
944  builder.Scale(GetContentScale().x, GetContentScale().y);
945  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
946 
947  DlPaint paint;
948  paint.setDrawStyle(DlDrawStyle::kStroke);
949  paint.setStrokeWidth(6.0f);
950  paint.setStrokeJoin(DlStrokeJoin::kMiter);
951  // Default miter of 4.0 does a miter on all of the centers, but
952  // using 3.0 will show some bevels on the widest interior angles...
953  paint.setStrokeMiter(3.0f);
954  paint.setColor(DlColor::kBlue());
955 
956  RenderArcFarm(builder, paint,
957  {
958  .use_center = true,
959  .full_circles = false,
960  .sweeps_over_360 = true,
961  });
962 
963  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
964 }

References x.

◆ TEST_P() [285/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithRoundEnds   
)

Definition at line 901 of file aiks_dl_basic_unittests.cc.

901  {
902  DisplayListBuilder builder;
903  builder.Scale(GetContentScale().x, GetContentScale().y);
904  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
905 
906  DlPaint paint;
907  paint.setDrawStyle(DlDrawStyle::kStroke);
908  paint.setStrokeWidth(6.0f);
909  paint.setStrokeCap(DlStrokeCap::kRound);
910  paint.setColor(DlColor::kBlue());
911 
912  RenderArcFarm(builder, paint,
913  {
914  .use_center = false,
915  .full_circles = false,
916  });
917 
918  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
919 }

References x.

◆ TEST_P() [286/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithRoundJoinsAndCenter   
)

Definition at line 966 of file aiks_dl_basic_unittests.cc.

966  {
967  DisplayListBuilder builder;
968  builder.Scale(GetContentScale().x, GetContentScale().y);
969  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
970 
971  DlPaint paint;
972  paint.setDrawStyle(DlDrawStyle::kStroke);
973  paint.setStrokeWidth(6.0f);
974  paint.setStrokeJoin(DlStrokeJoin::kRound);
975  paint.setColor(DlColor::kBlue());
976 
977  RenderArcFarm(builder, paint,
978  {
979  .use_center = true,
980  .full_circles = false,
981  .sweeps_over_360 = true,
982  });
983 
984  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
985 }

References x.

◆ TEST_P() [287/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithSquareAndButtAndRoundEnds   
)

Definition at line 1016 of file aiks_dl_basic_unittests.cc.

1016  {
1017  DisplayListBuilder builder;
1018  builder.Scale(GetContentScale().x, GetContentScale().y);
1019  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
1020 
1021  DlPaint paint;
1022  paint.setDrawStyle(DlDrawStyle::kStroke);
1023  paint.setStrokeWidth(8.0f);
1024  paint.setStrokeCap(DlStrokeCap::kSquare);
1025  paint.setColor(DlColor::kRed());
1026 
1027  RenderArcFarm(builder, paint,
1028  {
1029  .use_center = false,
1030  .full_circles = false,
1031  });
1032 
1033  paint.setStrokeCap(DlStrokeCap::kRound);
1034  paint.setColor(DlColor::kGreen());
1035 
1036  RenderArcFarm(builder, paint,
1037  {
1038  .use_center = false,
1039  .full_circles = false,
1040  });
1041 
1042  paint.setStrokeCap(DlStrokeCap::kButt);
1043  paint.setColor(DlColor::kBlue());
1044 
1045  RenderArcFarm(builder, paint,
1046  {
1047  .use_center = false,
1048  .full_circles = false,
1049  });
1050 
1051  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1052 }

References x.

◆ TEST_P() [288/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithSquareAndButtEnds   
)

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(8.0f);
995  paint.setStrokeCap(DlStrokeCap::kSquare);
996  paint.setColor(DlColor::kRed());
997 
998  RenderArcFarm(builder, paint,
999  {
1000  .use_center = false,
1001  .full_circles = false,
1002  });
1003 
1004  paint.setStrokeCap(DlStrokeCap::kButt);
1005  paint.setColor(DlColor::kBlue());
1006 
1007  RenderArcFarm(builder, paint,
1008  {
1009  .use_center = false,
1010  .full_circles = false,
1011  });
1012 
1013  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1014 }

References x.

◆ TEST_P() [289/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedArcsRenderCorrectlyWithSquareEnds   
)

Definition at line 881 of file aiks_dl_basic_unittests.cc.

881  {
882  DisplayListBuilder builder;
883  builder.Scale(GetContentScale().x, GetContentScale().y);
884  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
885 
886  DlPaint paint;
887  paint.setDrawStyle(DlDrawStyle::kStroke);
888  paint.setStrokeWidth(6.0f);
889  paint.setStrokeCap(DlStrokeCap::kSquare);
890  paint.setColor(DlColor::kBlue());
891 
892  RenderArcFarm(builder, paint,
893  {
894  .use_center = false,
895  .full_circles = false,
896  });
897 
898  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
899 }

References x.

◆ TEST_P() [290/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedCirclesRenderCorrectly   
)

Definition at line 623 of file aiks_dl_basic_unittests.cc.

623  {
624  DisplayListBuilder builder;
625  builder.Scale(GetContentScale().x, GetContentScale().y);
626  DlPaint paint;
627  const int color_count = 3;
628  DlColor colors[color_count] = {
629  DlColor::kBlue(),
630  DlColor::kGreen(),
631  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
632  };
633 
634  paint.setColor(DlColor::kWhite());
635  builder.DrawPaint(paint);
636 
637  int c_index = 0;
638 
639  auto draw = [&paint, &colors, &c_index](DlCanvas& canvas, DlPoint center,
640  Scalar r, Scalar dr, int n) {
641  for (int i = 0; i < n; i++) {
642  paint.setColor(colors[(c_index++) % color_count]);
643  canvas.DrawCircle(center, r, paint);
644  r += dr;
645  }
646  };
647 
648  paint.setDrawStyle(DlDrawStyle::kStroke);
649  paint.setStrokeWidth(1);
650  draw(builder, DlPoint(10, 10), 2, 2, 14); // r = [2, 28], covers [1,29]
651  paint.setStrokeWidth(5);
652  draw(builder, DlPoint(10, 10), 35, 10, 56); // r = [35, 585], covers [30,590]
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  draw(builder, DlPoint(500, 600), 5, 10, 10);
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  draw(builder, DlPoint(800, 300), 5, 10, 10);
685 
686  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
687 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [291/545]

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() [292/545]

impeller::testing::TEST_P ( AiksTest  ,
StrokedRectsRenderCorrectly   
)

Definition at line 427 of file aiks_dl_basic_unittests.cc.

427  {
428  DisplayListBuilder builder;
429  builder.Scale(GetContentScale().x, GetContentScale().y);
430 
431  DlPaint paint;
432  paint.setColor(DlColor::kPurple());
433  paint.setDrawStyle(DlDrawStyle::kStroke);
434  paint.setStrokeWidth(20.0f);
435 
436  DlPaint thin_paint = paint;
437  thin_paint.setColor(DlColor::kYellow());
438  thin_paint.setStrokeWidth(0.0f);
439 
440  DlRect rect = DlRect::MakeLTRB(10, 10, 90, 90);
441  DlRect thin_tall_rect = DlRect::MakeLTRB(120, 10, 120, 90);
442  DlRect thin_wide_rect = DlRect::MakeLTRB(10, 120, 90, 120);
443  DlRect empty_rect = DlRect::MakeLTRB(120, 120, 120, 120);
444 
445  // We draw the following sets of rectangles:
446  //
447  // A E X
448  // X
449  // B F X
450  // X
451  // C D G H X
452  //
453  // Purple A,B,C,D are all drawn with stroke width 20 (non-overflowing).
454  // Each of those sets has 4 rectangles of dimension 80x80, 80x0, 0x80,
455  // and 0,0 to demonstrate the basic behavior and also the behavior of
456  // empty dimensions.
457  //
458  // Blue E,F,G,H are the same 80x80 rectangles, but with an overflowing
459  // stroke width of 120 to show the behavior with degenerately large
460  // stroke widths.
461  //
462  // A,E are drawn with Bevel joins.
463  // B,F are drawn with Round joins.
464  // C,G are drawn with Miter joins and a large enough miter limit.
465  // D,H are drawn with Miter joins and a too small miter limit (== Bevel).
466  //
467  // All orange X rectangles are drawn with round joins and increasing stroke
468  // widths to demonstrate fidelity of the rounding code at various arc sizes.
469  // These X rectangles also help test that the variable sizing estimates in
470  // the round join code are accurate.
471 
472  // rects (A)
473  paint.setStrokeJoin(DlStrokeJoin::kBevel);
474  builder.DrawRect(rect.Shift({100, 100}), paint);
475  builder.DrawRect(rect.Shift({100, 100}), thin_paint);
476  builder.DrawRect(thin_tall_rect.Shift({100, 100}), paint);
477  builder.DrawRect(thin_tall_rect.Shift({100, 100}), thin_paint);
478  builder.DrawRect(thin_wide_rect.Shift({100, 100}), paint);
479  builder.DrawRect(thin_wide_rect.Shift({100, 100}), thin_paint);
480  builder.DrawRect(empty_rect.Shift({100, 100}), paint);
481  builder.DrawRect(empty_rect.Shift({100, 100}), thin_paint);
482 
483  // rects (B)
484  paint.setStrokeJoin(DlStrokeJoin::kRound);
485  builder.DrawRect(rect.Shift({100, 300}), paint);
486  builder.DrawRect(rect.Shift({100, 300}), thin_paint);
487  builder.DrawRect(thin_tall_rect.Shift({100, 300}), paint);
488  builder.DrawRect(thin_tall_rect.Shift({100, 300}), thin_paint);
489  builder.DrawRect(thin_wide_rect.Shift({100, 300}), paint);
490  builder.DrawRect(thin_wide_rect.Shift({100, 300}), thin_paint);
491  builder.DrawRect(empty_rect.Shift({100, 300}), paint);
492  builder.DrawRect(empty_rect.Shift({100, 300}), thin_paint);
493 
494  // rects (C)
495  paint.setStrokeJoin(DlStrokeJoin::kMiter);
496  paint.setStrokeMiter(kSqrt2 + flutter::kEhCloseEnough);
497  builder.DrawRect(rect.Shift({100, 500}), paint);
498  builder.DrawRect(rect.Shift({100, 500}), thin_paint);
499  builder.DrawRect(thin_tall_rect.Shift({100, 500}), paint);
500  builder.DrawRect(thin_tall_rect.Shift({100, 500}), thin_paint);
501  builder.DrawRect(thin_wide_rect.Shift({100, 500}), paint);
502  builder.DrawRect(thin_wide_rect.Shift({100, 500}), thin_paint);
503  builder.DrawRect(empty_rect.Shift({100, 500}), paint);
504  builder.DrawRect(empty_rect.Shift({100, 500}), thin_paint);
505 
506  // rects (D)
507  paint.setStrokeJoin(DlStrokeJoin::kMiter);
508  paint.setStrokeMiter(kSqrt2 - flutter::kEhCloseEnough);
509  builder.DrawRect(rect.Shift({300, 500}), paint);
510  builder.DrawRect(rect.Shift({300, 500}), thin_paint);
511  builder.DrawRect(thin_tall_rect.Shift({300, 500}), paint);
512  builder.DrawRect(thin_tall_rect.Shift({300, 500}), thin_paint);
513  builder.DrawRect(thin_wide_rect.Shift({300, 500}), paint);
514  builder.DrawRect(thin_wide_rect.Shift({300, 500}), thin_paint);
515  builder.DrawRect(empty_rect.Shift({300, 500}), paint);
516  builder.DrawRect(empty_rect.Shift({300, 500}), thin_paint);
517 
518  paint.setStrokeWidth(120.0f);
519  paint.setColor(DlColor::kBlue());
520  rect = rect.Expand(-20);
521 
522  // rect (E)
523  paint.setStrokeJoin(DlStrokeJoin::kBevel);
524  builder.DrawRect(rect.Shift({500, 100}), paint);
525  builder.DrawRect(rect.Shift({500, 100}), thin_paint);
526 
527  // rect (F)
528  paint.setStrokeJoin(DlStrokeJoin::kRound);
529  builder.DrawRect(rect.Shift({500, 300}), paint);
530  builder.DrawRect(rect.Shift({500, 300}), thin_paint);
531 
532  // rect (G)
533  paint.setStrokeJoin(DlStrokeJoin::kMiter);
534  paint.setStrokeMiter(kSqrt2 + flutter::kEhCloseEnough);
535  builder.DrawRect(rect.Shift({500, 500}), paint);
536  builder.DrawRect(rect.Shift({500, 500}), thin_paint);
537 
538  // rect (H)
539  paint.setStrokeJoin(DlStrokeJoin::kMiter);
540  paint.setStrokeMiter(kSqrt2 - flutter::kEhCloseEnough);
541  builder.DrawRect(rect.Shift({700, 500}), paint);
542  builder.DrawRect(rect.Shift({700, 500}), thin_paint);
543 
544  DlPaint round_mock_paint;
545  round_mock_paint.setColor(DlColor::kGreen());
546  round_mock_paint.setDrawStyle(DlDrawStyle::kFill);
547 
548  // array of rects (X)
549  Scalar x = 900;
550  Scalar y = 50;
551  for (int i = 0; i < 15; i++) {
552  paint.setStrokeWidth(i);
553  paint.setColor(DlColor::kOrange());
554  paint.setStrokeJoin(DlStrokeJoin::kRound);
555  builder.DrawRect(DlRect::MakeXYWH(x, y, 30, 30), paint);
556  y += 32 + i;
557  }
558 
559  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
560 }

References impeller::kEhCloseEnough, impeller::kSqrt2, and x.

◆ TEST_P() [293/545]

impeller::testing::TEST_P ( AiksTest  ,
SubpassWithClearColorOptimization   
)

Definition at line 1441 of file aiks_dl_basic_unittests.cc.

1441  {
1442  DisplayListBuilder builder;
1443 
1444  // Use a non-srcOver blend mode to ensure that we don't detect this as an
1445  // opacity peephole optimization.
1446  DlPaint paint;
1447  paint.setColor(DlColor::kBlue().modulateOpacity(0.5));
1448  paint.setBlendMode(DlBlendMode::kSrc);
1449 
1450  DlRect bounds = DlRect::MakeLTRB(0, 0, 200, 200);
1451  builder.SaveLayer(bounds, &paint);
1452 
1453  paint.setColor(DlColor::kTransparent());
1454  paint.setBlendMode(DlBlendMode::kSrc);
1455  builder.DrawPaint(paint);
1456  builder.Restore();
1457 
1458  paint.setColor(DlColor::kBlue());
1459  paint.setBlendMode(DlBlendMode::kDstOver);
1460  builder.SaveLayer(std::nullopt, &paint);
1461  builder.Restore();
1462 
1463  // This playground should appear blank on CI since we are only drawing
1464  // transparent black. If the clear color optimization is broken, the texture
1465  // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
1466  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1467 }

◆ TEST_P() [294/545]

impeller::testing::TEST_P ( AiksTest  ,
SupportsBlitToOnscreen   
)

Definition at line 377 of file canvas_unittests.cc.

377  {
378  ContentContext context(GetContext(), nullptr);
379  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
380  /*requires_readback=*/true);
381 
382  if (GetBackend() != PlaygroundBackend::kMetal) {
383  EXPECT_FALSE(canvas->SupportsBlitToOnscreen());
384  } else {
385  EXPECT_TRUE(canvas->SupportsBlitToOnscreen());
386  }
387 }

References CreateTestCanvas(), impeller::kMetal, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [295/545]

impeller::testing::TEST_P ( AiksTest  ,
TextContentsMismatchedTransformTest   
)

Definition at line 707 of file aiks_dl_text_unittests.cc.

707  {
708  AiksContext aiks_context(GetContext(),
709  std::make_shared<TypographerContextSkia>());
710 
711  // Verifies that TextContents only use the scale/transform that is
712  // computed during preroll.
713  constexpr const char* font_fixture = "Roboto-Regular.ttf";
714 
715  // Construct the text blob.
716  auto c_font_fixture = std::string(font_fixture);
717  auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
718  ASSERT_TRUE(mapping);
719 
720  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
721  SkFont sk_font(font_mgr->makeFromData(mapping), 16);
722 
723  auto blob = SkTextBlob::MakeFromString("Hello World", sk_font);
724  ASSERT_TRUE(blob);
725 
726  auto text_frame = MakeTextFrameFromTextBlobSkia(blob);
727 
728  // Simulate recording the text frame during preroll.
729  Matrix preroll_matrix =
730  Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
731  Point preroll_point = Point{23, 45};
732  {
733  auto scale = TextFrame::RoundScaledFontSize(
734  (preroll_matrix * Matrix::MakeTranslation(preroll_point))
735  .GetMaxBasisLengthXY());
736 
737  aiks_context.GetContentContext().GetLazyGlyphAtlas()->AddTextFrame(
738  text_frame, //
739  scale, //
740  preroll_point, //
741  preroll_matrix,
742  std::nullopt //
743  );
744  }
745 
746  // Now simulate rendering with a slightly different scale factor.
747  RenderTarget render_target =
748  aiks_context.GetContentContext()
749  .GetRenderTargetCache()
750  ->CreateOffscreenMSAA(*aiks_context.GetContext(), {100, 100}, 1);
751 
752  TextContents text_contents;
753  text_contents.SetTextFrame(text_frame);
754  text_contents.SetOffset(preroll_point);
755  text_contents.SetScale(1.6);
756  text_contents.SetColor(Color::Aqua());
757 
758  Matrix not_preroll_matrix =
759  Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
760 
761  Entity entity;
762  entity.SetTransform(not_preroll_matrix);
763 
764  std::shared_ptr<CommandBuffer> command_buffer =
765  aiks_context.GetContext()->CreateCommandBuffer();
766  std::shared_ptr<RenderPass> render_pass =
767  command_buffer->CreateRenderPass(render_target);
768 
769  EXPECT_TRUE(text_contents.Render(aiks_context.GetContentContext(), entity,
770  *render_pass));
771 }

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() [296/545]

impeller::testing::TEST_P ( AiksTest  ,
TextForegroundShaderWithTransform   
)

Definition at line 592 of file aiks_dl_text_unittests.cc.

592  {
593  auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
594  ASSERT_NE(mapping, nullptr);
595 
596  Scalar font_size = 100;
597  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
598  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
599 
600  DlPaint text_paint;
601  text_paint.setColor(DlColor::kBlue());
602 
603  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
604  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
605  std::vector<Scalar> stops = {
606  0.0,
607  1.0,
608  };
609  text_paint.setColorSource(DlColorSource::MakeLinear(
610  /*start_point=*/DlPoint(0, 0), //
611  /*end_point=*/DlPoint(100, 100), //
612  /*stop_count=*/2, //
613  /*colors=*/colors.data(), //
614  /*stops=*/stops.data(), //
615  /*tile_mode=*/DlTileMode::kRepeat //
616  ));
617 
618  DisplayListBuilder builder;
619  builder.Translate(100, 100);
620  builder.Rotate(45);
621 
622  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
623  ASSERT_NE(blob, nullptr);
624  auto frame = MakeTextFrameFromTextBlobSkia(blob);
625  builder.DrawTextFrame(frame, 0, 0, text_paint);
626 
627  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
628 }

References font_size, and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [297/545]

impeller::testing::TEST_P ( AiksTest  ,
TextFrameSubpixelAlignment   
)

Definition at line 316 of file aiks_dl_text_unittests.cc.

316  {
317  // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
318  std::array<Scalar, 20> phase_offsets = {
319  7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
320  0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
321  0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
322  0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
323  auto callback = [&]() -> sk_sp<DisplayList> {
324  static float font_size = 20;
325  static float phase_variation = 0.2;
326  static float speed = 0.5;
327  static float magnitude = 100;
328  if (AiksTest::ImGuiBegin("Controls", nullptr,
329  ImGuiWindowFlags_AlwaysAutoResize)) {
330  ImGui::SliderFloat("Font size", &font_size, 5, 50);
331  ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
332  ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
333  ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
334  ImGui::End();
335  }
336 
337  DisplayListBuilder builder;
338  builder.Scale(GetContentScale().x, GetContentScale().y);
339 
340  for (size_t i = 0; i < phase_offsets.size(); i++) {
341  DlPoint position = DlPoint(
342  200 +
343  magnitude * std::sin((-phase_offsets[i] * k2Pi * phase_variation +
344  GetSecondsElapsed() * speed)), //
345  200 + i * font_size * 1.1 //
346  );
348  GetContext(), builder,
349  "the quick brown fox jumped over "
350  "the lazy dog!.?",
351  "Roboto-Regular.ttf",
352  {.font_size = font_size, .position = position})) {
353  return nullptr;
354  }
355  }
356  return builder.Build();
357  };
358 
359  ASSERT_TRUE(OpenPlaygroundHere(callback));
360 }

References font_size, impeller::k2Pi, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [298/545]

impeller::testing::TEST_P ( AiksTest  ,
TextRotated   
)

Definition at line 488 of file aiks_dl_text_unittests.cc.

488  {
489  DisplayListBuilder builder;
490 
491  builder.Scale(GetContentScale().x, GetContentScale().y);
492  DlPaint paint;
493  paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
494  builder.DrawPaint(paint);
495 
496  builder.Transform(Matrix(0.25, -0.3, 0, -0.002, //
497  0, 0.5, 0, 0, //
498  0, 0, 0.3, 0, //
499  100, 100, 0, 1.3));
500  ASSERT_TRUE(RenderTextInCanvasSkia(
501  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
502  "Roboto-Regular.ttf"));
503 
504  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
505 }

References RenderTextInCanvasSkia(), and x.

◆ TEST_P() [299/545]

impeller::testing::TEST_P ( AiksTest  ,
TextRotated180Degrees   
)

Definition at line 279 of file aiks_dl_text_unittests.cc.

279  {
280  float fpivot[2] = {200 + 30, 200 - 20};
281  float rotation = 180;
282  float foffset[2] = {200, 200};
283 
284  auto callback = [&]() -> sk_sp<DisplayList> {
285  if (AiksTest::ImGuiBegin("Controls", nullptr,
286  ImGuiWindowFlags_AlwaysAutoResize)) {
287  ImGui::SliderFloat("pivotx", &fpivot[0], 0, 300);
288  ImGui::SliderFloat("pivoty", &fpivot[1], 0, 300);
289  ImGui::SliderFloat("rotation", &rotation, 0, 360);
290  ImGui::SliderFloat("foffsetx", &foffset[0], 0, 300);
291  ImGui::SliderFloat("foffsety", &foffset[1], 0, 300);
292  ImGui::End();
293  }
294  DisplayListBuilder builder;
295  builder.Scale(GetContentScale().x, GetContentScale().y);
296  builder.DrawPaint(DlPaint().setColor(DlColor(0xffffeeff)));
297 
298  builder.Save();
299  DlPoint pivot = Point(fpivot[0], fpivot[1]);
300  builder.Translate(pivot.x, pivot.y);
301  builder.Rotate(rotation);
302  builder.Translate(-pivot.x, -pivot.y);
303 
304  RenderTextInCanvasSkia(GetContext(), builder, "test", "Roboto-Regular.ttf",
305  TextRenderOptions{
306  .color = DlColor::kBlack(),
307  .position = DlPoint(foffset[0], foffset[1]),
308  });
309 
310  builder.Restore();
311  return builder.Build();
312  };
313  ASSERT_TRUE(OpenPlaygroundHere(callback));
314 }

References impeller::testing::TextRenderOptions::color, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [300/545]

impeller::testing::TEST_P ( AiksTest  ,
TextWithShadowCache   
)

Definition at line 773 of file aiks_dl_text_unittests.cc.

773  {
774  DisplayListBuilder builder;
775  builder.Scale(GetContentScale().x, GetContentScale().y);
776  DlPaint paint;
777  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
778  builder.DrawPaint(paint);
779 
780  AiksContext aiks_context(GetContext(),
781  std::make_shared<TypographerContextSkia>());
782  // Cache empty
783  EXPECT_EQ(aiks_context.GetContentContext()
784  .GetTextShadowCache()
785  .GetCacheSizeForTesting(),
786  0u);
787 
788  ASSERT_TRUE(RenderTextInCanvasSkia(
789  GetContext(), builder, "Hello World", kFontFixture,
790  TextRenderOptions{
791  .color = DlColor::kBlue(),
792  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
793 
794  DisplayListToTexture(builder.Build(), {400, 400}, aiks_context);
795 
796  // Text should be cached.
797  EXPECT_EQ(aiks_context.GetContentContext()
798  .GetTextShadowCache()
799  .GetCacheSizeForTesting(),
800  1u);
801 }

References impeller::testing::TextRenderOptions::color, impeller::DisplayListToTexture(), impeller::TextShadowCache::GetCacheSizeForTesting(), impeller::AiksContext::GetContentContext(), impeller::ContentContext::GetTextShadowCache(), kFontFixture, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [301/545]

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() [302/545]

impeller::testing::TEST_P ( AiksTest  ,
TransformMultipliesCorrectly   
)

Definition at line 70 of file canvas_unittests.cc.

70  {
71  ContentContext context(GetContext(), nullptr);
72  auto canvas = CreateTestCanvas(context);
73 
74  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(), Matrix());
75 
76  // clang-format off
77  canvas->Translate(Vector3(100, 200));
79  canvas->GetCurrentTransform(),
80  Matrix( 1, 0, 0, 0,
81  0, 1, 0, 0,
82  0, 0, 1, 0,
83  100, 200, 0, 1));
84 
85  canvas->Rotate(Radians(kPiOver2));
87  canvas->GetCurrentTransform(),
88  Matrix( 0, 1, 0, 0,
89  -1, 0, 0, 0,
90  0, 0, 1, 0,
91  100, 200, 0, 1));
92 
93  canvas->Scale(Vector3(2, 3));
95  canvas->GetCurrentTransform(),
96  Matrix( 0, 2, 0, 0,
97  -3, 0, 0, 0,
98  0, 0, 0, 0,
99  100, 200, 0, 1));
100 
101  canvas->Translate(Vector3(100, 200));
103  canvas->GetCurrentTransform(),
104  Matrix( 0, 2, 0, 0,
105  -3, 0, 0, 0,
106  0, 0, 0, 0,
107  -500, 400, 0, 1));
108  // clang-format on
109 }

References ASSERT_MATRIX_NEAR, CreateTestCanvas(), and impeller::kPiOver2.

◆ TEST_P() [303/545]

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() [304/545]

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() [305/545]

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() [306/545]

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() [307/545]

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() [308/545]

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() [309/545]

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() [310/545]

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() [311/545]

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() [312/545]

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() [313/545]

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() [314/545]

impeller::testing::TEST_P ( AiksTest  ,
VarietyOfTextScalesShowingRasterAndPath   
)

Definition at line 876 of file aiks_dl_text_unittests.cc.

876  {
877  DisplayListBuilder builder;
878  DlPaint paint;
879  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
880  builder.DrawPaint(paint);
881  builder.Scale(GetContentScale().x, GetContentScale().y);
882 
883  std::vector<Scalar> scales = {4, 8, 16, 24, 32};
884  std::vector<Scalar> spacing = {8, 8, 8, 8, 8};
885  Scalar space = 16;
886  Scalar x = 0;
887  for (auto i = 0u; i < scales.size(); i++) {
888  builder.Save();
889  builder.Scale(scales[i], scales[i]);
891  GetContext(), builder, "lo", "Roboto-Regular.ttf",
892  TextRenderOptions{.font_size = 16, .position = DlPoint(x, space)});
893  space += spacing[i];
894  if (i == 3) {
895  x = 10;
896  space = 16;
897  }
898  builder.Restore();
899  }
900  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
901 }

References impeller::testing::TextRenderOptions::font_size, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [315/545]

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() [316/545]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryColorUVPositionData   
)

Definition at line 97 of file aiks_dl_vertices_unittests.cc.

97  {
98  DisplayListBuilder builder;
99  DlPaint paint;
100  auto image =
101  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
102  auto size = image->impeller_texture()->GetSize();
103 
104  paint.setColorSource(
105  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp));
106 
107  std::vector<DlPoint> positions = {
108  DlPoint(0, 0), DlPoint(size.width, 0),
109  DlPoint(0, size.height), DlPoint(size.width, 0),
110  DlPoint(0, 0), DlPoint(size.width, size.height),
111  };
112  std::vector<DlColor> colors = {
113  DlColor::kRed().withAlpha(128), DlColor::kBlue().withAlpha(128),
114  DlColor::kGreen().withAlpha(128), DlColor::kRed().withAlpha(128),
115  DlColor::kBlue().withAlpha(128), DlColor::kGreen().withAlpha(128),
116  };
117 
118  auto vertices =
119  MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
120 
121  builder.DrawVertices(vertices, DlBlendMode::kDstOver, paint);
122  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
123 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [317/545]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryColorUVPositionDataAdvancedBlend   
)

Definition at line 125 of file aiks_dl_vertices_unittests.cc.

125  {
126  DisplayListBuilder builder;
127  DlPaint paint;
128  auto image =
129  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
130  auto size = image->impeller_texture()->GetSize();
131 
132  paint.setColorSource(
133  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp));
134 
135  std::vector<DlPoint> positions = {
136  DlPoint(0, 0), DlPoint(size.width, 0),
137  DlPoint(0, size.height), DlPoint(size.width, 0),
138  DlPoint(0, 0), DlPoint(size.width, size.height),
139  };
140  std::vector<DlColor> colors = {
141  DlColor::kRed().modulateOpacity(0.5),
142  DlColor::kBlue().modulateOpacity(0.5),
143  DlColor::kGreen().modulateOpacity(0.5),
144  DlColor::kRed().modulateOpacity(0.5),
145  DlColor::kBlue().modulateOpacity(0.5),
146  DlColor::kGreen().modulateOpacity(0.5),
147  };
148 
149  auto vertices =
150  MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
151 
152  builder.DrawVertices(vertices, DlBlendMode::kColorBurn, paint);
153  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
154 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [318/545]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionData   
)

Definition at line 49 of file aiks_dl_vertices_unittests.cc.

49  {
50  DisplayListBuilder builder;
51  DlPaint paint;
52  auto image =
53  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
54  auto size = image->impeller_texture()->GetSize();
55 
56  paint.setColorSource(
57  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp));
58 
59  std::vector<DlPoint> vertex_coordinates = {
60  DlPoint(0, 0),
61  DlPoint(size.width, 0),
62  DlPoint(0, size.height),
63  };
64  auto vertices = MakeVertices(DlVertexMode::kTriangleStrip, vertex_coordinates,
65  {0, 1, 2}, {}, {});
66 
67  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
68  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
69 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [319/545]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionDataWithTranslate   
)

Definition at line 72 of file aiks_dl_vertices_unittests.cc.

72  {
73  DisplayListBuilder builder;
74  DlPaint paint;
75  auto image =
76  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
77  auto size = image->impeller_texture()->GetSize();
78 
79  DlMatrix matrix = DlMatrix::MakeTranslation({100, 100});
80  paint.setColorSource(
81  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp,
82  DlImageSampling::kLinear, &matrix));
83 
84  std::vector<DlPoint> positions = {
85  DlPoint(0, 0),
86  DlPoint(size.width, 0),
87  DlPoint(0, size.height),
88  };
89  auto vertices =
90  MakeVertices(DlVertexMode::kTriangleStrip, positions, {0, 1, 2}, {}, {});
91 
92  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
93  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
94 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [320/545]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryWithMaskFilter   
)

Definition at line 555 of file aiks_dl_vertices_unittests.cc.

555  {
556  DisplayListBuilder builder;
557  DlPaint paint;
558  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 10));
559 
560  std::vector<DlPoint> vertex_coordinates = {
561  DlPoint(0, 0),
562  DlPoint(400, 0),
563  DlPoint(0, 400),
564  };
565  auto vertices = MakeVertices(DlVertexMode::kTriangleStrip, vertex_coordinates,
566  {0, 1, 2}, {}, {});
567 
568  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
569  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
570 }

◆ TEST_P() [321/545]

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() [322/545]

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() [323/545]

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 =
56  renderer->GetTransientsBuffer().Emplace(&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() [324/545]

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() [325/545]

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() [326/545]

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() [327/545]

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() [328/545]

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() [329/545]

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() [330/545]

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() [331/545]

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() [332/545]

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() [333/545]

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() [334/545]

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() [335/545]

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() [336/545]

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() [337/545]

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() [338/545]

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() [339/545]

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() [340/545]

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() [341/545]

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() [342/545]

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() [343/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanBlendDstOverAndDstCorrectly   
)

Definition at line 1176 of file dl_unittests.cc.

1176  {
1177  flutter::DisplayListBuilder builder;
1178 
1179  {
1180  builder.SaveLayer(std::nullopt, nullptr);
1181  builder.Translate(100, 100);
1182  flutter::DlPaint paint;
1183  paint.setColor(flutter::DlColor::kRed());
1184  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1185  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1186  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1187  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1188  builder.Restore();
1189  }
1190  {
1191  builder.SaveLayer(std::nullopt, nullptr);
1192  builder.Translate(300, 100);
1193  flutter::DlPaint paint;
1194  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1195  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1196  paint.setColor(flutter::DlColor::kRed());
1197  paint.setBlendMode(flutter::DlBlendMode::kDstOver);
1198  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1199  builder.Restore();
1200  }
1201  {
1202  builder.SaveLayer(std::nullopt, nullptr);
1203  builder.Translate(100, 300);
1204  flutter::DlPaint paint;
1205  paint.setColor(flutter::DlColor::kRed());
1206  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1207  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1208  paint.setBlendMode(flutter::DlBlendMode::kSrc);
1209  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1210  builder.Restore();
1211  }
1212  {
1213  builder.SaveLayer(std::nullopt, nullptr);
1214  builder.Translate(300, 300);
1215  flutter::DlPaint paint;
1216  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1217  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1218  paint.setColor(flutter::DlColor::kRed());
1219  paint.setBlendMode(flutter::DlBlendMode::kDst);
1220  builder.DrawRect(DlRect::MakeWH(200, 200), paint);
1221  builder.Restore();
1222  }
1223 
1224  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1225 }

◆ TEST_P() [344/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanClampTheResultingColorOfColorMatrixFilter   
)

Definition at line 622 of file dl_unittests.cc.

622  {
623  auto texture = CreateTextureForFixture("boston.jpg");
624  const float inner_color_matrix[20] = {
625  1, 0, 0, 0, 0, //
626  0, 1, 0, 0, 0, //
627  0, 0, 1, 0, 0, //
628  0, 0, 0, 2, 0, //
629  };
630  const float outer_color_matrix[20] = {
631  1, 0, 0, 0, 0, //
632  0, 1, 0, 0, 0, //
633  0, 0, 1, 0, 0, //
634  0, 0, 0, 0.5, 0, //
635  };
636  auto inner_color_filter =
637  flutter::DlColorFilter::MakeMatrix(inner_color_matrix);
638  auto outer_color_filter =
639  flutter::DlColorFilter::MakeMatrix(outer_color_matrix);
640  auto inner = flutter::DlImageFilter::MakeColorFilter(inner_color_filter);
641  auto outer = flutter::DlImageFilter::MakeColorFilter(outer_color_filter);
642  auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
643 
644  flutter::DisplayListBuilder builder;
645  flutter::DlPaint paint;
646  paint.setImageFilter(compose.get());
647  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
648  flutter::DlImageSampling::kNearestNeighbor, &paint);
649  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
650 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [345/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawAnOpenPath   
)

Definition at line 414 of file dl_unittests.cc.

414  {
415  flutter::DisplayListBuilder builder;
416  flutter::DlPaint paint;
417 
418  paint.setColor(flutter::DlColor::kRed());
419  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
420  paint.setStrokeWidth(10);
421 
422  builder.Translate(300, 300);
423 
424  // Move to (50, 50) and draw lines from:
425  // 1. (50, height)
426  // 2. (width, height)
427  // 3. (width, 50)
428  flutter::DlPathBuilder path_builder;
429  path_builder.MoveTo(DlPoint(50, 50));
430  path_builder.LineTo(DlPoint(50, 100));
431  path_builder.LineTo(DlPoint(100, 100));
432  path_builder.LineTo(DlPoint(100, 50));
433  builder.DrawPath(path_builder.TakePath(), paint);
434 
435  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
436 }

◆ TEST_P() [346/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawArc   
)

Definition at line 152 of file dl_unittests.cc.

152  {
153  auto callback = [&]() {
154  static float start_angle = 45;
155  static float sweep_angle = 270;
156  static float stroke_width = 10;
157  static bool use_center = true;
158 
159  static int selected_cap = 0;
160  const char* cap_names[] = {"Butt", "Round", "Square"};
161  flutter::DlStrokeCap cap;
162 
163  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
164  ImGui::SliderFloat("Start angle", &start_angle, -360, 360);
165  ImGui::SliderFloat("Sweep angle", &sweep_angle, -360, 360);
166  ImGui::SliderFloat("Stroke width", &stroke_width, 0, 300);
167  ImGui::Combo("Cap", &selected_cap, cap_names,
168  sizeof(cap_names) / sizeof(char*));
169  ImGui::Checkbox("Use center", &use_center);
170  ImGui::End();
171 
172  switch (selected_cap) {
173  case 0:
174  cap = flutter::DlStrokeCap::kButt;
175  break;
176  case 1:
177  cap = flutter::DlStrokeCap::kRound;
178  break;
179  case 2:
180  cap = flutter::DlStrokeCap::kSquare;
181  break;
182  default:
183  cap = flutter::DlStrokeCap::kButt;
184  break;
185  }
186 
187  static PlaygroundPoint point_a(Point(200, 200), 20, Color::White());
188  static PlaygroundPoint point_b(Point(400, 400), 20, Color::White());
189  auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
190 
191  flutter::DisplayListBuilder builder;
192  flutter::DlPaint paint;
193 
194  Vector2 scale = GetContentScale();
195  builder.Scale(scale.x, scale.y);
196  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
197  paint.setStrokeCap(cap);
198  paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
199  paint.setStrokeMiter(10);
200  auto rect = DlRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
201  paint.setColor(flutter::DlColor::kGreen());
202  paint.setStrokeWidth(2);
203  builder.DrawRect(rect, paint);
204  paint.setColor(flutter::DlColor::kRed());
205  paint.setStrokeWidth(stroke_width);
206  builder.DrawArc(rect, start_angle, sweep_angle, use_center, paint);
207 
208  return builder.Build();
209  };
210  ASSERT_TRUE(OpenPlaygroundHere(callback));
211 }
bool use_center

References impeller::DrawPlaygroundLine(), use_center, impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [347/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawBackdropFilter   
)

Definition at line 652 of file dl_unittests.cc.

652  {
653  auto texture = CreateTextureForFixture("embarcadero.jpg");
654 
655  auto callback = [&]() {
656  static float sigma[] = {10, 10};
657  static float ctm_scale = 1;
658  static bool use_bounds = true;
659  static bool draw_circle = true;
660  static bool add_clip = true;
661 
662  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
663  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
664  ImGui::SliderFloat("Scale", &ctm_scale, 0, 10);
665  ImGui::NewLine();
666  ImGui::TextWrapped(
667  "If everything is working correctly, none of the options below should "
668  "impact the filter's appearance.");
669  ImGui::Checkbox("Use SaveLayer bounds", &use_bounds);
670  ImGui::Checkbox("Draw child element", &draw_circle);
671  ImGui::Checkbox("Add pre-clip", &add_clip);
672  ImGui::End();
673 
674  flutter::DisplayListBuilder builder;
675 
676  Vector2 scale = ctm_scale * GetContentScale();
677  builder.Scale(scale.x, scale.y);
678 
679  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
680  flutter::DlTileMode::kClamp);
681 
682  std::optional<DlRect> bounds;
683  if (use_bounds) {
684  static PlaygroundPoint point_a(Point(350, 150), 20, Color::White());
685  static PlaygroundPoint point_b(Point(800, 600), 20, Color::White());
686  auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
687  bounds = DlRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
688  }
689 
690  // Insert a clip to test that the backdrop filter handles stencil depths > 0
691  // correctly.
692  if (add_clip) {
693  builder.ClipRect(DlRect::MakeLTRB(0, 0, 99999, 99999),
694  flutter::DlClipOp::kIntersect, true);
695  }
696 
697  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(200, 200),
698  flutter::DlImageSampling::kNearestNeighbor, nullptr);
699  builder.SaveLayer(bounds, nullptr, &filter);
700 
701  if (draw_circle) {
702  static PlaygroundPoint center_point(Point(500, 400), 20, Color::Red());
703  auto circle_center = DrawPlaygroundPoint(center_point);
704 
705  flutter::DlPaint paint;
706  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
707  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
708  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
709  paint.setStrokeWidth(10);
710  paint.setColor(flutter::DlColor::kRed().withAlpha(100));
711  builder.DrawCircle(DlPoint(circle_center.x, circle_center.y), 100, paint);
712  }
713 
714  return builder.Build();
715  };
716 
717  ASSERT_TRUE(OpenPlaygroundHere(callback));
718 }

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() [348/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCapsAndJoins   
)

Definition at line 103 of file dl_unittests.cc.

103  {
104  flutter::DisplayListBuilder builder;
105  flutter::DlPaint paint;
106 
107  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
108  paint.setStrokeWidth(30);
109  paint.setColor(flutter::DlColor::kRed());
110 
111  flutter::DlPathBuilder path_builder;
112  path_builder.MoveTo(DlPoint(-50, 0));
113  path_builder.LineTo(DlPoint(0, -50));
114  path_builder.LineTo(DlPoint(50, 0));
115  flutter::DlPath path = path_builder.TakePath();
116 
117  builder.Translate(100, 100);
118  {
119  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
120  paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
121  paint.setStrokeMiter(4);
122  builder.DrawPath(path, paint);
123  }
124 
125  {
126  builder.Save();
127  builder.Translate(0, 100);
128  // The joint in the path is 45 degrees. A miter length of 1 convert to a
129  // bevel in this case.
130  paint.setStrokeMiter(1);
131  builder.DrawPath(path, paint);
132  builder.Restore();
133  }
134 
135  builder.Translate(150, 0);
136  {
137  paint.setStrokeCap(flutter::DlStrokeCap::kSquare);
138  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
139  builder.DrawPath(path, paint);
140  }
141 
142  builder.Translate(150, 0);
143  {
144  paint.setStrokeCap(flutter::DlStrokeCap::kRound);
145  paint.setStrokeJoin(flutter::DlStrokeJoin::kRound);
146  builder.DrawPath(path, paint);
147  }
148 
149  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
150 }

◆ TEST_P() [349/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCorrectlyWithColorFilterAndImageFilter   
)

Definition at line 1227 of file dl_unittests.cc.

1227  {
1228  flutter::DisplayListBuilder builder;
1229  const float green_color_matrix[20] = {
1230  0, 0, 0, 0, 0, //
1231  0, 0, 0, 0, 1, //
1232  0, 0, 0, 0, 0, //
1233  0, 0, 0, 1, 0, //
1234  };
1235  const float blue_color_matrix[20] = {
1236  0, 0, 0, 0, 0, //
1237  0, 0, 0, 0, 0, //
1238  0, 0, 0, 0, 1, //
1239  0, 0, 0, 1, 0, //
1240  };
1241  auto green_color_filter =
1242  flutter::DlColorFilter::MakeMatrix(green_color_matrix);
1243  auto blue_color_filter =
1244  flutter::DlColorFilter::MakeMatrix(blue_color_matrix);
1245  auto blue_image_filter =
1246  flutter::DlImageFilter::MakeColorFilter(blue_color_filter);
1247 
1248  flutter::DlPaint paint;
1249  paint.setColor(flutter::DlColor::kRed());
1250  paint.setColorFilter(green_color_filter);
1251  paint.setImageFilter(blue_image_filter);
1252  builder.DrawRect(DlRect::MakeLTRB(100, 100, 500, 500), paint);
1253  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1254 }

◆ TEST_P() [350/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawImage   
)

Definition at line 95 of file dl_unittests.cc.

95  {
96  auto texture = CreateTextureForFixture("embarcadero.jpg");
97  flutter::DisplayListBuilder builder;
98  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
99  flutter::DlImageSampling::kNearestNeighbor, nullptr);
100  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
101 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [351/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImage   
)

Definition at line 720 of file dl_unittests.cc.

720  {
721  // Image is drawn with corners to scale and center pieces stretched to fit.
722  auto texture = CreateTextureForFixture("embarcadero.jpg");
723  flutter::DisplayListBuilder builder;
724  auto size = texture->GetSize();
725  builder.DrawImageNine(
726  DlImageImpeller::Make(texture),
727  DlIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
728  size.height * 3 / 4),
729  DlRect::MakeLTRB(0, 0, size.width * 2, size.height * 2),
730  flutter::DlFilterMode::kNearest, nullptr);
731  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
732 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [352/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterBiggerThanDest   
)

Definition at line 766 of file dl_unittests.cc.

766  {
767  // Edge case, the width and height of the corners does not leave any
768  // room for the center slices. Only the corners are displayed.
769  auto texture = CreateTextureForFixture("embarcadero.jpg");
770  flutter::DisplayListBuilder builder;
771  auto size = texture->GetSize();
772  builder.DrawImageNine(
773  DlImageImpeller::Make(texture),
774  DlIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
775  size.height * 3 / 4),
776  DlRect::MakeLTRB(0, 0, size.width / 2, size.height / 2),
777  flutter::DlFilterMode::kNearest, nullptr);
778  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
779 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [353/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterHeightBiggerThanDest   
)

Definition at line 750 of file dl_unittests.cc.

750  {
751  // Edge case, the height of the corners does not leave any room for the
752  // center slice. The center (across the horizontal axis) is folded out of the
753  // resulting image.
754  auto texture = CreateTextureForFixture("embarcadero.jpg");
755  flutter::DisplayListBuilder builder;
756  auto size = texture->GetSize();
757  builder.DrawImageNine(
758  DlImageImpeller::Make(texture),
759  DlIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
760  size.height * 3 / 4),
761  DlRect::MakeLTRB(0, 0, size.width, size.height / 2),
762  flutter::DlFilterMode::kNearest, nullptr);
763  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
764 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [354/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterWidthBiggerThanDest   
)

Definition at line 734 of file dl_unittests.cc.

734  {
735  // Edge case, the width of the corners does not leave any room for the
736  // center slice. The center (across the vertical axis) is folded out of the
737  // resulting image.
738  auto texture = CreateTextureForFixture("embarcadero.jpg");
739  flutter::DisplayListBuilder builder;
740  auto size = texture->GetSize();
741  builder.DrawImageNine(
742  DlImageImpeller::Make(texture),
743  DlIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
744  size.height * 3 / 4),
745  DlRect::MakeLTRB(0, 0, size.width / 2, size.height),
746  flutter::DlFilterMode::kNearest, nullptr);
747  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
748 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [355/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCornersScaledDown   
)

Definition at line 781 of file dl_unittests.cc.

781  {
782  // Edge case, there is not enough room for the corners to be drawn
783  // without scaling them down.
784  auto texture = CreateTextureForFixture("embarcadero.jpg");
785  flutter::DisplayListBuilder builder;
786  auto size = texture->GetSize();
787  builder.DrawImageNine(
788  DlImageImpeller::Make(texture),
789  DlIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
790  size.height * 3 / 4),
791  DlRect::MakeLTRB(0, 0, size.width / 4, size.height / 4),
792  flutter::DlFilterMode::kNearest, nullptr);
793  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
794 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [356/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPaintWithColorSource   
)

Definition at line 1124 of file dl_unittests.cc.

1124  {
1125  const flutter::DlColor colors[2] = {
1126  flutter::DlColor(0xFFF44336),
1127  flutter::DlColor(0xFF2196F3),
1128  };
1129  const float stops[2] = {0.0, 1.0};
1130  flutter::DlPaint paint;
1131  flutter::DisplayListBuilder builder;
1132  auto clip_bounds = DlRect::MakeWH(300.0, 300.0);
1133  builder.Save();
1134  builder.Translate(100, 100);
1135  builder.ClipRect(clip_bounds, flutter::DlClipOp::kIntersect, false);
1136  auto linear =
1137  flutter::DlColorSource::MakeLinear({0.0, 0.0}, {100.0, 100.0}, 2, colors,
1138  stops, flutter::DlTileMode::kRepeat);
1139  paint.setColorSource(linear);
1140  builder.DrawPaint(paint);
1141  builder.Restore();
1142 
1143  builder.Save();
1144  builder.Translate(500, 100);
1145  builder.ClipRect(clip_bounds, flutter::DlClipOp::kIntersect, false);
1146  auto radial = flutter::DlColorSource::MakeRadial(
1147  {100.0, 100.0}, 100.0, 2, colors, stops, flutter::DlTileMode::kRepeat);
1148  paint.setColorSource(radial);
1149  builder.DrawPaint(paint);
1150  builder.Restore();
1151 
1152  builder.Save();
1153  builder.Translate(100, 500);
1154  builder.ClipRect(clip_bounds, flutter::DlClipOp::kIntersect, false);
1155  auto sweep =
1156  flutter::DlColorSource::MakeSweep({100.0, 100.0}, 180.0, 270.0, 2, colors,
1157  stops, flutter::DlTileMode::kRepeat);
1158  paint.setColorSource(sweep);
1159  builder.DrawPaint(paint);
1160  builder.Restore();
1161 
1162  builder.Save();
1163  builder.Translate(500, 500);
1164  builder.ClipRect(clip_bounds, flutter::DlClipOp::kIntersect, false);
1165  auto texture = CreateTextureForFixture("table_mountain_nx.png");
1166  auto image = flutter::DlColorSource::MakeImage(DlImageImpeller::Make(texture),
1167  flutter::DlTileMode::kRepeat,
1168  flutter::DlTileMode::kRepeat);
1169  paint.setColorSource(image);
1170  builder.DrawPaint(paint);
1171  builder.Restore();
1172 
1173  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1174 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [357/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPoints   
)

Definition at line 808 of file dl_unittests.cc.

808  {
809  flutter::DisplayListBuilder builder;
810  DlPoint points[7] = {
811  {0, 0}, //
812  {100, 100}, //
813  {100, 0}, //
814  {0, 100}, //
815  {0, 0}, //
816  {48, 48}, //
817  {52, 52}, //
818  };
819  std::vector<flutter::DlStrokeCap> caps = {
820  flutter::DlStrokeCap::kButt,
821  flutter::DlStrokeCap::kRound,
822  flutter::DlStrokeCap::kSquare,
823  };
824  flutter::DlPaint paint =
825  flutter::DlPaint() //
826  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
827  .setStrokeWidth(20);
828  builder.Translate(50, 50);
829  for (auto cap : caps) {
830  paint.setStrokeCap(cap);
831  builder.Save();
832  builder.DrawPoints(flutter::DlPointMode::kPoints, 7, points, paint);
833  builder.Translate(150, 0);
834  builder.DrawPoints(flutter::DlPointMode::kLines, 5, points, paint);
835  builder.Translate(150, 0);
836  builder.DrawPoints(flutter::DlPointMode::kPolygon, 5, points, paint);
837  builder.Restore();
838  builder.Translate(0, 150);
839  }
840  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
841 }

References points.

◆ TEST_P() [358/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRect   
)

Definition at line 46 of file dl_unittests.cc.

46  {
47  flutter::DisplayListBuilder builder;
48  builder.DrawRect(DlRect::MakeXYWH(10, 10, 100, 100),
49  flutter::DlPaint(flutter::DlColor::kBlue()));
50  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
51 }

◆ TEST_P() [359/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRectWithLinearToSrgbColorFilter   
)

Definition at line 1110 of file dl_unittests.cc.

1110  {
1111  flutter::DlPaint paint;
1112  paint.setColor(flutter::DlColor(0xFF2196F3).withAlpha(128));
1113  flutter::DisplayListBuilder builder;
1114  paint.setColorFilter(flutter::DlColorFilter::MakeLinearToSrgbGamma());
1115  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), paint);
1116  builder.Translate(0, 200);
1117 
1118  paint.setColorFilter(flutter::DlColorFilter::MakeSrgbToLinearGamma());
1119  builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), paint);
1120 
1121  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1122 }

◆ TEST_P() [360/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawShadow   
)

Definition at line 866 of file dl_unittests.cc.

866  {
867  flutter::DisplayListBuilder builder;
868  flutter::DlPaint paint;
869 
870  auto content_scale = GetContentScale() * 0.8;
871  builder.Scale(content_scale.x, content_scale.y);
872 
873  constexpr size_t star_spikes = 5;
874  constexpr DlScalar half_spike_rotation = kPi / star_spikes;
875  constexpr DlScalar radius = 40;
876  constexpr DlScalar spike_size = 10;
877  constexpr DlScalar outer_radius = radius + spike_size;
878  constexpr DlScalar inner_radius = radius - spike_size;
879  std::array<DlPoint, star_spikes * 2> star;
880  for (size_t i = 0; i < star_spikes; i++) {
881  const DlScalar rotation = half_spike_rotation * i * 2;
882  star[i * 2] = DlPoint(50 + std::sin(rotation) * outer_radius,
883  50 - std::cos(rotation) * outer_radius);
884  star[i * 2 + 1] =
885  DlPoint(50 + std::sin(rotation + half_spike_rotation) * inner_radius,
886  50 - std::cos(rotation + half_spike_rotation) * inner_radius);
887  }
888 
889  std::array<DlPath, 4> paths = {
890  DlPath::MakeRect(DlRect::MakeXYWH(0, 0, 200, 100)),
891  DlPath::MakeRoundRectXY(DlRect::MakeXYWH(20, 0, 200, 100), 30, 30),
892  DlPath::MakeCircle(DlPoint(100, 50), 50),
893  DlPath::MakePoly(star.data(), star.size(), true),
894  };
895  paint.setColor(flutter::DlColor::kWhite());
896  builder.DrawPaint(paint);
897  paint.setColor(flutter::DlColor::kCyan());
898  builder.Translate(100, 50);
899  for (size_t x = 0; x < paths.size(); x++) {
900  builder.Save();
901  for (size_t y = 0; y < 6; y++) {
902  builder.DrawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
903  1);
904  builder.DrawPath(paths[x], paint);
905  builder.Translate(0, 150);
906  }
907  builder.Restore();
908  builder.Translate(250, 0);
909  }
910 
911  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
912 }

References impeller::kPi, and x.

◆ TEST_P() [361/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawStrokedText   
)

Definition at line 474 of file dl_unittests.cc.

474  {
475  flutter::DisplayListBuilder builder;
476  flutter::DlPaint paint;
477 
478  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
479  paint.setColor(flutter::DlColor::kRed());
480  builder.DrawTextBlob(
481  SkTextBlob::MakeFromString("stoked about stroked text", CreateTestFont()),
482  250, 250, paint);
483 
484  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
485 }

◆ TEST_P() [362/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlob   
)

Definition at line 53 of file dl_unittests.cc.

53  {
54  flutter::DisplayListBuilder builder;
55  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
56  100, 100, flutter::DlPaint(flutter::DlColor::kBlue()));
57  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
58 }

◆ TEST_P() [363/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlobWithGradient   
)

Definition at line 60 of file dl_unittests.cc.

60  {
61  flutter::DisplayListBuilder builder;
62 
63  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
64  flutter::DlColor::kRed()};
65  const float stops[2] = {0.0, 1.0};
66 
67  auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
68  2, colors.data(), stops,
69  flutter::DlTileMode::kClamp);
70  flutter::DlPaint paint;
71  paint.setColorSource(linear);
72 
73  builder.DrawTextBlob(
74  SkTextBlob::MakeFromString("Hello World", CreateTestFont()), 100, 100,
75  paint);
76  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
77 }

◆ TEST_P() [364/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextWithSaveLayer   
)

Definition at line 79 of file dl_unittests.cc.

79  {
80  flutter::DisplayListBuilder builder;
81  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
82  100, 100, flutter::DlPaint(flutter::DlColor::kRed()));
83 
84  flutter::DlPaint save_paint;
85  float alpha = 0.5;
86  save_paint.setAlpha(static_cast<uint8_t>(255 * alpha));
87  builder.SaveLayer(std::nullopt, &save_paint);
88  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello with half alpha",
89  CreateTestFontOfSize(100)),
90  100, 300, flutter::DlPaint(flutter::DlColor::kRed()));
91  builder.Restore();
92  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
93 }

◆ TEST_P() [365/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithBlendColorFilter   
)

Definition at line 526 of file dl_unittests.cc.

526  {
527  auto texture = CreateTextureForFixture("embarcadero.jpg");
528  flutter::DisplayListBuilder builder;
529  flutter::DlPaint paint;
530 
531  // Pipeline blended image.
532  {
533  auto filter = flutter::DlColorFilter::MakeBlend(
534  flutter::DlColor::kYellow(), flutter::DlBlendMode::kModulate);
535  paint.setColorFilter(filter);
536  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
537  flutter::DlImageSampling::kNearestNeighbor, &paint);
538  }
539 
540  // Advanced blended image.
541  {
542  auto filter = flutter::DlColorFilter::MakeBlend(
543  flutter::DlColor::kRed(), flutter::DlBlendMode::kScreen);
544  paint.setColorFilter(filter);
545  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(250, 250),
546  flutter::DlImageSampling::kNearestNeighbor, &paint);
547  }
548 
549  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
550 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [366/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithColorFilterImageFilter   
)

Definition at line 552 of file dl_unittests.cc.

552  {
553  const float invert_color_matrix[20] = {
554  -1, 0, 0, 0, 1, //
555  0, -1, 0, 0, 1, //
556  0, 0, -1, 0, 1, //
557  0, 0, 0, 1, 0, //
558  };
559  auto texture = CreateTextureForFixture("boston.jpg");
560  flutter::DisplayListBuilder builder;
561  flutter::DlPaint paint;
562 
563  auto color_filter = flutter::DlColorFilter::MakeMatrix(invert_color_matrix);
564  auto image_filter = flutter::DlImageFilter::MakeColorFilter(color_filter);
565 
566  paint.setImageFilter(image_filter);
567  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
568  flutter::DlImageSampling::kNearestNeighbor, &paint);
569 
570  builder.Translate(0, 700);
571  paint.setColorFilter(color_filter);
572  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
573  flutter::DlImageSampling::kNearestNeighbor, &paint);
574  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
575 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [367/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithComposeImageFilter   
)

Definition at line 602 of file dl_unittests.cc.

602  {
603  auto texture = CreateTextureForFixture("boston.jpg");
604  flutter::DisplayListBuilder builder;
605  flutter::DlPaint paint;
606 
607  auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
608  auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
609  auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
610  auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
611 
612  paint.setImageFilter(open.get());
613  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
614  flutter::DlImageSampling::kNearestNeighbor, &paint);
615  builder.Translate(0, 700);
616  paint.setImageFilter(close.get());
617  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
618  flutter::DlImageSampling::kNearestNeighbor, &paint);
619  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
620 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [368/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithImageBlurFilter   
)

Definition at line 577 of file dl_unittests.cc.

577  {
578  auto texture = CreateTextureForFixture("embarcadero.jpg");
579 
580  auto callback = [&]() {
581  static float sigma[] = {10, 10};
582 
583  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
584  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
585  ImGui::End();
586 
587  flutter::DisplayListBuilder builder;
588  flutter::DlPaint paint;
589 
590  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
591  flutter::DlTileMode::kClamp);
592  paint.setImageFilter(&filter);
593  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(200, 200),
594  flutter::DlImageSampling::kNearestNeighbor, &paint);
595 
596  return builder.Build();
597  };
598 
599  ASSERT_TRUE(OpenPlaygroundHere(callback));
600 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [369/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMaskBlur   
)

Definition at line 438 of file dl_unittests.cc.

438  {
439  auto texture = CreateTextureForFixture("embarcadero.jpg");
440  flutter::DisplayListBuilder builder;
441  flutter::DlPaint paint;
442 
443  // Mask blurred image.
444  {
445  auto filter =
446  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
447  paint.setMaskFilter(&filter);
448  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
449  flutter::DlImageSampling::kNearestNeighbor, &paint);
450  }
451 
452  // Mask blurred filled path.
453  {
454  paint.setColor(flutter::DlColor::kYellow());
455  auto filter =
456  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kOuter, 10.0f);
457  paint.setMaskFilter(&filter);
458  builder.DrawArc(DlRect::MakeXYWH(410, 110, 100, 100), 45, 270, true, paint);
459  }
460 
461  // Mask blurred text.
462  {
463  auto filter =
464  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kSolid, 10.0f);
465  paint.setMaskFilter(&filter);
466  builder.DrawTextBlob(
467  SkTextBlob::MakeFromString("Testing", CreateTestFont()), 220, 170,
468  paint);
469  }
470 
471  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
472 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [370/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilter   
)

Definition at line 948 of file dl_unittests.cc.

948  {
949  auto boston = CreateTextureForFixture("boston.jpg");
950 
951  auto callback = [&]() {
952  static int selected_matrix_type = 0;
953  const char* matrix_type_names[] = {"Matrix", "Local Matrix"};
954 
955  static float ctm_translation[2] = {200, 200};
956  static float ctm_scale[2] = {0.65, 0.65};
957  static float ctm_skew[2] = {0, 0};
958 
959  static bool enable = true;
960  static float translation[2] = {100, 100};
961  static float scale[2] = {0.8, 0.8};
962  static float skew[2] = {0.2, 0.2};
963 
964  static bool enable_savelayer = true;
965 
966  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
967  {
968  ImGui::Combo("Filter type", &selected_matrix_type, matrix_type_names,
969  sizeof(matrix_type_names) / sizeof(char*));
970 
971  ImGui::TextWrapped("Current Transform");
972  ImGui::SliderFloat2("CTM Translation", ctm_translation, 0, 1000);
973  ImGui::SliderFloat2("CTM Scale", ctm_scale, 0, 3);
974  ImGui::SliderFloat2("CTM Skew", ctm_skew, -3, 3);
975 
976  ImGui::TextWrapped(
977  "MatrixFilter and LocalMatrixFilter modify the CTM in the same way. "
978  "The only difference is that MatrixFilter doesn't affect the effect "
979  "transform, whereas LocalMatrixFilter does.");
980  // Note: See this behavior in:
981  // https://fiddle.skia.org/c/6cbb551ab36d06f163db8693972be954
982  ImGui::Checkbox("Enable", &enable);
983  ImGui::SliderFloat2("Filter Translation", translation, 0, 1000);
984  ImGui::SliderFloat2("Filter Scale", scale, 0, 3);
985  ImGui::SliderFloat2("Filter Skew", skew, -3, 3);
986 
987  ImGui::TextWrapped(
988  "Rendering the filtered image within a layer can expose bounds "
989  "issues. If the rendered image gets cut off when this setting is "
990  "enabled, there's a coverage bug in the filter.");
991  ImGui::Checkbox("Render in layer", &enable_savelayer);
992  }
993  ImGui::End();
994 
995  flutter::DisplayListBuilder builder;
996  flutter::DlPaint paint;
997 
998  if (enable_savelayer) {
999  builder.SaveLayer(std::nullopt, nullptr);
1000  }
1001  {
1002  auto content_scale = GetContentScale();
1003  builder.Scale(content_scale.x, content_scale.y);
1004 
1005  // Set the current transform
1006  auto ctm_matrix = Matrix::MakeRow(
1007  ctm_scale[0], ctm_skew[0], 0.0f, ctm_translation[0], //
1008  ctm_skew[1], ctm_scale[1], 0.0f, ctm_translation[1], //
1009  0, 0, 1, 0, //
1010  0, 0, 0, 1);
1011  builder.Transform(ctm_matrix);
1012 
1013  // Set the matrix filter
1014  auto filter_matrix =
1015  Matrix::MakeRow(scale[0], skew[0], 0.0f, translation[0], //
1016  skew[1], scale[1], 0.0f, translation[1], //
1017  0.0f, 0.0f, 1.0f, 0.0f, //
1018  0.0f, 0.0f, 0.0f, 1.0f);
1019 
1020  if (enable) {
1021  switch (selected_matrix_type) {
1022  case 0: {
1023  auto filter = flutter::DlMatrixImageFilter(
1024  filter_matrix, flutter::DlImageSampling::kLinear);
1025  paint.setImageFilter(&filter);
1026  break;
1027  }
1028  case 1: {
1029  auto internal_filter =
1030  flutter::DlBlurImageFilter(10, 10, flutter::DlTileMode::kDecal)
1031  .shared();
1032  auto filter = flutter::DlLocalMatrixImageFilter(filter_matrix,
1033  internal_filter);
1034  paint.setImageFilter(&filter);
1035  break;
1036  }
1037  }
1038  }
1039 
1040  builder.DrawImage(DlImageImpeller::Make(boston), DlPoint(),
1041  flutter::DlImageSampling::kLinear, &paint);
1042  }
1043  if (enable_savelayer) {
1044  builder.Restore();
1045  }
1046 
1047  return builder.Build();
1048  };
1049 
1050  ASSERT_TRUE(OpenPlaygroundHere(callback));
1051 }

References impeller::DlImageImpeller::Make(), and impeller::Matrix::MakeRow().

◆ TEST_P() [371/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilterWhenSavingLayer   
)

Definition at line 1053 of file dl_unittests.cc.

1053  {
1054  auto callback = [&]() {
1055  static float translation[2] = {0, 0};
1056  static bool enable_save_layer = true;
1057 
1058  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1059  ImGui::SliderFloat2("Translation", translation, -130, 130);
1060  ImGui::Checkbox("Enable save layer", &enable_save_layer);
1061  ImGui::End();
1062 
1063  flutter::DisplayListBuilder builder;
1064  builder.Save();
1065  builder.Scale(2.0, 2.0);
1066  flutter::DlPaint paint;
1067  paint.setColor(flutter::DlColor::kYellow());
1068  builder.DrawRect(DlRect::MakeWH(300, 300), paint);
1069  paint.setStrokeWidth(1.0);
1070  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1071  paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80));
1072  builder.DrawLine(DlPoint(150, 0), DlPoint(150, 300), paint);
1073  builder.DrawLine(DlPoint(0, 150), DlPoint(300, 150), paint);
1074 
1075  flutter::DlPaint save_paint;
1076  DlRect bounds = DlRect::MakeXYWH(100, 100, 100, 100);
1077  Matrix translate_matrix =
1078  Matrix::MakeTranslation({translation[0], translation[1]});
1079  if (enable_save_layer) {
1080  auto filter = flutter::DlMatrixImageFilter(
1081  translate_matrix, flutter::DlImageSampling::kNearestNeighbor);
1082  save_paint.setImageFilter(filter.shared());
1083  builder.SaveLayer(bounds, &save_paint);
1084  } else {
1085  builder.Save();
1086  builder.Transform(translate_matrix);
1087  }
1088 
1089  Matrix filter_matrix;
1090  filter_matrix.Translate({150, 150});
1091  filter_matrix.Scale({0.2f, 0.2f});
1092  filter_matrix.Translate({-150, -150});
1093  auto filter = flutter::DlMatrixImageFilter(
1094  filter_matrix, flutter::DlImageSampling::kNearestNeighbor);
1095 
1096  save_paint.setImageFilter(filter.shared());
1097 
1098  builder.SaveLayer(bounds, &save_paint);
1099  flutter::DlPaint paint2;
1100  paint2.setColor(flutter::DlColor::kBlue());
1101  builder.DrawRect(bounds, paint2);
1102  builder.Restore();
1103  builder.Restore();
1104  return builder.Build();
1105  };
1106 
1107  ASSERT_TRUE(OpenPlaygroundHere(callback));
1108 }

References impeller::Matrix::MakeTranslation(), impeller::Matrix::Scale(), and impeller::Matrix::Translate().

◆ TEST_P() [372/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithOddPathWinding   
)

Definition at line 394 of file dl_unittests.cc.

394  {
395  flutter::DisplayListBuilder builder;
396  flutter::DlPaint paint;
397 
398  paint.setColor(flutter::DlColor::kRed());
399  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
400 
401  builder.Translate(300, 300);
402  flutter::DlPathBuilder path_builder;
403  path_builder.AddCircle(DlPoint(0, 0), 100);
404  path_builder.AddCircle(DlPoint(0, 0), 50);
405  path_builder.SetFillType(flutter::DlPathFillType::kOdd);
406  builder.DrawPath(path_builder.TakePath(), paint);
407 
408  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
409 }

◆ TEST_P() [373/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroLengthLine   
)

Definition at line 843 of file dl_unittests.cc.

843  {
844  flutter::DisplayListBuilder builder;
845  std::vector<flutter::DlStrokeCap> caps = {
846  flutter::DlStrokeCap::kButt,
847  flutter::DlStrokeCap::kRound,
848  flutter::DlStrokeCap::kSquare,
849  };
850  flutter::DlPaint paint =
851  flutter::DlPaint() //
852  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
853  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
854  .setStrokeCap(flutter::DlStrokeCap::kButt) //
855  .setStrokeWidth(20);
856  DlPath path = DlPath::MakeLine({150, 50}, {150, 50});
857  for (auto cap : caps) {
858  paint.setStrokeCap(cap);
859  builder.DrawLine(DlPoint(50, 50), DlPoint(50, 50), paint);
860  builder.DrawPath(path, paint);
861  builder.Translate(0, 150);
862  }
863  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
864 }

◆ TEST_P() [374/545]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroWidthLine   
)

Definition at line 914 of file dl_unittests.cc.

914  {
915  flutter::DisplayListBuilder builder;
916  std::vector<flutter::DlStrokeCap> caps = {
917  flutter::DlStrokeCap::kButt,
918  flutter::DlStrokeCap::kRound,
919  flutter::DlStrokeCap::kSquare,
920  };
921  flutter::DlPaint paint = //
922  flutter::DlPaint() //
923  .setColor(flutter::DlColor::kWhite()) //
924  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
925  .setStrokeWidth(0);
926  flutter::DlPaint outline_paint = //
927  flutter::DlPaint() //
928  .setColor(flutter::DlColor::kYellow()) //
929  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
930  .setStrokeCap(flutter::DlStrokeCap::kSquare) //
931  .setStrokeWidth(1);
932  DlPath path = DlPath::MakeLine({150, 50}, {160, 50});
933  for (auto cap : caps) {
934  paint.setStrokeCap(cap);
935  builder.DrawLine(DlPoint(50, 50), DlPoint(60, 50), paint);
936  builder.DrawRect(DlRect::MakeLTRB(45, 45, 65, 55), outline_paint);
937  builder.DrawLine(DlPoint{100, 50}, DlPoint{100, 50}, paint);
938  if (cap != flutter::DlStrokeCap::kButt) {
939  builder.DrawRect(DlRect::MakeLTRB(95, 45, 105, 55), outline_paint);
940  }
941  builder.DrawPath(path, paint);
942  builder.DrawRect(path.GetBounds().Expand(5, 5), outline_paint);
943  builder.Translate(0, 150);
944  }
945  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
946 }

◆ TEST_P() [375/545]

impeller::testing::TEST_P ( DisplayListTest  ,
ClipDrawRRectWithNonCircularRadii   
)

Definition at line 1343 of file dl_unittests.cc.

1343  {
1344  flutter::DisplayListBuilder builder;
1345 
1346  flutter::DlPaint fill_paint = //
1347  flutter::DlPaint() //
1348  .setColor(flutter::DlColor::kBlue()) //
1349  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1350  .setStrokeWidth(10);
1351  flutter::DlPaint stroke_paint = //
1352  flutter::DlPaint() //
1353  .setColor(flutter::DlColor::kGreen()) //
1354  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1355  .setStrokeWidth(10);
1356 
1357  builder.DrawRoundRect(
1358  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1359  fill_paint);
1360  builder.DrawRoundRect(
1361  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1362  stroke_paint);
1363 
1364  builder.DrawRoundRect(
1365  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1366  fill_paint);
1367  builder.DrawRoundRect(
1368  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1369  stroke_paint);
1370 
1371  flutter::DlPaint reference_paint = //
1372  flutter::DlPaint() //
1373  .setColor(flutter::DlColor::kMidGrey()) //
1374  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1375  .setStrokeWidth(10);
1376 
1377  builder.DrawRoundRect(
1378  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(500, 500, 300, 300), 40, 40),
1379  reference_paint);
1380  builder.DrawRoundRect(
1381  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(100, 100, 300, 300), 120, 120),
1382  reference_paint);
1383 
1384  flutter::DlPaint clip_fill_paint = //
1385  flutter::DlPaint() //
1386  .setColor(flutter::DlColor::kCyan()) //
1387  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1388  .setStrokeWidth(10);
1389 
1390  builder.Save();
1391  builder.ClipRoundRect(
1392  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(900, 100, 300, 300), 120, 40));
1393  builder.DrawPaint(clip_fill_paint);
1394  builder.Restore();
1395 
1396  builder.Save();
1397  builder.ClipRoundRect(
1398  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(100, 900, 300, 300), 40, 120));
1399  builder.DrawPaint(clip_fill_paint);
1400  builder.Restore();
1401 
1402  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1403 }

◆ TEST_P() [376/545]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawMaskBlursThatMightUseSaveLayers   
)

Definition at line 1519 of file dl_unittests.cc.

1519  {
1520  flutter::DisplayListBuilder builder;
1521  builder.DrawColor(flutter::DlColor::kWhite(), flutter::DlBlendMode::kSrc);
1522  Vector2 scale = GetContentScale();
1523  builder.Scale(scale.x, scale.y);
1524 
1525  builder.Save();
1526  // We need a small transform op to avoid a deferred save
1527  builder.Translate(1.0f, 1.0f);
1528  auto solid_filter =
1529  flutter::DlBlurMaskFilter::Make(flutter::DlBlurStyle::kSolid, 5.0f);
1530  flutter::DlPaint solid_alpha_paint =
1531  flutter::DlPaint() //
1532  .setMaskFilter(solid_filter) //
1533  .setColor(flutter::DlColor::kBlue()) //
1534  .setAlpha(0x7f);
1535  for (int x = 1; x <= 4; x++) {
1536  for (int y = 1; y <= 4; y++) {
1537  builder.DrawRect(DlRect::MakeXYWH(x * 100, y * 100, 80, 80),
1538  solid_alpha_paint);
1539  }
1540  }
1541  builder.Restore();
1542 
1543  builder.Save();
1544  builder.Translate(500.0f, 0.0f);
1545  auto normal_filter =
1546  flutter::DlBlurMaskFilter::Make(flutter::DlBlurStyle::kNormal, 5.0f);
1547  auto rotate_if = flutter::DlMatrixImageFilter::Make(
1548  Matrix::MakeRotationZ(Degrees(10)), flutter::DlImageSampling::kLinear);
1549  flutter::DlPaint normal_if_paint =
1550  flutter::DlPaint() //
1551  .setMaskFilter(solid_filter) //
1552  .setImageFilter(rotate_if) //
1553  .setColor(flutter::DlColor::kGreen()) //
1554  .setAlpha(0x7f);
1555  for (int x = 1; x <= 4; x++) {
1556  for (int y = 1; y <= 4; y++) {
1557  builder.DrawRect(DlRect::MakeXYWH(x * 100, y * 100, 80, 80),
1558  normal_if_paint);
1559  }
1560  }
1561  builder.Restore();
1562 
1563  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1564 }

References impeller::Matrix::MakeRotationZ(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [377/545]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawPaintIgnoresMaskFilter   
)

Definition at line 1496 of file dl_unittests.cc.

1496  {
1497  flutter::DisplayListBuilder builder;
1498  builder.DrawPaint(flutter::DlPaint().setColor(flutter::DlColor::kWhite()));
1499 
1500  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
1501  builder.DrawCircle(DlPoint(300, 300), 200,
1502  flutter::DlPaint().setMaskFilter(&filter));
1503 
1504  std::vector<flutter::DlColor> colors = {flutter::DlColor::kGreen(),
1505  flutter::DlColor::kGreen()};
1506  const float stops[2] = {0.0, 1.0};
1507  auto linear = flutter::DlColorSource::MakeLinear(
1508  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1509  flutter::DlTileMode::kRepeat);
1510  flutter::DlPaint blend_paint =
1511  flutter::DlPaint() //
1512  .setColorSource(linear) //
1513  .setBlendMode(flutter::DlBlendMode::kScreen);
1514  builder.DrawPaint(blend_paint);
1515 
1516  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1517 }

◆ TEST_P() [378/545]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawShapes   
)

Definition at line 1304 of file dl_unittests.cc.

1304  {
1305  flutter::DisplayListBuilder builder;
1306  std::vector<flutter::DlStrokeJoin> joins = {
1307  flutter::DlStrokeJoin::kBevel,
1308  flutter::DlStrokeJoin::kRound,
1309  flutter::DlStrokeJoin::kMiter,
1310  };
1311  flutter::DlPaint paint = //
1312  flutter::DlPaint() //
1313  .setColor(flutter::DlColor::kWhite()) //
1314  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1315  .setStrokeWidth(10);
1316  flutter::DlPaint stroke_paint = //
1317  flutter::DlPaint() //
1318  .setColor(flutter::DlColor::kWhite()) //
1319  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1320  .setStrokeWidth(10);
1321  DlPath path = DlPath::MakeLine({150, 50}, {160, 50});
1322 
1323  builder.Translate(300, 50);
1324  builder.Scale(0.8, 0.8);
1325  for (auto join : joins) {
1326  paint.setStrokeJoin(join);
1327  stroke_paint.setStrokeJoin(join);
1328  builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), paint);
1329  builder.DrawRect(DlRect::MakeXYWH(0, 150, 100, 100), stroke_paint);
1330  builder.DrawRoundRect(
1331  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(150, 0, 100, 100), 30, 30),
1332  paint);
1333  builder.DrawRoundRect(
1334  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(150, 150, 100, 100), 30, 30),
1335  stroke_paint);
1336  builder.DrawCircle(DlPoint(350, 50), 50, paint);
1337  builder.DrawCircle(DlPoint(350, 200), 50, stroke_paint);
1338  builder.Translate(0, 300);
1339  }
1340  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1341 }

◆ TEST_P() [379/545]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesBlendModes   
)

Definition at line 1405 of file dl_unittests.cc.

1405  {
1406  std::vector<const char*> blend_mode_names;
1407  std::vector<flutter::DlBlendMode> blend_mode_values;
1408  {
1409  const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = {
1410  // Pipeline blends (Porter-Duff alpha compositing)
1411  {"Clear", flutter::DlBlendMode::kClear},
1412  {"Source", flutter::DlBlendMode::kSrc},
1413  {"Destination", flutter::DlBlendMode::kDst},
1414  {"SourceOver", flutter::DlBlendMode::kSrcOver},
1415  {"DestinationOver", flutter::DlBlendMode::kDstOver},
1416  {"SourceIn", flutter::DlBlendMode::kSrcIn},
1417  {"DestinationIn", flutter::DlBlendMode::kDstIn},
1418  {"SourceOut", flutter::DlBlendMode::kSrcOut},
1419  {"DestinationOut", flutter::DlBlendMode::kDstOut},
1420  {"SourceATop", flutter::DlBlendMode::kSrcATop},
1421  {"DestinationATop", flutter::DlBlendMode::kDstATop},
1422  {"Xor", flutter::DlBlendMode::kXor},
1423  {"Plus", flutter::DlBlendMode::kPlus},
1424  {"Modulate", flutter::DlBlendMode::kModulate},
1425  // Advanced blends (color component blends)
1426  {"Screen", flutter::DlBlendMode::kScreen},
1427  {"Overlay", flutter::DlBlendMode::kOverlay},
1428  {"Darken", flutter::DlBlendMode::kDarken},
1429  {"Lighten", flutter::DlBlendMode::kLighten},
1430  {"ColorDodge", flutter::DlBlendMode::kColorDodge},
1431  {"ColorBurn", flutter::DlBlendMode::kColorBurn},
1432  {"HardLight", flutter::DlBlendMode::kHardLight},
1433  {"SoftLight", flutter::DlBlendMode::kSoftLight},
1434  {"Difference", flutter::DlBlendMode::kDifference},
1435  {"Exclusion", flutter::DlBlendMode::kExclusion},
1436  {"Multiply", flutter::DlBlendMode::kMultiply},
1437  {"Hue", flutter::DlBlendMode::kHue},
1438  {"Saturation", flutter::DlBlendMode::kSaturation},
1439  {"Color", flutter::DlBlendMode::kColor},
1440  {"Luminosity", flutter::DlBlendMode::kLuminosity},
1441  };
1442  assert(blends.size() ==
1443  static_cast<size_t>(flutter::DlBlendMode::kLastMode) + 1);
1444  for (const auto& [name, mode] : blends) {
1445  blend_mode_names.push_back(name);
1446  blend_mode_values.push_back(mode);
1447  }
1448  }
1449 
1450  auto callback = [&]() {
1451  static int current_blend_index = 3;
1452  static float dst_alpha = 1;
1453  static float src_alpha = 1;
1454  static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1455  static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1456  static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1457  static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1458 
1459  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1460  {
1461  ImGui::ListBox("Blending mode", &current_blend_index,
1462  blend_mode_names.data(), blend_mode_names.size());
1463  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1464  ImGui::ColorEdit4("Color A", color0);
1465  ImGui::ColorEdit4("Color B", color1);
1466  ImGui::ColorEdit4("Color C", color2);
1467  ImGui::ColorEdit4("Source Color", src_color);
1468  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1469  }
1470  ImGui::End();
1471 
1472  std::vector<DlPoint> positions = {DlPoint(100, 300), //
1473  DlPoint(200, 100), //
1474  DlPoint(300, 300)};
1475  std::vector<flutter::DlColor> colors = {
1476  toColor(color0).modulateOpacity(dst_alpha),
1477  toColor(color1).modulateOpacity(dst_alpha),
1478  toColor(color2).modulateOpacity(dst_alpha)};
1479 
1480  auto vertices = flutter::DlVertices::Make(
1481  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1482  /*texture_coordinates=*/nullptr, colors.data());
1483 
1484  flutter::DisplayListBuilder builder;
1485  flutter::DlPaint paint;
1486 
1487  paint.setColor(toColor(src_color).modulateOpacity(src_alpha));
1488  builder.DrawVertices(vertices, blend_mode_values[current_blend_index],
1489  paint);
1490  return builder.Build();
1491  };
1492 
1493  ASSERT_TRUE(OpenPlaygroundHere(callback));
1494 }
flutter::DlColor toColor(const float *components)
Definition: dl_unittests.cc:38

References toColor().

◆ TEST_P() [380/545]

impeller::testing::TEST_P ( DisplayListTest  ,
IgnoreMaskFilterWhenSavingLayer   
)

Definition at line 513 of file dl_unittests.cc.

513  {
514  auto texture = CreateTextureForFixture("embarcadero.jpg");
515  flutter::DisplayListBuilder builder;
516  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
517  flutter::DlPaint paint;
518  paint.setMaskFilter(&filter);
519  builder.SaveLayer(std::nullopt, &paint);
520  builder.DrawImage(DlImageImpeller::Make(texture), DlPoint(100, 100),
521  flutter::DlImageSampling::kNearestNeighbor);
522  builder.Restore();
523  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
524 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [381/545]

impeller::testing::TEST_P ( DisplayListTest  ,
MaskBlursApplyCorrectlyToColorSources   
)

Definition at line 1256 of file dl_unittests.cc.

1256  {
1257  auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
1258  flutter::DlBlurStyle::kNormal, 10);
1259 
1260  flutter::DisplayListBuilder builder;
1261 
1262  std::array<flutter::DlColor, 2> colors = {flutter::DlColor::kBlue(),
1263  flutter::DlColor::kGreen()};
1264  std::array<float, 2> stops = {0, 1};
1265  auto texture = CreateTextureForFixture("airplane.jpg");
1266  auto matrix = flutter::DlMatrix::MakeTranslation({-300, -110});
1267  std::array<std::shared_ptr<flutter::DlColorSource>, 2> color_sources = {
1268  flutter::DlColorSource::MakeImage(
1269  DlImageImpeller::Make(texture), flutter::DlTileMode::kRepeat,
1270  flutter::DlTileMode::kRepeat, flutter::DlImageSampling::kLinear,
1271  &matrix),
1272  flutter::DlColorSource::MakeLinear(
1273  flutter::DlPoint(0, 0), flutter::DlPoint(100, 50), 2, colors.data(),
1274  stops.data(), flutter::DlTileMode::kClamp),
1275  };
1276 
1277  builder.Save();
1278  builder.Translate(0, 100);
1279  for (const auto& color_source : color_sources) {
1280  flutter::DlPaint paint;
1281  paint.setColorSource(color_source);
1282  paint.setMaskFilter(blur_filter);
1283 
1284  builder.Save();
1285  builder.Translate(100, 0);
1286  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
1287  builder.DrawRoundRect(
1288  DlRoundRect::MakeRectXY(DlRect::MakeWH(100, 50), 30, 30), paint);
1289 
1290  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1291  paint.setStrokeWidth(10);
1292  builder.Translate(200, 0);
1293  builder.DrawRoundRect(
1294  DlRoundRect::MakeRectXY(DlRect::MakeWH(100, 50), 30, 30), paint);
1295 
1296  builder.Restore();
1297  builder.Translate(0, 100);
1298  }
1299  builder.Restore();
1300 
1301  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1302 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [382/545]

impeller::testing::TEST_P ( DisplayListTest  ,
NinePatchImagePrecision   
)

Definition at line 796 of file dl_unittests.cc.

796  {
797  // Draw a nine patch image with colored corners and verify that the corner
798  // color does not leak outside the intended region.
799  auto texture = CreateTextureForFixture("nine_patch_corners.png");
800  flutter::DisplayListBuilder builder;
801  builder.DrawImageNine(DlImageImpeller::Make(texture),
802  DlIRect::MakeXYWH(10, 10, 1, 1),
803  DlRect::MakeXYWH(0, 0, 200, 100),
804  flutter::DlFilterMode::kNearest, nullptr);
805  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
806 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [383/545]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedPathsDrawCorrectly   
)

Definition at line 213 of file dl_unittests.cc.

213  {
214  auto callback = [&]() {
215  flutter::DisplayListBuilder builder;
216  flutter::DlPaint paint;
217 
218  paint.setColor(flutter::DlColor::kRed());
219  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
220 
221  static float stroke_width = 10.0f;
222  static int selected_stroke_type = 0;
223  static int selected_join_type = 0;
224  const char* stroke_types[] = {"Butte", "Round", "Square"};
225  const char* join_type[] = {"kMiter", "Round", "kBevel"};
226 
227  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
228  ImGui::Combo("Cap", &selected_stroke_type, stroke_types,
229  sizeof(stroke_types) / sizeof(char*));
230  ImGui::Combo("Join", &selected_join_type, join_type,
231  sizeof(join_type) / sizeof(char*));
232  ImGui::SliderFloat("Stroke Width", &stroke_width, 10.0f, 50.0f);
233  ImGui::End();
234 
235  flutter::DlStrokeCap cap;
236  flutter::DlStrokeJoin join;
237  switch (selected_stroke_type) {
238  case 0:
239  cap = flutter::DlStrokeCap::kButt;
240  break;
241  case 1:
242  cap = flutter::DlStrokeCap::kRound;
243  break;
244  case 2:
245  cap = flutter::DlStrokeCap::kSquare;
246  break;
247  default:
248  cap = flutter::DlStrokeCap::kButt;
249  break;
250  }
251  switch (selected_join_type) {
252  case 0:
253  join = flutter::DlStrokeJoin::kMiter;
254  break;
255  case 1:
256  join = flutter::DlStrokeJoin::kRound;
257  break;
258  case 2:
259  join = flutter::DlStrokeJoin::kBevel;
260  break;
261  default:
262  join = flutter::DlStrokeJoin::kMiter;
263  break;
264  }
265  paint.setStrokeCap(cap);
266  paint.setStrokeJoin(join);
267  paint.setStrokeWidth(stroke_width);
268 
269  // Make rendering better to watch.
270  builder.Scale(1.5f, 1.5f);
271 
272  // Rectangle
273  builder.Translate(100, 100);
274  builder.DrawRect(DlRect::MakeWH(100, 100), paint);
275 
276  // Rounded rectangle
277  builder.Translate(150, 0);
278  builder.DrawRoundRect(
279  DlRoundRect::MakeRectXY(DlRect::MakeWH(100, 50), 10, 10), paint);
280 
281  // Double rounded rectangle
282  builder.Translate(150, 0);
283  builder.DrawDiffRoundRect(
284  DlRoundRect::MakeRectXY(DlRect::MakeWH(100, 50), 10, 10),
285  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(10, 10, 80, 30), 10, 10),
286  paint);
287 
288  // Contour with duplicate join points
289  {
290  builder.Translate(150, 0);
291  flutter::DlPathBuilder path_builder;
292  path_builder.MoveTo(DlPoint(0, 0));
293  path_builder.LineTo(DlPoint(0, 0));
294  path_builder.LineTo(DlPoint(100, 0));
295  path_builder.LineTo(DlPoint(100, 0));
296  path_builder.LineTo(DlPoint(100, 100));
297  builder.DrawPath(path_builder.TakePath(), paint);
298  }
299 
300  // Contour with duplicate start and end points
301 
302  // Line.
303  builder.Translate(200, 0);
304  {
305  builder.Save();
306 
307  flutter::DlPathBuilder line_path_builder;
308  line_path_builder.MoveTo(DlPoint(0, 0));
309  line_path_builder.MoveTo(DlPoint(0, 0));
310  line_path_builder.LineTo(DlPoint(0, 0));
311  line_path_builder.LineTo(DlPoint(0, 0));
312  line_path_builder.LineTo(DlPoint(50, 50));
313  line_path_builder.LineTo(DlPoint(50, 50));
314  line_path_builder.LineTo(DlPoint(100, 0));
315  line_path_builder.LineTo(DlPoint(100, 0));
316  DlPath line_path = line_path_builder.TakePath();
317  builder.DrawPath(line_path, paint);
318 
319  builder.Translate(0, 100);
320  builder.DrawPath(line_path, paint);
321 
322  builder.Translate(0, 100);
323  flutter::DlPathBuilder line_path_builder2;
324  line_path_builder2.MoveTo(DlPoint(0, 0));
325  line_path_builder2.LineTo(DlPoint(0, 0));
326  line_path_builder2.LineTo(DlPoint(0, 0));
327  builder.DrawPath(line_path_builder2.TakePath(), paint);
328 
329  builder.Restore();
330  }
331 
332  // Cubic.
333  builder.Translate(150, 0);
334  {
335  builder.Save();
336 
337  flutter::DlPathBuilder cubic_path;
338  cubic_path.MoveTo(DlPoint(0, 0));
339  cubic_path.CubicCurveTo(DlPoint(0, 0), //
340  DlPoint(140.0, 100.0), //
341  DlPoint(140, 20));
342  builder.DrawPath(cubic_path.TakePath(), paint);
343 
344  builder.Translate(0, 100);
345  flutter::DlPathBuilder cubic_path2;
346  cubic_path2.MoveTo(DlPoint(0, 0));
347  cubic_path2.CubicCurveTo(DlPoint(0, 0), //
348  DlPoint(0, 0), //
349  DlPoint(150, 150));
350  builder.DrawPath(cubic_path2.TakePath(), paint);
351 
352  builder.Translate(0, 100);
353  flutter::DlPathBuilder cubic_path3;
354  cubic_path3.MoveTo(DlPoint(0, 0));
355  cubic_path3.CubicCurveTo(DlPoint(0, 0), //
356  DlPoint(0, 0), //
357  DlPoint(0, 0));
358  builder.DrawPath(cubic_path3.TakePath(), paint);
359 
360  builder.Restore();
361  }
362 
363  // Quad.
364  builder.Translate(200, 0);
365  {
366  builder.Save();
367 
368  flutter::DlPathBuilder quad_path;
369  quad_path.MoveTo(DlPoint(0, 0));
370  quad_path.MoveTo(DlPoint(0, 0));
371  quad_path.QuadraticCurveTo(DlPoint(100, 40), DlPoint(50, 80));
372  builder.DrawPath(quad_path.TakePath(), paint);
373 
374  builder.Translate(0, 150);
375  flutter::DlPathBuilder quad_path2;
376  quad_path2.MoveTo(DlPoint(0, 0));
377  quad_path2.MoveTo(DlPoint(0, 0));
378  quad_path2.QuadraticCurveTo(DlPoint(0, 0), DlPoint(100, 100));
379  builder.DrawPath(quad_path2.TakePath(), paint);
380 
381  builder.Translate(0, 100);
382  flutter::DlPathBuilder quad_path3;
383  quad_path3.MoveTo(DlPoint(0, 0));
384  quad_path3.QuadraticCurveTo(DlPoint(0, 0), DlPoint(0, 0));
385  builder.DrawPath(quad_path3.TakePath(), paint);
386 
387  builder.Restore();
388  }
389  return builder.Build();
390  };
391  ASSERT_TRUE(OpenPlaygroundHere(callback));
392 }

◆ TEST_P() [384/545]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedTextNotOffsetFromNormalText   
)

Definition at line 488 of file dl_unittests.cc.

488  {
489  flutter::DisplayListBuilder builder;
490  flutter::DlPaint paint;
491  auto const& text_blob = SkTextBlob::MakeFromString("00000", CreateTestFont());
492 
493  // https://api.flutter.dev/flutter/material/Colors/blue-constant.html.
494  auto const& mat_blue = flutter::DlColor(0xFF2196f3);
495 
496  // Draw a blue filled rectangle so the text is easier to see.
497  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
498  paint.setColor(mat_blue);
499  builder.DrawRect(DlRect::MakeXYWH(0, 0, 500, 500), paint);
500 
501  // Draw stacked text, with stroked text on top.
502  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
503  paint.setColor(flutter::DlColor::kWhite());
504  builder.DrawTextBlob(text_blob, 250, 250, paint);
505 
506  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
507  paint.setColor(flutter::DlColor::kBlack());
508  builder.DrawTextBlob(text_blob, 250, 250, paint);
509 
510  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
511 }

◆ TEST_P() [385/545]

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() [386/545]

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() [387/545]

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() [388/545]

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() [389/545]

impeller::testing::TEST_P ( EntityTest  ,
BezierCircleScaled   
)

Definition at line 878 of file entity_unittests.cc.

878  {
879  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
880  static float scale = 20;
881 
882  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
883  ImGui::SliderFloat("Scale", &scale, 1, 100);
884  ImGui::End();
885 
886  Entity entity;
887  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
888  auto path = flutter::DlPathBuilder{}
889  .MoveTo({97.325, 34.818})
890  .CubicCurveTo({98.50862885295136, 34.81812293973836},
891  {99.46822048142015, 33.85863261475589},
892  {99.46822048142015, 32.67499810206613})
893  .CubicCurveTo({99.46822048142015, 31.491363589376355},
894  {98.50862885295136, 30.53187326439389},
895  {97.32499434685802, 30.531998226542708})
896  .CubicCurveTo({96.14153655073771, 30.532123170035373},
897  {95.18222070648729, 31.491540299350355},
898  {95.18222070648729, 32.67499810206613})
899  .CubicCurveTo({95.18222070648729, 33.85845590478189},
900  {96.14153655073771, 34.81787303409686},
901  {97.32499434685802, 34.81799797758954})
902  .Close()
903  .TakePath();
904  entity.SetTransform(
905  Matrix::MakeScale({scale, scale, 1.0}).Translate({-90, -20, 0}));
906 
907  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
908 
909  auto contents = std::make_shared<SolidColorContents>();
910  contents->SetColor(Color::Red());
911  contents->SetGeometry(geom.get());
912 
913  entity.SetContents(contents);
914  return entity.Render(context, pass);
915  };
916  ASSERT_TRUE(OpenPlaygroundHere(callback));
917 }

References impeller::Close(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [390/545]

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.GetTransientsBuffer()));
833 
834  VS::FrameInfo frame_info;
835  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
836  VS::BindFrameInfo(
837  pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
838  FS::FragInfo frag_info;
839  frag_info.color = color.Premultiply();
840  FS::BindFragInfo(
841  pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
842  return pass.Draw().ok();
843  };
844 
845  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
846  static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
847  ImGui::ColorEdit4("Color 1", reinterpret_cast<float*>(&color1));
848  ImGui::ColorEdit4("Color 2", reinterpret_cast<float*>(&color2));
849  static int current_blend_index = 3;
850  ImGui::ListBox("Blending mode", &current_blend_index,
851  blend_mode_names.data(), blend_mode_names.size());
852  ImGui::End();
853 
854  BlendMode selected_mode = blend_mode_values[current_blend_index];
855 
856  Point a, b, c, d;
857  static PlaygroundPoint point_a(Point(400, 100), 20, Color::White());
858  static PlaygroundPoint point_b(Point(200, 300), 20, Color::White());
859  std::tie(a, b) = DrawPlaygroundLine(point_a, point_b);
860  static PlaygroundPoint point_c(Point(470, 190), 20, Color::White());
861  static PlaygroundPoint point_d(Point(270, 390), 20, Color::White());
862  std::tie(c, d) = DrawPlaygroundLine(point_c, point_d);
863 
864  bool result = true;
865  result = result &&
866  draw_rect(Rect::MakeXYWH(0, 0, pass.GetRenderTargetSize().width,
867  pass.GetRenderTargetSize().height),
868  Color(), BlendMode::kClear);
869  result = result && draw_rect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), color1,
870  BlendMode::kSrcOver);
871  result = result && draw_rect(Rect::MakeLTRB(c.x, c.y, d.x, d.y), color2,
872  selected_mode);
873  return result;
874  };
875  ASSERT_TRUE(OpenPlaygroundHere(callback));
876 }
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::GetTransientsBuffer(), 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() [391/545]

impeller::testing::TEST_P ( EntityTest  ,
BorderMaskBlurCoverageIsCorrect   
)

Definition at line 1319 of file entity_unittests.cc.

1319  {
1320  auto fill = std::make_shared<SolidColorContents>();
1321  auto geom = Geometry::MakeFillPath(
1322  flutter::DlPath::MakeRect(Rect::MakeXYWH(0, 0, 300, 400)));
1323  fill->SetGeometry(geom.get());
1324  fill->SetColor(Color::CornflowerBlue());
1325  auto border_mask_blur = FilterContents::MakeBorderMaskBlur(
1326  FilterInput::Make(fill), Radius{3}, Radius{4});
1327 
1328  {
1329  Entity e;
1330  e.SetTransform(Matrix());
1331  auto actual = border_mask_blur->GetCoverage(e);
1332  auto expected = Rect::MakeXYWH(-3, -4, 306, 408);
1333  ASSERT_TRUE(actual.has_value());
1334  ASSERT_RECT_NEAR(actual.value(), expected);
1335  }
1336 
1337  {
1338  Entity e;
1339  e.SetTransform(Matrix::MakeRotationZ(Radians{kPi / 4}));
1340  auto actual = border_mask_blur->GetCoverage(e);
1341  auto expected = Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1342  ASSERT_TRUE(actual.has_value());
1343  ASSERT_RECT_NEAR(actual.value(), expected);
1344  }
1345 }
#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() [392/545]

impeller::testing::TEST_P ( EntityTest  ,
CanComputeGeometryForEmptyPathsWithoutCrashing   
)

Definition at line 2314 of file entity_unittests.cc.

2314  {
2315  flutter::DlPath path = flutter::DlPath::MakeRect(Rect::MakeLTRB(0, 0, 0, 0));
2316 
2317  EXPECT_TRUE(path.GetBounds().IsEmpty());
2318 
2319  auto geom = Geometry::MakeFillPath(path);
2320 
2321  Entity entity;
2322  RenderTarget target =
2323  GetContentContext()->GetRenderTargetCache()->CreateOffscreen(
2324  *GetContext(), {1, 1}, 1u);
2325  testing::MockRenderPass render_pass(GetContext(), target);
2326  auto position_result =
2327  geom->GetPositionBuffer(*GetContentContext(), entity, render_pass);
2328 
2329  EXPECT_EQ(position_result.vertex_buffer.vertex_count, 0u);
2330 
2331  EXPECT_EQ(geom->GetResultMode(), GeometryResult::Mode::kNormal);
2332 }

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

◆ TEST_P() [393/545]

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() [394/545]

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() [395/545]

impeller::testing::TEST_P ( EntityTest  ,
CanRenderEmptyPathsWithoutCrashing   
)

Definition at line 2334 of file entity_unittests.cc.

2334  {
2335  flutter::DlPath path = flutter::DlPath::MakeRect(Rect::MakeLTRB(0, 0, 0, 0));
2336 
2337  EXPECT_TRUE(path.GetBounds().IsEmpty());
2338 
2339  auto contents = std::make_shared<SolidColorContents>();
2340  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
2341  contents->SetGeometry(geom.get());
2342  contents->SetColor(Color::Red());
2343 
2344  Entity entity;
2345  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2346  entity.SetContents(contents);
2347 
2348  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2349 }

References impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [396/545]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterContentsWithLargeGeometry   
)

Definition at line 2158 of file entity_unittests.cc.

2158  {
2159  Entity entity;
2160  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2161  auto src_contents = std::make_shared<SolidColorContents>();
2162  auto src_geom = Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000));
2163  src_contents->SetGeometry(src_geom.get());
2164  src_contents->SetColor(Color::Red());
2165 
2166  auto dst_contents = std::make_shared<SolidColorContents>();
2167  auto dst_geom = Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000));
2168  dst_contents->SetGeometry(dst_geom.get());
2169  dst_contents->SetColor(Color::Blue());
2170 
2171  auto contents = ColorFilterContents::MakeBlend(
2172  BlendMode::kSrcOver, {FilterInput::Make(dst_contents, false),
2173  FilterInput::Make(src_contents, false)});
2174  entity.SetContents(std::move(contents));
2175  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2176 }

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() [397/545]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorAdvancedBlend   
)

Definition at line 1921 of file entity_unittests.cc.

1921  {
1922  auto image = CreateTextureForFixture("boston.jpg");
1923  auto filter = ColorFilterContents::MakeBlend(
1924  BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());
1925 
1926  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1927  Entity entity;
1928  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1929  Matrix::MakeTranslation({500, 300}) *
1930  Matrix::MakeScale(Vector2{0.5, 0.5}));
1931  entity.SetContents(filter);
1932  return entity.Render(context, pass);
1933  };
1934  ASSERT_TRUE(OpenPlaygroundHere(callback));
1935 }

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() [398/545]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorClearBlend   
)

Definition at line 1937 of file entity_unittests.cc.

1937  {
1938  auto image = CreateTextureForFixture("boston.jpg");
1939  auto filter = ColorFilterContents::MakeBlend(
1940  BlendMode::kClear, FilterInput::Make({image}), Color::Red());
1941 
1942  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1943  Entity entity;
1944  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1945  Matrix::MakeTranslation({500, 300}) *
1946  Matrix::MakeScale(Vector2{0.5, 0.5}));
1947  entity.SetContents(filter);
1948  return entity.Render(context, pass);
1949  };
1950  ASSERT_TRUE(OpenPlaygroundHere(callback));
1951 }

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() [399/545]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorDstBlend   
)

Definition at line 1969 of file entity_unittests.cc.

1969  {
1970  auto image = CreateTextureForFixture("boston.jpg");
1971  auto filter = ColorFilterContents::MakeBlend(
1972  BlendMode::kDst, FilterInput::Make({image}), Color::Red());
1973 
1974  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1975  Entity entity;
1976  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1977  Matrix::MakeTranslation({500, 300}) *
1978  Matrix::MakeScale(Vector2{0.5, 0.5}));
1979  entity.SetContents(filter);
1980  return entity.Render(context, pass);
1981  };
1982  ASSERT_TRUE(OpenPlaygroundHere(callback));
1983 }

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() [400/545]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcBlend   
)

Definition at line 1953 of file entity_unittests.cc.

1953  {
1954  auto image = CreateTextureForFixture("boston.jpg");
1955  auto filter = ColorFilterContents::MakeBlend(
1956  BlendMode::kSrc, FilterInput::Make({image}), Color::Red());
1957 
1958  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1959  Entity entity;
1960  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1961  Matrix::MakeTranslation({500, 300}) *
1962  Matrix::MakeScale(Vector2{0.5, 0.5}));
1963  entity.SetContents(filter);
1964  return entity.Render(context, pass);
1965  };
1966  ASSERT_TRUE(OpenPlaygroundHere(callback));
1967 }

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() [401/545]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcInBlend   
)

Definition at line 1985 of file entity_unittests.cc.

1985  {
1986  auto image = CreateTextureForFixture("boston.jpg");
1987  auto filter = ColorFilterContents::MakeBlend(
1988  BlendMode::kSrcIn, FilterInput::Make({image}), Color::Red());
1989 
1990  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1991  Entity entity;
1992  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1993  Matrix::MakeTranslation({500, 300}) *
1994  Matrix::MakeScale(Vector2{0.5, 0.5}));
1995  entity.SetContents(filter);
1996  return entity.Render(context, pass);
1997  };
1998  ASSERT_TRUE(OpenPlaygroundHere(callback));
1999 }

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() [402/545]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterCoverageIsCorrect   
)

Definition at line 1446 of file entity_unittests.cc.

1446  {
1447  // Set up a simple color background.
1448  auto fill = std::make_shared<SolidColorContents>();
1449  auto geom = Geometry::MakeFillPath(
1450  flutter::DlPath::MakeRect(Rect::MakeXYWH(0, 0, 300, 400)));
1451  fill->SetGeometry(geom.get());
1452  fill->SetColor(Color::Coral());
1453 
1454  // Set the color matrix filter.
1455  ColorMatrix matrix = {
1456  1, 1, 1, 1, 1, //
1457  1, 1, 1, 1, 1, //
1458  1, 1, 1, 1, 1, //
1459  1, 1, 1, 1, 1, //
1460  };
1461 
1462  auto filter =
1463  ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);
1464 
1465  Entity e;
1466  e.SetTransform(Matrix());
1467 
1468  // Confirm that the actual filter coverage matches the expected coverage.
1469  auto actual = filter->GetCoverage(e);
1470  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1471 
1472  ASSERT_TRUE(actual.has_value());
1473  ASSERT_RECT_NEAR(actual.value(), expected);
1474 }

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() [403/545]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterEditable   
)

Definition at line 1476 of file entity_unittests.cc.

1476  {
1477  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
1478  ASSERT_TRUE(bay_bridge);
1479 
1480  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1481  // UI state.
1482  static ColorMatrix color_matrix = {
1483  1, 0, 0, 0, 0, //
1484  0, 3, 0, 0, 0, //
1485  0, 0, 1, 0, 0, //
1486  0, 0, 0, 1, 0, //
1487  };
1488  static float offset[2] = {500, 400};
1489  static float rotation = 0;
1490  static float scale[2] = {0.65, 0.65};
1491  static float skew[2] = {0, 0};
1492 
1493  // Define the ImGui
1494  ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1495  {
1496  std::string label = "##1";
1497  for (int i = 0; i < 20; i += 5) {
1498  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1499  &(color_matrix.array[i]), 5, nullptr, nullptr,
1500  "%.2f", 0);
1501  label[2]++;
1502  }
1503 
1504  ImGui::SliderFloat2("Translation", &offset[0], 0,
1505  pass.GetRenderTargetSize().width);
1506  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1507  ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
1508  ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
1509  }
1510  ImGui::End();
1511 
1512  // Set the color matrix filter.
1513  auto filter = ColorFilterContents::MakeColorMatrix(
1514  FilterInput::Make(bay_bridge), color_matrix);
1515 
1516  // Define the entity with the color matrix filter.
1517  Entity entity;
1518  entity.SetTransform(
1519  Matrix::MakeScale(GetContentScale()) *
1520  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1521  Matrix::MakeRotationZ(Radians(rotation)) *
1522  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1523  Matrix::MakeSkew(skew[0], skew[1]) *
1524  Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
1525  entity.SetContents(filter);
1526  entity.Render(context, pass);
1527 
1528  return true;
1529  };
1530 
1531  ASSERT_TRUE(OpenPlaygroundHere(callback));
1532 }

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() [404/545]

impeller::testing::TEST_P ( EntityTest  ,
ConicalGradientContentsIsOpaque   
)

Definition at line 2046 of file entity_unittests.cc.

2046  {
2047  Matrix matrix;
2048  ConicalGradientContents contents;
2049  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2050  contents.SetGeometry(geom.get());
2051 
2052  contents.SetColors({Color::CornflowerBlue()});
2053  EXPECT_FALSE(contents.IsOpaque(matrix));
2054  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2055  EXPECT_FALSE(contents.IsOpaque(matrix));
2056 
2057  // Create stroked path that required alpha coverage.
2058  geom = Geometry::MakeStrokePath(
2059  flutter::DlPathBuilder{}.MoveTo({0, 0}).LineTo({100, 100}).TakePath(),
2060  {.width = 0.05f});
2061  contents.SetGeometry(geom.get());
2062  contents.SetColors({Color::CornflowerBlue()});
2063 
2064  EXPECT_FALSE(contents.IsOpaque(matrix));
2065 }

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() [405/545]

impeller::testing::TEST_P ( EntityTest  ,
ContentContextOptionsHasReasonableHashFunctions   
)

Definition at line 2225 of file entity_unittests.cc.

2225  {
2226  ContentContextOptions opts;
2227  auto hash_a = opts.ToKey();
2228 
2229  opts.blend_mode = BlendMode::kColorBurn;
2230  auto hash_b = opts.ToKey();
2231 
2232  opts.has_depth_stencil_attachments = false;
2233  auto hash_c = opts.ToKey();
2234 
2235  opts.primitive_type = PrimitiveType::kPoint;
2236  auto hash_d = opts.ToKey();
2237 
2238  EXPECT_NE(hash_a, hash_b);
2239  EXPECT_NE(hash_b, hash_c);
2240  EXPECT_NE(hash_c, hash_d);
2241 }

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() [406/545]

impeller::testing::TEST_P ( EntityTest  ,
ContentsGetBoundsForEmptyPathReturnsNullopt   
)

Definition at line 1242 of file entity_unittests.cc.

1242  {
1243  Entity entity;
1244  entity.SetContents(std::make_shared<SolidColorContents>());
1245  ASSERT_FALSE(entity.GetCoverage().has_value());
1246 }

References impeller::Entity::GetCoverage(), and impeller::Entity::SetContents().

◆ TEST_P() [407/545]

impeller::testing::TEST_P ( EntityTest  ,
CoverageForStrokePathWithNegativeValuesInTransform   
)

Definition at line 2001 of file entity_unittests.cc.

2001  {
2002  auto arrow_head = flutter::DlPathBuilder{}
2003  .MoveTo({50, 120})
2004  .LineTo({120, 190})
2005  .LineTo({190, 120})
2006  .TakePath();
2007  auto geometry = Geometry::MakeStrokePath(arrow_head, //
2008  {
2009  .width = 15.0f,
2010  .cap = Cap::kRound,
2011  .join = Join::kRound,
2012  .miter_limit = 4.0f,
2013  });
2014 
2015  auto transform = Matrix::MakeTranslation({300, 300}) *
2016  Matrix::MakeRotationZ(Radians(kPiOver2));
2017  // Note that e[0][0] used to be tested here, but it was -epsilon solely
2018  // due to floating point inaccuracy in the transcendental trig functions.
2019  // e[1][0] is the intended negative value that we care about (-1.0) as it
2020  // comes from the rotation of pi/2.
2021  EXPECT_LT(transform.e[1][0], 0.0f);
2022  auto coverage = geometry->GetCoverage(transform);
2023  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
2024 }

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() [408/545]

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() [409/545]

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() [410/545]

impeller::testing::TEST_P ( EntityTest  ,
DecalSpecializationAppliedToMorphologyFilter   
)

Definition at line 2209 of file entity_unittests.cc.

2209  {
2210  auto content_context = GetContentContext();
2211  auto default_color_burn = content_context->GetMorphologyFilterPipeline({
2212  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2213  });
2214 
2215  auto decal_supported = static_cast<Scalar>(
2216  GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2217  std::vector<Scalar> expected_constants = {decal_supported};
2218  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2219  expected_constants);
2220 }

References impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [411/545]

impeller::testing::TEST_P ( EntityTest  ,
DrawRoundSuperEllipse   
)

Definition at line 2384 of file entity_unittests.cc.

2384  {
2385  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2386  // UI state.
2387  static int style_index = 0;
2388  static float center[2] = {830, 830};
2389  static float size[2] = {600, 600};
2390  static bool horizontal_symmetry = true;
2391  static bool vertical_symmetry = true;
2392  static bool corner_symmetry = true;
2393 
2394  const char* style_options[] = {"Fill", "Stroke"};
2395 
2396  // Initially radius_tl[0] will be mirrored to all 8 values since all 3
2397  // symmetries are enabled.
2398  static std::array<float, 2> radius_tl = {200};
2399  static std::array<float, 2> radius_tr;
2400  static std::array<float, 2> radius_bl;
2401  static std::array<float, 2> radius_br;
2402 
2403  auto AddRadiusControl = [](std::array<float, 2>& radii, const char* tb_name,
2404  const char* lr_name) {
2405  std::string name = "Radius";
2406  if (!horizontal_symmetry || !vertical_symmetry) {
2407  name += ":";
2408  }
2409  if (!vertical_symmetry) {
2410  name = name + " " + tb_name;
2411  }
2412  if (!horizontal_symmetry) {
2413  name = name + " " + lr_name;
2414  }
2415  if (corner_symmetry) {
2416  ImGui::SliderFloat(name.c_str(), radii.data(), 0, 1000);
2417  } else {
2418  ImGui::SliderFloat2(name.c_str(), radii.data(), 0, 1000);
2419  }
2420  };
2421 
2422  if (corner_symmetry) {
2423  radius_tl[1] = radius_tl[0];
2424  radius_tr[1] = radius_tr[0];
2425  radius_bl[1] = radius_bl[0];
2426  radius_br[1] = radius_br[0];
2427  }
2428 
2429  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
2430  {
2431  ImGui::Combo("Style", &style_index, style_options,
2432  sizeof(style_options) / sizeof(char*));
2433  ImGui::SliderFloat2("Center", center, 0, 1000);
2434  ImGui::SliderFloat2("Size", size, 0, 1000);
2435  ImGui::Checkbox("Symmetry: Horizontal", &horizontal_symmetry);
2436  ImGui::Checkbox("Symmetry: Vertical", &vertical_symmetry);
2437  ImGui::Checkbox("Symmetry: Corners", &corner_symmetry);
2438  AddRadiusControl(radius_tl, "Top", "Left");
2439  if (!horizontal_symmetry) {
2440  AddRadiusControl(radius_tr, "Top", "Right");
2441  } else {
2442  radius_tr = radius_tl;
2443  }
2444  if (!vertical_symmetry) {
2445  AddRadiusControl(radius_bl, "Bottom", "Left");
2446  } else {
2447  radius_bl = radius_tl;
2448  }
2449  if (!horizontal_symmetry && !vertical_symmetry) {
2450  AddRadiusControl(radius_br, "Bottom", "Right");
2451  } else {
2452  if (horizontal_symmetry) {
2453  radius_br = radius_bl;
2454  } else {
2455  radius_br = radius_tr;
2456  }
2457  }
2458  }
2459 
2460  ImGui::End();
2461 
2462  RoundingRadii radii{
2463  .top_left = {radius_tl[0], radius_tl[1]},
2464  .top_right = {radius_tr[0], radius_tr[1]},
2465  .bottom_left = {radius_bl[0], radius_bl[1]},
2466  .bottom_right = {radius_br[0], radius_br[1]},
2467  };
2468 
2469  auto rse = RoundSuperellipse::MakeRectRadii(
2470  RectMakeCenterSize({center[0], center[1]}, {size[0], size[1]}), radii);
2471 
2472  flutter::DlPath path;
2473  std::unique_ptr<Geometry> geom;
2474  if (style_index == 0) {
2475  geom = std::make_unique<RoundSuperellipseGeometry>(
2476  RectMakeCenterSize({center[0], center[1]}, {size[0], size[1]}),
2477  radii);
2478  } else {
2479  path = flutter::DlPath::MakeRoundSuperellipse(rse);
2480  geom = Geometry::MakeStrokePath(path, {.width = 2.0f});
2481  }
2482 
2483  auto contents = std::make_shared<SolidColorContents>();
2484  contents->SetColor(Color::Red());
2485  contents->SetGeometry(geom.get());
2486 
2487  Entity entity;
2488  entity.SetContents(contents);
2489 
2490  return entity.Render(context, pass);
2491  };
2492 
2493  ASSERT_TRUE(OpenPlaygroundHere(callback));
2494 }
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() [412/545]

impeller::testing::TEST_P ( EntityTest  ,
DrawSuperEllipse   
)

Definition at line 2351 of file entity_unittests.cc.

2351  {
2352  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2353  // UI state.
2354  static float alpha = 10;
2355  static float beta = 10;
2356  static float radius = 40;
2357  static int degree = 4;
2358  static Color color = Color::Red();
2359 
2360  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
2361  ImGui::SliderFloat("Alpha", &alpha, 0, 100);
2362  ImGui::SliderFloat("Beta", &beta, 0, 100);
2363  ImGui::SliderInt("Degreee", &degree, 1, 20);
2364  ImGui::SliderFloat("Radius", &radius, 0, 400);
2365  ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
2366  ImGui::End();
2367 
2368  auto contents = std::make_shared<SolidColorContents>();
2369  std::unique_ptr<SuperellipseGeometry> geom =
2370  std::make_unique<SuperellipseGeometry>(Point{400, 400}, radius, degree,
2371  alpha, beta);
2372  contents->SetColor(color);
2373  contents->SetGeometry(geom.get());
2374 
2375  Entity entity;
2376  entity.SetContents(contents);
2377 
2378  return entity.Render(context, pass);
2379  };
2380 
2381  ASSERT_TRUE(OpenPlaygroundHere(callback));
2382 }

References impeller::Color::Red(), impeller::Entity::Render(), and impeller::Entity::SetContents().

◆ TEST_P() [413/545]

impeller::testing::TEST_P ( EntityTest  ,
FailOnValidationError   
)

Definition at line 2300 of file entity_unittests.cc.

2300  {
2301  if (GetParam() != PlaygroundBackend::kVulkan) {
2302  GTEST_SKIP() << "Validation is only fatal on Vulkan backend.";
2303  }
2304  EXPECT_DEATH(
2305  // The easiest way to trigger a validation error is to try to compile
2306  // a shader with an unsupported pixel format.
2307  GetContentContext()->GetBlendColorBurnPipeline({
2308  .color_attachment_pixel_format = PixelFormat::kUnknown,
2309  .has_depth_stencil_attachments = false,
2310  }),
2311  "");
2312 }

References impeller::kUnknown, and impeller::kVulkan.

◆ TEST_P() [414/545]

impeller::testing::TEST_P ( EntityTest  ,
FillPathGeometryGetPositionBufferReturnsExpectedMode   
)

Definition at line 2269 of file entity_unittests.cc.

2269  {
2270  RenderTarget target;
2271  testing::MockRenderPass mock_pass(GetContext(), target);
2272 
2273  auto get_result = [this, &mock_pass](const flutter::DlPath& path) {
2274  auto geometry = Geometry::MakeFillPath(
2275  path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
2276  return geometry->GetPositionBuffer(*GetContentContext(), {}, mock_pass);
2277  };
2278 
2279  // Convex path
2280  {
2281  GeometryResult result =
2282  get_result(flutter::DlPath::MakeRect(Rect::MakeLTRB(0, 0, 100, 100)));
2283  EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
2284  }
2285 
2286  // Concave path
2287  {
2288  flutter::DlPath path = flutter::DlPathBuilder{}
2289  .MoveTo({0, 0})
2290  .LineTo({100, 0})
2291  .LineTo({100, 100})
2292  .LineTo({51, 50})
2293  .Close()
2294  .TakePath();
2295  GeometryResult result = get_result(path);
2296  EXPECT_EQ(result.mode, GeometryResult::Mode::kNonZero);
2297  }
2298 }

References impeller::Close(), impeller::GeometryResult::kNonZero, impeller::GeometryResult::kNormal, impeller::LineTo(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::GeometryResult::mode.

◆ TEST_P() [415/545]

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() [416/545]

impeller::testing::TEST_P ( EntityTest  ,
Filters   
)

Definition at line 919 of file entity_unittests.cc.

919  {
920  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
921  auto boston = CreateTextureForFixture("boston.jpg");
922  auto kalimba = CreateTextureForFixture("kalimba.jpg");
923  ASSERT_TRUE(bridge && boston && kalimba);
924 
925  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
926  auto fi_bridge = FilterInput::Make(bridge);
927  auto fi_boston = FilterInput::Make(boston);
928  auto fi_kalimba = FilterInput::Make(kalimba);
929 
930  std::shared_ptr<FilterContents> blend0 = ColorFilterContents::MakeBlend(
931  BlendMode::kModulate, {fi_kalimba, fi_boston});
932 
933  auto blend1 = ColorFilterContents::MakeBlend(
934  BlendMode::kScreen,
935  {FilterInput::Make(blend0), fi_bridge, fi_bridge, fi_bridge});
936 
937  Entity entity;
938  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
939  Matrix::MakeTranslation({500, 300}) *
940  Matrix::MakeScale(Vector2{0.5, 0.5}));
941  entity.SetContents(blend1);
942  return entity.Render(context, pass);
943  };
944  ASSERT_TRUE(OpenPlaygroundHere(callback));
945 }

References impeller::kModulate, impeller::kScreen, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [417/545]

impeller::testing::TEST_P ( EntityTest  ,
GaussianBlurFilter   
)

Definition at line 947 of file entity_unittests.cc.

947  {
948  auto boston =
949  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
950  ASSERT_TRUE(boston);
951 
952  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
953  const char* input_type_names[] = {"Texture", "Solid Color"};
954  const char* blur_type_names[] = {"Image blur", "Mask blur"};
955  const char* pass_variation_names[] = {"New"};
956  const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
957  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
958  const FilterContents::BlurStyle blur_styles[] = {
959  FilterContents::BlurStyle::kNormal, FilterContents::BlurStyle::kSolid,
960  FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};
961  const Entity::TileMode tile_modes[] = {
962  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
963  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
964 
965  // UI state.
966  static int selected_input_type = 0;
967  static Color input_color = Color::Black();
968  static int selected_blur_type = 0;
969  static int selected_pass_variation = 0;
970  static bool combined_sigma = false;
971  static float blur_amount_coarse[2] = {0, 0};
972  static float blur_amount_fine[2] = {10, 10};
973  static int selected_blur_style = 0;
974  static int selected_tile_mode = 3;
975  static Color cover_color(1, 0, 0, 0.2);
976  static Color bounds_color(0, 1, 0, 0.1);
977  static float offset[2] = {500, 400};
978  static float rotation = 0;
979  static float scale[2] = {0.65, 0.65};
980  static float skew[2] = {0, 0};
981  static float path_rect[4] = {0, 0,
982  static_cast<float>(boston->GetSize().width),
983  static_cast<float>(boston->GetSize().height)};
984 
985  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
986  {
987  ImGui::Combo("Input type", &selected_input_type, input_type_names,
988  sizeof(input_type_names) / sizeof(char*));
989  if (selected_input_type == 0) {
990  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
991  } else {
992  ImGui::ColorEdit4("Input color",
993  reinterpret_cast<float*>(&input_color));
994  }
995  ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
996  sizeof(blur_type_names) / sizeof(char*));
997  if (selected_blur_type == 0) {
998  ImGui::Combo("Pass variation", &selected_pass_variation,
999  pass_variation_names,
1000  sizeof(pass_variation_names) / sizeof(char*));
1001  }
1002  ImGui::Checkbox("Combined sigma", &combined_sigma);
1003  if (combined_sigma) {
1004  ImGui::SliderFloat("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1005  ImGui::SliderFloat("Sigma (fine)", blur_amount_fine, 0, 10);
1006  blur_amount_coarse[1] = blur_amount_coarse[0];
1007  blur_amount_fine[1] = blur_amount_fine[0];
1008  } else {
1009  ImGui::SliderFloat2("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1010  ImGui::SliderFloat2("Sigma (fine)", blur_amount_fine, 0, 10);
1011  }
1012  ImGui::Combo("Blur style", &selected_blur_style, blur_style_names,
1013  sizeof(blur_style_names) / sizeof(char*));
1014  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1015  sizeof(tile_mode_names) / sizeof(char*));
1016  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1017  ImGui::ColorEdit4("Bounds color ",
1018  reinterpret_cast<float*>(&bounds_color));
1019  ImGui::SliderFloat2("Translation", offset, 0,
1020  pass.GetRenderTargetSize().width);
1021  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1022  ImGui::SliderFloat2("Scale", scale, 0, 3);
1023  ImGui::SliderFloat2("Skew", skew, -3, 3);
1024  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1025  }
1026  ImGui::End();
1027 
1028  auto blur_sigma_x = Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
1029  auto blur_sigma_y = Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
1030 
1031  std::shared_ptr<Contents> input;
1032  Size input_size;
1033 
1034  auto input_rect =
1035  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1036 
1037  std::unique_ptr<Geometry> solid_color_input;
1038  if (selected_input_type == 0) {
1039  auto texture = std::make_shared<TextureContents>();
1040  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1041  texture->SetDestinationRect(input_rect);
1042  texture->SetTexture(boston);
1043  texture->SetOpacity(input_color.alpha);
1044 
1045  input = texture;
1046  input_size = input_rect.GetSize();
1047  } else {
1048  auto fill = std::make_shared<SolidColorContents>();
1049  fill->SetColor(input_color);
1050  solid_color_input =
1051  Geometry::MakeFillPath(flutter::DlPath::MakeRect(input_rect));
1052 
1053  fill->SetGeometry(solid_color_input.get());
1054 
1055  input = fill;
1056  input_size = input_rect.GetSize();
1057  }
1058 
1059  std::shared_ptr<FilterContents> blur;
1060  switch (selected_pass_variation) {
1061  case 0:
1062  blur = std::make_shared<GaussianBlurFilterContents>(
1063  blur_sigma_x.sigma, blur_sigma_y.sigma,
1064  tile_modes[selected_tile_mode], blur_styles[selected_blur_style],
1065  /*geometry=*/nullptr);
1066  blur->SetInputs({FilterInput::Make(input)});
1067  break;
1068  case 1:
1069  blur = FilterContents::MakeGaussianBlur(
1070  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1071  tile_modes[selected_tile_mode], blur_styles[selected_blur_style]);
1072  break;
1073  };
1074  FML_CHECK(blur);
1075 
1076  auto mask_blur = FilterContents::MakeBorderMaskBlur(
1077  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1078  blur_styles[selected_blur_style]);
1079 
1080  auto ctm = Matrix::MakeScale(GetContentScale()) *
1081  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1082  Matrix::MakeRotationZ(Radians(rotation)) *
1083  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1084  Matrix::MakeSkew(skew[0], skew[1]) *
1085  Matrix::MakeTranslation(-Point(input_size) / 2);
1086 
1087  auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1088 
1089  Entity entity;
1090  entity.SetContents(target_contents);
1091  entity.SetTransform(ctm);
1092 
1093  entity.Render(context, pass);
1094 
1095  // Renders a red "cover" rectangle that shows the original position of the
1096  // unfiltered input.
1097  Entity cover_entity;
1098  std::unique_ptr<Geometry> geom =
1099  Geometry::MakeFillPath(flutter::DlPath::MakeRect(input_rect));
1100  auto contents = std::make_shared<SolidColorContents>();
1101  contents->SetColor(cover_color);
1102  contents->SetGeometry(geom.get());
1103  cover_entity.SetContents(std::move(contents));
1104  cover_entity.SetTransform(ctm);
1105  cover_entity.Render(context, pass);
1106 
1107  // Renders a green bounding rect of the target filter.
1108  Entity bounds_entity;
1109  std::optional<Rect> target_contents_coverage =
1110  target_contents->GetCoverage(entity);
1111  if (target_contents_coverage.has_value()) {
1112  std::unique_ptr<Geometry> geom =
1113  Geometry::MakeFillPath(flutter::DlPath::MakeRect(
1114  target_contents->GetCoverage(entity).value()));
1115  auto contents = std::make_shared<SolidColorContents>();
1116  contents->SetColor(bounds_color);
1117  contents->SetGeometry(geom.get());
1118 
1119  bounds_entity.SetContents(contents);
1120  bounds_entity.SetTransform(Matrix());
1121  bounds_entity.Render(context, pass);
1122  }
1123 
1124  return true;
1125  };
1126  ASSERT_TRUE(OpenPlaygroundHere(callback));
1127 }

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() [418/545]

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() [419/545]

impeller::testing::TEST_P ( EntityTest  ,
GiantStrokePathAllocation   
)

Definition at line 2526 of file entity_unittests.cc.

2526  {
2527  flutter::DlPathBuilder builder;
2528  for (int i = 0; i < 10000; i++) {
2529  builder.LineTo(Point(i, i));
2530  }
2531  flutter::DlPath path = builder.TakePath();
2532  auto geom = Geometry::MakeStrokePath(path, {.width = 10.0f});
2533 
2534  ContentContext content_context(GetContext(), /*typographer_context=*/nullptr);
2535  Entity entity;
2536 
2537  auto cmd_buffer = content_context.GetContext()->CreateCommandBuffer();
2538 
2539  RenderTargetAllocator allocator(
2540  content_context.GetContext()->GetResourceAllocator());
2541 
2542  auto render_target = allocator.CreateOffscreen(
2543  *content_context.GetContext(), /*size=*/{10, 10}, /*mip_count=*/1);
2544  auto pass = cmd_buffer->CreateRenderPass(render_target);
2545 
2546  GeometryResult result =
2547  geom->GetPositionBuffer(content_context, entity, *pass);
2548 
2549  // Validate the buffer data overflowed the small buffer
2550  EXPECT_GT(result.vertex_buffer.vertex_count, kPointArenaSize);
2551 
2552  // Validate that there are no uninitialized points near the gap.
2553  Point* written_data = reinterpret_cast<Point*>(
2554  (result.vertex_buffer.vertex_buffer.GetBuffer()->OnGetContents() +
2555  result.vertex_buffer.vertex_buffer.GetRange().offset));
2556 
2557  std::vector<Point> expected = {
2558  Point(2043.46, 2050.54), //
2559  Point(2050.54, 2043.46), //
2560  Point(2044.46, 2051.54), //
2561  Point(2051.54, 2044.46), //
2562  Point(2045.46, 2052.54) //
2563  };
2564 
2565  Point point = written_data[kPointArenaSize - 2];
2566  EXPECT_NEAR(point.x, expected[0].x, 0.1);
2567  EXPECT_NEAR(point.y, expected[0].y, 0.1);
2568 
2569  point = written_data[kPointArenaSize - 1];
2570  EXPECT_NEAR(point.x, expected[1].x, 0.1);
2571  EXPECT_NEAR(point.y, expected[1].y, 0.1);
2572 
2573  point = written_data[kPointArenaSize];
2574  EXPECT_NEAR(point.x, expected[2].x, 0.1);
2575  EXPECT_NEAR(point.y, expected[2].y, 0.1);
2576 
2577  point = written_data[kPointArenaSize + 1];
2578  EXPECT_NEAR(point.x, expected[3].x, 0.1);
2579  EXPECT_NEAR(point.y, expected[3].y, 0.1);
2580 
2581  point = written_data[kPointArenaSize + 2];
2582  EXPECT_NEAR(point.x, expected[4].x, 0.1);
2583  EXPECT_NEAR(point.y, expected[4].y, 0.1);
2584 }
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() [420/545]

impeller::testing::TEST_P ( EntityTest  ,
LinearGradientContentsIsOpaque   
)

Definition at line 2067 of file entity_unittests.cc.

2067  {
2068  Matrix matrix;
2069  LinearGradientContents contents;
2070  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2071  contents.SetGeometry(geom.get());
2072 
2073  contents.SetColors({Color::CornflowerBlue()});
2074  EXPECT_TRUE(contents.IsOpaque(matrix));
2075  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2076  EXPECT_FALSE(contents.IsOpaque(matrix));
2077  contents.SetColors({Color::CornflowerBlue()});
2078  contents.SetTileMode(Entity::TileMode::kDecal);
2079  EXPECT_FALSE(contents.IsOpaque(matrix));
2080 
2081  // Create stroked path that required alpha coverage.
2082  geom = Geometry::MakeStrokePath(
2083  flutter::DlPathBuilder{}.MoveTo({0, 0}).LineTo({100, 100}).TakePath(),
2084  {.width = 0.05f});
2085  contents.SetGeometry(geom.get());
2086  contents.SetColors({Color::CornflowerBlue()});
2087 
2088  EXPECT_FALSE(contents.IsOpaque(matrix));
2089 }

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() [421/545]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilter   
)

Definition at line 1556 of file entity_unittests.cc.

1556  {
1557  auto image = CreateTextureForFixture("kalimba.jpg");
1558  ASSERT_TRUE(image);
1559 
1560  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1561  auto filtered =
1562  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));
1563 
1564  // Define the entity that will serve as the control image as a Gaussian blur
1565  // filter with no filter at all.
1566  Entity entity_left;
1567  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1568  Matrix::MakeTranslation({100, 300}) *
1569  Matrix::MakeScale(Vector2{0.5, 0.5}));
1570  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1571  Sigma{0}, Sigma{0});
1572  entity_left.SetContents(unfiltered);
1573 
1574  // Define the entity that will be filtered from linear to sRGB.
1575  Entity entity_right;
1576  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1577  Matrix::MakeTranslation({500, 300}) *
1578  Matrix::MakeScale(Vector2{0.5, 0.5}));
1579  entity_right.SetContents(filtered);
1580  return entity_left.Render(context, pass) &&
1581  entity_right.Render(context, pass);
1582  };
1583 
1584  ASSERT_TRUE(OpenPlaygroundHere(callback));
1585 }

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() [422/545]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilterCoverageIsCorrect   
)

Definition at line 1534 of file entity_unittests.cc.

1534  {
1535  // Set up a simple color background.
1536  auto geom = Geometry::MakeFillPath(
1537  flutter::DlPath::MakeRect(Rect::MakeXYWH(0, 0, 300, 400)));
1538  auto fill = std::make_shared<SolidColorContents>();
1539  fill->SetGeometry(geom.get());
1540  fill->SetColor(Color::MintCream());
1541 
1542  auto filter =
1543  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));
1544 
1545  Entity e;
1546  e.SetTransform(Matrix());
1547 
1548  // Confirm that the actual filter coverage matches the expected coverage.
1549  auto actual = filter->GetCoverage(e);
1550  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1551 
1552  ASSERT_TRUE(actual.has_value());
1553  ASSERT_RECT_NEAR(actual.value(), expected);
1554 }

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() [423/545]

impeller::testing::TEST_P ( EntityTest  ,
MorphologyFilter   
)

Definition at line 1129 of file entity_unittests.cc.

1129  {
1130  auto boston = CreateTextureForFixture("boston.jpg");
1131  ASSERT_TRUE(boston);
1132 
1133  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1134  const char* morphology_type_names[] = {"Dilate", "Erode"};
1135  const FilterContents::MorphType morphology_types[] = {
1136  FilterContents::MorphType::kDilate, FilterContents::MorphType::kErode};
1137  static Color input_color = Color::Black();
1138  // UI state.
1139  static int selected_morphology_type = 0;
1140  static float radius[2] = {20, 20};
1141  static Color cover_color(1, 0, 0, 0.2);
1142  static Color bounds_color(0, 1, 0, 0.1);
1143  static float offset[2] = {500, 400};
1144  static float rotation = 0;
1145  static float scale[2] = {0.65, 0.65};
1146  static float skew[2] = {0, 0};
1147  static float path_rect[4] = {0, 0,
1148  static_cast<float>(boston->GetSize().width),
1149  static_cast<float>(boston->GetSize().height)};
1150  static float effect_transform_scale = 1;
1151 
1152  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1153  {
1154  ImGui::Combo("Morphology type", &selected_morphology_type,
1155  morphology_type_names,
1156  sizeof(morphology_type_names) / sizeof(char*));
1157  ImGui::SliderFloat2("Radius", radius, 0, 200);
1158  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1159  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1160  ImGui::ColorEdit4("Bounds color ",
1161  reinterpret_cast<float*>(&bounds_color));
1162  ImGui::SliderFloat2("Translation", offset, 0,
1163  pass.GetRenderTargetSize().width);
1164  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1165  ImGui::SliderFloat2("Scale", scale, 0, 3);
1166  ImGui::SliderFloat2("Skew", skew, -3, 3);
1167  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1168  ImGui::SliderFloat("Effect transform scale", &effect_transform_scale, 0,
1169  3);
1170  }
1171  ImGui::End();
1172 
1173  std::shared_ptr<Contents> input;
1174  Size input_size;
1175 
1176  auto input_rect =
1177  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1178  auto texture = std::make_shared<TextureContents>();
1179  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1180  texture->SetDestinationRect(input_rect);
1181  texture->SetTexture(boston);
1182  texture->SetOpacity(input_color.alpha);
1183 
1184  input = texture;
1185  input_size = input_rect.GetSize();
1186 
1187  auto contents = FilterContents::MakeMorphology(
1188  FilterInput::Make(input), Radius{radius[0]}, Radius{radius[1]},
1189  morphology_types[selected_morphology_type]);
1190  contents->SetEffectTransform(Matrix::MakeScale(
1191  Vector2{effect_transform_scale, effect_transform_scale}));
1192 
1193  auto ctm = Matrix::MakeScale(GetContentScale()) *
1194  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1195  Matrix::MakeRotationZ(Radians(rotation)) *
1196  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1197  Matrix::MakeSkew(skew[0], skew[1]) *
1198  Matrix::MakeTranslation(-Point(input_size) / 2);
1199 
1200  Entity entity;
1201  entity.SetContents(contents);
1202  entity.SetTransform(ctm);
1203 
1204  entity.Render(context, pass);
1205 
1206  // Renders a red "cover" rectangle that shows the original position of the
1207  // unfiltered input.
1208  Entity cover_entity;
1209  std::unique_ptr<Geometry> geom =
1210  Geometry::MakeFillPath(flutter::DlPath::MakeRect(input_rect));
1211  auto cover_contents = std::make_shared<SolidColorContents>();
1212  cover_contents->SetColor(cover_color);
1213  cover_contents->SetGeometry(geom.get());
1214  cover_entity.SetContents(cover_contents);
1215  cover_entity.SetTransform(ctm);
1216  cover_entity.Render(context, pass);
1217 
1218  // Renders a green bounding rect of the target filter.
1219  Entity bounds_entity;
1220  std::unique_ptr<Geometry> bounds_geom = Geometry::MakeFillPath(
1221  flutter::DlPath::MakeRect(contents->GetCoverage(entity).value()));
1222  auto bounds_contents = std::make_shared<SolidColorContents>();
1223  bounds_contents->SetColor(bounds_color);
1224  bounds_contents->SetGeometry(bounds_geom.get());
1225  bounds_entity.SetContents(std::move(bounds_contents));
1226  bounds_entity.SetTransform(Matrix());
1227 
1228  bounds_entity.Render(context, pass);
1229 
1230  return true;
1231  };
1232  ASSERT_TRUE(OpenPlaygroundHere(callback));
1233 }

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() [424/545]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryCoverage   
)

Definition at line 2150 of file entity_unittests.cc.

2150  {
2151  std::vector<Point> points = {{10, 20}, {100, 200}};
2152  PointFieldGeometry geometry(points.data(), 2, 5.0, false);
2153  ASSERT_EQ(geometry.GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2154  ASSERT_EQ(geometry.GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2155  Rect::MakeLTRB(35, 15, 135, 205));
2156 }

References impeller::PointFieldGeometry::GetCoverage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), and points.

◆ TEST_P() [425/545]

impeller::testing::TEST_P ( EntityTest  ,
RadialGradientContentsIsOpaque   
)

Definition at line 2091 of file entity_unittests.cc.

2091  {
2092  Matrix matrix;
2093  RadialGradientContents contents;
2094  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2095  contents.SetGeometry(geom.get());
2096 
2097  contents.SetColors({Color::CornflowerBlue()});
2098  EXPECT_TRUE(contents.IsOpaque(matrix));
2099  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2100  EXPECT_FALSE(contents.IsOpaque(matrix));
2101  contents.SetColors({Color::CornflowerBlue()});
2102  contents.SetTileMode(Entity::TileMode::kDecal);
2103  EXPECT_FALSE(contents.IsOpaque(matrix));
2104 
2105  // Create stroked path that required alpha coverage.
2106  geom = Geometry::MakeStrokePath(
2107  flutter::DlPathBuilder{}.MoveTo({0, 0}).LineTo({100, 100}).TakePath(),
2108  {.width = 0.05});
2109  contents.SetGeometry(geom.get());
2110  contents.SetColors({Color::CornflowerBlue()});
2111 
2112  EXPECT_FALSE(contents.IsOpaque(matrix));
2113 }

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() [426/545]

impeller::testing::TEST_P ( EntityTest  ,
RoundSuperellipseGetPositionBufferFlushes   
)

Definition at line 2644 of file entity_unittests.cc.

2644  {
2645  RenderTarget target;
2646  testing::MockRenderPass mock_pass(GetContext(), target);
2647 
2648  auto content_context = std::make_shared<FlushTestContentContext>(
2649  GetContext(), GetTypographerContext(),
2650  std::make_shared<FlushTestAllocator>());
2651  auto geometry =
2652  Geometry::MakeRoundSuperellipse(Rect::MakeLTRB(0, 0, 100, 100), 5);
2653  auto result = geometry->GetPositionBuffer(*content_context, {}, mock_pass);
2654 
2655  auto device_buffer = reinterpret_cast<const FlushTestDeviceBuffer*>(
2656  result.vertex_buffer.vertex_buffer.GetBuffer());
2657  EXPECT_TRUE(device_buffer->flush_called());
2658 }

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

◆ TEST_P() [427/545]

impeller::testing::TEST_P ( EntityTest  ,
RRectShadowTest   
)

Definition at line 1392 of file entity_unittests.cc.

1392  {
1393  auto callback = [&](ContentContext& context, RenderPass& pass) {
1394  static Color color = Color::Red();
1395  static float corner_radius = 100;
1396  static float blur_radius = 100;
1397  static bool show_coverage = false;
1398  static Color coverage_color = Color::Green().WithAlpha(0.2);
1399  static PlaygroundPoint top_left_point(Point(200, 200), 30, Color::White());
1400  static PlaygroundPoint bottom_right_point(Point(600, 400), 30,
1401  Color::White());
1402 
1403  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1404  ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
1405  ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
1406  ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
1407  ImGui::Checkbox("Show coverage", &show_coverage);
1408  if (show_coverage) {
1409  ImGui::ColorEdit4("Coverage color",
1410  reinterpret_cast<Scalar*>(&coverage_color));
1411  }
1412  ImGui::End();
1413 
1414  auto [top_left, bottom_right] =
1415  DrawPlaygroundLine(top_left_point, bottom_right_point);
1416  auto rect =
1417  Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1418 
1419  auto contents = std::make_unique<SolidRRectBlurContents>();
1420  contents->SetShape(rect, corner_radius);
1421  contents->SetColor(color);
1422  contents->SetSigma(Radius(blur_radius));
1423 
1424  Entity entity;
1425  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
1426  entity.SetContents(std::move(contents));
1427  entity.Render(context, pass);
1428 
1429  auto coverage = entity.GetCoverage();
1430  if (show_coverage && coverage.has_value()) {
1431  auto bounds_contents = std::make_unique<SolidColorContents>();
1432  auto geom = Geometry::MakeFillPath(
1433  flutter::DlPath::MakeRect(entity.GetCoverage().value()));
1434  bounds_contents->SetGeometry(geom.get());
1435  bounds_contents->SetColor(coverage_color.Premultiply());
1436  Entity bounds_entity;
1437  bounds_entity.SetContents(std::move(bounds_contents));
1438  bounds_entity.Render(context, pass);
1439  }
1440 
1441  return true;
1442  };
1443  ASSERT_TRUE(OpenPlaygroundHere(callback));
1444 }

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() [428/545]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffect   
)

Definition at line 1752 of file entity_unittests.cc.

1752  {
1753  auto runtime_stages =
1754  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1755  auto runtime_stage =
1756  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1757  ASSERT_TRUE(runtime_stage);
1758  ASSERT_TRUE(runtime_stage->IsDirty());
1759 
1760  bool expect_dirty = true;
1761 
1762  PipelineRef first_pipeline;
1763  std::unique_ptr<Geometry> geom = Geometry::MakeCover();
1764 
1765  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1766  EXPECT_EQ(runtime_stage->IsDirty(), expect_dirty);
1767 
1768  auto contents = std::make_shared<RuntimeEffectContents>();
1769  contents->SetGeometry(geom.get());
1770  contents->SetRuntimeStage(runtime_stage);
1771 
1772  struct FragUniforms {
1773  Vector2 iResolution;
1774  Scalar iTime;
1775  } frag_uniforms = {
1776  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1777  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1778  };
1779  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1780  uniform_data->resize(sizeof(FragUniforms));
1781  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1782  contents->SetUniformData(uniform_data);
1783 
1784  Entity entity;
1785  entity.SetContents(contents);
1786  bool result = contents->Render(context, entity, pass);
1787 
1788  if (expect_dirty) {
1789  first_pipeline = pass.GetCommands().back().pipeline;
1790  } else {
1791  EXPECT_EQ(pass.GetCommands().back().pipeline, first_pipeline);
1792  }
1793  expect_dirty = false;
1794  return result;
1795  };
1796 
1797  // Simulate some renders and hot reloading of the shader.
1798  auto content_context = GetContentContext();
1799  {
1800  RenderTarget target =
1801  content_context->GetRenderTargetCache()->CreateOffscreen(
1802  *content_context->GetContext(), {1, 1}, 1u);
1803 
1804  testing::MockRenderPass mock_pass(GetContext(), target);
1805  callback(*content_context, mock_pass);
1806  callback(*content_context, mock_pass);
1807 
1808  // Dirty the runtime stage.
1809  runtime_stages = OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1810  runtime_stage =
1811  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1812 
1813  ASSERT_TRUE(runtime_stage->IsDirty());
1814  expect_dirty = true;
1815 
1816  callback(*content_context, mock_pass);
1817  }
1818 }
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() [429/545]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanPrecache   
)

Definition at line 1867 of file entity_unittests.cc.

1867  {
1868  auto runtime_stages =
1869  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1870  auto runtime_stage =
1871  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1872  ASSERT_TRUE(runtime_stage);
1873  ASSERT_TRUE(runtime_stage->IsDirty());
1874 
1875  auto contents = std::make_shared<RuntimeEffectContents>();
1876  contents->SetRuntimeStage(runtime_stage);
1877 
1878  EXPECT_TRUE(contents->BootstrapShader(*GetContentContext()));
1879 }

References impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [430/545]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanSuccessfullyRender   
)

Definition at line 1820 of file entity_unittests.cc.

1820  {
1821  auto runtime_stages =
1822  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1823  auto runtime_stage =
1824  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1825  ASSERT_TRUE(runtime_stage);
1826  ASSERT_TRUE(runtime_stage->IsDirty());
1827 
1828  auto contents = std::make_shared<RuntimeEffectContents>();
1829  auto geom = Geometry::MakeCover();
1830  contents->SetGeometry(geom.get());
1831  contents->SetRuntimeStage(runtime_stage);
1832 
1833  struct FragUniforms {
1834  Vector2 iResolution;
1835  Scalar iTime;
1836  } frag_uniforms = {
1837  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1838  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1839  };
1840  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1841  uniform_data->resize(sizeof(FragUniforms));
1842  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1843  contents->SetUniformData(uniform_data);
1844 
1845  Entity entity;
1846  entity.SetContents(contents);
1847 
1848  // Create a render target with a depth-stencil, similar to how EntityPass
1849  // does.
1850  RenderTarget target =
1851  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
1852  *GetContext(), {GetWindowSize().width, GetWindowSize().height}, 1,
1853  "RuntimeEffect Texture");
1854  testing::MockRenderPass pass(GetContext(), target);
1855 
1856  ASSERT_TRUE(contents->Render(*GetContentContext(), entity, pass));
1857  ASSERT_EQ(pass.GetCommands().size(), 1u);
1858  const auto& command = pass.GetCommands()[0];
1859  ASSERT_TRUE(command.pipeline->GetDescriptor()
1860  .GetDepthStencilAttachmentDescriptor()
1861  .has_value());
1862  ASSERT_TRUE(command.pipeline->GetDescriptor()
1863  .GetFrontStencilAttachmentDescriptor()
1864  .has_value());
1865 }

References impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [431/545]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectSetsRightSizeWhenUniformIsStruct   
)

Definition at line 1881 of file entity_unittests.cc.

1881  {
1882  if (GetBackend() != PlaygroundBackend::kVulkan) {
1883  GTEST_SKIP() << "Test only applies to Vulkan";
1884  }
1885 
1886  auto runtime_stages =
1887  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1888  auto runtime_stage =
1889  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1890  ASSERT_TRUE(runtime_stage);
1891  ASSERT_TRUE(runtime_stage->IsDirty());
1892 
1893  auto contents = std::make_shared<RuntimeEffectContents>();
1894  auto geom = Geometry::MakeCover();
1895  contents->SetGeometry(geom.get());
1896  contents->SetRuntimeStage(runtime_stage);
1897 
1898  struct FragUniforms {
1899  Vector2 iResolution;
1900  Scalar iTime;
1901  } frag_uniforms = {
1902  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1903  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1904  };
1905  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1906  uniform_data->resize(sizeof(FragUniforms));
1907  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1908 
1909  auto buffer_view = RuntimeEffectContents::EmplaceVulkanUniform(
1910  uniform_data, GetContentContext()->GetTransientsBuffer(),
1911  runtime_stage->GetUniforms()[0],
1912  GetContentContext()->GetTransientsBuffer().GetMinimumUniformAlignment());
1913 
1914  // 16 bytes:
1915  // 8 bytes for iResolution
1916  // 4 bytes for iTime
1917  // 4 bytes padding
1918  EXPECT_EQ(buffer_view.GetRange().length, 16u);
1919 }

References buffer_view, impeller::RuntimeEffectContents::EmplaceVulkanUniform(), impeller::kVulkan, impeller::Geometry::MakeCover(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [432/545]

impeller::testing::TEST_P ( EntityTest  ,
SetBlendMode   
)

Definition at line 1235 of file entity_unittests.cc.

1235  {
1236  Entity entity;
1237  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSrcOver);
1238  entity.SetBlendMode(BlendMode::kClear);
1239  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kClear);
1240 }

References impeller::Entity::GetBlendMode(), impeller::kClear, impeller::kSrcOver, and impeller::Entity::SetBlendMode().

◆ TEST_P() [433/545]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorApplyColorFilter   
)

Definition at line 2496 of file entity_unittests.cc.

2496  {
2497  auto contents = SolidColorContents();
2498  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
2499  auto result = contents.ApplyColorFilter([](const Color& color) {
2500  return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
2501  });
2502  ASSERT_TRUE(result);
2503  ASSERT_COLOR_NEAR(contents.GetColor(),
2504  Color(0.424452, 0.828743, 0.79105, 0.9375));
2505 }

References ASSERT_COLOR_NEAR, impeller::Color::Blend(), impeller::Color::CornflowerBlue(), impeller::kScreen, and impeller::Color::LimeGreen().

◆ TEST_P() [434/545]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsIsOpaque   
)

Definition at line 2026 of file entity_unittests.cc.

2026  {
2027  Matrix matrix;
2028  SolidColorContents contents;
2029  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2030  contents.SetGeometry(geom.get());
2031 
2032  contents.SetColor(Color::CornflowerBlue());
2033  EXPECT_TRUE(contents.IsOpaque(matrix));
2034  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
2035  EXPECT_FALSE(contents.IsOpaque(matrix));
2036 
2037  // Create stroked path that required alpha coverage.
2038  geom = Geometry::MakeStrokePath(flutter::DlPath::MakeLine({0, 0}, {100, 100}),
2039  {.width = 0.05});
2040  contents.SetGeometry(geom.get());
2041  contents.SetColor(Color::CornflowerBlue());
2042 
2043  EXPECT_FALSE(contents.IsOpaque(matrix));
2044 }

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() [435/545]

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() [436/545]

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() [437/545]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillCoverageIsCorrect   
)

Definition at line 1347 of file entity_unittests.cc.

1347  {
1348  // No transform
1349  {
1350  auto fill = std::make_shared<SolidColorContents>();
1351  fill->SetColor(Color::CornflowerBlue());
1352  auto expected = Rect::MakeLTRB(100, 110, 200, 220);
1353  auto geom = Geometry::MakeFillPath(flutter::DlPath::MakeRect(expected));
1354  fill->SetGeometry(geom.get());
1355 
1356  auto coverage = fill->GetCoverage({});
1357  ASSERT_TRUE(coverage.has_value());
1358  ASSERT_RECT_NEAR(coverage.value(), expected);
1359  }
1360 
1361  // Entity transform
1362  {
1363  auto fill = std::make_shared<SolidColorContents>();
1364  auto geom = Geometry::MakeFillPath(
1365  flutter::DlPath::MakeRect(Rect::MakeLTRB(100, 110, 200, 220)));
1366  fill->SetColor(Color::CornflowerBlue());
1367  fill->SetGeometry(geom.get());
1368 
1369  Entity entity;
1370  entity.SetTransform(Matrix::MakeTranslation(Vector2(4, 5)));
1371  entity.SetContents(std::move(fill));
1372 
1373  auto coverage = entity.GetCoverage();
1374  auto expected = Rect::MakeLTRB(104, 115, 204, 225);
1375  ASSERT_TRUE(coverage.has_value());
1376  ASSERT_RECT_NEAR(coverage.value(), expected);
1377  }
1378 
1379  // No coverage for fully transparent colors
1380  {
1381  auto fill = std::make_shared<SolidColorContents>();
1382  auto geom = Geometry::MakeFillPath(
1383  flutter::DlPath::MakeRect(Rect::MakeLTRB(100, 110, 200, 220)));
1384  fill->SetColor(Color::WhiteTransparent());
1385  fill->SetGeometry(geom.get());
1386 
1387  auto coverage = fill->GetCoverage({});
1388  ASSERT_FALSE(coverage.has_value());
1389  }
1390 }

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() [438/545]

impeller::testing::TEST_P ( EntityTest  ,
SolidStrokeCoverageIsCorrect   
)

Definition at line 1248 of file entity_unittests.cc.

1248  {
1249  {
1250  auto geometry = Geometry::MakeStrokePath(
1251  flutter::DlPath::MakeLine({0, 0}, {10, 10}), //
1252  {
1253  .width = 4.0f,
1254  .cap = Cap::kButt,
1255  .join = Join::kBevel,
1256  .miter_limit = 4.0f,
1257  });
1258 
1259  Entity entity;
1260  auto contents = std::make_unique<SolidColorContents>();
1261  contents->SetGeometry(geometry.get());
1262  contents->SetColor(Color::Black());
1263  entity.SetContents(std::move(contents));
1264  auto actual = entity.GetCoverage();
1265  auto expected = Rect::MakeLTRB(-2, -2, 12, 12);
1266 
1267  ASSERT_TRUE(actual.has_value());
1268  ASSERT_RECT_NEAR(actual.value(), expected);
1269  }
1270 
1271  // Cover the Cap::kSquare case.
1272  {
1273  auto geometry = Geometry::MakeStrokePath(
1274  flutter::DlPath::MakeLine({0, 0}, {10, 10}), //
1275  {
1276  .width = 4.0,
1277  .cap = Cap::kSquare,
1278  .join = Join::kBevel,
1279  .miter_limit = 4.0,
1280  });
1281 
1282  Entity entity;
1283  auto contents = std::make_unique<SolidColorContents>();
1284  contents->SetGeometry(geometry.get());
1285  contents->SetColor(Color::Black());
1286  entity.SetContents(std::move(contents));
1287  auto actual = entity.GetCoverage();
1288  auto expected =
1289  Rect::MakeLTRB(-sqrt(8), -sqrt(8), 10 + sqrt(8), 10 + sqrt(8));
1290 
1291  ASSERT_TRUE(actual.has_value());
1292  ASSERT_RECT_NEAR(actual.value(), expected);
1293  }
1294 
1295  // Cover the Join::kMiter case.
1296  {
1297  auto geometry = Geometry::MakeStrokePath(
1298  flutter::DlPath::MakeLine({0, 0}, {10, 10}), //
1299  {
1300  .width = 4.0f,
1301  .cap = Cap::kSquare,
1302  .join = Join::kMiter,
1303  .miter_limit = 2.0f,
1304  });
1305 
1306  Entity entity;
1307  auto contents = std::make_unique<SolidColorContents>();
1308  contents->SetGeometry(geometry.get());
1309  contents->SetColor(Color::Black());
1310  entity.SetContents(std::move(contents));
1311  auto actual = entity.GetCoverage();
1312  auto expected = Rect::MakeLTRB(-4, -4, 14, 14);
1313 
1314  ASSERT_TRUE(actual.has_value());
1315  ASSERT_RECT_NEAR(actual.value(), expected);
1316  }
1317 }

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() [439/545]

impeller::testing::TEST_P ( EntityTest  ,
SpecializationConstantsAreAppliedToVariants   
)

Definition at line 2186 of file entity_unittests.cc.

2186  {
2187  auto content_context = GetContentContext();
2188 
2189  auto default_gyph = content_context->GetGlyphAtlasPipeline({
2190  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2191  .has_depth_stencil_attachments = false,
2192  });
2193  auto alt_gyph = content_context->GetGlyphAtlasPipeline(
2194  {.color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2195  .has_depth_stencil_attachments = true});
2196 
2197  EXPECT_NE(default_gyph, alt_gyph);
2198  EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2199  alt_gyph->GetDescriptor().GetSpecializationConstants());
2200 
2201  auto use_a8 = GetContext()->GetCapabilities()->GetDefaultGlyphAtlasFormat() ==
2202  PixelFormat::kA8UNormInt;
2203 
2204  std::vector<Scalar> expected_constants = {static_cast<Scalar>(use_a8)};
2205  EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2206  expected_constants);
2207 }

References impeller::kA8UNormInt, and impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [440/545]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilter   
)

Definition at line 1609 of file entity_unittests.cc.

1609  {
1610  auto image = CreateTextureForFixture("embarcadero.jpg");
1611  ASSERT_TRUE(image);
1612 
1613  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1614  auto filtered =
1615  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));
1616 
1617  // Define the entity that will serve as the control image as a Gaussian blur
1618  // filter with no filter at all.
1619  Entity entity_left;
1620  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1621  Matrix::MakeTranslation({100, 300}) *
1622  Matrix::MakeScale(Vector2{0.5, 0.5}));
1623  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1624  Sigma{0}, Sigma{0});
1625  entity_left.SetContents(unfiltered);
1626 
1627  // Define the entity that will be filtered from sRGB to linear.
1628  Entity entity_right;
1629  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1630  Matrix::MakeTranslation({500, 300}) *
1631  Matrix::MakeScale(Vector2{0.5, 0.5}));
1632  entity_right.SetContents(filtered);
1633  return entity_left.Render(context, pass) &&
1634  entity_right.Render(context, pass);
1635  };
1636 
1637  ASSERT_TRUE(OpenPlaygroundHere(callback));
1638 }

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() [441/545]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilterCoverageIsCorrect   
)

Definition at line 1587 of file entity_unittests.cc.

1587  {
1588  // Set up a simple color background.
1589  auto fill = std::make_shared<SolidColorContents>();
1590  auto geom = Geometry::MakeFillPath(
1591  flutter::DlPath::MakeRect(Rect::MakeXYWH(0, 0, 300, 400)));
1592  fill->SetGeometry(geom.get());
1593  fill->SetColor(Color::DeepPink());
1594 
1595  auto filter =
1596  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));
1597 
1598  Entity e;
1599  e.SetTransform(Matrix());
1600 
1601  // Confirm that the actual filter coverage matches the expected coverage.
1602  auto actual = filter->GetCoverage(e);
1603  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1604 
1605  ASSERT_TRUE(actual.has_value());
1606  ASSERT_RECT_NEAR(actual.value(), expected);
1607 }

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() [442/545]

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() [443/545]

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() [444/545]

impeller::testing::TEST_P ( EntityTest  ,
SweepGradientContentsIsOpaque   
)

Definition at line 2115 of file entity_unittests.cc.

2115  {
2116  Matrix matrix;
2117  RadialGradientContents contents;
2118  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2119  contents.SetGeometry(geom.get());
2120 
2121  contents.SetColors({Color::CornflowerBlue()});
2122  EXPECT_TRUE(contents.IsOpaque(matrix));
2123  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2124  EXPECT_FALSE(contents.IsOpaque(matrix));
2125  contents.SetColors({Color::CornflowerBlue()});
2126  contents.SetTileMode(Entity::TileMode::kDecal);
2127  EXPECT_FALSE(contents.IsOpaque(matrix));
2128 
2129  // Create stroked path that required alpha coverage.
2130  geom = Geometry::MakeStrokePath(
2131  flutter::DlPathBuilder{}.MoveTo({0, 0}).LineTo({100, 100}).TakePath(),
2132  {.width = 0.05f});
2133  contents.SetGeometry(geom.get());
2134  contents.SetColors({Color::CornflowerBlue()});
2135 
2136  EXPECT_FALSE(contents.IsOpaque(matrix));
2137 }

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() [445/545]

impeller::testing::TEST_P ( EntityTest  ,
TextContentsCeilsGlyphScaleToDecimal   
)

Definition at line 2178 of file entity_unittests.cc.

2178  {
2179  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f), Rational(43, 100));
2180  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f), Rational(53, 100));
2181  ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f), Rational(21, 10));
2182  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f), Rational(0, 1));
2183  ASSERT_EQ(TextFrame::RoundScaledFontSize(100000000.0f), Rational(48, 1));
2184 }

References impeller::TextFrame::RoundScaledFontSize().

◆ TEST_P() [446/545]

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() [447/545]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsIsOpaque   
)

Definition at line 2139 of file entity_unittests.cc.

2139  {
2140  Matrix matrix;
2141  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
2142  TiledTextureContents contents;
2143  contents.SetTexture(bay_bridge);
2144  // This is a placeholder test. Images currently never decompress as opaque
2145  // (whether in Flutter or the playground), and so this should currently always
2146  // return false in practice.
2147  EXPECT_FALSE(contents.IsOpaque(matrix));
2148 }

References impeller::TiledTextureContents::IsOpaque(), and impeller::TiledTextureContents::SetTexture().

◆ TEST_P() [448/545]

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() [449/545]

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() [450/545]

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() [451/545]

impeller::testing::TEST_P ( EntityTest  ,
YUVToRGBFilter   
)

Definition at line 1718 of file entity_unittests.cc.

1718  {
1719  if (GetParam() == PlaygroundBackend::kOpenGLES) {
1720  // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
1721  GTEST_SKIP()
1722  << "YUV to RGB filter is not supported on OpenGLES backend yet.";
1723  }
1724 
1725  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1726  YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
1727  YUVColorSpace::kBT601LimitedRange};
1728  for (int i = 0; i < 2; i++) {
1729  auto yuv_color_space = yuv_color_space_array[i];
1730  auto textures =
1731  CreateTestYUVTextures(GetContext().get(), yuv_color_space);
1732  auto filter_contents = FilterContents::MakeYUVToRGBFilter(
1733  textures[0], textures[1], yuv_color_space);
1734  Entity filter_entity;
1735  filter_entity.SetContents(filter_contents);
1736  auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
1737 
1738  Entity entity;
1739  auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
1740  contents->SetTexture(snapshot->texture);
1741  contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
1742  entity.SetContents(contents);
1743  entity.SetTransform(
1744  Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
1745  entity.Render(context, pass);
1746  }
1747  return true;
1748  };
1749  ASSERT_TRUE(OpenPlaygroundHere(callback));
1750 }
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() [452/545]

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() [453/545]

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() [454/545]

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() [455/545]

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() [456/545]

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() [457/545]

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() [458/545]

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() [459/545]

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() [460/545]

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() [461/545]

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() [462/545]

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() [463/545]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplaceWithFailingAllocationDoesntCrash   
)

Definition at line 221 of file host_buffer_unittests.cc.

221  {
222  ScopedValidationDisable disable;
223  std::shared_ptr<FailingAllocator> allocator =
224  std::make_shared<FailingAllocator>(GetContext()->GetResourceAllocator());
225  auto buffer =
226  HostBuffer::Create(allocator, GetContext()->GetIdleWaiter(), 256);
227 
228  auto view = buffer->Emplace(nullptr, kMagicFailingAllocation, 0);
229 
230  EXPECT_EQ(view.GetBuffer(), nullptr);
231  EXPECT_EQ(view.GetRange().offset, 0u);
232  EXPECT_EQ(view.GetRange().length, 0u);
233 }
static constexpr const size_t kMagicFailingAllocation

References impeller::HostBuffer::Create(), and kMagicFailingAllocation.

◆ TEST_P() [464/545]

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() [465/545]

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() [466/545]

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() [467/545]

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() [468/545]

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() [469/545]

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() [470/545]

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() [471/545]

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() [472/545]

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() [473/545]

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() [474/545]

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() [475/545]

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() [476/545]

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() [477/545]

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() [478/545]

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() [479/545]

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() [480/545]

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() [481/545]

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() [482/545]

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() [483/545]

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() [484/545]

impeller::testing::TEST_P ( RendererTest  ,
ArrayUniforms   
)

Definition at line 1029 of file renderer_unittests.cc.

1029  {
1030  using VS = ArrayVertexShader;
1031  using FS = ArrayFragmentShader;
1032 
1033  auto context = GetContext();
1034  auto pipeline_descriptor =
1035  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
1036  ASSERT_TRUE(pipeline_descriptor.has_value());
1037  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1038  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1039  auto pipeline =
1040  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1041  ASSERT_TRUE(pipeline && pipeline->IsValid());
1042 
1043  auto host_buffer = HostBuffer::Create(
1044  context->GetResourceAllocator(), context->GetIdleWaiter(),
1045  context->GetCapabilities()->GetMinimumUniformAlignment());
1046  SinglePassCallback callback = [&](RenderPass& pass) {
1047  auto size = pass.GetRenderTargetSize();
1048 
1049  pass.SetPipeline(pipeline);
1050  pass.SetCommandLabel("Google Dots");
1051  VertexBufferBuilder<VS::PerVertexData> builder;
1052  builder.AddVertices({{Point()},
1053  {Point(0, size.height)},
1054  {Point(size.width, 0)},
1055  {Point(size.width, 0)},
1056  {Point(0, size.height)},
1057  {Point(size.width, size.height)}});
1058  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1059 
1060  VS::FrameInfo frame_info;
1061  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1062  frame_info.mvp =
1063  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1064  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1065 
1066  auto time = GetSecondsElapsed();
1067  auto y_pos = [&time](float x) {
1068  return 400 + 10 * std::cos(time * 5 + x / 6);
1069  };
1070 
1071  FS::FragInfo fs_uniform = {
1072  .circle_positions = {Point(430, y_pos(0)), Point(480, y_pos(1)),
1073  Point(530, y_pos(2)), Point(580, y_pos(3))},
1074  .colors = {Color::MakeRGBA8(66, 133, 244, 255),
1075  Color::MakeRGBA8(219, 68, 55, 255),
1076  Color::MakeRGBA8(244, 180, 0, 255),
1077  Color::MakeRGBA8(15, 157, 88, 255)},
1078  };
1079  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1080 
1081  pass.Draw();
1082  host_buffer->Reset();
1083  return true;
1084  };
1085  OpenPlaygroundHere(callback);
1086 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), 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() [485/545]

impeller::testing::TEST_P ( RendererTest  ,
BabysFirstTriangle   
)

Definition at line 123 of file renderer_unittests.cc.

123  {
124  auto context = GetContext();
125  ASSERT_TRUE(context);
126 
127  // Declare a shorthand for the shaders we are going to use.
128  using VS = BabyVertexShader;
129  using FS = BabyFragmentShader;
130 
131  // Create a pipeline descriptor that uses the shaders together and default
132  // initializes the fixed function state.
133  //
134  // If the vertex shader outputs disagree with the fragment shader inputs, this
135  // will be a compile time error.
136  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
137  ASSERT_TRUE(desc.has_value());
138 
139  // Modify the descriptor for our environment. This is specific to our test.
140  desc->SetSampleCount(SampleCount::kCount4);
141  desc->SetStencilAttachmentDescriptors(std::nullopt);
142 
143  // Create a pipeline from our descriptor. This is expensive to do. So just do
144  // it once.
145  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
146 
147  // Create a host side buffer to build the vertex and uniform information.
148  auto host_buffer = HostBuffer::Create(
149  context->GetResourceAllocator(), context->GetIdleWaiter(),
150  context->GetCapabilities()->GetMinimumUniformAlignment());
151 
152  // Specify the vertex buffer information.
153  VertexBufferBuilder<VS::PerVertexData> vertex_buffer_builder;
154  vertex_buffer_builder.AddVertices({
155  {{-0.5, -0.5}, Color::Red(), Color::Green()},
156  {{0.0, 0.5}, Color::Green(), Color::Blue()},
157  {{0.5, -0.5}, Color::Blue(), Color::Red()},
158  });
159 
160  auto vertex_buffer = vertex_buffer_builder.CreateVertexBuffer(
161  *context->GetResourceAllocator());
162 
163  SinglePassCallback callback = [&](RenderPass& pass) {
164  pass.SetPipeline(pipeline);
165  pass.SetVertexBuffer(vertex_buffer);
166 
167  FS::FragInfo frag_info;
168  frag_info.time = fml::TimePoint::Now().ToEpochDelta().ToSecondsF();
169 
170  auto host_buffer = HostBuffer::Create(
171  context->GetResourceAllocator(), context->GetIdleWaiter(),
172  context->GetCapabilities()->GetMinimumUniformAlignment());
173  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(frag_info));
174 
175  return pass.Draw().ok();
176  };
177  OpenPlaygroundHere(callback);
178 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Color::Blue(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Color::Green(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), and impeller::Color::Red().

◆ TEST_P() [486/545]

impeller::testing::TEST_P ( RendererTest  ,
BindingNullTexturesDoesNotCrash   
)

Definition at line 1630 of file renderer_unittests.cc.

1630  {
1631  using FS = BoxFadeFragmentShader;
1632 
1633  auto context = GetContext();
1634  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
1635  auto command_buffer = context->CreateCommandBuffer();
1636 
1637  RenderTargetAllocator allocator(context->GetResourceAllocator());
1638  RenderTarget target = allocator.CreateOffscreen(*context, {1, 1}, 1);
1639 
1640  auto pass = command_buffer->CreateRenderPass(target);
1641  EXPECT_FALSE(FS::BindContents2(*pass, nullptr, sampler));
1642 }

References impeller::RenderTargetAllocator::CreateOffscreen().

◆ TEST_P() [487/545]

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() [488/545]

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() [489/545]

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() [490/545]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToBuffer   
)

Definition at line 642 of file renderer_unittests.cc.

642  {
643  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
644  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
645  }
646  auto context = GetContext();
647  ASSERT_TRUE(context);
648 
649  using VS = MipmapsVertexShader;
650  using FS = MipmapsFragmentShader;
651  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
652  ASSERT_TRUE(desc.has_value());
653  desc->SetSampleCount(SampleCount::kCount4);
654  desc->SetStencilAttachmentDescriptors(std::nullopt);
655  auto mipmaps_pipeline =
656  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
657  ASSERT_TRUE(mipmaps_pipeline);
658 
659  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
660  auto boston = CreateTextureForFixture("boston.jpg");
661  ASSERT_TRUE(bridge && boston);
662  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
663  ASSERT_TRUE(sampler);
664 
665  TextureDescriptor texture_desc;
666  texture_desc.storage_mode = StorageMode::kHostVisible;
667  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
668  texture_desc.size = bridge->GetTextureDescriptor().size;
669  texture_desc.mip_count = 1u;
670  texture_desc.usage = TextureUsage::kRenderTarget |
671  TextureUsage::kShaderWrite | TextureUsage::kShaderRead;
672  DeviceBufferDescriptor device_buffer_desc;
673  device_buffer_desc.storage_mode = StorageMode::kHostVisible;
674  device_buffer_desc.size =
675  bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
676  auto device_buffer =
677  context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
678 
679  // Vertex buffer.
680  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
681  vertex_builder.SetLabel("Box");
682  auto size = Point(boston->GetSize());
683  vertex_builder.AddVertices({
684  {{0, 0}, {0.0, 0.0}}, // 1
685  {{size.x, 0}, {1.0, 0.0}}, // 2
686  {{size.x, size.y}, {1.0, 1.0}}, // 3
687  {{0, 0}, {0.0, 0.0}}, // 1
688  {{size.x, size.y}, {1.0, 1.0}}, // 3
689  {{0, size.y}, {0.0, 1.0}}, // 4
690  });
691  auto vertex_buffer =
692  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
693  ASSERT_TRUE(vertex_buffer);
694 
695  auto host_buffer = HostBuffer::Create(
696  context->GetResourceAllocator(), context->GetIdleWaiter(),
697  context->GetCapabilities()->GetMinimumUniformAlignment());
698  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
699  {
700  auto buffer = context->CreateCommandBuffer();
701  if (!buffer) {
702  return false;
703  }
704  buffer->SetLabel("Playground Command Buffer");
705  auto pass = buffer->CreateBlitPass();
706  if (!pass) {
707  return false;
708  }
709  pass->SetLabel("Playground Blit Pass");
710 
711  // Blit `bridge` to the top left corner of the texture.
712  pass->AddCopy(bridge, device_buffer);
713  pass->EncodeCommands();
714 
715  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
716  return false;
717  }
718  }
719 
720  {
721  auto buffer = context->CreateCommandBuffer();
722  if (!buffer) {
723  return false;
724  }
725  buffer->SetLabel("Playground Command Buffer");
726 
727  auto pass = buffer->CreateRenderPass(render_target);
728  if (!pass) {
729  return false;
730  }
731  pass->SetLabel("Playground Render Pass");
732  {
733  pass->SetCommandLabel("Image");
734  pass->SetPipeline(mipmaps_pipeline);
735  pass->SetVertexBuffer(vertex_buffer);
736 
737  VS::FrameInfo frame_info;
738  EXPECT_EQ(pass->GetOrthographicTransform(),
739  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
740  frame_info.mvp = pass->GetOrthographicTransform() *
741  Matrix::MakeScale(GetContentScale());
742  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
743 
744  FS::FragInfo frag_info;
745  frag_info.lod = 0;
746  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
747 
748  raw_ptr<const Sampler> sampler =
749  context->GetSamplerLibrary()->GetSampler({});
750  auto buffer_view = DeviceBuffer::AsBufferView(device_buffer);
751  auto texture =
752  context->GetResourceAllocator()->CreateTexture(texture_desc);
753  if (!texture->SetContents(device_buffer->OnGetContents(),
754  buffer_view.GetRange().length)) {
755  VALIDATION_LOG << "Could not upload texture to device memory";
756  return false;
757  }
758  FS::BindTex(*pass, texture, sampler);
759 
760  pass->Draw().ok();
761  }
762  pass->EncodeCommands();
763  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
764  return false;
765  }
766  }
767  host_buffer->Reset();
768  return true;
769  };
770  OpenPlaygroundHere(callback);
771 }
#define VALIDATION_LOG
Definition: validation.h:91

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::DeviceBuffer::AsBufferView(), buffer_view, impeller::HostBuffer::Create(), 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() [491/545]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToTexture   
)

Definition at line 530 of file renderer_unittests.cc.

530  {
531  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
532  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
533  }
534  auto context = GetContext();
535  ASSERT_TRUE(context);
536 
537  using VS = MipmapsVertexShader;
538  using FS = MipmapsFragmentShader;
539  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
540  ASSERT_TRUE(desc.has_value());
541  desc->SetSampleCount(SampleCount::kCount4);
542  desc->SetStencilAttachmentDescriptors(std::nullopt);
543  auto mipmaps_pipeline =
544  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
545  ASSERT_TRUE(mipmaps_pipeline);
546 
547  TextureDescriptor texture_desc;
548  texture_desc.storage_mode = StorageMode::kHostVisible;
549  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
550  texture_desc.size = {800, 600};
551  texture_desc.mip_count = 1u;
552  texture_desc.usage = TextureUsage::kRenderTarget | TextureUsage::kShaderRead;
553  auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
554  ASSERT_TRUE(texture);
555 
556  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
557  auto boston = CreateTextureForFixture("boston.jpg");
558  ASSERT_TRUE(bridge && boston);
559  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
560  ASSERT_TRUE(sampler);
561 
562  // Vertex buffer.
563  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
564  vertex_builder.SetLabel("Box");
565  auto size = Point(boston->GetSize());
566  vertex_builder.AddVertices({
567  {{0, 0}, {0.0, 0.0}}, // 1
568  {{size.x, 0}, {1.0, 0.0}}, // 2
569  {{size.x, size.y}, {1.0, 1.0}}, // 3
570  {{0, 0}, {0.0, 0.0}}, // 1
571  {{size.x, size.y}, {1.0, 1.0}}, // 3
572  {{0, size.y}, {0.0, 1.0}}, // 4
573  });
574  auto vertex_buffer =
575  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
576  ASSERT_TRUE(vertex_buffer);
577 
578  auto host_buffer = HostBuffer::Create(
579  context->GetResourceAllocator(), context->GetIdleWaiter(),
580  context->GetCapabilities()->GetMinimumUniformAlignment());
581  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
582  auto buffer = context->CreateCommandBuffer();
583  if (!buffer) {
584  return false;
585  }
586  buffer->SetLabel("Playground Command Buffer");
587 
588  {
589  auto pass = buffer->CreateBlitPass();
590  if (!pass) {
591  return false;
592  }
593  pass->SetLabel("Playground Blit Pass");
594 
595  // Blit `bridge` to the top left corner of the texture.
596  pass->AddCopy(bridge, texture);
597 
598  if (!pass->EncodeCommands()) {
599  return false;
600  }
601  }
602 
603  {
604  auto pass = buffer->CreateRenderPass(render_target);
605  if (!pass) {
606  return false;
607  }
608  pass->SetLabel("Playground Render Pass");
609  {
610  pass->SetCommandLabel("Image");
611  pass->SetPipeline(mipmaps_pipeline);
612  pass->SetVertexBuffer(vertex_buffer);
613 
614  VS::FrameInfo frame_info;
615  EXPECT_EQ(pass->GetOrthographicTransform(),
616  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
617  frame_info.mvp = pass->GetOrthographicTransform() *
618  Matrix::MakeScale(GetContentScale());
619  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
620 
621  FS::FragInfo frag_info;
622  frag_info.lod = 0;
623  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
624 
625  auto sampler = context->GetSamplerLibrary()->GetSampler({});
626  FS::BindTex(*pass, texture, sampler);
627 
628  pass->Draw();
629  }
630  pass->EncodeCommands();
631  }
632 
633  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
634  return false;
635  }
636  host_buffer->Reset();
637  return true;
638  };
639  OpenPlaygroundHere(callback);
640 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), 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() [492/545]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateBoxPrimitive   
)

Definition at line 53 of file renderer_unittests.cc.

53  {
54  using VS = BoxFadeVertexShader;
55  using FS = BoxFadeFragmentShader;
56  auto context = GetContext();
57  ASSERT_TRUE(context);
58  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
59  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
60  ASSERT_TRUE(desc.has_value());
61  desc->SetSampleCount(SampleCount::kCount4);
62  desc->SetStencilAttachmentDescriptors(std::nullopt);
63 
64  // Vertex buffer.
65  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
66  vertex_builder.SetLabel("Box");
67  vertex_builder.AddVertices({
68  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
69  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
70  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
71  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
72  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
73  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
74  });
75  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
76  auto boston = CreateTextureForFixture("boston.jpg");
77  ASSERT_TRUE(bridge && boston);
78  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
79  ASSERT_TRUE(sampler);
80 
81  auto host_buffer = HostBuffer::Create(
82  context->GetResourceAllocator(), context->GetIdleWaiter(),
83  context->GetCapabilities()->GetMinimumUniformAlignment());
84  SinglePassCallback callback = [&](RenderPass& pass) {
85  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
86  static bool wireframe;
87  ImGui::Checkbox("Wireframe", &wireframe);
88  ImGui::End();
89 
90  desc->SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
91  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
92 
93  assert(pipeline && pipeline->IsValid());
94 
95  pass.SetCommandLabel("Box");
96  pass.SetPipeline(pipeline);
97  pass.SetVertexBuffer(
98  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()));
99 
100  VS::UniformBuffer uniforms;
101  EXPECT_EQ(pass.GetOrthographicTransform(),
102  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
103  uniforms.mvp =
104  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
105  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
106 
107  FS::FrameInfo frame_info;
108  frame_info.current_time = GetSecondsElapsed();
109  frame_info.cursor_position = GetCursorPosition();
110  frame_info.window_size.x = GetWindowSize().width;
111  frame_info.window_size.y = GetWindowSize().height;
112 
113  FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
114  FS::BindContents1(pass, boston, sampler);
115  FS::BindContents2(pass, bridge, sampler);
116 
117  host_buffer->Reset();
118  return pass.Draw().ok();
119  };
120  OpenPlaygroundHere(callback);
121 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), 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() [493/545]

impeller::testing::TEST_P ( RendererTest  ,
CanGenerateMipmaps   
)

Definition at line 773 of file renderer_unittests.cc.

773  {
774  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
775  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
776  }
777  auto context = GetContext();
778  ASSERT_TRUE(context);
779 
780  using VS = MipmapsVertexShader;
781  using FS = MipmapsFragmentShader;
782  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
783  ASSERT_TRUE(desc.has_value());
784  desc->SetSampleCount(SampleCount::kCount4);
785  desc->SetStencilAttachmentDescriptors(std::nullopt);
786  auto mipmaps_pipeline =
787  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
788  ASSERT_TRUE(mipmaps_pipeline);
789 
790  auto boston = CreateTextureForFixture("boston.jpg", true);
791  ASSERT_TRUE(boston);
792 
793  // Vertex buffer.
794  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
795  vertex_builder.SetLabel("Box");
796  auto size = Point(boston->GetSize());
797  vertex_builder.AddVertices({
798  {{0, 0}, {0.0, 0.0}}, // 1
799  {{size.x, 0}, {1.0, 0.0}}, // 2
800  {{size.x, size.y}, {1.0, 1.0}}, // 3
801  {{0, 0}, {0.0, 0.0}}, // 1
802  {{size.x, size.y}, {1.0, 1.0}}, // 3
803  {{0, size.y}, {0.0, 1.0}}, // 4
804  });
805  auto vertex_buffer =
806  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
807  ASSERT_TRUE(vertex_buffer);
808 
809  bool first_frame = true;
810  auto host_buffer = HostBuffer::Create(
811  context->GetResourceAllocator(), context->GetIdleWaiter(),
812  context->GetCapabilities()->GetMinimumUniformAlignment());
813  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
814  const char* mip_filter_names[] = {"Base", "Nearest", "Linear"};
815  const MipFilter mip_filters[] = {MipFilter::kBase, MipFilter::kNearest,
816  MipFilter::kLinear};
817  const char* min_filter_names[] = {"Nearest", "Linear"};
818  const MinMagFilter min_filters[] = {MinMagFilter::kNearest,
819  MinMagFilter::kLinear};
820 
821  // UI state.
822  static int selected_mip_filter = 1;
823  static int selected_min_filter = 0;
824  static float lod = 4.5;
825 
826  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
827  ImGui::Combo("Mip filter", &selected_mip_filter, mip_filter_names,
828  sizeof(mip_filter_names) / sizeof(char*));
829  ImGui::Combo("Min filter", &selected_min_filter, min_filter_names,
830  sizeof(min_filter_names) / sizeof(char*));
831  ImGui::SliderFloat("LOD", &lod, 0, boston->GetMipCount() - 1);
832  ImGui::End();
833 
834  auto buffer = context->CreateCommandBuffer();
835  if (!buffer) {
836  return false;
837  }
838  buffer->SetLabel("Playground Command Buffer");
839 
840  if (first_frame) {
841  auto pass = buffer->CreateBlitPass();
842  if (!pass) {
843  return false;
844  }
845  pass->SetLabel("Playground Blit Pass");
846 
847  pass->GenerateMipmap(boston, "Boston Mipmap");
848 
849  pass->EncodeCommands();
850  }
851 
852  first_frame = false;
853 
854  {
855  auto pass = buffer->CreateRenderPass(render_target);
856  if (!pass) {
857  return false;
858  }
859  pass->SetLabel("Playground Render Pass");
860  {
861  pass->SetCommandLabel("Image LOD");
862  pass->SetPipeline(mipmaps_pipeline);
863  pass->SetVertexBuffer(vertex_buffer);
864 
865  VS::FrameInfo frame_info;
866  EXPECT_EQ(pass->GetOrthographicTransform(),
867  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
868  frame_info.mvp = pass->GetOrthographicTransform() *
869  Matrix::MakeScale(GetContentScale());
870  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
871 
872  FS::FragInfo frag_info;
873  frag_info.lod = lod;
874  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
875 
876  SamplerDescriptor sampler_desc;
877  sampler_desc.mip_filter = mip_filters[selected_mip_filter];
878  sampler_desc.min_filter = min_filters[selected_min_filter];
879  raw_ptr<const Sampler> sampler =
880  context->GetSamplerLibrary()->GetSampler(sampler_desc);
881  FS::BindTex(*pass, boston, sampler);
882 
883  pass->Draw();
884  }
885  pass->EncodeCommands();
886  }
887 
888  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
889  return false;
890  }
891  host_buffer->Reset();
892  return true;
893  };
894  OpenPlaygroundHere(callback);
895 }
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::HostBuffer::Create(), 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() [494/545]

impeller::testing::TEST_P ( RendererTest  ,
CanLookupRenderTargetProperties   
)

Definition at line 1378 of file renderer_unittests.cc.

1378  {
1379  auto context = GetContext();
1380  auto cmd_buffer = context->CreateCommandBuffer();
1381  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1382  GetContext()->GetResourceAllocator());
1383 
1384  auto render_target = render_target_cache->CreateOffscreen(
1385  *context, {100, 100}, /*mip_count=*/1);
1386  auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1387 
1388  EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1389  EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1390  render_target.GetRenderTargetPixelFormat());
1391  EXPECT_EQ(render_pass->HasStencilAttachment(),
1392  render_target.GetStencilAttachment().has_value());
1393  EXPECT_EQ(render_pass->GetRenderTargetSize(),
1394  render_target.GetRenderTargetSize());
1395  render_pass->EncodeCommands();
1396 }

◆ TEST_P() [495/545]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderInstanced   
)

Definition at line 471 of file renderer_unittests.cc.

471  {
472  if (GetParam() == PlaygroundBackend::kOpenGLES) {
473  GTEST_SKIP() << "Instancing is not supported on OpenGL.";
474  }
475  using VS = InstancedDrawVertexShader;
476  using FS = InstancedDrawFragmentShader;
477 
478  VertexBufferBuilder<VS::PerVertexData> builder;
479  builder.AddVertices({
480  VS::PerVertexData{Point{10, 10}},
481  VS::PerVertexData{Point{10, 110}},
482  VS::PerVertexData{Point{110, 10}},
483  VS::PerVertexData{Point{10, 110}},
484  VS::PerVertexData{Point{110, 10}},
485  VS::PerVertexData{Point{110, 110}},
486  });
487 
488  ASSERT_NE(GetContext(), nullptr);
489  auto pipeline =
490  GetContext()
491  ->GetPipelineLibrary()
492  ->GetPipeline(PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(
493  *GetContext())
494  ->SetSampleCount(SampleCount::kCount4)
495  .SetStencilAttachmentDescriptors(std::nullopt))
496 
497  .Get();
498  ASSERT_TRUE(pipeline && pipeline->IsValid());
499 
500  static constexpr size_t kInstancesCount = 5u;
501  VS::InstanceInfo<kInstancesCount> instances;
502  for (size_t i = 0; i < kInstancesCount; i++) {
503  instances.colors[i] = Color::Random();
504  }
505 
506  auto host_buffer = HostBuffer::Create(
507  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
508  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
509  ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
510  pass.SetPipeline(pipeline);
511  pass.SetCommandLabel("InstancedDraw");
512 
513  VS::FrameInfo frame_info;
514  EXPECT_EQ(pass.GetOrthographicTransform(),
515  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
516  frame_info.mvp =
517  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
518  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
519  VS::BindInstanceInfo(pass, host_buffer->EmplaceStorageBuffer(instances));
520  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
521 
522  pass.SetInstanceCount(kInstancesCount);
523  pass.Draw();
524 
525  host_buffer->Reset();
526  return true;
527  }));
528 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), 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() [496/545]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderMultiplePrimitives   
)

Definition at line 293 of file renderer_unittests.cc.

293  {
294  using VS = BoxFadeVertexShader;
295  using FS = BoxFadeFragmentShader;
296  auto context = GetContext();
297  ASSERT_TRUE(context);
298  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
299  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
300  ASSERT_TRUE(desc.has_value());
301  desc->SetSampleCount(SampleCount::kCount4);
302  desc->SetStencilAttachmentDescriptors(std::nullopt);
303  auto box_pipeline =
304  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
305  ASSERT_TRUE(box_pipeline);
306 
307  // Vertex buffer.
308  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
309  vertex_builder.SetLabel("Box");
310  vertex_builder.AddVertices({
311  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
312  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
313  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
314  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
315  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
316  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
317  });
318  auto vertex_buffer =
319  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
320  ASSERT_TRUE(vertex_buffer);
321 
322  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
323  auto boston = CreateTextureForFixture("boston.jpg");
324  ASSERT_TRUE(bridge && boston);
325  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
326  ASSERT_TRUE(sampler);
327 
328  auto host_buffer = HostBuffer::Create(
329  context->GetResourceAllocator(), context->GetIdleWaiter(),
330  context->GetCapabilities()->GetMinimumUniformAlignment());
331  SinglePassCallback callback = [&](RenderPass& pass) {
332  for (size_t i = 0; i < 1; i++) {
333  for (size_t j = 0; j < 1; j++) {
334  pass.SetCommandLabel("Box");
335  pass.SetPipeline(box_pipeline);
336  pass.SetVertexBuffer(vertex_buffer);
337 
338  FS::FrameInfo frame_info;
339  frame_info.current_time = GetSecondsElapsed();
340  frame_info.cursor_position = GetCursorPosition();
341  frame_info.window_size.x = GetWindowSize().width;
342  frame_info.window_size.y = GetWindowSize().height;
343 
344  FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
345  FS::BindContents1(pass, boston, sampler);
346  FS::BindContents2(pass, bridge, sampler);
347 
348  VS::UniformBuffer uniforms;
349  EXPECT_EQ(pass.GetOrthographicTransform(),
350  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
351  uniforms.mvp = pass.GetOrthographicTransform() *
352  Matrix::MakeScale(GetContentScale()) *
353  Matrix::MakeTranslation({i * 50.0f, j * 50.0f, 0.0f});
354  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
355  if (!pass.Draw().ok()) {
356  return false;
357  }
358  }
359  }
360 
361  host_buffer->Reset();
362  return true;
363  };
364  OpenPlaygroundHere(callback);
365 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [497/545]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderPerspectiveCube   
)

Definition at line 180 of file renderer_unittests.cc.

180  {
181  using VS = ColorsVertexShader;
182  using FS = ColorsFragmentShader;
183  auto context = GetContext();
184  ASSERT_TRUE(context);
185  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
186  ASSERT_TRUE(desc.has_value());
187  desc->SetCullMode(CullMode::kBackFace);
188  desc->SetWindingOrder(WindingOrder::kCounterClockwise);
189  desc->SetSampleCount(SampleCount::kCount4);
190  desc->ClearStencilAttachments();
191 
192  // Setup the vertex layout to take two bindings. The first for positions and
193  // the second for colors.
194  auto vertex_desc = std::make_shared<VertexDescriptor>();
195  ShaderStageIOSlot position_slot = VS::kInputPosition;
196  ShaderStageIOSlot color_slot = VS::kInputColor;
197  position_slot.binding = 0;
198  position_slot.offset = 0;
199  color_slot.binding = 1;
200  color_slot.offset = 0;
201  const std::vector<ShaderStageIOSlot> io_slots = {position_slot, color_slot};
202  const std::vector<ShaderStageBufferLayout> layouts = {
203  ShaderStageBufferLayout{.stride = 12u, .binding = 0},
204  ShaderStageBufferLayout{.stride = 16u, .binding = 1}};
205  vertex_desc->RegisterDescriptorSetLayouts(VS::kDescriptorSetLayouts);
206  vertex_desc->RegisterDescriptorSetLayouts(FS::kDescriptorSetLayouts);
207  vertex_desc->SetStageInputs(io_slots, layouts);
208  desc->SetVertexDescriptor(std::move(vertex_desc));
209  auto pipeline =
210  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
211  ASSERT_TRUE(pipeline);
212 
213  struct Cube {
214  Vector3 positions[8] = {
215  // -Z
216  {-1, -1, -1},
217  {1, -1, -1},
218  {1, 1, -1},
219  {-1, 1, -1},
220  // +Z
221  {-1, -1, 1},
222  {1, -1, 1},
223  {1, 1, 1},
224  {-1, 1, 1},
225  };
226  Color colors[8] = {
227  Color::Red(), Color::Yellow(), Color::Green(), Color::Blue(),
228  Color::Green(), Color::Blue(), Color::Red(), Color::Yellow(),
229  };
230  uint16_t indices[36] = {
231  1, 5, 2, 2, 5, 6, // +X
232  4, 0, 7, 7, 0, 3, // -X
233  4, 5, 0, 0, 5, 1, // +Y
234  3, 2, 7, 7, 2, 6, // -Y
235  5, 4, 6, 6, 4, 7, // +Z
236  0, 1, 3, 3, 1, 2, // -Z
237  };
238  } cube;
239 
240  auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
241  reinterpret_cast<uint8_t*>(&cube), sizeof(cube));
242 
243  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
244  ASSERT_TRUE(sampler);
245 
246  Vector3 euler_angles;
247  auto host_buffer = HostBuffer::Create(
248  context->GetResourceAllocator(), context->GetIdleWaiter(),
249  context->GetCapabilities()->GetMinimumUniformAlignment());
250  SinglePassCallback callback = [&](RenderPass& pass) {
251  static Degrees fov_y(60);
252  static Scalar distance = 10;
253 
254  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
255  ImGui::SliderFloat("Field of view", &fov_y.degrees, 0, 180);
256  ImGui::SliderFloat("Camera distance", &distance, 0, 30);
257  ImGui::End();
258 
259  pass.SetCommandLabel("Perspective Cube");
260  pass.SetPipeline(pipeline);
261 
262  std::array<BufferView, 2> vertex_buffers = {
263  BufferView(device_buffer,
264  Range(offsetof(Cube, positions), sizeof(Cube::positions))),
265  BufferView(device_buffer,
266  Range(offsetof(Cube, colors), sizeof(Cube::colors))),
267  };
268 
269  BufferView index_buffer(
270  device_buffer, Range(offsetof(Cube, indices), sizeof(Cube::indices)));
271  pass.SetVertexBuffer(vertex_buffers.data(), vertex_buffers.size());
272  pass.SetElementCount(36);
273  pass.SetIndexBuffer(index_buffer, IndexType::k16bit);
274 
275  VS::UniformBuffer uniforms;
276  Scalar time = GetSecondsElapsed();
277  euler_angles = Vector3(0.19 * time, 0.7 * time, 0.43 * time);
278 
279  uniforms.mvp =
280  Matrix::MakePerspective(fov_y, pass.GetRenderTargetSize(), 0, 10) *
281  Matrix::MakeTranslation({0, 0, distance}) *
282  Matrix::MakeRotationX(Radians(euler_angles.x)) *
283  Matrix::MakeRotationY(Radians(euler_angles.y)) *
284  Matrix::MakeRotationZ(Radians(euler_angles.z));
285  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
286 
287  host_buffer->Reset();
288  return pass.Draw().ok();
289  };
290  OpenPlaygroundHere(callback);
291 }

References impeller::ShaderStageIOSlot::binding, impeller::Color::Blue(), impeller::HostBuffer::Create(), 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() [498/545]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderToTexture   
)

Definition at line 367 of file renderer_unittests.cc.

367  {
368  using VS = BoxFadeVertexShader;
369  using FS = BoxFadeFragmentShader;
370  auto context = GetContext();
371  ASSERT_TRUE(context);
372  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
373  auto pipeline_desc =
374  BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
375  pipeline_desc->SetSampleCount(SampleCount::kCount1);
376  pipeline_desc->ClearDepthAttachment();
377  pipeline_desc->SetStencilPixelFormat(PixelFormat::kS8UInt);
378 
379  ASSERT_TRUE(pipeline_desc.has_value());
380  auto box_pipeline =
381  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
382  ASSERT_TRUE(box_pipeline);
383  auto host_buffer = HostBuffer::Create(
384  context->GetResourceAllocator(), context->GetIdleWaiter(),
385  context->GetCapabilities()->GetMinimumUniformAlignment());
386 
387  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
388  vertex_builder.SetLabel("Box");
389  vertex_builder.AddVertices({
390  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
391  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
392  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
393  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
394  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
395  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
396  });
397  auto vertex_buffer =
398  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
399  ASSERT_TRUE(vertex_buffer);
400 
401  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
402  auto boston = CreateTextureForFixture("boston.jpg");
403  ASSERT_TRUE(bridge && boston);
404  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
405  ASSERT_TRUE(sampler);
406 
407  std::shared_ptr<RenderPass> r2t_pass;
408  auto cmd_buffer = context->CreateCommandBuffer();
409  ASSERT_TRUE(cmd_buffer);
410  {
411  ColorAttachment color0;
412  color0.load_action = LoadAction::kClear;
413  color0.store_action = StoreAction::kStore;
414 
415  TextureDescriptor texture_descriptor;
416  ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u), nullptr);
417  texture_descriptor.format =
418  pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
419  texture_descriptor.storage_mode = StorageMode::kHostVisible;
420  texture_descriptor.size = {400, 400};
421  texture_descriptor.mip_count = 1u;
422  texture_descriptor.usage = TextureUsage::kRenderTarget;
423 
424  color0.texture =
425  context->GetResourceAllocator()->CreateTexture(texture_descriptor);
426 
427  ASSERT_TRUE(color0.IsValid());
428 
429  color0.texture->SetLabel("r2t_target");
430 
431  StencilAttachment stencil0;
432  stencil0.load_action = LoadAction::kClear;
433  stencil0.store_action = StoreAction::kDontCare;
434  TextureDescriptor stencil_texture_desc;
435  stencil_texture_desc.storage_mode = StorageMode::kDeviceTransient;
436  stencil_texture_desc.size = texture_descriptor.size;
437  stencil_texture_desc.format = PixelFormat::kS8UInt;
438  stencil_texture_desc.usage = TextureUsage::kRenderTarget;
439  stencil0.texture =
440  context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
441 
442  RenderTarget r2t_desc;
443  r2t_desc.SetColorAttachment(color0, 0u);
444  r2t_desc.SetStencilAttachment(stencil0);
445  r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
446  ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
447  }
448 
449  r2t_pass->SetCommandLabel("Box");
450  r2t_pass->SetPipeline(box_pipeline);
451  r2t_pass->SetVertexBuffer(vertex_buffer);
452 
453  FS::FrameInfo frame_info;
454  frame_info.current_time = GetSecondsElapsed();
455  frame_info.cursor_position = GetCursorPosition();
456  frame_info.window_size.x = GetWindowSize().width;
457  frame_info.window_size.y = GetWindowSize().height;
458 
459  FS::BindFrameInfo(*r2t_pass, host_buffer->EmplaceUniform(frame_info));
460  FS::BindContents1(*r2t_pass, boston, sampler);
461  FS::BindContents2(*r2t_pass, bridge, sampler);
462 
463  VS::UniformBuffer uniforms;
464  uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) *
465  Matrix::MakeTranslation({50.0f, 50.0f, 0.0f});
466  VS::BindUniformBuffer(*r2t_pass, host_buffer->EmplaceUniform(uniforms));
467  ASSERT_TRUE(r2t_pass->Draw().ok());
468  ASSERT_TRUE(r2t_pass->EncodeCommands());
469 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), 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() [499/545]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneThenSwizzleWithSubpasses   
)

Definition at line 1521 of file renderer_unittests.cc.

1521  {
1522  // Define shader types
1523  using TextureVS = TextureVertexShader;
1524  using TextureFS = TextureFragmentShader;
1525 
1526  using SwizzleVS = SepiaVertexShader;
1527  using SwizzleFS = SwizzleFragmentShader;
1528 
1529  using SepiaVS = SepiaVertexShader;
1530  using SepiaFS = SepiaFragmentShader;
1531 
1532  auto context = GetContext();
1533  ASSERT_TRUE(context);
1534 
1535  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1536  GTEST_SKIP() << "This test uses framebuffer fetch and the backend doesn't "
1537  "support it.";
1538  return;
1539  }
1540 
1541  // Create pipelines.
1542  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1543  auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1544  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1545 
1546  ASSERT_TRUE(texture_pipeline);
1547  ASSERT_TRUE(swizzle_pipeline);
1548  ASSERT_TRUE(sepia_pipeline);
1549 
1550  // Vertex buffer builders.
1551  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1552  texture_vtx_builder.AddVertices({
1553  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1554  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1555  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1556  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1557  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1558  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1559  });
1560 
1561  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1562  sepia_vtx_builder.AddVertices({
1563  {{100, 100, 0.0}}, // 1
1564  {{800, 100, 0.0}}, // 2
1565  {{800, 800, 0.0}}, // 3
1566  {{100, 100, 0.0}}, // 1
1567  {{800, 800, 0.0}}, // 3
1568  {{100, 800, 0.0}}, // 4
1569  });
1570 
1571  auto boston = CreateTextureForFixture("boston.jpg");
1572  ASSERT_TRUE(boston);
1573 
1574  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1575  ASSERT_TRUE(sampler);
1576 
1577  SinglePassCallback callback = [&](RenderPass& pass) {
1578  auto buffer = HostBuffer::Create(
1579  context->GetResourceAllocator(), context->GetIdleWaiter(),
1580  context->GetCapabilities()->GetMinimumUniformAlignment());
1581 
1582  // Draw the texture.
1583  {
1584  pass.SetPipeline(texture_pipeline);
1585  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1586  *context->GetResourceAllocator()));
1587  TextureVS::UniformBuffer uniforms;
1588  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1589  Matrix::MakeScale(GetContentScale());
1590  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1591  TextureFS::BindTextureContents(pass, boston, sampler);
1592  if (!pass.Draw().ok()) {
1593  return false;
1594  }
1595  }
1596 
1597  // Draw the sepia toner.
1598  {
1599  pass.SetPipeline(sepia_pipeline);
1600  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1601  *context->GetResourceAllocator()));
1602  SepiaVS::UniformBuffer uniforms;
1603  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1604  Matrix::MakeScale(GetContentScale());
1605  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1606  if (!pass.Draw().ok()) {
1607  return false;
1608  }
1609  }
1610 
1611  // Draw the swizzle.
1612  {
1613  pass.SetPipeline(swizzle_pipeline);
1614  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1615  *context->GetResourceAllocator()));
1616  SwizzleVS::UniformBuffer uniforms;
1617  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1618  Matrix::MakeScale(GetContentScale());
1619  SwizzleVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1620  if (!pass.Draw().ok()) {
1621  return false;
1622  }
1623  }
1624 
1625  return true;
1626  };
1627  OpenPlaygroundHere(callback);
1628 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [500/545]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneWithSubpasses   
)

Definition at line 1431 of file renderer_unittests.cc.

1431  {
1432  // Define shader types
1433  using TextureVS = TextureVertexShader;
1434  using TextureFS = TextureFragmentShader;
1435 
1436  using SepiaVS = SepiaVertexShader;
1437  using SepiaFS = SepiaFragmentShader;
1438 
1439  auto context = GetContext();
1440  ASSERT_TRUE(context);
1441 
1442  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1443  GTEST_SKIP() << "This test uses framebuffer fetch and the backend doesn't "
1444  "support it.";
1445  return;
1446  }
1447 
1448  // Create pipelines.
1449  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1450  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1451 
1452  ASSERT_TRUE(texture_pipeline);
1453  ASSERT_TRUE(sepia_pipeline);
1454 
1455  // Vertex buffer builders.
1456  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1457  texture_vtx_builder.AddVertices({
1458  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1459  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1460  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1461  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1462  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1463  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1464  });
1465 
1466  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1467  sepia_vtx_builder.AddVertices({
1468  {{100, 100, 0.0}}, // 1
1469  {{800, 100, 0.0}}, // 2
1470  {{800, 800, 0.0}}, // 3
1471  {{100, 100, 0.0}}, // 1
1472  {{800, 800, 0.0}}, // 3
1473  {{100, 800, 0.0}}, // 4
1474  });
1475 
1476  auto boston = CreateTextureForFixture("boston.jpg");
1477  ASSERT_TRUE(boston);
1478 
1479  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1480  ASSERT_TRUE(sampler);
1481 
1482  SinglePassCallback callback = [&](RenderPass& pass) {
1483  auto buffer = HostBuffer::Create(
1484  context->GetResourceAllocator(), context->GetIdleWaiter(),
1485  context->GetCapabilities()->GetMinimumUniformAlignment());
1486 
1487  // Draw the texture.
1488  {
1489  pass.SetPipeline(texture_pipeline);
1490  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1491  *context->GetResourceAllocator()));
1492  TextureVS::UniformBuffer uniforms;
1493  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1494  Matrix::MakeScale(GetContentScale());
1495  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1496  TextureFS::BindTextureContents(pass, boston, sampler);
1497  if (!pass.Draw().ok()) {
1498  return false;
1499  }
1500  }
1501 
1502  // Draw the sepia toner.
1503  {
1504  pass.SetPipeline(sepia_pipeline);
1505  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1506  *context->GetResourceAllocator()));
1507  SepiaVS::UniformBuffer uniforms;
1508  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1509  Matrix::MakeScale(GetContentScale());
1510  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1511  if (!pass.Draw().ok()) {
1512  return false;
1513  }
1514  }
1515 
1516  return true;
1517  };
1518  OpenPlaygroundHere(callback);
1519 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [501/545]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexBehavior   
)

Definition at line 1147 of file renderer_unittests.cc.

1147  {
1148  using VS = BoxFadeVertexShader;
1149 
1150  // Do not create any index buffer if no indices were provided.
1151  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1152  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::kNone);
1153 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::kNone.

◆ TEST_P() [502/545]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexSize   
)

Definition at line 1137 of file renderer_unittests.cc.

1137  {
1138  using VS = BoxFadeVertexShader;
1139 
1140  // Default to 16bit index buffer size, as this is a reasonable default and
1141  // supported on all backends without extensions.
1142  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1143  vertex_builder.AppendIndex(0u);
1144  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::k16bit);
1145 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::k16bit.

◆ TEST_P() [503/545]

impeller::testing::TEST_P ( RendererTest  ,
InactiveUniforms   
)

Definition at line 1088 of file renderer_unittests.cc.

1088  {
1089  using VS = InactiveUniformsVertexShader;
1090  using FS = InactiveUniformsFragmentShader;
1091 
1092  auto context = GetContext();
1093  auto pipeline_descriptor =
1094  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
1095  ASSERT_TRUE(pipeline_descriptor.has_value());
1096  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1097  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1098  auto pipeline =
1099  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1100  ASSERT_TRUE(pipeline && pipeline->IsValid());
1101 
1102  auto host_buffer = HostBuffer::Create(
1103  context->GetResourceAllocator(), context->GetIdleWaiter(),
1104  context->GetCapabilities()->GetMinimumUniformAlignment());
1105  SinglePassCallback callback = [&](RenderPass& pass) {
1106  auto size = pass.GetRenderTargetSize();
1107 
1108  pass.SetPipeline(pipeline);
1109  pass.SetCommandLabel("Inactive Uniform");
1110 
1111  VertexBufferBuilder<VS::PerVertexData> builder;
1112  builder.AddVertices({{Point()},
1113  {Point(0, size.height)},
1114  {Point(size.width, 0)},
1115  {Point(size.width, 0)},
1116  {Point(0, size.height)},
1117  {Point(size.width, size.height)}});
1118  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1119 
1120  VS::FrameInfo frame_info;
1121  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1122  frame_info.mvp =
1123  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1124  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1125 
1126  FS::FragInfo fs_uniform = {.unused_color = Color::Red(),
1127  .color = Color::Green()};
1128  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1129 
1130  pass.Draw().ok();
1131  host_buffer->Reset();
1132  return true;
1133  };
1134  OpenPlaygroundHere(callback);
1135 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), 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() [504/545]

impeller::testing::TEST_P ( RendererTest  ,
Planet   
)

Definition at line 961 of file renderer_unittests.cc.

961  {
962  using VS = PlanetVertexShader;
963  using FS = PlanetFragmentShader;
964 
965  auto context = GetContext();
966  auto pipeline_descriptor =
967  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
968  ASSERT_TRUE(pipeline_descriptor.has_value());
969  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
970  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
971  auto pipeline =
972  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
973  ASSERT_TRUE(pipeline && pipeline->IsValid());
974 
975  auto host_buffer = HostBuffer::Create(
976  context->GetResourceAllocator(), context->GetIdleWaiter(),
977  context->GetCapabilities()->GetMinimumUniformAlignment());
978 
979  SinglePassCallback callback = [&](RenderPass& pass) {
980  static Scalar speed = 0.1;
981  static Scalar planet_size = 550.0;
982  static bool show_normals = false;
983  static bool show_noise = false;
984  static Scalar seed_value = 42.0;
985 
986  auto size = pass.GetRenderTargetSize();
987 
988  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
989  ImGui::SliderFloat("Speed", &speed, 0.0, 10.0);
990  ImGui::SliderFloat("Planet Size", &planet_size, 0.1, 1000);
991  ImGui::Checkbox("Show Normals", &show_normals);
992  ImGui::Checkbox("Show Noise", &show_noise);
993  ImGui::InputFloat("Seed Value", &seed_value);
994  ImGui::End();
995 
996  pass.SetPipeline(pipeline);
997  pass.SetCommandLabel("Planet scene");
998  VertexBufferBuilder<VS::PerVertexData> builder;
999  builder.AddVertices({{Point()},
1000  {Point(0, size.height)},
1001  {Point(size.width, 0)},
1002  {Point(size.width, 0)},
1003  {Point(0, size.height)},
1004  {Point(size.width, size.height)}});
1005  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1006 
1007  VS::FrameInfo frame_info;
1008  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1009  frame_info.mvp = pass.GetOrthographicTransform();
1010  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1011 
1012  FS::FragInfo fs_uniform;
1013  fs_uniform.resolution = Point(size);
1014  fs_uniform.time = GetSecondsElapsed();
1015  fs_uniform.speed = speed;
1016  fs_uniform.planet_size = planet_size;
1017  fs_uniform.show_normals = show_normals ? 1.0 : 0.0;
1018  fs_uniform.show_noise = show_noise ? 1.0 : 0.0;
1019  fs_uniform.seed_value = seed_value;
1020  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1021 
1022  pass.Draw().ok();
1023  host_buffer->Reset();
1024  return true;
1025  };
1026  OpenPlaygroundHere(callback);
1027 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), and impeller::Matrix::MakeOrthographic().

◆ TEST_P() [505/545]

impeller::testing::TEST_P ( RendererTest  ,
RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat   
)

Definition at line 1398 of file renderer_unittests.cc.

1399  {
1400  auto context = GetContext();
1401  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1402  GetContext()->GetResourceAllocator());
1403 
1404  RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1405  *context, {100, 100}, /*mip_count=*/1);
1406  EXPECT_EQ(render_target.GetDepthAttachment()
1407  ->texture->GetTextureDescriptor()
1408  .format,
1409  GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1410 }

References impeller::RenderTarget::GetDepthAttachment().

◆ TEST_P() [506/545]

impeller::testing::TEST_P ( RendererTest  ,
StencilMask   
)

Definition at line 1225 of file renderer_unittests.cc.

1225  {
1226  using VS = BoxFadeVertexShader;
1227  using FS = BoxFadeFragmentShader;
1228  auto context = GetContext();
1229  ASSERT_TRUE(context);
1230  using BoxFadePipelineBuilder = PipelineBuilder<VS, FS>;
1231  auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1232  ASSERT_TRUE(desc.has_value());
1233 
1234  // Vertex buffer.
1235  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1236  vertex_builder.SetLabel("Box");
1237  vertex_builder.AddVertices({
1238  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1239  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1240  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1241  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1242  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1243  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1244  });
1245  auto vertex_buffer =
1246  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
1247  ASSERT_TRUE(vertex_buffer);
1248 
1249  desc->SetSampleCount(SampleCount::kCount4);
1250  desc->SetStencilAttachmentDescriptors(std::nullopt);
1251 
1252  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1253  auto boston = CreateTextureForFixture("boston.jpg");
1254  ASSERT_TRUE(bridge && boston);
1255  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
1256  ASSERT_TRUE(sampler);
1257 
1258  static bool mirror = false;
1259  static int stencil_reference_write = 0xFF;
1260  static int stencil_reference_read = 0x1;
1261  std::vector<uint8_t> stencil_contents;
1262  static int last_stencil_contents_reference_value = 0;
1263  static int current_front_compare =
1264  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1265  static int current_back_compare =
1266  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1267 
1268  auto host_buffer = HostBuffer::Create(
1269  context->GetResourceAllocator(), context->GetIdleWaiter(),
1270  context->GetCapabilities()->GetMinimumUniformAlignment());
1271  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
1272  auto buffer = context->CreateCommandBuffer();
1273  if (!buffer) {
1274  return false;
1275  }
1276  buffer->SetLabel("Playground Command Buffer");
1277 
1278  {
1279  // Configure the stencil attachment for the test.
1280  RenderTarget::AttachmentConfig stencil_config;
1281  stencil_config.load_action = LoadAction::kLoad;
1282  stencil_config.store_action = StoreAction::kDontCare;
1283  stencil_config.storage_mode = StorageMode::kHostVisible;
1284  render_target.SetupDepthStencilAttachments(
1285  *context, *context->GetResourceAllocator(),
1286  render_target.GetRenderTargetSize(), true, "stencil", stencil_config);
1287  // Fill the stencil buffer with an checkerboard pattern.
1288  const auto target_width = render_target.GetRenderTargetSize().width;
1289  const auto target_height = render_target.GetRenderTargetSize().height;
1290  const size_t target_size = target_width * target_height;
1291  if (stencil_contents.size() != target_size ||
1292  last_stencil_contents_reference_value != stencil_reference_write) {
1293  stencil_contents.resize(target_size);
1294  last_stencil_contents_reference_value = stencil_reference_write;
1295  for (int y = 0; y < target_height; y++) {
1296  for (int x = 0; x < target_width; x++) {
1297  const auto index = y * target_width + x;
1298  const auto kCheckSize = 64;
1299  const auto value =
1300  (((y / kCheckSize) + (x / kCheckSize)) % 2 == 0) *
1301  stencil_reference_write;
1302  stencil_contents[index] = value;
1303  }
1304  }
1305  }
1306  if (!render_target.GetStencilAttachment()->texture->SetContents(
1307  stencil_contents.data(), stencil_contents.size(), 0, false)) {
1308  VALIDATION_LOG << "Could not upload stencil contents to device memory";
1309  return false;
1310  }
1311  auto pass = buffer->CreateRenderPass(render_target);
1312  if (!pass) {
1313  return false;
1314  }
1315  pass->SetLabel("Stencil Buffer");
1316  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1317  ImGui::SliderInt("Stencil Write Value", &stencil_reference_write, 0,
1318  0xFF);
1319  ImGui::SliderInt("Stencil Compare Value", &stencil_reference_read, 0,
1320  0xFF);
1321  ImGui::Checkbox("Back face mode", &mirror);
1322  ImGui::ListBox("Front face compare function", &current_front_compare,
1323  CompareFunctionUI().labels(), CompareFunctionUI().size());
1324  ImGui::ListBox("Back face compare function", &current_back_compare,
1325  CompareFunctionUI().labels(), CompareFunctionUI().size());
1326  ImGui::End();
1327 
1328  StencilAttachmentDescriptor front;
1329  front.stencil_compare =
1330  CompareFunctionUI().FunctionOf(current_front_compare);
1331  StencilAttachmentDescriptor back;
1332  back.stencil_compare =
1333  CompareFunctionUI().FunctionOf(current_back_compare);
1334  desc->SetStencilAttachmentDescriptors(front, back);
1335  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1336 
1337  assert(pipeline && pipeline->IsValid());
1338 
1339  pass->SetCommandLabel("Box");
1340  pass->SetPipeline(pipeline);
1341  pass->SetStencilReference(stencil_reference_read);
1342  pass->SetVertexBuffer(vertex_buffer);
1343 
1344  VS::UniformBuffer uniforms;
1345  EXPECT_EQ(pass->GetOrthographicTransform(),
1346  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
1347  uniforms.mvp = pass->GetOrthographicTransform() *
1348  Matrix::MakeScale(GetContentScale());
1349  if (mirror) {
1350  uniforms.mvp = Matrix::MakeScale(Vector2(-1, 1)) * uniforms.mvp;
1351  }
1352  VS::BindUniformBuffer(*pass, host_buffer->EmplaceUniform(uniforms));
1353 
1354  FS::FrameInfo frame_info;
1355  frame_info.current_time = GetSecondsElapsed();
1356  frame_info.cursor_position = GetCursorPosition();
1357  frame_info.window_size.x = GetWindowSize().width;
1358  frame_info.window_size.y = GetWindowSize().height;
1359 
1360  FS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
1361  FS::BindContents1(*pass, boston, sampler);
1362  FS::BindContents2(*pass, bridge, sampler);
1363  if (!pass->Draw().ok()) {
1364  return false;
1365  }
1366  pass->EncodeCommands();
1367  }
1368 
1369  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1370  return false;
1371  }
1372  host_buffer->Reset();
1373  return true;
1374  };
1375  OpenPlaygroundHere(callback);
1376 }
CompareFunction FunctionOf(int index) const
int IndexOf(CompareFunction func) const
static const CompareFunctionUIData & CompareFunctionUI()

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), CompareFunctionUI(), impeller::HostBuffer::Create(), 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() [507/545]

impeller::testing::TEST_P ( RendererTest  ,
TheImpeller   
)

Definition at line 897 of file renderer_unittests.cc.

897  {
898  using VS = ImpellerVertexShader;
899  using FS = ImpellerFragmentShader;
900 
901  auto context = GetContext();
902  auto pipeline_descriptor =
903  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
904  ASSERT_TRUE(pipeline_descriptor.has_value());
905  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
906  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
907  auto pipeline =
908  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
909  ASSERT_TRUE(pipeline && pipeline->IsValid());
910 
911  auto blue_noise = CreateTextureForFixture("blue_noise.png");
912  SamplerDescriptor noise_sampler_desc;
913  noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
914  noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat;
915  raw_ptr<const Sampler> noise_sampler =
916  context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
917 
918  auto cube_map = CreateTextureCubeForFixture(
919  {"table_mountain_px.png", "table_mountain_nx.png",
920  "table_mountain_py.png", "table_mountain_ny.png",
921  "table_mountain_pz.png", "table_mountain_nz.png"});
922  raw_ptr<const Sampler> cube_map_sampler =
923  context->GetSamplerLibrary()->GetSampler({});
924  auto host_buffer = HostBuffer::Create(
925  context->GetResourceAllocator(), context->GetIdleWaiter(),
926  context->GetCapabilities()->GetMinimumUniformAlignment());
927 
928  SinglePassCallback callback = [&](RenderPass& pass) {
929  auto size = pass.GetRenderTargetSize();
930 
931  pass.SetPipeline(pipeline);
932  pass.SetCommandLabel("Impeller SDF scene");
933  VertexBufferBuilder<VS::PerVertexData> builder;
934  builder.AddVertices({{Point()},
935  {Point(0, size.height)},
936  {Point(size.width, 0)},
937  {Point(size.width, 0)},
938  {Point(0, size.height)},
939  {Point(size.width, size.height)}});
940  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
941 
942  VS::FrameInfo frame_info;
943  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
944  frame_info.mvp = pass.GetOrthographicTransform();
945  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
946 
947  FS::FragInfo fs_uniform;
948  fs_uniform.texture_size = Point(size);
949  fs_uniform.time = GetSecondsElapsed();
950  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
951  FS::BindBlueNoise(pass, blue_noise, noise_sampler);
952  FS::BindCubeMap(pass, cube_map, cube_map_sampler);
953 
954  pass.Draw().ok();
955  host_buffer->Reset();
956  return true;
957  };
958  OpenPlaygroundHere(callback);
959 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), 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() [508/545]

impeller::testing::TEST_P ( RendererTest  ,
VertexBufferBuilder   
)

Definition at line 1155 of file renderer_unittests.cc.

1155  {
1156  // Does not create index buffer if one is provided.
1157  using VS = BoxFadeVertexShader;
1158  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1159  vertex_builder.SetLabel("Box");
1160  vertex_builder.AddVertices({
1161  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1162  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1163  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1164  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1165  });
1166  vertex_builder.AppendIndex(0);
1167  vertex_builder.AppendIndex(1);
1168  vertex_builder.AppendIndex(2);
1169  vertex_builder.AppendIndex(1);
1170  vertex_builder.AppendIndex(2);
1171  vertex_builder.AppendIndex(3);
1172 
1173  ASSERT_EQ(vertex_builder.GetIndexCount(), 6u);
1174  ASSERT_EQ(vertex_builder.GetVertexCount(), 4u);
1175 }

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() [509/545]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachedTextureGetsNewAttachmentConfig   
)

Definition at line 122 of file render_target_cache_unittests.cc.

122  {
123  auto render_target_cache = RenderTargetCache(
124  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
125 
126  render_target_cache.Start();
127  RenderTarget::AttachmentConfig color_attachment_config =
128  RenderTarget::kDefaultColorAttachmentConfig;
129  RenderTarget target1 = render_target_cache.CreateOffscreen(
130  *GetContext(), {100, 100}, 1, "Offscreen1", color_attachment_config);
131  render_target_cache.End();
132 
133  render_target_cache.Start();
134  color_attachment_config.clear_color = Color::Red();
135  RenderTarget target2 = render_target_cache.CreateOffscreen(
136  *GetContext(), {100, 100}, 1, "Offscreen2", color_attachment_config);
137  render_target_cache.End();
138 
139  ColorAttachment color1 = target1.GetColorAttachment(0);
140  ColorAttachment color2 = target2.GetColorAttachment(0);
141  // The second color attachment should reuse the first attachment's texture
142  // but with attributes from the second AttachmentConfig.
143  EXPECT_EQ(color2.texture, color1.texture);
144  EXPECT_EQ(color2.clear_color, Color::Red());
145 }

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() [510/545]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachesUsedTexturesAcrossFrames   
)

Definition at line 52 of file render_target_cache_unittests.cc.

52  {
53  auto render_target_cache = RenderTargetCache(
54  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
55 
56  render_target_cache.Start();
57  // Create two render targets of the same exact size/shape. Both should be
58  // marked as used this frame, so the cached data set will contain two.
59  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
60  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
61 
62  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
63 
64  render_target_cache.End();
65  render_target_cache.Start();
66 
67  // Next frame, only create one texture. The set will still contain two,
68  // but one will be removed at the end of the frame.
69  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
70  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
71 
72  render_target_cache.End();
73  EXPECT_EQ(render_target_cache.CachedTextureCount(), 1u);
74 }

◆ TEST_P() [511/545]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachesUsedTexturesAcrossFramesWithKeepAlive   
)

Definition at line 76 of file render_target_cache_unittests.cc.

76  {
77  auto render_target_cache = RenderTargetCache(
78  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/3);
79 
80  render_target_cache.Start();
81  // Create two render targets of the same exact size/shape. Both should be
82  // marked as used this frame, so the cached data set will contain two.
83  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
84  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
85 
86  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
87 
88  render_target_cache.End();
89  render_target_cache.Start();
90 
91  // The unused texture is kept alive until the keep alive countdown
92  // reaches 0.
93  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
94 
95  for (auto i = 0; i < 3; i++) {
96  render_target_cache.Start();
97  render_target_cache.End();
98  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
99  }
100  // After the countdown has elapsed the texture is removed.
101  render_target_cache.Start();
102  render_target_cache.End();
103  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
104 }

◆ TEST_P() [512/545]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CreateWithEmptySize   
)

Definition at line 147 of file render_target_cache_unittests.cc.

147  {
148  auto render_target_cache = RenderTargetCache(
149  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
150 
151  render_target_cache.Start();
152  RenderTarget empty_target =
153  render_target_cache.CreateOffscreen(*GetContext(), {100, 0}, 1);
154  RenderTarget empty_target_msaa =
155  render_target_cache.CreateOffscreenMSAA(*GetContext(), {0, 0}, 1);
156  render_target_cache.End();
157 
158  {
159  ScopedValidationDisable disable_validation;
160  EXPECT_FALSE(empty_target.IsValid());
161  EXPECT_FALSE(empty_target_msaa.IsValid());
162  }
163 }

References impeller::RenderTarget::IsValid().

◆ TEST_P() [513/545]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
DoesNotPersistFailedAllocations   
)

Definition at line 106 of file render_target_cache_unittests.cc.

106  {
107  ScopedValidationDisable disable;
108  auto allocator = std::make_shared<TestAllocator>();
109  auto render_target_cache =
110  RenderTargetCache(allocator, /*keep_alive_frame_count=*/0);
111 
112  render_target_cache.Start();
113  allocator->should_fail = true;
114 
115  auto render_target =
116  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
117 
118  EXPECT_FALSE(render_target.IsValid());
119  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
120 }

◆ TEST_P() [514/545]

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() [515/545]

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() [516/545]

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() [517/545]

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() [518/545]

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() [519/545]

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() [520/545]

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() [521/545]

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() [522/545]

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() [523/545]

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> 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(), *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 &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() [524/545]

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> 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(), *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() [525/545]

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> 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(), *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() [526/545]

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> 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(), *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() [527/545]

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> 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(), *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() [528/545]

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> 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(), *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() [529/545]

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> 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(), *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() [530/545]

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() [531/545]

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 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(), *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 &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() [532/545]

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() [533/545]

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 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(), *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(), *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() [534/545]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecycledIfUnchanged   
)

Definition at line 262 of file typographer_unittests.cc.

262  {
263  auto 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(), *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(), *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() [535/545]

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 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(), *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(), *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() [536/545]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithLotsOfdUniqueGlyphSize   
)

Definition at line 212 of file typographer_unittests.cc.

212  {
213  auto 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  *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() [537/545]

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 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(), *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() [538/545]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsIgnoredForNonEmojiFonts   
)

Definition at line 337 of file typographer_unittests.cc.

337  {
338  auto 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(), *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() [539/545]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsPartOfCacheKey   
)

Definition at line 301 of file typographer_unittests.cc.

301  {
302  auto 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(), *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() [540/545]

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 host_buffer = HostBuffer::Create(
641  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
642  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
643 
644  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *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(), *host_buffer,
666  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() [541/545]

impeller::testing::TEST_P ( TypographerTest  ,
LazyAtlasTracksColor   
)

Definition at line 120 of file typographer_unittests.cc.

120  {
121  auto 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(), *host_buffer, GlyphAtlas::Type::kColorBitmap);
154 
155  auto bitmap_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
156  *GetContext(), *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() [542/545]

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() [543/545]

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 host_buffer = HostBuffer::Create(
588  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
589  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
590 
591  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *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(), *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(), *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() [544/545]

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 host_buffer = HostBuffer::Create(
518  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
519  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
520 
521  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *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(), *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() [545/545]

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 host_buffer = HostBuffer::Create(
552  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
553  GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
554 
555  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *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(), *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 38 of file dl_unittests.cc.

38  {
39  return flutter::DlColor(Color::ToIColor(
40  Color(components[0], components[1], components[2], components[3])));
41 }

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 375 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.